An audit after 0.10.1 found the docs behind the code. architecture.md named no reload command (#120) and still said a changed title was picked up, false since #96 until #141; it now says what a scan writes again, and what the Directory page's endpoint sends (#142). cli.md lacked add's --list and --category, and that add, rm and import tell a running daemon to read the catalogue again. users.md did not mention Currently Listening or its search (#127). configuration.md says that ipx no longer waits for the disk on each write, on SQLite or Postgres (#135, #140), and what that can lose. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
98 lines
4.1 KiB
Markdown
98 lines
4.1 KiB
Markdown
# Command line
|
|
|
|
```
|
|
ipx [--config PATH] [--local] <command>
|
|
```
|
|
|
|
Every command that has a wire form probes the control socket first: if a daemon is running, the
|
|
daemon does the work and the CLI just renders the events it streams back. That is deliberate — two
|
|
processes must never download the same thing. `--local` forces the work to happen in-process.
|
|
|
|
| Command | What it does |
|
|
|---|---|
|
|
| `ipx list` | Subscriptions and their state |
|
|
| `ipx status` | Counts: feeds, pending, downloaded |
|
|
| `ipx fetch [FEED] [--force]` | Scan everything, or one feed. `--force` ignores the TTL |
|
|
| `ipx add <url> [--folder X] [--keywords a,b] [--list] [--category C]` | Subscribe; the id comes from the feed title. `--list` puts it in the Directory for anyone to subscribe to instead, and keeps it there when its last subscriber leaves; `--category` files it under one of the Directory's categories. Run for a feed already in the catalogue, these list it or set its category |
|
|
| `ipx rm <feed>` | Unsubscribe; downloads and history are kept |
|
|
| `ipx import <file.opml>` / `ipx export <file.opml>` | Move subscriptions in or out. Import subscribes the first admin, as the shared web token does; in the web UI it subscribes whoever is signed in |
|
|
| `ipx reap [--dry-run]` | Run retention now |
|
|
| `ipx user <add\|list\|passwd\|rm>` | Accounts for the web UI |
|
|
| `ipx daemon [--web ADDR]` | Scheduler, control socket and web UI |
|
|
|
|
`add`, `rm` and `import` change the catalogue in a process of their own. With a daemon running they
|
|
then tell it to read the catalogue again; without that it kept its own copy and wrote it back at
|
|
its next change, undoing them. If it does not answer they say so: restart it.
|
|
|
|
## Accounts
|
|
|
|
Passwords are read from **stdin**, so they miss the shell history and any `ps` listing.
|
|
|
|
```sh
|
|
echo -n 'a good password' | ipx user add ray # local account
|
|
ipx user add ray@example.com --no-password # signs in through the proxy only
|
|
echo -n 'a good password' | ipx user passwd admin # change a password
|
|
ipx user list # who exists, and how each signs in
|
|
ipx user rm sam # account, subscriptions and read state
|
|
```
|
|
|
|
The first account created is an admin; later ones are ordinary users. A database with no accounts
|
|
at all gets **admin / ipodderx** on the next daemon start, announced in the log — change it.
|
|
|
|
To avoid even the command line, read it interactively:
|
|
|
|
```sh
|
|
read -s PW && echo -n "$PW" | ipx user passwd admin
|
|
```
|
|
|
|
## Scanning
|
|
|
|
```sh
|
|
ipx fetch # everything due
|
|
ipx fetch atp --force # one feed, ignoring its TTL and schedule
|
|
```
|
|
|
|
A scan: conditional GET (`If-None-Match` / `If-Modified-Since`), parse, record new entries, apply
|
|
the filters, then download up to the per-scan cap, newest first. A feed nothing has changed in
|
|
answers `304` and costs one request.
|
|
|
|
## Retention
|
|
|
|
```sh
|
|
ipx reap --dry-run # what would go, oldest first
|
|
ipx reap # actually delete
|
|
```
|
|
|
|
Files are deleted to get back under `max_total_gb`, oldest first, and items past `max_age_days`
|
|
with no file are pruned from the database. **An item anyone kept keeps its file**, and one only counts
|
|
as read when everyone subscribed has read it. The enclosure row survives as `reaped`, which is what
|
|
stops the next scan fetching it again.
|
|
|
|
## The daemon
|
|
|
|
```sh
|
|
ipx daemon # scheduler + socket + web UI
|
|
ipx daemon --web 0.0.0.0:8099 # override the configured bind for one run
|
|
```
|
|
|
|
One daemon per socket; a second refuses to start rather than fight over the database. It shuts down
|
|
cleanly on SIGTERM, including mid-download.
|
|
|
|
To kill it, match the binary exactly:
|
|
|
|
```sh
|
|
pkill -x ipx
|
|
```
|
|
|
|
`pkill -f ipx` matches the shell running the command too, and kills your own session. On a machine
|
|
that also runs ipx in a container, `pkill -x ipx` stops that one as well, since the host sees a
|
|
container's processes: stop the one you started by its PID instead (`kill <pid>`).
|
|
|
|
## Talking to it directly
|
|
|
|
```sh
|
|
printf '{"cmd":"fetch","force":true}\n' | socat - UNIX-CONNECT:$XDG_RUNTIME_DIR/ipx.sock
|
|
```
|
|
|
|
See [architecture.md](architecture.md#control-socket) for the protocol.
|