readTorrentFile only returned parsed metadata for the preview, so a
file-based add sent no torrent content and the server rejected it. Include
the raw bytes as base64 ("data") alongside the preview fields so uploads
actually add.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|---|---|---|
| public | ||
| server | ||
| .gitignore | ||
| package.json | ||
| README.md | ||
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.
node server/index.js # → http://localhost:8088
# or
npm start
PORT=9000 npm start # custom port
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 ·Nadd ·Spacepause/resume ·Enterproperties ·Delremove ·Ctrl/⌘-Aselect all ·Escclose.
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
API (stub)
| Method | Path | Purpose |
|---|---|---|
| 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.