51 KiB
51 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.
Unreleased
0.12.0 - 2026-10-11
Added
- With
[web] metrics_bindset, ipx serves Prometheus metrics on a port and thread of their own: the database pool, the worker's job and queue, jobs done and their time, scans, downloads and requests in progress, download speed, live-update listeners and missed updates, DeadAir's backlog, the artwork cache's fill, hit rate and evictions, memory, open files and the library's counts. The iPX dashboard graphs them in a Daemon row (#194, #195, #198, #199). - The page reports its errors, the player's, how long play takes to start and how long it stalls to the server's log, and the requests one tap sets off share a trace, the playlist, audio and saved place of what it played included (#190, #192).
- Saving an episode from a show with DeadAir on saves it without its dead air, at your breathing room (#186).
- Choose the pause DeadAir leaves where it cuts a silence, from 0.2 to 0.5 seconds, for each show in its settings, as its breathing room, on a slider from brisk to relaxed. It is 0.3 seconds unless you change it, up from 0.2, which made speech sound rushed (#182, #183).
Changed
- DeadAir no longer makes a shortened copy of each episode. It plays the original with its long silences left out, ready a few seconds after the download, with no gap where a silence was cut and no extra disk space; the copies already made are removed (#179, #181, #196).
- DeadAir is in the same box as a show's download settings, below them, and stays there when automatic downloads are off (#185).
- The container is built on Debian 13 (trixie) instead of 12, so DeadAir uses ffmpeg 7.1 instead of 5.1 (#177).
- On Postgres, ipx keeps up to 20 connections to the database instead of 10, for the bursts of a page load asking for many covers at once (#200).
- Traces of the disk sweep, episode lists and DeadAir's work on each file show each step, and the sweep's trace says what it removed (#187).
Fixed
- All Subscriptions, and every item list, comes up faster, most of all the first time after a quiet spell: it took half a second to two (#188).
- Checking for new episodes no longer waits up to 12 seconds each time on a clear-out of dead feeds from the Directory, which now runs once a day (#193).
- A page left open no longer misses updates after a check for new episodes: the note that each feed not due was skipped, one per feed, filled the queue they share (#197).
Security
- Cloudflare no longer keeps a copy of the audio you play, which it served to anyone it let in without checking they subscribe (#189).
0.11.0 - 2026-10-09
Added
- DeadAir: turn it on for a show in its settings, or with the button beside the speed while it plays, and its episodes play with long silences shortened, so podcasts finish sooner without sounding sped up. Your place carries over when you turn it on or off, each episode says how much shorter it is ("Cutting dead air…" until it is done), and Settings shows the time it has saved you. It is off for every show until you turn it on (#171, #172, #173, #174, #176).
Fixed
- A downloaded file's play, save, share and delete buttons stay on one row in the Files pane, instead of delete wrapping underneath (#175).
- Cover art up to 20 MB is shown, instead of nothing for anything over 5 MB, as for five of the Glass Cannon Network's feeds.
- Seeking in an episode while many people listen answers in about 10 ms instead of 40, and files stream about four times as fast: each connection now sends what is ready without waiting for the browser to acknowledge the last part.
- Artwork that could not be fetched is not fetched again for an hour, instead of on every page load, and the server's log says which image it was and why.
0.10.3 - 2026-10-09
Changed
- Swiping past the last item shows the theme's accent colour, without the words "No more items".
- An empty list and the reader with nothing picked say nothing, instead of "Nothing here yet — try Scan now." and "Pick an item to read it."; a search that finds nothing still says so.
- In Settings, the API tokens sit in a box of their own.
- A feed's settings are redesigned: downloading on its own is a switch with what depends on it beneath, how many is Default, Newest or All shown on a strip of the show's own episodes, words to pick or hide are chips, the feed's address is at the top with a copy button, and Save is always in reach. Its folder and Directory category are no longer in it.
- The feed list's traces show each of its database queries, so it can be told where its time goes.
- Saving a feed's settings asks the database for your subscription once, not twice.
ipx addand Add feed in the page add a feed the same way, through one piece of code.- A pinned item or feed's pin button is filled with the theme's accent, in the reader, on the feed's page and in the toolbar, so pinned no longer looks like not pinned.
- A feed's page in the Directory says how many people here subscribe only when someone does, without "Nobody here subscribes yet".
Fixed
- The unread counts catch up when you come back to the page: an item read on another device, or while the phone app was in the background, no longer stays counted as unread until a reload.
- A feed set to download 0 of its newest items downloads all of them, the whole back catalogue, as the server's 0 does; it downloaded nothing.
- The feed list loads faster: it counts the items and files of your own feeds, not of every feed on the server, and asks for a group's title once, not once for every feed in it.
- Downloading or deleting a file the server no longer has answers "not found" instead of a server error.
- A feed's page in the Directory, and subscribing from it, no longer wait while the whole Directory is put together to check that the one feed is in it.
- An episode that came as a torrent of several files plays its largest file, and can be deleted, by hand or to free space, instead of staying on disk for good.
- Removing an account takes the feeds only that person read off the server, as unsubscribing does, instead of leaving them downloading every new episode for no one.
- Freeing disk space counts only the people who subscribe to a feed: an episode is no longer taken as heard by everyone because someone who has since unsubscribed heard it, and their pins no longer keep files for good.
- An episode whose file turns out to be a torrent shows as downloaded once it is, instead of being fetched again on every check of its feed, and no longer holds up the checking of other feeds while it downloads and seeds.
- Downloading the latest 65 to 100 items of a feed queues them at once, instead of hanging until most had downloaded and holding up adding feeds and Refresh meanwhile.
- Changes to the feed list made at the same moment, such as two people adding feeds, or a feed added while the server settings change, no longer undo one another.
- A download that stops partway is given up after two minutes without data, instead of holding up every scan and download until a restart.
- On a phone, the closed feed list no longer shades the left edge of the page with its shadow.
- On an iPhone, the top bar's colour runs all the way up behind the status bar and the Dynamic Island, with no band of another colour above it. In Glass the bar is solid on a phone, in the colour its glass showed.
- A feed's buttons stay on one row on a narrow phone, and the reader's buttons stay together instead of breaking across lines under a long feed name.
- A moment's DNS failure no longer marks a feed as failing for a day or calls it gone: iPX tries it again in ten minutes. One failed lookup one morning left 205 podcasts unread, uncategorised and labelled gone until the next day. A name that does not resolve is said to be maybe gone, and only once it has been failing a day, on its Directory page as on its own.
0.10.2 - 2026-10-05
Fixed
- A publisher's correction to an item already in iPX, a retitled episode, mended text, new artwork or a fixed length, arrives on the next read. Since 0.9.1 an item kept what it first said: Ain't It Cool News's items each showed the text of the one before, long after the feed was fixed.
- A feed's page in the Directory says when the feed is failing, and why, and no longer says nobody here subscribes to a feed someone does.
0.10.1 - 2026-10-05
Fixed
- A feed whose address answers with nothing, as a lapsed domain does behind a DNS filter's block page, shows as failing, with what to do about it, instead of as a show that has not posted yet.
- The search box finds episodes in Currently Listening. It did nothing there.
ipx add,ipx rmandipx import, run while the daemon runs, reach it at once. It kept its old list of feeds and wrote it back at its next change, undoing them.- On SQLite, several requests are answered at once instead of one at a time. With 25 people browsing, a page of a feed's items comes back in 10ms rather than 130.
- On Postgres, a write no longer waits for the database server's disk. A scan read about one feed a second and now reads 1,500 in 20 seconds.
- Checking every feed no longer makes every icon in the feed list flash while it runs: the list keeps the icons it has already drawn.
Security
- A flood of sign-in attempts no longer stalls the site for everyone else. Passwords are checked a few at a time, away from the threads that answer every other request; forty wrong passwords at a time made everything else take four seconds.
- A wrong password is refused in the same time whether or not the name is an account here, so how long it takes no longer tells anyone which names are.
0.10.0 - 2026-10-05
Added
- API tokens: in Settings, make a named token that lets a script or an agent use iPX as you, sent as
Authorization: Bearer, and revoke it there. Each shows when it was last used. - In the Directory, a feed you do not subscribe to opens a page of its own: its cover, its category, how many people here subscribe, what the feed says it is, and its latest episodes or posts, with a button to subscribe. Before, only its subscribe button did anything.
- Feeds that don't set a category, as most blogs don't, now get one automatically, so they show up under a category in the Directory. iPX picks the closest of Apple's podcast categories from the feed's title and latest headlines. This happens once per feed: the first time a new feed is read, or for a feed you already had, the next time you force a refresh. It needs
TYPESAFE_KEYset. An admin can change the category in the feed's settings. - Artwork is kept on disk once shown and loads from iPX, not from each publisher's server: fast after the first time, and still there when the publisher's server is not. The admin page sets how much is kept (500 MB by default).
ipx add --list --category News <url>puts a feed in the Directory for anyone to subscribe to, and it stays there when its last subscriber leaves. Run for a feed already in the catalogue, it lists it or sets its category.- Feeds nobody subscribes to that are dead for a month or quiet for a year are removed, so the Directory lists feeds worth taking.
Changed
- The Directory is laid out as Apple's is. It opens on the ten most subscribed feeds, ranked, and the categories as tiles showing some of their shows' covers. A category opens a page of its own with its most subscribed feeds, its subcategories (Tech News under News, Video Games under Leisure) and its feeds; See all lists every one, A to Z, Z to A or by most subscribers. This replaces the grid of every feed under rows of category buttons, and Popular, which is gone from the feed list with its key, g p.
- A pinned item in a list wears the same disc as a pinned feed, in the theme's accent, instead of a plain solid pin.
- An item published without a title shows its opening words, in plain text rather than bold, instead of "(untitled)"; one with no text either shows its file's name, or its show and date. Opened, it starts with its text.
- A feed that has moved for good (a permanent redirect) is followed to its new address, which iPX then reads from, and says so in the log as
feed_moved. A temporary redirect changes nothing. - The daemon sleeps until the next feed is due, at most ten minutes, instead of looking every minute; refreshing or adding a feed still wakes it at once.
- A pinned feed's pin sits on the corner of its artwork, as a failing feed's mark does, instead of before its name.
- The Directory lists feeds nobody subscribes to yet; its most subscribed still lists what people subscribe to. A feed nobody subscribes to is checked once a day, and at once when someone subscribes. A listed feed downloads nothing until someone subscribes.
- The Directory loads faster: it asked the database three questions per feed.
Fixed
- A database on SQLite, the default, no longer waits for the disk after nearly every write. On a slow disk a scan of 1,500 feeds took most of an hour and now takes half a minute. Postgres is unaffected.
- The search box finds a feed in the Directory by name. It did nothing there.
- Feeds that file themselves under Apple's Football or Soccer show under Sports, and those under the old Software How-To under Technology, instead of as categories of their own.
- The download queue, in
ipx status,/api/statusand the dashboard, counts only what iPX will download on its own: older episodes beyond a show's limit, and files of feeds that do not download automatically, are listed but no longer counted as waiting. - Artwork published on http is stored on https when its host serves it there, so the page loads it directly; the rest still comes through iPX.
- An iPhone adding the site to its home screen finds the icon at the first address it tries.
- A feed whose server hangs no longer holds up every scan: a feed gets 30 seconds, and connecting anywhere 10.
Security
- A feed's items and files reach only the people who subscribe to it. Anyone signed in could read any feed's items, a paid feed's included, with the addresses of its files, which can carry the subscriber's key, and could play, download or delete its files.
0.9.1 - 2026-09-29
Added
IPX_LOG_FORMAT=jsonlogs one JSON object a line, for Loki and the like: a request's method, route, status andduration_ms, a scan's or download's details, a failure's kind inerror.type(and its HTTP status inhttp.response.status_code), and each line'strace_idandspan_id.- A Grafana dashboard for iPX, from its log in Loki and its traces in Tempo (
grafana/dashboard.py). - With
OTEL_EXPORTER_OTLP_ENDPOINTset, the daemon sends traces of its scans, downloads and web requests to a collector such as Tempo; a scan's shows the time each feed spends fetching, on its artwork and in the database. - A feed with no artwork of its own, or whose artwork is missing, shows its website's icon, or the
site's
/favicon.ico, and follows the site when it changes. It is asked for again only when the artwork changes or you refresh the feed. - The refresh button turns while its feed is being checked, and the check-every-feed buttons while any of yours is.
- Adding a website's address, with or without
https://, subscribes to the feed that site links. An address is checked before it is added, and anything that is neither a feed nor a page linking one is refused with the reason, instead of being added and failing on every check. /api/statusgives the number of feeds, items waiting to download and files downloaded, and the version, for a dashboard such as Homepage.
Changed
- The start-up line about the web UI being reachable off the machine says what guards it, and is a warning only when there is no Cloudflare Access in front of it.
- The feed list updates just the feed that changed, as a scan checks it or you read an item, instead of reloading the whole list every minute.
- A scan fetches several feeds at once, so a refresh no longer waits on every site in turn.
- A feed that was failing when its last subscriber left is forgotten, rather than kept with its error for good. One that worked, or has files on disk, is kept as before.
- A feed that keeps failing is checked less and less often, waiting as long as it has been failing, up to once a day; it goes back to its schedule as soon as it works. Refreshing it still checks it at once.
ipx listshows each feed's id on a line of its own, labelled, under its title.- Each browser keeps its own theme, so a phone and a desktop can differ. A browser that has not chosen one yet starts from the theme your account had.
- The Modern theme takes its colours from the new logo: its navy, the blue of its bars and the orange of its needle.
- The logo is in the top bar beside the add-feed button, in place of the name at the top of the feed list, and left out on a phone, for the search box. It follows the page, dark in a dark theme and light in a light one, as the browser tab's icon does, and hovering it shows iPX's version, which says so between releases: 0.9.1-dev, not 0.9.0.
- The logo's needle is a brighter, redder orange that stands apart from the blue bars.
Removed
ipx copy-db, the one-off move from SQLite to Postgres. Going back needs only the oldstate.db.- Starting up no longer looks for files downloaded twice before 0.6.0 read WordPress's player links correctly; that clean-up has run.
Fixed
- A limit on new downloads per check means a show's newest episodes: with it set to 3, ipx no longer works back through the show's history three at a time. Set to 0, it still takes the whole back catalogue.
- With no limit on new downloads per check (
max_new_per_check = 0), downloads work on Postgres; they failed. - Checking a feed with a long history is much quicker: items already stored are no longer written again on every check.
- The feed list loads several times faster: it was asking the database six questions per feed.
- Artwork a feed offers only over plain http shows on the https site too.
- A failing feed is easy to spot in any theme: a mark on its artwork, what is wrong in place of its counts, and its artwork greyed out once it has failed for a day.
- The log has no terminal colour codes when it is not going to a terminal, as in
docker logs. - The read button shows whether an item is read, as the pin beside it shows whether it is pinned: a tick when read, an envelope when not. It used to show the opposite.
- In Directory and Popular, Subscribe is a plus again, not the tick that marks a feed you have.
- A feed's refresh button looks like the buttons beside it, instead of standing out filled in.
- Refreshing reads your feeds in full, instead of only asking each one whether it changed, so a feed that has not changed is still read again.
- Pulling the item list down to check for new items shows a spinner for a couple of seconds, and a second pull meanwhile does nothing, instead of no sign at all that the check started.
- Settings no longer lists the server's download folder, which only an admin can change, on the admin page.
- On the Unread tab, a swipe back (or k) goes to the item you just read, instead of past it or back to the list. The items read on the way leave the Unread tab once you close the reader.
0.9.0 - 2026-09-28
Added
- A new logo, on every page, in the browser tab and on the home screen: the old radio's screen, its tuning scale and orange needle, drawn flat to Apple's app icon guidelines, with a dark version. The 2004 icon is still at /icon.png.
- Words that hide items. Settings has a list for every feed you read, and each feed's settings a list of its own; an item with one of those words or phrases in its title or text is hidden from you and is not downloaded on your account. Other people's lists never hide anything from you.
- Share buttons for a feed, an item and a file. On a phone they open the system's share sheet; elsewhere they copy the link. A link that looks like it carries your own access to a paid feed asks before it goes anywhere.
Changed
- iPodderX is now called iPX, on every page and in the tab. The repository is rays/ipx.
- On a phone, iPodderX looks like an iOS app: filled round buttons and capsules instead of outlined boxes, no rules between the bars and the page, the feed's name as a large title, a segmented control for the tabs, taller rows with 17px text, and dialogs as sheets from the bottom. Tapping a text box no longer zooms the page in. High contrast, and Increase Contrast, keep their outlines.
- The Glass theme's panels catch the light: a bright rim along the top and left edges, a fainter one along the far edges, and a soft sheen from the top-left corner.
Fixed
- A new tab or home-screen icon shows up as soon as it is deployed, instead of a day later.
- Opened from the home screen on an iPhone, the top bar, the reader's back button and the top of the feed list keep clear of the Dynamic Island and the status bar instead of sitting under them.
- Swiping between items on a phone takes a quarter of the screen, so a diagonal scroll no longer jumps ahead by accident, and no longer shows the item list through the reader: the next or previous item sits beside the one you are reading and comes across with it, following your finger, the end of the list says so, and swiping right from the first item draws the reader off the list, dimmed until it is uncovered. A swipe from the screen's left edge stays with the page, rather than Safari taking it as Back.
0.8.4 - 2026-09-19
Added
- A Glass theme, light and dark, with frosted see-through panels after Apple's Liquid Glass. It goes solid when the system asks for less transparency or more contrast.
- The page can hand playback to a native app. Opened inside an iOS or Android shell, an episode plays through the host's own player instead of the page's, so it keeps going when the screen locks and the car can control it; the player bar, the row buttons and the keyboard shortcuts work as they always did. Video still plays in the page. In a browser nothing changes.
Fixed
- On a phone, the bottom bar keeps clear of the home indicator, so the seek bar and the times are no longer cut off when the page has the whole screen: in a native shell, or added to the iOS home screen. In landscape the bars keep clear of the notch as well.
0.8.3 - 2026-09-19
Security
- The daemon no longer prints the web token when it starts, so it stays out of
docker logs. It says where the token is kept instead:[web] tokenin config.toml. - Signing in through Cloudflare Access can check the token Access signs: set
access_teamandaccess_audunder[web], and a request has to carry a validCf-Access-Jwt-Assertionas well as the email header. Without it, anything on the same Docker host as ipx could send the header. See docs/sso.md.
Fixed
- A Substack post shows its subtitle above the post, as Substack does. Only posts that arrive from now on have it.
0.8.2 - 2026-09-19
Added
- Four themes, each in light and dark: Catppuccin (Latte and Mocha), Gruvbox, Solarized, and High contrast, black and white with every colour at 7:1 or more.
Changed
- The themes in Settings are listed in alphabetical order.
Fixed
- Links in Classic, and hints and headings in Modern's dark half, are dark or light enough to read comfortably. A failed-action message is easier to read in every theme.
0.8.1 - 2026-09-19
Changed
- A feed being checked shows a small spinner in place of its unread count (and its folder's), instead of toasts: no more "Scanning…" or "1 new" pop-ups, and none at all for feeds you do not read. A "Downloaded" toast is only for a file on your screen.
- "Check every feed" checks every feed you subscribe to, not every feed on the server.
- The Classic theme is listed in Settings as just "Classic".
- Settings and the keyboard shortcuts close from an X in their top corner, not a button at the bottom.
Fixed
- Unread counts, the unread dot and the Gone and Error tags are readable in every theme: several light themes (Flat Remix, Paper, Adwaita, Nordic, Modern) drew them below AA contrast.
- The sign-in page follows the system's light or dark setting, and fits a phone's screen instead of drawing at desktop width.
- In Classic, a selected item's play and delete buttons are white on the blue, not grey.
- In Nordic's dark half, button and toolbar borders show.
- A zero unread count on the selected feed no longer disappears into the selection.
0.8.0 - 2026-09-18
Added
- ipx can keep its data in Postgres: set
IPX_DATABASE_URLto apostgres://URL. Without it, it is the SQLitestate.dbas before.ipx copy-db <state.db>moves an existing database across, everything in one go. - The catalogue of feeds and the server settings the admin page edits are kept in the database
rather than config.toml, which keeps where things are, the torrent settings and who may sign
in. The first start takes them from config.toml and trims it, keeping the original as
config.toml.pre-database; feeds added to config.toml after that are ignored, with a warning.
Changed
- The database is reached through SeaORM, which is what lets it be SQLite or Postgres; on SQLite nothing you see changes. On Postgres, sorting by title or feed follows the language's order (an accented letter beside the plain one) rather than raw bytes. A database from before 0.7 has to be opened by a 0.7 release first, which brings its tables up to date.
0.7.0 - 2026-09-18
Added
- Six more themes in Settings: Dracula, Material, Adwaita, Flat Remix, Paper and Nordic, beside Classic and Modern (the existing dark and light). Each that comes both ways has its own Light, Dark or Auto setting; Classic and Paper come one way only, so that setting is hidden for them. A theme chosen before this carries over.
- Your theme is kept on your account rather than in the browser, so it follows you to another browser or computer, and the page arrives in it with no flash of the default. The theme a browser already had is saved to your account the first time you load the page.
- Pin a feed to the top of the feed list with the pin on its page, a feed from inside an OPML or Patreon folder included, which comes out of the folder while pinned. Pins are yours alone.
- Touch gestures: pull the item list down from its top to check the feed for new items, and swipe the item you are reading left for the next one and right for the one before, or back to the list from the first.
- A favicon: the logo, squared up, also at /favicon.ico for browsers that ask there on their own, and on white for an iPhone's home screen.
Changed
- The server's settings, the accounts and the log are on their own admin page, /admin, reached by the wrench in the header. Only an admin is sent the page, its script, or the link to it. Settings is now yours alone: your theme and your subscriptions.
- A feed that fails to check gets a red exclamation mark in the feed list, in the margin where a folder's triangle sits, and its page says why, in place of a pop-up per failure that everyone saw during a scan of every feed. A folder holding a failing feed has its triangle turn red.
- The theme is chosen in Settings only; the button beside the iPodderX name is gone.
- Add a feed asks only for the feed; Popular and Directory in the sidebar are where you browse.
- On a phone, an item's files, with play and delete, sit above its show notes rather than below them, where long notes left them looking missing.
- On a phone, an item with no files goes straight to its text, without a box saying "No files".
- The page is served minified, about a quarter smaller, with its script in a file of its own,
/app.js, which your browser keeps between visits and fetches again only when an update changes it. The script is TypeScript inweb/src, type-checked and built with swc; building ipx needs node.
Fixed
- Switching tabs straight after marking everything read no longer shows the previous tab's items: of two lists asked for at once, only the later one is shown.
- The file icon of an item not yet downloaded sits level with the rest of its row, instead of higher than a downloaded one's.
- Images in posts from sites that refuse images to other sites' pages, such as Jeff Geerling's, now show: ipx asks for them without saying it is the page showing them.
- While an episode plays, its play buttons in the files pane, its row and the toolbar show pause, as the player bar's does, and pause it when pressed.
- An item you open stays read. A list refresh that crossed with marking it read could put its unread dot back until the next refresh.
- On the Unread tab, the item you were reading leaves the list as soon as you move to the next one, rather than a few read items lingering until a refresh cleared them.
- An image or link in a post given relative to the post, such as The Observation Deck's, now points at the post's site rather than at ipx, and shows.
0.6.1 - 2026-09-15
Fixed
- Time left, and when an episode counts as finished, go by the length your player measured rather than the feed's, which can be minutes out: one episode said 0:08 left with 2:33 to play.
- A player left open in another tab or on another device no longer saves its older place over where you have got to since, which could drop an episode out of Currently Listening.
0.6.0 - 2026-09-15
Added
- Each episode in Currently Listening has a cross that takes it off the list. It forgets where you got to, so playing it again starts from the beginning.
- An admin can give a feed a Directory category in its settings (
categoryin config.toml), for the blogs and other feeds that name none of their own. A feed's own iTunes category still wins. - Keyboard shortcuts after Feedly's: j and k through items, Shift-J and Shift-K through feeds, g and a letter to go to a place, o to play, s to pin, and more. Press ? for the whole list.
- Directory can be filtered to Podcasts or Blogs, and by each show's own iTunes category as a row of chips, the narrower one where a show gives two (Games, not Leisure). The two combine, and both filter in place.
Changed
- Currently Listening marks the episode in the player with the EQ bars, as the item list does, and its progress and time left move as it plays. Each row says how much is left.
- Directory shows each feed as its cover art in a grid, title and subscriber count underneath, instead of a list. Popular and the Add a feed dialog keep their rows.
- The pages are set in Inter, served by ipx itself. Classic keeps Lucida Grande.
- Keeping an item is now pinning it: a thumbtack in place of the flag, and Pin, Pinned and Unpin in place of Keep, Kept and Stop keeping. A pinned item is still never deleted.
- Currently Listening is its own place in the feed list, below Popular, instead of a section at the bottom of the Popular page.
- The first scan after upgrading fetches every feed in full once, on its usual schedule, so each picks up its category without waiting for the publisher to change something.
Fixed
- An episode that fails to load, or is paused before it has, no longer forgets where you left off in it, and so no longer drops out of Currently Listening.
- Currently Listening lists the episodes you have started. It left out anything marked read, and opening an episode marks it read, so it usually showed nothing. An episode now leaves the list once 90% of it has played.
- A WordPress post that embeds the file it encloses no longer lists, and downloads, that file twice. Items that already had it twice are folded into one at startup, and the spare copy deleted.
- The pinned column's heading lines up with the pins under it, and every heading sits a pixel further right, over its column.
- The feeds left behind by an OPML subscription removed before ipx retired them are cleared at startup: forgotten if nothing was downloaded, kept as orphaned if something was. Feeds from it that have since been given their own settings stay as they are, with their items. Removing an OPML or Patreon subscription no longer deletes the items of a feed inside it that has its own settings.
- Titles that arrive as HTML, such as The Verge's, no longer show their entities as text: "Meta’s" reads "Meta’s". Titles already stored are corrected the next time their feed changes.
0.5.5 - 2026-09-14
Changed
- A feed whose site sends a message instead of the feed, such as "Unable to establish a DB connection", now shows that message and is flagged as the publisher's problem, instead of two parser errors about reaching the end of input.
Fixed
- Add a feed opened over Directory or Popular now shows its Popular list instead of staying on "Loading…", and no longer cuts the Directory behind it down to ten.
0.5.4 - 2026-09-14
Added
- Currently Listening, below Popular: episodes you started and have not finished, across every feed you subscribe to. Tap one to pick up where you left off.
- Theme has an Auto option, alongside Dark, Light and Classic, that follows your system's light/dark setting. All four are now also in Settings, as a dropdown next to the header button's one-click-at-a-time toggle -- the same setting either way.
Changed
- The feed (or Directory/Popular/All Subscriptions) and the tab you had open are remembered across a reload or a new visit. A feed you no longer subscribe to, or a first visit with nothing remembered yet, lands on All Subscriptions instead of the first feed alphabetically.
Fixed
- On iOS, the topbar (the hamburger menu included) could stop responding to taps until a hard
refresh. The page sized itself with
100vh, which iOS Safari measures against the address bar's collapsed state rather than what is actually visible;100dvhtracks the real viewport as the bar shows and hides.
0.5.3 - 2026-09-14
Added
- A feed that has been failing for a day shows a plain-English reason in the sidebar and on its own page, sorted from a 404, a 401/403, a 402, a name that no longer resolves, or a web page in place of the feed -- with Unsubscribe or, when the page links its new feed, Use the new address. A feed that fails once and reads fine again within a day is never flagged.
Changed
- Unsubscribing from the last person's OPML or Patreon subscription now retires the feeds it
listed, the same as a feed the list itself drops: removed if nothing was downloaded, kept and
marked orphaned otherwise. Until now they stayed in the database and kept being scanned hourly
with auto-download on, which is how 922 defunct
davewinerfeeds outlived the OPML that listed them.
Fixed
- A feed whose XML uses a bare
&instead of&(kcpw, both feedland feeds) is now read instead of refused. - A feed URL that now serves a web page says so, and names the feed the page links to when it has one, instead of a raw XML parser error.
- A publisher answering with an empty body (British Antarctic Survey's 202) is read as nothing new to report, not a parse failure.
- A link in an item's show notes opens in a new tab instead of navigating away from ipx.
- A video file plays as video, in a small floating pane above the player bar, instead of silently as sound only.
- On the Unread tab, opening an item no longer makes it disappear from the list -- it stays until you open a different one, even if a scan finishes and refreshes the list while it is open.
- Subscribe and Unsubscribe have their own icons (a circled check and a circled minus) instead of sharing the generic plus and minus used for adding feeds, users and imports.
- Settings no longer disappears for a non-admin account. It was hiding the whole Settings modal along with the log and the users screen, but a non-admin has settings of their own in there -- their subscriptions' Export and Import, and the schedule and quota are worth seeing even without a say in them. Only the log and the users screen, which the server also refuses them, are gone.
0.5.2 - 2026-09-12
Added
- Settings → Users and
ipx user listshow when each account was added and when it last signed in, to the hour. ipx user rename <name> <new name>renames an account and keeps its feeds, read state and admin rights. An account made before the proxy was set up can take the name the proxy signs it in as.
Changed
- Directory and Popular list the feeds inside an OPML one by one, and no longer the OPML itself, so you can subscribe to just the shows you want.
- The database no longer records when subscriptions and sign-in sessions were created. Nothing ever read it, and an existing database drops the columns on its next start.
Fixed
- Show notes that the podcast's host cut off in the middle of a tag no longer open with a scrap of HTML: the item's other copy of its notes is used instead, from the next time the feed changes. Daily Meditation Podcast had 57.
- Docker no longer shows ipodderx as starting, or calls it unhealthy, while it scans or downloads:
ipx statusanswers at once instead of waiting for the job in progress to finish. - Signing out after signing in through Cloudflare Access no longer lands on ipodderx's own password
page. With the new
sign_out_urlset, Sign out ends the Access session, and the password page sends anyone the proxy signs in straight to their feeds. - The sign-in guide,
docs/sso.md, describes the setup ipodderx.sdf1.net really runs: Authentik as Cloudflare Access's identity provider, and how to find the address ipx has to trust. It had never been checked against a real setup, and pointed at the wrong address.
0.5.1 - 2026-09-12
Fixed
- The triangle that opens an OPML or Patreon folder was cramped against the folder's art. It has more room now, and a wider target to click.
0.5.0 - 2026-09-12
Added
- A Patreon token pasted into Add feed, or a creator's RSS link without
&show=, becomes a folder of that creator's shows, kept in step on every scan like a subscribed OPML. A creator with only one show stays a plain feed. One already added as a single long feed is split into its shows on its next scan, keeping its files and what you had read. - Add feed has an "Allow items marked explicit" box, so a new feed's first scan no longer skips every explicit item.
Changed
- Unread counts, unread dots and download progress are amber, the colour of the icon's EQ bars. Blue is kept for the primary action and links, so a count no longer looks like a button.
- What is playing is marked by small EQ bars, in its row and in the player. They move only while it plays.
- A folder in the sidebar shows its first four shows' art as a mosaic, and its shows sit under its title. Only folders have a triangle, so every feed lines up with Directory and Popular above.
- Feeds without art get initials in a colour of their own, instead of all the same grey.
- The Flagged tab is called Kept, as the Keep button and Settings already said.
- A feed's header is one short line; when it checks next is in its tooltip.
- The item list takes more of the window, and the Files pane shows only when the item has files.
- Column headings and tags are in sentence case, and fewer things are bold.
- Unsubscribe is a round button beside the feed's other actions.
- Export and Import in Settings say what they do.
- The sign-in page shows the original icon large.
- Nothing animates when your system asks for reduced motion.
- The pages are about 90 KB smaller: the icon is served once instead of written into each.
- A web token generated for a new install is 64 characters instead of 32.
- The README is a short overview of what ipx does and how to run it, and points into
docs/for the rest. It still described the layout from before 0.4.0.
Removed
- The systemd units in
contrib/. Run ipx with Docker, or point a unit of your own atipx daemon. - Upgrading from before 0.3.0 directly: what was read, kept or part-played before accounts is no
longer carried over to the admin, and OPML feeds that old versions wrote into
config.tomlare no longer moved out of it. Upgrade through 0.4.0 first. interval_minsinconfig.tomlis ignored; useschedule.
Fixed
- The feed list works from the keyboard: Tab reaches every feed, Enter opens it, and Right and Left open and close a folder. Every button shows where the focus is, including in the toolbar, which used to clip the ring.
- "1 items" reads "1 item".
- A selected feed without art no longer loses its initials tile in Dark and Light.
- The player shows the feed's initials when there is no art, not the episode's.
- Turning on Allow explicit, or changing keywords or auto-download, brings back what those settings had skipped on the feed's next scan. Before, an item was judged once, when first seen, and a skipped one stayed skipped whatever you changed.
- Feeds inside an OPML or a Patreon creator follow your settings on the folder unless you set their own, as the folder's settings dialog said they did. Before, the folder's settings reached nothing inside it.
- A new feed no longer takes the name of one you removed earlier and shows that feed's old items. Re-adding the same feed still gets its old name, and its history, back.
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, unsubscribe and scan; play, mark read and keep for the selected item, showing its state; 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. 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; its size is in KB for small files instead of "0 MB".
- 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, one meaning per icon: minus unsubscribes, x closes or cancels, plus adds or subscribes, a dialog's confirm button carries the icon of what it does, Keep is a flag, as it was in the original, mark unread is an envelope, and Subscribed is a green check. 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 words and font characters such as ⟳ ⤓ ↗, which came out thin and tiny and differed from font to font, and the feed header's x for unsubscribe, which read as closing the page.
- An OPML subscription's page has the same header as a feed's, with its buttons in the same places.
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
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 something that is not OPML answered
500. It is now400"that is not an OPML file", refused before anything changes.
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. Opening an item marks it read; playing it marks it read only at the end or past 90%.
- 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), set by an admin, as are the global settings. [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
- Feeds from an OPML live in the database, not
config.toml. - Torrents run detached, two at a time.
Fixed
- The daemon ignored SIGTERM until the current download finished.
- A torrent could freeze scanning for up to an hour.
- Image enclosures were downloaded as episodes.
- A feed whose entries had been deleted stayed empty, because the server kept answering
304. - An item with several enclosures kept only the last.
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/.