Sketch out site content derived from README

This commit is contained in:
Wesley Moore 2024-03-08 21:57:12 +10:00
parent dacb4bfd47
commit b4cf16ab83
No known key found for this signature in database
10 changed files with 451 additions and 1 deletions

View file

@ -8,6 +8,9 @@ compile_sass = false
build_search_index = false build_search_index = false
generate_feed = true generate_feed = true
feed_filename = "index.xml"
theme = "juice"
[markdown] [markdown]
# Whether to do syntax highlighting # Whether to do syntax highlighting
@ -16,4 +19,12 @@ highlight_code = true
smart_punctuation = true smart_punctuation = true
[extra] [extra]
# Put all your custom variables here email = "wes@wezm.net"
author = "Wesley Moore"
juice_logo_name = "RSS Please"
juice_logo_path = "feed-icon.svg"
juice_extra_menu = [
{ title = "News", link = "/news/"},
{ title = "GitHub", link = "https://github.com/wezm/rsspls"},
]
repository_url = "https://github.com/wezm/rsspls"

58
content/_index.md Normal file
View file

@ -0,0 +1,58 @@
+++
title = "Home"
sort_by = "weight"
#paginate_by = 10
+++
<div align="center">
<strong>A small tool (<code>rsspls</code>) to generate RSS feeds from web pages that lack them.
It runs on BSD, Linux, macOS, Windows, and more.</strong>
</div>
<br>
<div align="center">
<a href="https://cirrus-ci.com/github/wezm/rsspls">
<img src="https://api.cirrus-ci.com/github/wezm/rsspls.svg" alt="Build Status"></a>
<a href="https://crates.io/crates/rsspls">
<img src="https://img.shields.io/crates/v/rsspls.svg" alt="Version">
</a>
<img src="https://img.shields.io/crates/l/rsspls.svg" alt="License">
</div>
<br>
`rsspls` generates RSS feeds from web pages. Example use cases:
* Create a feed for a blog that does not have one so that you will know when
there are new posts.
* Create a feed from the search results on real estate agent's website so that
you know when there are new listings—without having to check manually all the
time.
* Create a feed of the upcoming tour dates of your favourite band or DJ.
* Create a feed of the product page for a company, so you know when new
products are added.
The idea is that you will then subscribe to the generated feeds in your feed
reader. This will typically require the feeds to be hosted via a web server.
Credits
-------
* [RSS feed icon](http://www.feedicons.com/) by The Mozilla Foundation
Licence
-------
This project is dual licenced under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/wezm/rsspls/blob/master/LICENSE-APACHE))
- MIT license ([LICENSE-MIT](https://github.com/wezm/rsspls/blob/master/LICENSE-MIT))
at your option.
[rustup]: https://www.rust-lang.org/tools/install
[toml]: https://toml.io/
[selectors]: https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors
[cron]: https://en.wikipedia.org/wiki/Cron
[timers]: https://wiki.archlinux.org/title/Systemd/Timers

183
content/documentation.md Normal file
View file

@ -0,0 +1,183 @@
+++
title = "Documentation"
description = "Documentation"
weight = 2
+++
### Configuration
Unless specified via the `--config` command line option `rsspls` reads its
configuration from one of the following paths:
* UNIX-like systems:
* `$XDG_CONFIG_HOME/rsspls/feeds.toml`
* `~/.config/rsspls/feeds.toml` if `XDG_CONFIG_HOME` is unset.
* Windows:
* `C:\Users\You\AppData\Roaming\rsspls\feeds.toml`
The configuration file is in [TOML][toml] format.
The parts of the page to extract for the feed are specified using [CSS
selectors][selectors].
#### Annotated Sample Configuration
The sample file below demonstrates all the parts of the configuration.
```toml
# The configuration must start with the [rsspls] section
[rsspls]
# Optional output directory to write the feeds to. If not specified it must be supplied via
# the --output command line option.
output = "/tmp"
# Optional proxy address. If specified, all requests will be routed through it.
# The address needs to be in the format: protocol://ip_address:port
# The supported protocols are: http, https, socks and socks5h.
# It can also be specified as environment variable `http_proxy` or `HTTPS_PROXY`.
# The config file takes precedence, then the env vars in the above order.
# proxy = socks5://10.64.0.1:1080
# Next is the array of feeds, each one starts with [[feed]]
[[feed]]
# The title of the channel in the feed
title = "My Great RSS Feed"
# The output filename without the output directory to write this feed to.
# Note: this is a filename only, not a path. It should not contain slashes.
filename = "wezm.rss"
# Optional User-Agent header to be set for the HTTP request.
# user_agent = "Mozilla/5.0"
# The configuration for the feed
[feed.config]
# The URL of the web page to generate the feed from.
url = "https://www.wezm.net/"
# A CSS selector to select elements on the page that represent items in the feed.
item = "article"
# A CSS selector relative to `item` to an element that will supply the title for the item.
heading = "h3"
# A CSS selector relative to `item` to an element that will supply the link for the item.
# Note: This element must have a `href` attribute.
# Note: If not supplied rsspls will attempt to use the heading selector for link for backwards
# compatibility with earlier versions. A message will be emitted in this case.
link = "h3 a"
# Optional CSS selector relative to `item` that will supply the content of the RSS item.
summary = ".post-body"
# Optional CSS selector relative to `item` that supplies media content (audio, video, image)
# to be added as an RSS enclosure.
# Note: The media URL must be given by the `src` or `href` attribute of the selected element.
# Note: Currently if the item does not match the media selector then it will be skipped.
# media = "figure img"
# Optional CSS selector relative to `item` that supples the publication date of the RSS item.
date = "time"
# Alternatively for more control `date` can be specified as a table:
# [feed.config.date]
# selector = "time"
# # Optional type of value being parsed.
# # Defaults to DateTime, can also be Date if you're parsing a value without a time.
# type = "Date"
# # format of the date to parse. See the following for the syntax
# # https://time-rs.github.io/book/api/format-description.html
# format = "[day padding:none]/[month padding:none]/[year]" # will parse 1/2/1934 style dates
# A second example feed
[[feed]]
title = "Example Site"
filename = "example.rss"
[feed.config]
url = "https://example.com/"
item = "div"
heading = "a"
```
The first example above (for my blog WezM.net) matches HTML that looks like this:
```html
<section class="posts-section">
<h2>Recent Posts</h2>
<article id="garage-door-monitor">
<h3><a href="https://www.wezm.net/v2/posts/2022/garage-door-monitor/">Monitoring My Garage Door With a Raspberry Pi, Rust, and a 13Mb Linux System</a></h3>
<div class="post-metadata">
<div class="date-published">
<time datetime="2022-04-20T06:38:27+10:00">20 April 2022</time>
</div>
</div>
<div class="post-body">
<p>Ive accidentally left our garage door open a few times. To combat this I built
a monitor that sends an alert via Mattermost when the door has been left open
for more than 5 minutes. This turned out to be a super fun project. I used
parts on hand as much as possible, implemented the monitoring application in
Rust, and then built a stripped down Linux image to run it.
</p>
</div>
<a href="https://www.wezm.net/v2/posts/2022/garage-door-monitor/">Continue Reading →</a>
</article>
<article id="monospace-kobo-ereader">
<!-- another article -->
</article>
<!-- more articles -->
<a href="https://www.wezm.net/v2/posts/">View more posts →</a>
</section>
```
#### More Detail on Date Handling
The `date` key in the configuration can be a string or a table. If it's a
string then it's used as selector to find the element containing the date and
`rsspls` will attempt to automatically parse the value. If automatic parsing
fails you can manually specify the format using the table form of `date`:
```toml
[feed.config.date]
selector = "time" # required
type = "Date"
format = "[day padding:none]/[month padding:none]/[year]"
```
* `type` is `Date` when you want to parse just a date. Use `DateTime` if you're
parsing a date and time with the format. Defaults to `DateTime`.
* `format` is a format description using the syntax described on this page:
<https://time-rs.github.io/book/api/format-description.html>.
If the element matched by the `date` selector is a `<time>` element then
`rsspls` will first try to parse the value in the `datetime` attribute if
present. If the attribute is missing or the element is not a `time` element
then `rsspls` will use the supplied format or attempt automatic parsing of the
text content of the element.
### Hosting
It is expected that `rsspls` will be run on a web server that is serving the
directory the feeds are written to. `rsspls` just generates the feeds, it's not
a server. In order to have the feeds update you will need to arrange for
`rsspls` to be run periodically. You might do this with [cron], [systemd
timers][timers], or the Windows equivalent.
### Caveats
`rsspls` just fetches and parses the HTML of the web page you specify. It does
not run JavaScript. If the website is entirely generated by JavaScript (such as
Twitter) then `rsspls` will not work.
### Caching
When websites respond with cache headers `rsspls` will make a conditional
request on subsequent runs and will not regenerate the feed if the server
responds with 304 Not Modified. Cache data is stored in
`$XDG_CACHE_HOME/rsspls`, which defaults to `~/.cache/rsspls` on UNIX-like
systems or `C:\Users\You\AppData\Local\rsspls` on Windows.

18
content/feed-icon.svg Executable file
View file

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="128px" height="128px" id="RSSicon" viewBox="0 0 256 256">
<defs>
<linearGradient x1="0.085" y1="0.085" x2="0.915" y2="0.915" id="RSSg">
<stop offset="0.0" stop-color="#E3702D"/><stop offset="0.1071" stop-color="#EA7D31"/>
<stop offset="0.3503" stop-color="#F69537"/><stop offset="0.5" stop-color="#FB9E3A"/>
<stop offset="0.7016" stop-color="#EA7C31"/><stop offset="0.8866" stop-color="#DE642B"/>
<stop offset="1.0" stop-color="#D95B29"/>
</linearGradient>
</defs>
<rect width="256" height="256" rx="55" ry="55" x="0" y="0" fill="#CC5D15"/>
<rect width="246" height="246" rx="50" ry="50" x="5" y="5" fill="#F49C52"/>
<rect width="236" height="236" rx="47" ry="47" x="10" y="10" fill="url(#RSSg)"/>
<circle cx="68" cy="189" r="24" fill="#FFF"/>
<path d="M160 213h-34a82 82 0 0 0 -82 -82v-34a116 116 0 0 1 116 116z" fill="#FFF"/>
<path d="M184 213A140 140 0 0 0 44 73 V 38a175 175 0 0 1 175 175z" fill="#FFF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

52
content/install.md Normal file
View file

@ -0,0 +1,52 @@
+++
title = "Install"
description = "Install"
weight = 1
+++
`rsspls` can be installed via one of the following methods:
* [Package Manager](#package-manager)
* [Pre-compiled Binary](#pre-compiled-binary)
* [Build From Source](#build-from-source)
### Package Manager
`rsspls` is packaged in these package managers:
* AUR: [rsspls](https://aur.archlinux.org/packages/rsspls)
* Homebrew: `brew install wezm/taps/rsspls`
* MacPorts: [rsspls](https://ports.macports.org/port/rsspls/summary/)
### Pre-compiled Binary
Pre-compiled binaries are available for a number of platforms.
They require no additional dependencies on your computer.
* [FreeBSD 13 amd64](https://releases.wezm.net/rsspls/0.8.1/rsspls-0.8.1-amd64-unknown-freebsd.tar.gz)
* [Linux x86\_64](https://releases.wezm.net/rsspls/0.8.1/rsspls-0.8.1-x86_64-unknown-linux-musl.tar.gz)
* [MacOS Universal](https://releases.wezm.net/rsspls/0.8.1/rsspls-0.8.1-universal-apple-darwin.tar.gz)
* [Windows x86\_64](https://releases.wezm.net/rsspls/0.8.1/rsspls-0.8.1-x86_64-pc-windows-msvc.zip)
Example to download and extract a binary:
curl https://releases.wezm.net/rsspls/0.7.1/rsspls-0.7.1-x86_64-unknown-linux-musl.tar.gz | tar zxf -
This will result in the `rsspls` binary in the current directory.
Build From Source
-----------------
**Minimum Supported Rust Version:** 1.70.0
`rsspls` is implemented in Rust. See the Rust website for [instructions on
installing the toolchain][rustup].
### From Git Checkout or Release Tarball
Build the binary with `cargo build --release --locked`. The binary will be in
`target/release/rsspls`.
### From crates.io
`cargo install rsspls`

9
content/news/_index.md Normal file
View file

@ -0,0 +1,9 @@
+++
title = "News"
description = "News"
sort_by = "date"
paginate_by = 10
weight = 3
+++
News

21
content/news/hello.md Normal file
View file

@ -0,0 +1,21 @@
+++
title = "Version 0.8.1 and Website"
date = 2024-03-08T21:30:39+10:00
#[extra]
#updated = 2024-02-20T22:57:15+10:00
+++
RSS Please now has it's own website.
Of course it has an RSS feed: <https://rsspls.7bit.org/index.xml>
## Version 0.8.1
Many thanks to @Lcchy for all the new features in this release:
* Add per feed user-agent option to config file https://github.com/wezm/rsspls/pull/27
* Add a media selector to include as RSS enclosure https://github.com/wezm/rsspls/pull/29
* Add option to proxy requests https://github.com/wezm/rsspls/pull/32
* Recover from item parsing error and continue https://github.com/wezm/rsspls/pull/35
**Full Changelog**: https://github.com/wezm/rsspls/compare/0.7.1...0.8.1

51
templates/index.html Normal file
View file

@ -0,0 +1,51 @@
{% extends "juice/templates/index.html" %}
{% block hero %}
{# <script async defer src="https://buttons.github.io/buttons.js"></script> #}
<section class="text-center">
<h1 class="heading-text" style="font-size: 50px">
Generate RSS feeds from web pages
</h1>
<h3 class="title-text">
<b>Juice</b> is an intuitive, elegant, and lightweight Zola theme for product websites.
</h3>
{# <div> #}
{# <a class="github-button" href="https://github.com/huhu/juice" data-size="large" data-show-count="true" #}
{# aria-label="Star huhu/juice on GitHub">Star</a> #}
{# <a class="github-button" href="https://github.com/huhu/juice/fork" data-size="large" #}
{# data-show-count="true" aria-label="Fork huhu/juice on GitHub">Fork</a> #}
{# </div> #}
</section>
<img class="hero-image" style="width: 50%" src="{{ get_url(path="juice.svg") }}">
<div class="explore-more text"
onclick="document.getElementById('features').scrollIntoView({behavior: 'smooth'})">
Explore More ⇩
</div>
<style>
.hero section {
padding: 0 5rem;
}
@media screen and (max-width: 768px) {
.hero section {
padding: 0 2rem;
}
.hero-image {
display: none
}
}
</style>
{% endblock hero %}
{% block head %}
<link rel="alternate" type="application/rss+xml" title="RSS" href="{{ get_url(path="index.xml", trailing_slash=false) }}">
{% endblock %}
{% block footer %}
<footer>
<small class="subtext">
© 2024 <a href="https://www.wezm.net/">Wesley Moore</a>
</small>
</footer>
{% endblock %}

31
templates/index.xml Normal file
View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
{% if term %}
<title>{{ config.title }} {{ term.name }}</title>
{% else %}
<title>{{ config.title }}</title>
{% endif %}
<link>{{ config.base_url }}</link>
<description>{{ config.description }}</description>
<generator>Zola</generator>
<language>{{ config.default_language }}</language>
<managingEditor>{{ config.extra.email }} ({{ config.extra.author }})</managingEditor>
<webMaster>{{ config.extra.email }} ({{ config.extra.author }})</webMaster>
<atom:link href="{{ feed_url }}" rel="self" type="application/rss+xml"/>
<lastBuildDate>{{ last_updated | date(format="%a, %d %b %Y %H:%M:%S %z") }}</lastBuildDate>
{% for page in pages %}
<item>
<title>{{ page.title }}</title>
<pubDate>{{ page.date | date(format="%a, %d %b %Y %H:%M:%S %z") }}</pubDate>
<atom:published>{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}</atom:published>
{% if page.extra.updated %}<atom:updated>{{ page.extra.updated | date(format="%Y-%m-%dT%H:%M:%S%:z") }}</atom:updated>{% endif %}
<author>{{ config.extra.email }} ({{ config.extra.author }})</author>
<link>{{ page.permalink }}</link>
<guid>{{ page.permalink }}</guid>
<description>{{ page.content }}</description>
</item>
{% endfor %}
</channel>
</rss>

16
templates/section.html Normal file
View file

@ -0,0 +1,16 @@
{% import "_macros.html" as macros %}
{% extends "index.html" %}
{% block title %}{{ section.title }} | {{ super() }} {% endblock title %}
{% block header %}
<header class="box-shadow">
{{ macros::render_header() }}
</header>
{% endblock header %}
{% block content %}
<div class="heading-text">{{ section.description }}</div>
{{ section.content | safe }}
{% endblock content %}