The original iPodderX layout (toolbar, places, item table, Files pane), the Classic theme, Directory and Popular, All Subscriptions with mark everything read, sortable columns and a Size column, one meaning per icon across the UI, and fixes for the double play, Escape in dialogs, the dark-theme password box and paid feeds listed in Popular. See CHANGELOG.md [0.4.0] and docs/history.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0173mGu6rK18Ne7UGTwAaVJV
207 lines
11 KiB
Markdown
207 lines
11 KiB
Markdown
# Changelog
|
|
|
|
All notable changes to this project will be documented in this file.
|
|
|
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
|
The long form, with what was wrong before and how it was found, is in
|
|
[docs/history.md](docs/history.md).
|
|
|
|
## [Unreleased]
|
|
|
|
## [0.4.0] - 2026-09-11
|
|
|
|
### Added
|
|
|
|
- A Classic theme after the 2004 Mac app, beside Dark and Light: brushed-metal toolbar, Aqua
|
|
blue selection, red unread badges, a striped table and Lucida Grande. The theme button steps
|
|
through all three and remembers the choice.
|
|
- 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, title, feed, file, size, published) with a Files pane beside
|
|
it, and a status bar with the totals.
|
|
- Mark everything read from All Subscriptions, across every feed you subscribe to
|
|
(`POST /api/read-all`). It asks first. All Subscriptions can also check every feed from its header.
|
|
- Click a column heading in the item table to sort by it (kept, title, feed, file type, size,
|
|
published); click again to reverse. The server sorts, so it covers the whole list, not just the
|
|
fifty shown, and the choice is remembered.
|
|
|
|
### 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.
|
|
- Adding a feed scans it straight away, and an OPML import that added feeds scans them, so their
|
|
items show without pressing Scan.
|
|
- A file deleted to save space, or by hand, looks as if it was never downloaded: no "reaped"
|
|
label, just the Download button. The retention summary says "deleted", not "reaped".
|
|
- Buttons are icons, with the words in their tooltips: the Files pane (save, delete, view,
|
|
download), an item's own buttons (mark read, keep, open the original), the feed header (scan,
|
|
download latest, mark all read, settings, unsubscribe), and the Settings, feed settings and
|
|
Download latest dialogs (save, download, cancel). The icons are Font Awesome Free, embedded as
|
|
SVG: only the ones used, no font to download, and nothing fetched from anyone else. They
|
|
replace font characters such as ⟳ ⤓ ↗, which came out thin and tiny and differed from font to
|
|
font. Keep is a flag everywhere, as it was in the original, and mark unread is an envelope.
|
|
- One meaning per icon. Minus unsubscribes, x closes or cancels, plus adds or subscribes, and a
|
|
dialog's confirm button carries the icon of what it does. The feed header's unsubscribe was an x
|
|
and read as closing the page. The remaining word buttons are icons too:
|
|
- Log, Add feed, Users, Unsubscribe and OPML.
|
|
- Popular's Subscribe, Copy and Sign out.
|
|
- The Subscribed label in Popular, the Directory and Add feed, which is now a green check.
|
|
- The player's back, play, forward and close, which were font characters, and the folder arrow.
|
|
- The toolbar's read and keep buttons show the selected item's state, with the same icons as the
|
|
item's own buttons. Play, read and keep sit together, and Scan sits with add and unsubscribe.
|
|
- An OPML subscription's page has the same header as a feed's, with its buttons in the same places.
|
|
- The item table's size has its own column, apart from the file's type, and shows KB for small
|
|
files instead of "0 MB". The Item heading is now Title.
|
|
- A file's type is an icon (audio, video, image, PDF, torrent, other), green once it is
|
|
downloaded and red when the download failed, with the details in its tooltip. One icon per
|
|
row keeps the column lined up. The DOWNLOADED and PENDING labels are gone.
|
|
|
|
### Fixed
|
|
|
|
- Playing a file from the Files pane played it twice at once, in the pane and in the player bar.
|
|
The pane has a play button now, and the player bar is the only player.
|
|
- The password box in Manage users was white in the dark theme.
|
|
- An item with no date showed a stray dot in its details.
|
|
- Escape did not close a dialog while the cursor was in one of its boxes, so Add feed, which opens
|
|
in its URL box, could not be closed with Escape.
|
|
|
|
### Security
|
|
|
|
- Feeds from paid-feed services (Patreon, Supercast, Supporting Cast, Glow, Memberful) are never
|
|
listed in Popular or the Directory. A Supercast feed, which keeps its key in the URL's path
|
|
rather than the query, was being listed.
|
|
|
|
## [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/`.
|
|
|
|
[unreleased]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.4.0...main
|
|
[0.4.0]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.3.0...v0.4.0
|
|
[0.3.0]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.2.0...v0.3.0
|
|
[0.2.0]: https://git.sdf1.net/rays/ipodderx-rs/compare/v0.1.0...v0.2.0
|
|
[0.1.0]: https://git.sdf1.net/rays/ipodderx-rs/releases/tag/v0.1.0
|