Drop the web UI that was compiled into nautctl and serve the torrent-ui front end (../torrent-ui/public) from a native plugin (plugins/webui) loaded via `nautd --plugin`. The plugin talks to the engine only through the host call_rpc ABI and adapts the daemon's RPC surface to the qBittorrent-style contract the UI expects (snapshot/SSE, torrent detail tabs, add/delete, cookie auth). Also folds in the daemon refactor that owns per-torrent worker threads and the swarm engine (naut_swarm) used by the plugin's data source. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
83 lines
3 KiB
Markdown
83 lines
3 KiB
Markdown
# Examples
|
|
|
|
Drop-in Lua scripts for the `nautd` scripting layer (see
|
|
[`../docs/scripting.md`](../docs/scripting.md)).
|
|
|
|
## `anime_sort.lua` — sort anime into a library as it downloads
|
|
|
|
Files each episode into a clean, media-server-friendly tree **the moment its
|
|
file finishes verifying** — before the rest of the torrent completes — using
|
|
Naut-Torrent's `on_file_complete` hook + `naut.move_file()`:
|
|
|
|
```
|
|
<SORTED_ROOT>/<Anime Title>/Season NN/<Anime Title> - SNNENN.<ext>
|
|
```
|
|
|
|
Movies (no detectable episode) go to `<SORTED_ROOT>/<Title>/<Title> (year).<ext>`.
|
|
|
|
### Use it
|
|
|
|
```sh
|
|
# Start the engine, load the script, and add a download.
|
|
nautd --socket /tmp/nautd.sock
|
|
nautctl --socket /tmp/nautd.sock script examples/anime_sort.lua
|
|
nautctl --socket /tmp/nautd.sock add show.torrent /downloads/1
|
|
```
|
|
|
|
As each file completes you'll see, e.g.:
|
|
|
|
```
|
|
[anime_sort] [SubsPlease] Frieren - 12 [1080p].mkv -> /library/Frieren/Season 01/Frieren - S01E12.mkv
|
|
```
|
|
|
|
### Options (top of the script)
|
|
|
|
| Option | Default | Effect |
|
|
|---|---|---|
|
|
| `SORTED_ROOT` | `/sorted` | destination library root |
|
|
| `ONLY_VIDEO` | `true` | skip non-video files (subtitles, `.nfo`, samples) and leave them in place |
|
|
| `KEEP_ORIGINAL_NAME` | `false` | `true` keeps the original filename instead of `Title - SNNENN.ext` |
|
|
|
|
## `anitomy.lua` — the anime filename parser
|
|
|
|
A compact, dependency-free reimplementation of the ideas in
|
|
[Anitomy](https://github.com/erengy/anitomy): given a scene/fansub filename it
|
|
returns the anime **title**, **season**, **episode** (plus release group,
|
|
resolution, year, extension). Pure Lua, no `require`/`io`/`os`, so it can be
|
|
embedded verbatim in a sandboxed script — which is exactly what `anime_sort.lua`
|
|
does.
|
|
|
|
```lua
|
|
local anitomy = require("anitomy")
|
|
local p = anitomy.parse("[Erai-raws] Jujutsu Kaisen 2nd Season - 17 [1080p].mkv")
|
|
-- p.title = "Jujutsu Kaisen", p.season = 2, p.episode = 17, p.extension = "mkv"
|
|
```
|
|
|
|
`anime_sort.lua` carries a **verbatim copy** of this parser (the sandbox can't
|
|
`require`); `test_anime_sort.lua` asserts the two stay in agreement.
|
|
|
|
### What it recognizes
|
|
|
|
- `[Group] Title - 12 [1080p].mkv` (dash-delimited episode)
|
|
- `Title S04E28`, `Title S2 - 03`, `Title 2nd Season - 17`, `Title Season 2 - 14`
|
|
- `Title.S03E11.1080p.x264.mkv` (dotted delimiters)
|
|
- `Title_-_01v2_[720p].mkv` (underscores, version suffix)
|
|
- `Episode 25`, `Ep5`, `#07`, absolute numbering (`- 500`)
|
|
- ranges (`01-12`), release-group and CRC/resolution stripping, movie years
|
|
|
|
### Heuristic limitations (honest)
|
|
|
|
- A title that ends in a number with no episode marker (`Mob Psycho 100.mkv`)
|
|
treats the number as the episode — same as Anitomy.
|
|
- Absolute episode numbering reports season 1 (there is no season marker to read).
|
|
- Episode *titles* after the number (`- 05 - The Battle`) are dropped.
|
|
|
|
## Tests
|
|
|
|
```sh
|
|
lua examples/test_anitomy.lua # parser battery
|
|
lua examples/test_anime_sort.lua # end-to-end path building + drift guard
|
|
```
|
|
|
|
These also run under `ctest` (as `example_anitomy` / `example_anime_sort`) when a
|
|
`lua` interpreter is on `PATH`.
|