obsolete.computer

feedfetcher/README.md

File Type: text/plain


# feedfetcher

Reads a list of feeds and writes an HTML page of the five most recent entries from each one.

## Usage

```bash
./feedfetcher.py
./feedfetcher.py --feeds feeds.txt --output feeds.html
./feedfetcher.py --items 8 --new-interval 3d --copy user@host:~/feeds/
./feedfetcher.py --from-cache --open

With no arguments it reads feeds.txt and writes feeds.html to $XDG_CACHE_HOME/feedfetcher/, or ~/.cache/feedfetcher/ when XDG_CACHE_HOME is unset. The fetched-feed cache is feeds-cache.json in that same directory. --from-cache rebuilds the page from the cache without fetching. --copy copies the written HTML file, and --open opens it in the default browser.

Option Default
--feeds FILE feeds.txt Feed list to read
--output FILE $XDG_CACHE_HOME/feedfetcher/feeds.html HTML file to write. Without XDG_CACHE_HOME, this is ~/.cache/feedfetcher/feeds.html
--copy DEST n/a Also copy the written HTML here. A destination containing : is sent with scp, the same way rsync tells a remote path from a local one. A missing local directory is skipped.
--no-copy Write the HTML and do not copy it
--items N 5 Entries to keep from each feed
--new-interval DURATION 7d Mark entries newer than this as NEW. 7d, 12h, or 30m
--cache FILE $XDG_CACHE_HOME/feedfetcher/feeds-cache.json JSON file of the fetched feeds. Without XDG_CACHE_HOME, this is ~/.cache/feedfetcher/feeds-cache.json
--from-cache Build the page from the cache without fetching
--open Open the generated HTML file in the default browser

A feed that fails to refresh is rendered from its cached copy when one exists, and that copy stays in the cache.

Needs Python 3. No extra packages. Copying to a remote path needs scp. The page shell, styles, and script are page.html, page.css, and page.js next to the script; they are read when the HTML file is written.

Feed list

feeds.txt is one feed URL per line.

===Retro Tech===

###The 8-bit Guy
https://www.youtube.com/feeds/videos.xml?channel_id=UC8uT9cgJorJPWu7ITLGo9Ww
  • A line wrapped in === starts a category. It covers every feed until the next category line, and becomes a heading and a filter chip on the page.
  • Lines starting with # are comments and are skipped. ###Name notes above a URL are comments too; the channel name shown on the page comes from the feed.
  • Blank lines are skipped.
  • YouTube Shorts are left out. If a channel feed is mostly Shorts, the long-form uploads playlist is used so the page can still show five videos.
  • A semicolon after the URL adds a title filter: https://example.com/feed;interview keeps entries whose titles contain that text. Quote the filter to keep spaces, as in ;"live in". A filter starting with ! excludes matching titles instead. Filtered entries are skipped the same way Shorts are, so the page still shows five entries when the feed lists enough matches. A YouTube feed only lists its 15 most recent videos.

The page

Entries from the last seven days are marked NEW. Entries published in the last 24 hours are marked TODAY and are included in the new filter. The search box matches entry titles and feed names. The category chips and the new and today buttons can be used alone or together, and a feed or category with nothing left to show is hidden. The header stays put while scrolling.

```

Meta