A terminal reader, ipx; the server is ipxd (#437)

ipx-tui (crates/tui) is iPX's reader in ratatui: your feeds, a feed's
items, an item's text as plain text, read and flagged as on the page,
through the API with an API token. It installs as `ipx`, so the daemon's
binary is now `ipxd`: the Dockerfile, release script, tests and every
doc and message that names its commands follow.

Naming the binary ipxd alone renamed its crate, and with it every log
target (ipx::scan became ipxd::scan): the default filters are ipx=info,
so nearly every line would have been dropped and the dashboard's queries
on the targets gone blank. The daemon's code is now a library still
called ipx, under a five-line ipxd main.rs, and the targets are as they
were.

ratatui is taken without its default features: 32 new packages in place
of 78.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RqkrVDqdiQEMWAkNGQ2tYA
This commit is contained in:
2026-11-09 11:52:10 +00:00
parent f844cf349a
commit 711b0395f1
40 changed files with 1128 additions and 238 deletions

View File

@@ -5,7 +5,7 @@ Three services, each a container of its own with its own version and changelog (
| Service | What it is | Source | Image |
|---|---|---|---|
| ipx-web | Caddy: serves the page, a static site built from `web/`, and passes `/api` and `/media` to ipx on the same address. It asks ipx before it serves the app or the admin page (`/api/page-check`) | `web/`, `web/Caddyfile` | `Dockerfile.web` |
| ipx | The daemon and CLI, one binary. `ipx daemon` runs a scheduler, a Unix-socket control server and the HTTP API in one process; everything else is a CLI that either does the work itself or hands it to a running daemon | `crates/ipx` | `Dockerfile` |
| ipx | The daemon and CLI, one binary, `ipxd`. `ipxd daemon` runs a scheduler, a Unix-socket control server and the HTTP API in one process; everything else is a CLI that either does the work itself or hands it to a running daemon | `crates/ipx` | `Dockerfile` |
| ipx-directory | The directory of public podcasts that ipx servers share. ipx asks it on its people's behalf; the page never talks to it ([directory.md](directory.md)) | `crates/directory` | `Dockerfile.directory` |
The Rust source is a Cargo workspace (#202); `crates/feed` (`ipx-feed`) fetches and parses feeds
@@ -27,7 +27,8 @@ id, and Caddy's request lines theirs. ipx also serves Prometheus metrics (`[web]
| File | Responsibility | What it replaced in the Python |
|---|---|---|
| `crates/ipx/src/main.rs` | The module list and `main`: reads the command line and hands it on | `iPXAgent.py` |
| `crates/ipx/src/lib.rs` | The module list and `main`: reads the command line and hands it on | `iPXAgent.py` |
| `crates/ipx/src/main.rs` | `ipxd`, which calls `main`: a library under it keeps the modules' log targets `ipx::...` | — |
| `crates/ipx/src/cli.rs` | The commands, and what each does when no daemon takes it | `iPXAgent.py` |
| `crates/ipx/src/ctx.rs` | `Ctx`, what every command shares: configuration, database, clients | — |
| `crates/ipx/src/daemon.rs` | The daemon: worker loop, web server, shutdown, `status` | `iPXAgent.py` |
@@ -68,6 +69,7 @@ id, and Caddy's request lines theirs. ipx also serves Prometheus metrics (`[web]
| `crates/directory/src/store.rs` | The directory's database: feeds, snapshots, blocked | — |
| `crates/directory/src/config.rs` | The directory's config file: its tokens and their access | — |
| `crates/directory/src/otel.rs` | Traces for both Rust services: the exporter, `traceparent` in and out | — |
| `crates/tui/src/main.rs` | `ipx` (package `ipx-tui`), the reader in a terminal: ratatui over the API, with an API token | — |
| `web/index.html` | The app's markup | — |
| `web/admin.html` | The admin page's markup: server settings, accounts, the log. Sent to admins only | — |
| `web/app.css` | The stylesheet both pages share | — |
@@ -156,7 +158,7 @@ printf '{"cmd":"fetch","force":true}\n' | socat - UNIX-CONNECT:$XDG_RUNTIME_DIR/
**Commands** — `fetch` (optional `feed`, `force`), `reap` (optional `dry_run`), `download`
(`enclosure`), `status`, `reload` (read the catalogue and settings again from the database, which
`ipx add`, `rm` and `import` send after changing them in a process of their own; answered with
`ipxd add`, `rm` and `import` send after changing them in a process of their own; answered with
`status`).
**Events** — `feed_start`, `feed_skip`, `feed_done`, `feed_error`, `progress`, `download_done`,