- Automation tab: settings form (define_settings) beside the editor, stacking above it when narrow; script/settings save split. - Set location modal: current location + reset checkbox. - saveScriptSettings/setSavePath API wiring; plugins panel. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
162 lines
7.7 KiB
Markdown
162 lines
7.7 KiB
Markdown
# NAUT — Torrent Console
|
||
|
||
*Naut* — short for nautical; a nod to the sea (and "psychonaut"-style explorer of the swarm).
|
||
|
||
|
||
An advanced, power-user-focused **web UI for a torrent client**, with a fully
|
||
**stubbed server** so you can run it and click around immediately. No build step,
|
||
no npm dependencies — just Node.
|
||
|
||
```bash
|
||
node server/index.js # → http://localhost:8088
|
||
# or
|
||
npm start
|
||
PORT=9000 npm start # custom port
|
||
```
|
||
|
||
The UI requires a login. If you do not configure one, the server prints a
|
||
generated password at startup for the default `admin` user. For a stable public
|
||
deployment, set credentials explicitly:
|
||
|
||
```bash
|
||
NAUT_AUTH_USER=admin NAUT_AUTH_PASSWORD='change-me' npm start
|
||
```
|
||
|
||
You can also set `NAUT_AUTH_PASSWORD_HASH` to a `pbkdf2-sha256$...` hash emitted
|
||
by the same password hashing format used by the server.
|
||
|
||
The server ships 24 mock torrents in varied states and runs a 1-second
|
||
**simulator** that fluctuates speeds, advances downloads, fills the piece map,
|
||
drifts the swarm, and accumulates session/ratio stats — so the UI is genuinely
|
||
*live*, not static.
|
||
|
||
---
|
||
|
||
## Design rationale (researched against qBittorrent, Flood, Deluge, Tixati)
|
||
|
||
Advanced users want **information density + fast bulk control**. The layout is the
|
||
classic three-pane "fleet console":
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ Toolbar: add · resume/pause/recheck/delete · queue · filter · ▼▲ rates · 🐢 │
|
||
├────────────┬─────────────────────────────────────────────────┤
|
||
│ Sidebar │ View tabs: Torrents · RSS · Search · Engine │
|
||
│ • Status │ ┌─────────────────────────────────────────────┐ │
|
||
│ • Categories│ │ Sortable, multi-select torrent grid │ │
|
||
│ • Tags │ │ (progress bars, state dots, tags, columns) │ │
|
||
│ • Trackers │ ├─────────────────────────────────────────────┤ │
|
||
│ │ │ Detail: General·Trackers·Peers·Content·Pieces│ │
|
||
├────────────┴─┴─────────────────────────────────────────────┴─┤
|
||
│ Status bar: DHT · port · active · session ▼▲ · ratio · cache · disk │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Feature set built for advanced users
|
||
- **Dense sortable grid** — click any header to sort; columns include seeds/peers
|
||
(connected vs swarm total), availability, ratio, ETA, category, tags, queue #.
|
||
- **Multi-select + bulk ops** — click / Ctrl-click / Shift-click; toolbar and
|
||
right-click context menu act on the whole selection.
|
||
- **Detail panel** with the five tabs power users live in:
|
||
- *General* — transfer + torrent metadata (pieces, hash, privacy, save/content
|
||
paths, sequential/super-seed/auto-TMM flags, session totals, time active).
|
||
- *Trackers* — tier, status, seeds/peers/leeches, announce message, plus the
|
||
DHT/PeX/LSD pseudo-trackers.
|
||
- *Peers* — IP:port, country, client, connection type, **BT flag string**,
|
||
progress, per-peer up/down, relevance.
|
||
- *Content* — file tree with per-file **priority selector** (Skip/Normal/High/Max)
|
||
and per-file progress/availability.
|
||
- *Pieces* — live **piece map** (have / downloading / missing).
|
||
- **Sidebar filters** — status (downloading, seeding, completed, active, stalled,
|
||
paused, errored…), categories, tags, and tracker hosts, each with live counts.
|
||
- **RSS & automation** — feeds, unread articles, and auto-download rules
|
||
(must/must-not contain, regex, target category + save path, add-paused).
|
||
- **Integrated search** — multi-indexer search with seeds/leeches, one-click add.
|
||
- **Engine view** — bandwidth, connection, queueing, and privacy/BitTorrent
|
||
(DHT/PeX/LSD, encryption mode, µTP) preferences.
|
||
- **Alt-speed (🐢) toggle**, global rate display vs. limits, resizable detail pane.
|
||
- **Keyboard shortcuts**: `/` filter · `N` add · `Space` pause/resume ·
|
||
`Enter` properties · `Del` remove · `Ctrl/⌘-A` select all · `Esc` close.
|
||
|
||
---
|
||
|
||
## Architecture
|
||
|
||
```
|
||
server/
|
||
index.js Zero-dependency http server: static + JSON API + SSE stream
|
||
data.js Mock fleet generator (torrents, trackers, peers, files, pieces,
|
||
categories, tags, RSS feeds/rules, search, preferences)
|
||
simulator.js 1 Hz mutation of the fleet + derived global stats
|
||
public/
|
||
index.html App shell
|
||
css/styles.css Dark, dense theme
|
||
js/
|
||
app.js Controller: state, sidebar, grid, selection, context menu,
|
||
views (RSS/Search/Engine), modals, hotkeys, status bar
|
||
detail.js Detail panel tabs + live refresh + resize
|
||
api.js fetch wrappers + EventSource live stream
|
||
format.js bytes/rate/eta/ratio/date/state formatters
|
||
plugins.js Frontend plugin registry and extension-point loader
|
||
plugins/
|
||
plugins.json Plugin manifest
|
||
health.js Example plugin
|
||
```
|
||
|
||
### Plugin system
|
||
Frontend plugins are ES modules listed in `public/plugins/plugins.json`. Each
|
||
module calls `window.Naut.registerPlugin()` and can contribute:
|
||
|
||
- `views` — new top-level tabs in the main tab bar.
|
||
- `sidebarSections` — new sections in the left sidebar, with optional mount code.
|
||
- `detailTabs` — new tabs in the selected torrent detail panel.
|
||
- `detailPanels` — additional information panels appended to the General detail tab.
|
||
|
||
Minimal plugin:
|
||
|
||
```js
|
||
window.Naut.registerPlugin({
|
||
id: 'example',
|
||
name: 'Example',
|
||
views: [{
|
||
id: 'example',
|
||
label: 'Example',
|
||
render(host, { state, f }) {
|
||
host.innerHTML = `<div class="pane">Loaded ${state.snapshot.torrents.length} torrents</div>`;
|
||
},
|
||
}],
|
||
});
|
||
```
|
||
|
||
Add the module path to `public/plugins/plugins.json`:
|
||
|
||
```json
|
||
{ "modules": ["/plugins/example.js"] }
|
||
```
|
||
|
||
### API (stub)
|
||
| Method | Path | Purpose |
|
||
|---|---|---|
|
||
| GET | `/api/auth/status` | Session state and login metadata |
|
||
| POST | `/api/login`, `/api/logout` | Create or clear a session |
|
||
| GET | `/api/plugins` | Authenticated plugin manifest |
|
||
| GET | `/api/stream` | **SSE** — pushes a compact snapshot (~1/s) |
|
||
| GET | `/api/snapshot` | One-shot snapshot (grid + server stats) |
|
||
| GET | `/api/meta` | Categories, tags, tracker hosts, prefs, search plugins |
|
||
| GET | `/api/torrents/:hash` | Full general properties |
|
||
| GET | `/api/torrents/:hash/{trackers,peers,files,pieces}` | Tab data |
|
||
| POST | `/api/action` | `{action, hashes, params}` — pause/resume/recheck/queue/category/limits… |
|
||
| POST | `/api/delete` | `{hashes, deleteFiles}` |
|
||
| POST | `/api/add` | `{magnet, name, category, savePath, paused, seqDl, skipCheck}` |
|
||
| POST | `/api/altspeed` | Toggle alternative speed limits |
|
||
| GET | `/api/rss`, `/api/rss/rules` | Feeds + auto-download rules |
|
||
| GET | `/api/search?q=` | Indexer search |
|
||
|
||
### Wiring to a real client
|
||
The stub mirrors common client semantics. To go live, replace the handlers in
|
||
`server/index.js` with adapters to a real backend — the shapes map closely to:
|
||
- **qBittorrent** Web API v2 (`/api/v2/torrents/info`, `/sync/maindata`, …)
|
||
- **Transmission** RPC (`torrent-get`/`torrent-set`)
|
||
- **Deluge** JSON-RPC
|
||
|
||
Keep the SSE `snapshot` contract and the frontend needs no changes.
|