examples: anime library sorter + pure-Lua Anitomy parser
Add a worked nautd scripting example that files each anime episode into a
media-server-friendly library the moment its file finishes verifying:
<SORTED_ROOT>/<Title>/Season NN/<Title> - SNNENN.<ext>
- examples/anitomy.lua: a compact, dependency-free reimplementation of Anitomy
(title/season/episode/release-group/resolution/year) in pure Lua — no
require/io/os, so it embeds in the sandbox.
- examples/anime_sort.lua: on_file_complete hook that parses the filename and
calls naut.move_file(); the embedded parser is a verbatim copy of anitomy.lua.
- examples/test_anitomy.lua, test_anime_sort.lua: parser battery + end-to-end
path-building test with an embedded-vs-module drift guard. Wired into ctest as
example_anitomy / example_anime_sort when a lua interpreter is present.
- docs: examples/README.md plus pointers from README and docs/scripting.md.
Verified end to end against a live nautd: file_complete -> move_file -> on-disk
relocate into the sorted tree.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
2178d6a70c
commit
50a357968a
8 changed files with 837 additions and 1 deletions
75
examples/test_anitomy.lua
Normal file
75
examples/test_anitomy.lua
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
-- Battery test for anitomy.lua. Run: lua examples/test_anitomy.lua
|
||||
package.path = (arg[0]:match("^(.*/)") or "./") .. "?.lua;" .. package.path
|
||||
local anitomy = require("anitomy")
|
||||
|
||||
local fails = 0
|
||||
local function check(name, want)
|
||||
local p = anitomy.parse(name)
|
||||
local ok = true
|
||||
local why = {}
|
||||
for _, k in ipairs({ "title", "season", "episode" }) do
|
||||
if want[k] ~= nil and p[k] ~= want[k] then
|
||||
ok = false
|
||||
why[#why + 1] = string.format("%s: got %s want %s",
|
||||
k, tostring(p[k]), tostring(want[k]))
|
||||
end
|
||||
end
|
||||
if not ok then
|
||||
fails = fails + 1
|
||||
print("FAIL " .. name)
|
||||
for _, w in ipairs(why) do print(" " .. w) end
|
||||
else
|
||||
print(string.format("ok %-58s -> %s / S%s / E%s",
|
||||
name, p.title, tostring(p.season), tostring(p.episode)))
|
||||
end
|
||||
end
|
||||
|
||||
-- title, season, episode expectations
|
||||
check("[HorribleSubs] Boku no Hero Academia - 12 [1080p].mkv",
|
||||
{ title = "Boku no Hero Academia", season = 1, episode = 12 })
|
||||
check("[SubsPlease] Spy x Family - 05 (1080p) [A1B2C3D4].mkv",
|
||||
{ title = "Spy x Family", season = 1, episode = 5 })
|
||||
check("[Group] Attack on Titan S04E28 [BD 1080p HEVC].mkv",
|
||||
{ title = "Attack on Titan", season = 4, episode = 28 })
|
||||
check("Kaguya-sama wa Kokurasetai S2 - 03 [720p].mkv",
|
||||
{ title = "Kaguya-sama wa Kokurasetai", season = 2, episode = 3 })
|
||||
check("[Erai-raws] Jujutsu Kaisen 2nd Season - 17 [1080p][Multiple Subtitle].mkv",
|
||||
{ title = "Jujutsu Kaisen", season = 2, episode = 17 })
|
||||
check("One.Piece.S01E1071.1080p.WEB.x264.mkv",
|
||||
{ title = "One Piece", season = 1, episode = 1071 })
|
||||
check("Anime_Name_-_01v2_[BD][720p].mkv",
|
||||
{ title = "Anime Name", season = 1, episode = 1 })
|
||||
check("[Judas] Chainsaw Man - 08v2 [1080p][HEVC x265 10bit].mkv",
|
||||
{ title = "Chainsaw Man", season = 1, episode = 8 })
|
||||
check("Mob Psycho 100 II - 05 [1080p].mkv",
|
||||
{ title = "Mob Psycho 100 II", season = 1, episode = 5 })
|
||||
check("[Commie] Steins;Gate 0 - 12 [BD 1080p].mkv",
|
||||
{ title = "Steins;Gate 0", season = 1, episode = 12 })
|
||||
check("[Group] Re Zero kara Hajimeru Isekai Seikatsu - Episode 25 [1080p].mkv",
|
||||
{ title = "Re Zero kara Hajimeru Isekai Seikatsu", season = 1, episode = 25 })
|
||||
check("Naruto Shippuuden - 500 [720p].mkv",
|
||||
{ title = "Naruto Shippuuden", season = 1, episode = 500 })
|
||||
check("[Group] Bleach - Season 2 - 14 [1080p].mkv",
|
||||
{ title = "Bleach", season = 2, episode = 14 })
|
||||
check("Demon.Slayer.Kimetsu.no.Yaiba.S03E11.1080p.mkv",
|
||||
{ title = "Demon Slayer Kimetsu no Yaiba", season = 3, episode = 11 })
|
||||
check("[Doki] K-On! - 01 (1280x720 Hi10P AAC) [12345678].mkv",
|
||||
{ title = "K-On!", season = 1, episode = 1 })
|
||||
check("[Group] Vinland Saga S2 - 24 END [1080p].mkv",
|
||||
{ title = "Vinland Saga", season = 2, episode = 24 })
|
||||
check("Frieren - 28 [Multi Sub] [1080p].mkv",
|
||||
{ title = "Frieren", season = 1, episode = 28 })
|
||||
|
||||
-- movie / no-episode cases: episode must be nil
|
||||
check("[Group] A Silent Voice [BD 1080p FLAC].mkv",
|
||||
{ title = "A Silent Voice", episode = nil })
|
||||
check("Spirited.Away.2001.1080p.BluRay.x264.mkv",
|
||||
{ title = "Spirited Away", episode = nil })
|
||||
|
||||
if fails == 0 then
|
||||
print("\nALL PASS")
|
||||
os.exit(0)
|
||||
else
|
||||
print("\n" .. fails .. " FAILED")
|
||||
os.exit(1)
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue