- A toolbar across the window with the original's groups: add and unsubscribe, play, mark read and keep for the selected item, scan, a search box for what is showing, and Settings and Log (admins only). - Directory, Popular and All Subscriptions sit at the top of the feed list and open in the main pane; the Popular and Directory buttons and their dialogs are gone. - All Subscriptions lists every item from every feed you subscribe to: GET /api/entries, the per-feed query with its scope widened. The enclosure lookup after it matches files to rows by feed and guid, since a page can now span feeds. - Items are a table (unread, kept, item, feed, file, published) with a Files pane beside it, the text below, and a status bar with totals. On a phone the files follow the text and the table is title and date. - Tests: enclosures are checked in #files; the toolbar's read, keep and play act on the selected item; All Subscriptions holds only your feeds. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016HdTEWQNrzyFULijigkmMn
7.7 KiB
7.7 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
The long form, with what was wrong before and how it was found, is in docs/history.md.
Unreleased
Added
- A toolbar across the top, after the original iPodderX: add and unsubscribe, play, mark read and keep for the selected item, scan, a search box for what is showing, and Settings and Log.
- Directory, Popular and All Subscriptions at the top of the feed list, opening in the main pane.
Directory lists every feed anyone here subscribes to, A to Z (
GET /api/directory). All Subscriptions lists every item from every feed you subscribe to (GET /api/entries). - Items show as a table (unread, kept, item, feed, file, published) with a Files pane beside it, and a status bar with the totals.
Changed
- Popular shows the top 10, not 20, and counts everyone, you included. Your own feeds stay on it, marked Subscribed, and clicking one opens it.
0.3.0 - 2026-09-11
Added
- Add feed lists what other people on this server subscribe to, most subscribers first, and
subscribes you by id (
GET /api/popular,POST /api/popular/{id}). Feeds from an OPML, and feeds with a login or a key in their URL, are never listed. - Upload an OPML file to import, beside the paste box. The page checks it looks like OPML before sending it and clears the picker afterwards.
- Settings → Manage users: add and remove accounts, and choose who is an admin
(
GET/POST /api/users,PATCH/DELETE /api/users/{id}). - Per-user subscriptions, and per-user read, starred and playback state. The existing library is adopted by the admin on first start.
- Subscribing to a feed someone else already has costs no second fetch and no second copy. Scanning merges every subscriber's wants.
- Delete on a shared feed reads Delete for everyone, and the server answers
409while anyone else has starred the item or not played it (?force=trueoverrides). - A shared feed's header says how many other people read it.
docs/for configuration, the CLI, users, SSO and architecture, andCLAUDE.mdfor anyone working on the code.- Browser tests for OPML import and export by every route, user admin, unread ordering, and
ipx import/ipx export.
Changed
- Feeds inside an OPML subscription list the ones with unread items first.
- OPML import subscribes you to every feed in the file.
ipx importsubscribes the first admin. - OPML export lists only your own subscriptions.
- Production runs as a Docker image pushed to
192.168.1.130:5000and recreated withdocker compose. - This changelog follows Keep a Changelog. The long-form entries moved to
docs/history.md.
Fixed
- Importing another account's OPML export subscribed nobody and reported "Imported 0 feed(s)". Feeds it added had no subscriber, so they were never scanned.
- Importing something that is not OPML answered
500. It is now400"that is not an OPML file", refused before anything changes. - Starring stopped protecting a file from the quota and age sweeps once read state became per-user.
Security
- The log is admin-only (
GET /api/logsanswers403, and the Log button is hidden). It names every account, every feed and every failed sign-in. - OPML export no longer hands anyone signed in the whole catalogue, including other people's private feed URLs.
0.2.0 - 2026-09-10
Added
- Web UI served by the daemon: plain HTML and JS compiled into the binary, with feeds, items, filters, search, sanitised show notes and live progress over SSE.
- Player bar with resume, speed, keyboard shortcuts and lock-screen controls.
- Three-pane layout: feeds beside, items above, and the selected item's text and files below.
- Phone layout.
- Accounts and sign-in: Argon2id passwords, session cookies,
ipx user add|list|passwd|rm, and a trusted proxy header for Cloudflare Zero Trust or Authentik (docs/sso.md). - Subscribing to an OPML: it is re-read every scan and its feeds show as a folder. A feed dropped from it is removed unless it has downloads.
- Scheduling: a global interval with per-feed overrides (
every 30m,4h,1d,2w). [general] media_types, default audio and video, andmax_new_per_check, default 3.- Every enclosure of an item, a View link for files that are not audio or video, and per-item artwork.
- In-app log view with Daemon I/O, Scans and HTTP tabs.
- Mark all read on an OPML subscription.
- Editable feed URL with a copy button.
- Docker image whose healthcheck goes through the control socket.
- The iPodderX name, icon, and a colour scheme taken from the icon.
tests/page-smoke.jsand a Playwright browser suite.
Changed
- Global settings and scan schedules are admin-only. The per-feed schedule picker is gone.
- Feeds from an OPML live in the database, not
config.toml. - Opening an item marks it read. Playing it marks it read only at the end or past 90%.
- "Episodes" became "items", since half the library is text.
- A burst of scan events causes one refresh, not one per feed.
- All is the default filter. OPML import and export, Settings and Log moved out of the header.
- Torrents run detached, two at a time.
Fixed
- Download fetched the next queued episodes instead of the one clicked.
- Pressing play made an item vanish from the Unread list.
- Clearing a folder, schedule or cap from the UI did nothing.
- The daemon ignored SIGTERM until the current download finished.
- A missing function stopped the page script and left the whole UI dead.
- One download painted progress on every pending row.
- A torrent could freeze scanning for up to an hour.
- Downloading from an OPML feed failed with "belongs to unsubscribed feed".
- Image enclosures were downloaded, counted as episodes and given a play button.
- A feed whose entries had been deleted stayed empty, because the server kept answering
304. - An item with several enclosures kept only the last.
- OPML folders rendered open by default.
- Mark read in the text pane recursed until the stack overflowed.
- The Unread, Downloaded and Flagged filters answered
500without a search term. - An OPML subscription always showed 0 unread.
- Folder names kept doubled spaces where separators were stripped.
- Sidebar rows had four different left edges.
Security
- The web UI needs a token or a sign-in. The token is compared in constant time, and an empty token refuses to serve.
- Show notes are sanitised with
ammonia. - A proxy's user header is honoured only from an address in
trusted_proxies. - A feed URL must be http(s), so
file:///etc/passwdis refused. - Download folders are sanitised per path segment, so
../../etc/Showcannot climb out.
0.1.0 - 2026-09-09
Added
ipx, a Rust rewrite of the iPodderX engine: TOML config, SQLite state, andipx list,add,rmandfetch.- RSS and Atom parsing with conditional GET,
<ttl>and basic auth. - Streaming downloads with explicit, keyword and per-scan filters, deduplicated by enclosure URL.
- Quota and age retention that never touches a starred file, and
ipx reap [--dry-run]. ipx daemonwith a JSON-lines Unix socket. CLI commands proxy to a running daemon.- Torrent enclosures through librqbit, seeding to a ratio or a time, with a stall timeout.
ipx importandipx exportfor OPML, and systemd units incontrib/.