Files
ipodderx-rs/CHANGELOG.md
rays df9b7645d6 The original iPodderX layout: toolbar, places, item table, Files pane
- 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
2026-09-11 14:39:05 +00:00

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 409 while anyone else has starred the item or not played it (?force=true overrides).
  • A shared feed's header says how many other people read it.
  • docs/ for configuration, the CLI, users, SSO and architecture, and CLAUDE.md for 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 import subscribes the first admin.
  • OPML export lists only your own subscriptions.
  • Production runs as a Docker image pushed to 192.168.1.130:5000 and recreated with docker 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 now 400 "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/logs answers 403, 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, and max_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.js and 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 500 without 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/passwd is refused.
  • Download folders are sanitised per path segment, so ../../etc/Show cannot climb out.

0.1.0 - 2026-09-09

Added

  • ipx, a Rust rewrite of the iPodderX engine: TOML config, SQLite state, and ipx list, add, rm and fetch.
  • 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 daemon with 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 import and ipx export for OPML, and systemd units in contrib/.