Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

202 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

anime-organizer

CI Crates.io License: AGPL-3.0

่ฝป้‡็บงใ€่ทจๅนณๅฐๅ‘ฝไปค่กŒๅทฅๅ…ท๏ผŒไธ“ไธบๅŠจๆผซๆ”ถ่—่€…ๆ‰น้‡ๆ•ด็†่ง†้ข‘ๆ–‡ไปถ๏ผŒๆ”ฏๆŒ็กฌ้“พๆŽฅๆจกๅผๅฎž็Žฐ้›ถ้ขๅค–็ฉบ้—ดๅ ็”จใ€‚

English | ไธญๆ–‡


ไธญๆ–‡

๐Ÿ“– ้กน็›ฎๆ่ฟฐ

anime-organizer๏ผˆ็ฎ€็งฐ aniorg๏ผ‰ๆ˜ฏไธ€ๆฌพไธ“ไธบๅŠจๆผซๆ”ถ่—่€…่ฎพ่ฎก็š„ๅ‘ฝไปค่กŒๅทฅๅ…ท๏ผŒๆ—จๅœจ่‡ชๅŠจๅŒ–ๆ•ด็†ไธ‹่ฝฝ็›ฎๅฝ•ไธญ็š„ๅŠจๆผซ่ง†้ข‘ๆ–‡ไปถใ€‚

ๆ ธๅฟƒๅŠŸ่ƒฝ๏ผš

  • ่‡ชๅŠจ่งฃๆžๆ–‡ไปถๅ๏ผŒ่ฏ†ๅˆซๅŠจๆผซๅ็งฐใ€้›†ๆ•ฐใ€ๅ‘ๅธƒ็ป„็ญ‰ไฟกๆฏ
  • ๆ”ฏๆŒ็กฌ้“พๆŽฅๆจกๅผ๏ผŒๆ•ด็†ๅŽไธๅ ็”จ้ขๅค–็ฃ็›˜็ฉบ้—ด
  • ่‡ชๅŠจ็”Ÿๆˆ Kodi ๅ…ผๅฎน็š„ NFO ๅ…ƒๆ•ฐๆฎๆ–‡ไปถ
  • ไธ‹่ฝฝๅฐ้ขๆตทๆŠฅๅ’Œ่ƒŒๆ™ฏๅ›พ
  • ็”Ÿๆˆ MiruPlay ๅฏ็›ดๆŽฅๅฏผๅ…ฅ็š„ MLIP library.db๏ผŒๅนถ่กฅ้ฝ Bangumi ๅ…ƒๆ•ฐๆฎๅ’ŒๆตทๆŠฅ
  • ๆ”ฏๆŒ RSS ่ฎข้˜…ๅ’Œ 115 ็ฝ‘็›˜ๅŒๆญฅ๏ผˆ้œ€ๅฏ็”จ clouddrive feature๏ผ‰

้€‚็”จๅœบๆ™ฏ๏ผš

  • ๆ•ด็†ไธ‹่ฝฝ็›ฎๅฝ•ไธญ็š„ๅŠจๆผซๆ–‡ไปถ
  • ่‡ชๅŠจๅŒ–็ฎก็†ๅŠจๆผซๅช’ไฝ“ๅบ“
  • ไธบ Kodi/Jellyfin/Plex ็ญ‰ๅช’ไฝ“ไธญๅฟƒ็”Ÿๆˆๅ…ƒๆ•ฐๆฎ

๐Ÿš€ ๅŠŸ่ƒฝ็‰นๆ€ง

  • ๆ™บ่ƒฝ่งฃๆž: ่‡ชๅŠจ่ฏ†ๅˆซ [ๅ‘ๅธƒ็ป„] ๅŠจๆผซๅ - ้›†ๆ•ฐ [ๆ ‡็ญพ].ext ๆ ผๅผ
  • ็ตๆดปๆ•ด็†: ้‡ๆž„ไธบ ๅŠจๆผซๅ/Season N/้›†ๆ•ฐ [ๆ ‡็ญพ].ext ็ป“ๆž„
  • ๅคš็งๆจกๅผ: ๆ”ฏๆŒ็งปๅŠจใ€ๅคๅˆถใ€็กฌ้“พๆŽฅไธ‰็งๆ“ไฝœๆจกๅผ
  • ๅ…ƒๆ•ฐๆฎๅˆฎๅ‰Š: ๅŸบไบŽ Bangumi ็”Ÿๆˆ Kodi ๅ…ผๅฎน็š„ NFO ๆ–‡ไปถ
  • ๅฐ้ขไธ‹่ฝฝ: ไผ˜ๅ…ˆ้€š่ฟ‡ Bangumi ไธ‹่ฝฝๆตทๆŠฅ๏ผŒTMDB ไฝœไธบๅค‡้€‰ๅนถ่กฅๅ……่ƒŒๆ™ฏๅ›พ๏ผŒAniDB ไฝœไธบๆœ€็ปˆๆตทๆŠฅๅ…œๅบ•
  • ๅˆซๅๅŒน้…: ๆ”ฏๆŒๆœฌๅœฐ bangumi.db ๅˆซๅๅบ“ๅ’Œ่‡ชๅฎšไน‰ JSON ่ฆ†็›–๏ผŒ็ผบๅคฑๆ—ถๅ›ž้€€ๅˆฐ Bangumi ๅ็งฐ/ๆœ็ดขๅŒน้…
  • RSS ่ฎข้˜…: ๆ”ฏๆŒ RSS ่‡ชๅŠจ่ฎข้˜…ๅ’Œ 115 ็ฝ‘็›˜ๅŒๆญฅ๏ผˆ้œ€ clouddrive feature๏ผ‰
  • ่ทจๅนณๅฐ: ๆ”ฏๆŒ Windowsใ€Linuxใ€macOS
  • ไพฟๆบ้ƒจ็ฝฒ: ๅคงๅคšๆ•ฐๅนณๅฐไธบๅ•ๆ–‡ไปถ๏ผ›Windows x64 AniFileBERT ๅ‘ๅธƒๅŒ…้œ€่ฎฉ DirectML.dll ไธŽ aniorg.exe ไฟๆŒๅŒ็›ฎๅฝ•
  • ้ซ˜ๆ€ง่ƒฝ: Rust ๅŽŸ็”Ÿๅฎž็Žฐ๏ผŒๆž้€Ÿๅค„็†

๐Ÿ“ฅ ๅฎ‰่ฃ…ๆ–นๅผ

ๆ–นๅผไธ€๏ผšไธ‹่ฝฝ้ข„็ผ–่ฏ‘ไบŒ่ฟ›ๅˆถ

ไปŽ GitHub Releases ไธ‹่ฝฝๅฏนๅบ”ๅนณๅฐ็š„ไบŒ่ฟ›ๅˆถๆ–‡ไปถ๏ผš

ๅนณๅฐ ๆ–‡ไปถ
Windows x64 aniorg-<version>-x86_64-pc-windows-msvc.zip
Windows ARM64 aniorg-<version>-aarch64-pc-windows-msvc.zip
Linux x64 aniorg-<version>-x86_64-unknown-linux-gnu.tar.gz
Linux x64 (musl) aniorg-<version>-x86_64-unknown-linux-musl.tar.gz
Linux ARM64 aniorg-<version>-aarch64-unknown-linux-gnu.tar.gz
macOS x64 aniorg-<version>-x86_64-apple-darwin.tar.gz
macOS ARM64 aniorg-<version>-aarch64-apple-darwin.tar.gz

Windows x64 ๅŽ‹็ผฉๅŒ…ไธญ็š„ aniorg.exe ๅ’Œ DirectML.dll ๅบ”ไธ€่ตท่งฃๅŽ‹ใ€‚ๅณไฝฟไฝฟ็”จ CPU provider๏ผŒไนŸๅปบ่ฎฎไฟ็•™ๅ‘ๅธƒๅŒ…็š„ๅฎŒๆ•ดๅ†…ๅฎนใ€‚

ๆ–นๅผไบŒ๏ผšไปŽๆบ็ ๆž„ๅปบ

git clone https://github.com/ModerRAS/anime-organizer.git
cd anime-organizer

# ้ป˜่ฎคๆž„ๅปบ๏ผˆๅฏ็”จ metadata feature๏ผ‰
cargo build --release

# ๅ…จๅŠŸ่ƒฝๆž„ๅปบ
cargo build --release --features "scraper clouddrive torrent-scraper"

# ๅฏ็”จๅตŒๅ…ฅๅผ AniFileBERT ONNX ๆ–‡ไปถๅ่งฃๆžๅ™จ๏ผˆCPU๏ผ‰
cargo build --release --features "anifilebert"

# ๅฏ็”จ AniFileBERT + Windows DirectML๏ผˆGPU๏ผ›NPU ๅฏๆ˜พๅผ้€‰ๆ‹ฉ๏ผ‰
cargo build --release --features "anifilebert-directml"

็ผ–่ฏ‘ๅŽ็š„ไบŒ่ฟ›ๅˆถๆ–‡ไปถไฝไบŽ target/release/aniorgใ€‚ANIORG_BERT_PROVIDER=cpu|auto|directml-gpu|directml-npu|directml-any ๆŽงๅˆถ ONNX Runtime provider๏ผ›ANIORG_DIRECTML_DEVICE_ID=0 ๅฏๆŒ‡ๅฎš DirectML ่ฎพๅค‡ใ€‚ๆœชๅฏ็”จ anifilebert-directml ๆ—ถ้ป˜่ฎค CPU๏ผ›ๅฏ็”จๅŽ้ป˜่ฎค auto๏ผŒไผšๅ…ˆๅฐ่ฏ• DirectML GPU๏ผŒๅคฑ่ดฅๅˆ™ๅ›ž้€€ CPUใ€‚CPU ็บฟ็จ‹ๆ•ฐๅฏ็”จ ANIORG_ORT_INTRA_THREADS ๅ’Œ ANIORG_ORT_INTER_THREADS ่ฐƒๆ•ด๏ผŒ้ป˜่ฎคๅ‡ไธบ 1ใ€‚anifilebert-amd-npu ไปๅฏ็”จ๏ผŒๆ˜ฏ anifilebert-directml ็š„ๅ…ผๅฎนๅˆซๅ๏ผ›VitisAI ้œ€่ฆ้ขๅค–็š„ ONNX Runtime provider ๅŒ…๏ผŒๆœชๆ”พๅ…ฅ้ป˜่ฎคๆž„ๅปบใ€‚

ๅฆ‚ๆžœๆœฌๆœบ้ป˜่ฎคๆ˜ฏ GNU Rust ๅทฅๅ…ท้“พ๏ผŒWindows ไธŠ้ชŒ่ฏ AniFileBERT/DirectML ๆ—ถ่ฏทๆ˜พๅผๆŒ‡ๅฎš MSVC rustcใ€‚่‹ฅ ONNX Runtime ๅœจๆœฌๅœฐ้“พๆŽฅ้˜ถๆฎตๆŠฅ้”™๏ผŒๅฏๅฐ† ORT_LIB_LOCATION ๆŒ‡ๅ‘่งฃๅŽ‹ๅŽ็š„ ORT ็›ฎๅฝ•๏ผŒๅนถ่ฎพ็ฝฎ ORT_PREFER_DYNAMIC_LINK=1 ๆ”น่ตฐ import-lib/dll ่ทฏ็บฟใ€‚

Daemon ไธŽ WebUI

Windows ไฝฟ็”จไปฅไธ‹ๅ”ฏไธ€ๅ…ฅๅฃๅฏๅŠจๆœฌๅœฐ daemon๏ผš

aniorg.exe --daemon

WebUI ๅ’Œ typed WebAPI ไป…็›‘ๅฌ http://127.0.0.1:32145/ใ€‚ๆœ‰้™ไปปๅŠก็”ฑไธ€ไธชๆŒไน…ๅŒ– worker ไธฒ่กŒๆ‰ง่กŒ๏ผ›daemon ๆ•ฐๆฎไฝไบŽ %LOCALAPPDATA%\anime-organizer\daemon.dbใ€‚CloudDrive token ไปฅๅŠ CloudDrive/WebDAV ็”จๆˆทๅๅ’Œๅฏ†็ ไพ่ต–ๅฝ“ๅ‰ Windows ็”จๆˆทๅฏน่ฏฅ็›ฎๅฝ•็š„ ACL ไฟๆŠค๏ผŒไปฅๆ˜Žๆ–‡ๅญ˜ๅ‚จๅœจๆœฌๅœฐๆ•ฐๆฎๅบ“ไธญ๏ผŒไฝ†ไธไผš็”ฑ API ่ฟ”ๅ›ž๏ผŒไนŸไธไผšๅ†™ๅ…ฅๆต่งˆๅ™จๅญ˜ๅ‚จใ€‚v1 ไป…้€‚็”จไบŽๅ—ไฟกไปป็š„ๆœฌๆœบๅ•็”จๆˆท็Žฏๅขƒใ€‚

RSS ่‡ชๅŠจๆ•ด็†ๆ”ฏๆŒไธค็งๆฅๆบๆจกๅผ๏ผšoffline ้€š่ฟ‡ BTIH ๅ…ณ่” CloudDrive ็ฆป็บฟไปปๅŠก๏ผŒoriginal ็›ดๆŽฅๆ‰ซๆ่ฎข้˜…้…็ฝฎ็š„่ฟœ็ซฏๆบ็›ฎๅฝ•๏ผŒไธไพ่ต–็ฆป็บฟไธ‹่ฝฝ่ฎฐๅฝ•ใ€‚RSS ไธ‹่ฝฝ่ฟžๆŽฅๅฟ…้กปๆ˜ฏ CloudDrive๏ผ›ๆ•ด็†็›ฎๆ ‡่ฟžๆŽฅๅฏ็‹ฌ็ซ‹้€‰ๆ‹ฉ CloudDrive ๆˆ– WebDAVใ€‚ๅฏ็”จโ€œ่ฟœ็ซฏ MLIPโ€ๆ—ถ๏ผŒdaemon ๅชๅœจ hash ็ผ“ๅญ˜ๆœชๅ‘ฝไธญๆ—ถๆŠŠๅŽŸๅง‹ๅช’ไฝ“ไธ‹่ฝฝๅˆฐ็ณป็ปŸไธดๆ—ถๆ–‡ไปถ๏ผŒๆ ก้ชŒๅคงๅฐๅนถๅœจๆœฌๅœฐ่ฎก็ฎ—ๅฎŒๆ•ด SHA-256๏ผ›้šๅŽไธ‹่ฝฝ็›ฎๆ ‡ๆ น็›ฎๅฝ•็š„ library.db ๆ‰ง่กŒ SQLite ๅขž้‡ไบ‹ๅŠก๏ผŒๅ†้€š่ฟ‡่ฟœ็ซฏไธดๆ—ถๆ–‡ไปถใ€ๅค‡ไปฝ้‡ๅ‘ฝๅๅ’Œ SHA-256 ๆ ก้ชŒๅ‘ๅธƒ๏ผŒๆœ€ๅŽๆ‰็งปๅŠจๅช’ไฝ“ใ€‚ๅ…ณ้—ญโ€œ่ฟœ็ซฏ MLIPโ€็š„ๅŽŸๅง‹ๆจกๅผไธไผš hash ๅช’ไฝ“๏ผ›ๅŒ่ฟžๆŽฅไฝฟ็”จๅŽŸ็”Ÿ CopyFile๏ผŒ่ทจ่ฟžๆŽฅไฝฟ็”จ็ป่ฟ‡ๅคงๅฐๅ’Œ SHA-256 ้ชŒ่ฏ็š„ๆตๅผไผ ่พ“ใ€‚MLIP ๅ‘ๅธƒๅคฑ่ดฅๆ—ถไธไผš็งปๅŠจๆบ bundleใ€ๅฎŒๆˆ RSS ไปปๅŠกๆˆ–ๅˆ ้™คๆบ็›ฎๅฝ•ใ€‚

้€š็”จ storage_organize typed job ๆ”ฏๆŒๆœฌๅœฐ็›ฎๅฝ•ใ€CloudDrive ่ฟžๆŽฅๅ’Œ WebDAV ่ฟžๆŽฅไน‹้—ด็š„ copy/move ็ป„ๅˆใ€‚็›ธๅŒ่ฟœ็ซฏ่ฟžๆŽฅไผ˜ๅ…ˆไฝฟ็”จๅŽ็ซฏๅŽŸ็”Ÿ COPY/MOVE๏ผ›่ทจ็ซฏ็‚นๅ…ˆไธ‹่ฝฝๅˆฐ daemon ไธดๆ—ถๆ–‡ไปถ๏ผŒๅ†ไปฅ้š่—ไธดๆ—ถๅไธŠไผ ๏ผŒๆŒ‰ๅคงๅฐๅ’Œ SHA-256 ๆ ก้ชŒ๏ผŒ้‡ๅ‘ฝๅไธบๆœ€็ปˆๆ–‡ไปถ๏ผŒๆœ€ๅŽๆ‰ๅˆ ้™คๆบใ€‚WebDAV ่ฟžๆŽฅๆ”ฏๆŒๆ ‡ๅ‡† PROPFIND/MKCOL/GET/PUT/COPY/MOVE/DELETE ๅ’Œๅฏ้€‰ Basic Auth๏ผŒไธๆไพ› magnet/offline ไธ‹่ฝฝใ€‚็กฌ้“พๆŽฅไป็”ฑๅŽŸๆœฌๅœฐ organize job ๅค„็†ใ€‚

{
  "origin": "manual",
  "confirmed": true,
  "job": {
    "type": "storage_organize",
    "args": {
      "source": { "type": "local", "path": "C:\\Downloads\\Anime" },
      "target": { "type": "connection", "connection_id": 2, "path": "/Anime" },
      "mode": "move",
      "season_mode": true,
      "mlip": true,
      "remove_empty_dirs": true
    }
  }
}

ๆœฌๅœฐ move ๆˆๅŠŸๅŽ้ป˜่ฎคไปŽๆœ€ๆทฑๅฑ‚ๅผ€ๅง‹ๆธ…็†ๆœฌๆฌกๆ–‡ไปถๆถ‰ๅŠ็š„็ฉบๆบ็›ฎๅฝ•๏ผŒไฟ็•™ๆบๆ น็›ฎๅฝ•ๅŠไปปไฝ•ไปๅซๆ–‡ไปถ็š„็›ฎๅฝ•ใ€‚ๆ–ฐ RSS ่ฎข้˜…้ป˜่ฎคๅˆ ้™คๅทฒๅฎŒๆˆ็ฆป็บฟไปปๅŠก็•™ไธ‹็š„็ฉบๆ น็›ฎๅฝ•ใ€‚่ฎข้˜…่ฏฆๆƒ…้กต่ฟ˜ๆไพ›โ€œ้ข„่งˆ็ฉบ็›ฎๅฝ•โ€ๅ’Œโ€œๆธ…็†็ฉบ็›ฎๅฝ•โ€๏ผšๆ‰‹ๅŠจๆธ…็†ไผš้€’ๅฝ’ๅค„็†่ฏฅ่ฎข้˜…ๆบ็›ฎๅฝ•ไธ‹ๆ‰€ๆœ‰็ฉบ็›ฎๅฝ•๏ผŒไฝ†ไฟ็•™่ฎข้˜…ๆ น็›ฎๅฝ•๏ผ›ๅช่ฆ CloudDrive ไปๆŠฅๅ‘Š init ๆˆ– downloading ็ฆป็บฟไปปๅŠก๏ผŒdaemon ๅฐฑๆ‹’็ปๅผ€ๅง‹ๆธ…็†ใ€‚

๐ŸŽฏ ๅฟซ้€Ÿๅผ€ๅง‹

ๅŸบๆœฌ็”จๆณ•

# ็กฌ้“พๆŽฅๆจกๅผ๏ผˆ้ป˜่ฎค๏ผŒ้›ถ้ขๅค–็ฉบ้—ด๏ผ‰
aniorg --source="/path/to/downloads"

# ๅคๅˆถๆจกๅผ
aniorg --source="/path/to/downloads" --mode=copy --target="/path/to/anime"

# ๅฏ็”จ็กฌ้“พๆŽฅๅคฑ่ดฅๅ›ž้€€ไธบๅคๅˆถ
aniorg --source="/path/to/downloads" --fallback-on-link-failure=copy

# ๅฏ็”จๅˆ†ๅญฃ็›ฎๅฝ•็ป“ๆž„
aniorg --source="/path/to/downloads" --season-mode --target="/path/to/anime"

# ็”Ÿๆˆ NFO ๅ’ŒๆตทๆŠฅ
aniorg --source="/path/to/downloads" --scrape-metadata

# ็”Ÿๆˆ/ๆ›ดๆ–ฐ็›ฎๆ ‡็›ฎๅฝ•ๆ น้ƒจ็š„ MLIP ๅช’ไฝ“ๅบ“็ดขๅผ•
aniorg --source="/path/to/downloads" --target="/path/to/anime" --library-index

# ็”Ÿๆˆ MiruPlay ๅฏ็›ดๆŽฅๅฏผๅ…ฅ็š„ MLIP ๅช’ไฝ“ๅบ“๏ผˆๅซ Bangumi ๅ…ƒๆ•ฐๆฎๅ’ŒๆตทๆŠฅ๏ผ‰
aniorg --source="/path/to/downloads" --target="/path/to/anime" --mlip

# ๅช้‡ๅปบๆ–‡ไปถ็ดขๅผ•๏ผŒไธ่”็ฝ‘ใ€ไธไธ‹่ฝฝๅ›พ็‰‡
aniorg --source="/path/to/empty" --target="/path/to/anime" --library-index --rebuild-library-index

# ้‡ๅปบ MiruPlay ๆˆๅ“ๅบ“๏ผŒๅนถ่กฅ้ฝ Bangumi ๅ…ƒๆ•ฐๆฎๅ’Œ็ผบๅคฑๆตทๆŠฅ
aniorg --source="/path/to/empty" --target="/path/to/anime" --mlip --rebuild-library-index

# ๅช่ฏปๅ–็Žฐๆœ‰ library.db ้‡ๆ–ฐๅˆฎๅ‰Šๅ…ƒๆ•ฐๆฎ๏ผ›ไธๆ‰ซๆๅช’ไฝ“็›ฎๅฝ•
aniorg --target="/path/to/anime" --mlip --refresh-library-metadata

# ๅช่ฏป็”Ÿๆˆ็›ฎๅฝ•็ปŸไธ€/ๅŽป้‡่ฎกๅˆ’๏ผ›ไธไผš็งปๅŠจๆˆ–ๅˆ ้™คๅช’ไฝ“
aniorg normalize-layout --target="/path/to/anime" --dry-run --plan="layout-plan.json"

# ๅช่ฏป้ชŒ่ฏ artwork catalog ๅนถ็”ŸๆˆๅŽ‹ๅฎž่ฎกๅˆ’
aniorg compact-artwork-packs --target="/path/to/anime" --dry-run --plan="artwork-compact-plan.json"

normalize-layout --apply-plan ๅ’Œ compact-artwork-packs --apply-plan ๅช่ƒฝไฝœไธบ daemon typed job ๆ‰ง่กŒ๏ผŒๅนถ่ฆๆฑ‚่ฏทๆฑ‚้กถๅฑ‚ confirmed=trueใ€‚็›ดๆŽฅ CLI apply ไผšๆ‹’็ปๆ‰ง่กŒใ€‚่ฏทๅ…ˆๅฎกๆ ธ JSON plan ไธญ็š„ conflictใ€unresolvedใ€ๅˆ ้™คๆ•ฐ้‡ๅ’Œ้ข„่ฎก้‡Šๆ”พ็ฉบ้—ด๏ผ›็”Ÿๆˆ layout plan ๅชๆžšไธพ่ทฏๅพ„ใ€ๆ–‡ไปถๅใ€ๅคงๅฐ/ๆ—ถ้—ดๅ’Œ library.db ็ผ“ๅญ˜๏ผŒไธ่ฏปๅ–ๅช’ไฝ“ๆˆ– sidecar ๅ†…ๅฎน๏ผŒไนŸไธ่ฎก็ฎ—ๆ–ฐ hashใ€‚

้ข„่งˆๆจกๅผ

ๅœจๅฎž้™…ๆ“ไฝœๅ‰ๅ…ˆ้ข„่งˆๅ˜ๆ›ด๏ผš

aniorg --source="/path/to/downloads" --dry-run --verbose

๐Ÿ“‹ ๅ‚ๆ•ฐ่ฏดๆ˜Ž

ๅ‚ๆ•ฐ ็ผฉๅ†™ ็ฑปๅž‹ ๅฟ…ๅกซ ้ป˜่ฎคๅ€ผ ่ฏดๆ˜Ž
--source -s string โœ… - ๆบ็›ฎๅฝ•่ทฏๅพ„
--target -t string โŒ source ็›ฎๆ ‡ๆ น็›ฎๅฝ•
--mode -m enum โŒ link ๆ“ไฝœๆจกๅผ๏ผšmove/copy/link
--dry-run bool โŒ false ไป…้ข„่งˆไธๆ‰ง่กŒ
--include-ext string โŒ mp4,mkv,... ๅค„็†็š„ๆ‰ฉๅฑ•ๅ๏ผˆ้€—ๅทๅˆ†้š”๏ผ‰
--filename-parser enum โŒ rules ๆ–‡ไปถๅ่งฃๆžๅ™จ๏ผšrulesใ€anifilebertใ€auto๏ผˆ่ง„ๅˆ™ๅคฑ่ดฅๅŽๅ›ž้€€ AniFileBERT๏ผ‰
--verbose -v bool โŒ false ๆ˜พ็คบ่ฏฆ็ป†ๆ—ฅๅฟ—
--fallback-on-link-failure enum โŒ - ็กฌ้“พๆŽฅๅคฑ่ดฅๆ—ถๅ›ž้€€ๆจกๅผ๏ผšmove ๆˆ– copy๏ผˆ้ป˜่ฎคไธๅ›ž้€€๏ผ‰
--season-mode / --ๅˆ†ๅญฃ bool โŒ false ๆŒ‰ ็•ชๅ/Season N/ ็ป“ๆž„ๆ•ด็†ๅคšๅญฃไฝœๅ“
--scrape-metadata / --ๅˆฎๅ‰Š bool โŒ false ๅฏ็”จ Bangumi ๅ…ƒๆ•ฐๆฎๅˆฎๅ‰Š๏ผˆTMDB ๅฏ้€‰่กฅๅ›พ๏ผ‰
--tmdb-api-key string โŒ - TMDB API Key๏ผŒ็”จไบŽๅค‡้€‰ๆตทๆŠฅๅ’Œ่ƒŒๆ™ฏๅ›พ
--alias-file string โŒ - ่‡ชๅฎšไน‰ๅˆซๅ JSON ๆ–‡ไปถ๏ผŒ่ฆ†็›–ๆœฌๅœฐ bangumi.db ไธญ็š„ๅŒๅ้กน
--no-images bool โŒ false ่ทณ่ฟ‡ Kodi/MLIP ๅ›พ็‰‡ไธ‹่ฝฝ๏ผ›ไปๅ†™ๅ…ฅๅฏ็”จ็š„ๆ–‡ๆœฌๅ…ƒๆ•ฐๆฎ
--no-episode-metadata bool โŒ false ่ทณ่ฟ‡ Bangumi ๅˆ†้›†ๆ ‡้ข˜ใ€็ฎ€ไป‹ๅ’Œๆ—ถ้•ฟๆŸฅ่ฏข
--force-overwrite bool โŒ false ่ฆ†็›–ๅทฒๆœ‰็š„ NFO ๅ’Œๅ›พ็‰‡ๆ–‡ไปถ
--bangumi-cache string โŒ ็ณป็ปŸ็ผ“ๅญ˜็›ฎๅฝ• Bangumi Archive ๅ’Œ AnimeAtlas SQLite ็ผ“ๅญ˜็›ฎๅฝ•๏ผ›้ป˜่ฎคไธๅ†™ๅ…ฅๅช’ไฝ“ target
--metadata-source string โŒ - ๆŒ‡ๅฎšๆœฌๅœฐ subject.jsonlines ๆˆ–ๅ…ถ็›ฎๅฝ•๏ผ›ๆ˜พๅผๆŒ‡ๅฎšๅŽไฟๆŒ็ฆป็บฟ๏ผŒไธ่‡ชๅŠจๅˆทๆ–ฐ AnimeAtlas
--library-index bool โŒ false ็”Ÿๆˆ/ๆ›ดๆ–ฐ็›ฎๆ ‡็›ฎๅฝ•ๆ น้ƒจ็š„ library.db
--mlip bool โŒ false ็”Ÿๆˆ MiruPlay ๆˆๅ“ๅบ“๏ผšlibrary.dbใ€Bangumi ๅ…ƒๆ•ฐๆฎๅ’Œ็ผบๅคฑๆตทๆŠฅ๏ผ›ไธ็”Ÿๆˆ Kodi NFO
--rebuild-library-index bool โŒ false ไธŽ --library-index ๆˆ– --mlip ๅˆ็”จ๏ผŒๅ…จ้‡้‡ๆ‰ซ target๏ผ›ๅŽ่€…่ฟ˜ไผš่กฅๅ…ƒๆ•ฐๆฎๅ’Œ็ผบๅคฑๅ›พ็‰‡
--refresh-library-metadata bool โŒ false ไธŽ --mlip ๅˆ็”จ๏ผŒๅช่ฏปๅ–็Žฐๆœ‰ library.db ้‡ๆ–ฐๅŒน้…ๅ…ƒๆ•ฐๆฎ๏ผ›ไธๆ‰ซๆๅช’ไฝ“็›ฎๅฝ•๏ผŒๆ–ฐๅ›พ็‰‡ไผšๅ†™ๅ…ฅ artwork tar
--probe-runtime bool โŒ false ไฝฟ็”จ ffprobe ๆŽขๆต‹่ง†้ข‘ๆ—ถ้•ฟๅนถๅ†™ๅ…ฅ episode.runtime๏ผˆ็ง’๏ผ‰
--help -h bool โŒ false ๆ˜พ็คบๅธฎๅŠฉ
--version -V bool โŒ false ๆ˜พ็คบ็‰ˆๆœฌ

๐Ÿงพ ๅ…ƒๆ•ฐๆฎๅˆฎๅ‰Š

ๅฏ็”จ --scrape-metadata ๅŽ๏ผŒ็จ‹ๅบไผš๏ผš

  • ไผ˜ๅ…ˆไฝฟ็”จ --alias-file JSON ๅ’Œๆœฌๅœฐๅˆซๅๅบ“ๅŒน้… Bangumi ๆก็›ฎ๏ผ›่‹ฅๆœชๆไพ›ๆœฌๅœฐ animeatlas.sqlite/bangumi.db๏ผŒไผšไปŽ AnimeAtlas ๅ›บๅฎšๅ‘ๅธƒๅœฐๅ€ไธ‹่ฝฝ animeatlas.sqlite ๅˆฐ็ผ“ๅญ˜็›ฎๅฝ•๏ผŒๅคฑ่ดฅๆ—ถๅ›ž้€€ๅˆฐ็Žฐๆœ‰็ผ“ๅญ˜ๆˆ– Bangumi ๅ็งฐ/ๆœ็ดขๅŒน้…
  • ๅœจๅŠจ็”ปๆ น็›ฎๅฝ•็”Ÿๆˆ tvshow.nfo
  • ๅœจ Season N/ ็›ฎๅฝ•ไธ‹็”ŸๆˆไธŽ่ง†้ข‘ๅŒๅ็š„ *.nfo
  • ไผ˜ๅ…ˆไปŽ Bangumi ไธ‹่ฝฝ poster.jpg ๅ’Œ seasonXX-poster.jpg๏ผ›ๅฆ‚ๆžœๆไพ›ไบ† TMDB API Key๏ผŒๅˆ™ TMDB ไฝœไธบๆตทๆŠฅๅค‡้€‰ๅนถ่กฅๅ…… fanart.jpg

้ป˜่ฎค็ผ“ๅญ˜ไฝไบŽ็ณป็ปŸ็ผ“ๅญ˜็›ฎๅฝ•๏ผšWindows ไธบ %LOCALAPPDATA%\anime-organizer\bangumi-cache๏ผˆ็ผบๅคฑๆ—ถๅ›ž้€€ %APPDATA%๏ผ‰๏ผŒLinux/macOS ไผ˜ๅ…ˆ $XDG_CACHE_HOME/anime-organizer/bangumi-cache๏ผŒๅฆๅˆ™ไฝฟ็”จ ~/.cache/anime-organizer/bangumi-cacheใ€‚--bangumi-cache ๅฏๆ˜พๅผ่ฆ†็›–ใ€‚็ผ“ๅญ˜ไธไผš้ป˜่ฎคๆ”พ่ฟ›ๅช’ไฝ“ targetใ€‚

ๆœชๆŒ‡ๅฎš --metadata-source ๆ—ถ๏ผŒๅ…ƒๆ•ฐๆฎๆจกๅผไผšๆŒ‰ 24 ๅฐๆ—ถ TTL ๅˆทๆ–ฐๅ›บๅฎšๅ‘ๅธƒๅœฐๅ€็š„ AnimeAtlas animeatlas.sqlite๏ผ›daemon ่ฟ˜ไผšๆฏๅฐๆ—ถๆฃ€ๆŸฅไธ€ๆฌก็ผ“ๅญ˜๏ผŒ่ฟ‡ๆœŸๅŽ่‡ชๅŠจๅˆทๆ–ฐใ€‚ๅˆทๆ–ฐๅคฑ่ดฅไผš็ปง็ปญไฝฟ็”จ็Žฐๆœ‰็ผ“ๅญ˜ใ€‚ๆ˜พๅผๆŒ‡ๅฎš --metadata-source ่กจ็คบไฝฟ็”จๆœฌๅœฐๆ•ฐๆฎๅนถไฟๆŒ็ฆป็บฟ๏ผŒไธไผš่งฆๅ‘ AnimeAtlas ่‡ชๅŠจไธ‹่ฝฝ๏ผ›--alias-file JSON ไปๅ…ทๆœ‰ๆœ€้ซ˜ไผ˜ๅ…ˆ็บงใ€‚

--alias-file ๅฏ็›ดๆŽฅๅค็”จ extract-aliases ๅฏผๅ‡บ็š„ JSON ๅฏน่ฑกๆ ผๅผ๏ผŒไพ‹ๅฆ‚๏ผš

{
  "่Š™่މ่Žฒ": {
    "bangumi_id": 444444,
    "name": "่‘ฌ้€ใฎใƒ•ใƒชใƒผใƒฌใƒณ",
    "tmdb_id": 209867,
    "anidb_id": 18597
  }
}

๐Ÿ—ƒ๏ธ MLIP ๅช’ไฝ“ๅบ“็ดขๅผ•

ๅฏ็”จ --library-index ๅŽ๏ผŒ็จ‹ๅบไผšๅ›บๅฎš็ฎก็†็›ฎๆ ‡็›ฎๅฝ•ๆ น้ƒจ็š„ library.db๏ผš

  • ๅฆ‚ๆžœ library.db ไธๅญ˜ๅœจ๏ผšๆ•ด็†ๅฎŒๆˆๅŽๆ‰ซๆๆ•ดไธช target๏ผŒๅˆๅง‹ๅŒ–ๅปบๅบ“ใ€‚
  • ๅฆ‚ๆžœ library.db ๅทฒๅญ˜ๅœจ๏ผš้ป˜่ฎคๅชๆŠŠๆœฌๆฌกๆ•ด็†ๆˆๅŠŸ็š„ๆ–ฐๆ–‡ไปถๅขž้‡ๆ›ดๆ–ฐ่ฟ›ๅŽปใ€‚
  • ๅฆ‚ๆžœๅŒๆ—ถไผ ๅ…ฅ --rebuild-library-index๏ผšๆ•ด็†ๅฎŒๆˆๅŽ้‡ๆ–ฐๆ‰ซๆๆ•ดไธช target ๅนถ้‡ๅปบๆ•ฐๆฎๅบ“ใ€‚
  • --dry-run ไธ‹ๅชๆ‰“ๅฐๅฐ†ๆ‰ง่กŒ็š„ๆจกๅผๅ’Œ็ปŸ่ฎก๏ผŒไธๅˆ›ๅปบๆˆ–ไฟฎๆ”นๆ•ฐๆฎๅบ“ใ€‚

--library-index ๅชๅ†™ๆ–‡ไปถ็ดขๅผ•๏ผŒไธ่”็ฝ‘ใ€ไธไธ‹่ฝฝๅ›พ็‰‡ใ€‚็ป™ MiruPlay ไฝฟ็”จๆ—ถๆŽจ่ --mlip๏ผšๅฎƒไผš็”Ÿๆˆ library.db๏ผŒๅ†™ๅ…ฅ Bangumi ไฝœๅ“ไธŽๅˆ†้›†ๅ…ƒๆ•ฐๆฎ๏ผŒๅนถๆŠŠ็ผบๅคฑ็š„ poster.jpg ๅ’Œ seasonXX-poster.jpg ไธ‹่ฝฝๅˆฐๅฏนๅบ”ๅช’ไฝ“็›ฎๅฝ•ใ€‚ๅทฒๆœ‰ๅ›พ็‰‡้ป˜่ฎคไฟ็•™๏ผ›--force-overwrite ๆ‰ไผš้‡ๆ–ฐไธ‹่ฝฝ่ฆ†็›–๏ผŒ--no-images ๅˆ™ๅฎŒๅ…จ่ทณ่ฟ‡ๅ›พ็‰‡ไธ‹่ฝฝใ€‚Kodi NFO ไปๅช็”ฑ --scrape-metadata ็”Ÿๆˆใ€‚

ๅฆ‚ๆžœๆไพ› TMDB API Key๏ผŒTMDB ไผšไฝœไธบๆตทๆŠฅๅค‡้€‰ๆฅๆบๅนถ่กฅๅ…… fanart.jpgใ€‚Bangumi ๅˆ†้›†ๆ•ฐๆฎๆœ‰ duration_seconds ๆ—ถไผšๅ†™ๅ…ฅ episode.runtime๏ผ›ๅฆ‚้œ€ไปฅๆœฌๅœฐ่ง†้ข‘ไธบๅ‡†๏ผŒๅฏ้ขๅค–ไผ ๅ…ฅ --probe-runtime ไฝฟ็”จ ffprobe ๆŽขๆต‹ๅฎž้™…ๆ—ถ้•ฟใ€‚้ป˜่ฎคไธไผšๆŽขๆต‹่ง†้ข‘๏ผŒ้ฟๅ…ๅฏน NASใ€WebDAV ๆˆ–ไบ‘็›˜้€ๆ–‡ไปถ่ฏปๅ–ใ€‚

ๅ…จ้‡ๆ‰ซๆๅทฒๆ•ด็†็š„ target ๆ—ถ๏ผŒ็›ดๆŽฅ็ˆถ็›ฎๅฝ• Season N ๆ˜ฏๅญฃๅท็š„ๆƒๅจๆฅๆบใ€‚ๆ น็›ฎๅฝ•็›ดๆ”พ็š„ S1 ๆ–‡ไปถใ€Season 1 ๅญ็›ฎๅฝ•ๅ’ŒๅŽ็ปญ Season N ๅฏไปฅๅœจๅŒไธ€ๅช’ไฝ“ๅบ“ไธญๅ…ฑๅญ˜๏ผ›็›ฎๅฝ•ๅญฃๅทไธŽๆ–‡ไปถๅๅญฃๅทๅ†ฒ็ชๆ—ถไปฅ็›ฎๅฝ•ไธบๅ‡†ใ€‚ๅ›พ็‰‡่ทฏๅพ„ๅง‹็ปˆ็›ธๅฏนๅฎž้™…ๅช’ไฝ“็›ฎๅฝ•ๅ†™ๅ…ฅ๏ผŒไธไผšๆŒ‰่งฃๆžๅŽ็š„ๅˆซๅๅฆๅปบ็›ฎๅฝ•ใ€‚

ๆœฌๆ•ฐๆฎๅบ“ๆ˜ฏๅช่ฏปๅ่ฎฎใ€‚ไปปไฝ•ๆ’ญๆ”พๅ™จไธๅพ—ไฟฎๆ”นๆœฌๆ•ฐๆฎๅบ“๏ผ›ๆ’ญๆ”พๅކๅฒใ€ๆ”ถ่—ใ€็ปง็ปญๆ’ญๆ”พ็ญ‰ๆ•ฐๆฎๅฟ…้กปไฟๅญ˜ๅœจๆ’ญๆ”พๅ™จ่‡ชๅทฑ็š„ๆ•ฐๆฎๅบ“ใ€‚

ไฝฟ็”จๆ–นๅผ

้ฆ–ๆฌกๅฏ็”จๆ—ถ๏ผŒlibrary.db ไธๅญ˜ๅœจ๏ผŒ็จ‹ๅบไผšๅ…ˆๅฎŒๆˆๆœฌๆฌกๆ•ด็†๏ผŒๅ†ๆ‰ซๆๆ•ดไธช target ็›ฎๅฝ•ๅปบ็ซ‹็ดขๅผ•๏ผš

aniorg \
  --source="/path/to/downloads" \
  --target="/path/to/anime" \
  --library-index

็”Ÿๆˆ็ป“ๆžœๅ›บๅฎšๆ”พๅœจ็›ฎๆ ‡็›ฎๅฝ•ๆ น้ƒจ๏ผš

/path/to/anime/
โ”œโ”€โ”€ library.db
โ”œโ”€โ”€ Bocchi the Rock!/
โ”‚   โ””โ”€โ”€ 01 [1080P].mkv
โ””โ”€โ”€ Spy x Family/
    โ””โ”€โ”€ Season 2/
        โ””โ”€โ”€ 01 [1080P].mkv

ไปฅๅŽ็ปง็ปญๆ•ด็†ๆ–ฐไธ‹่ฝฝๆ—ถ๏ผŒไป็„ถไฝฟ็”จๅŒไธ€ไธชๅ‘ฝไปคใ€‚ๅช่ฆ library.db ๅทฒๅญ˜ๅœจ๏ผŒ้ป˜่ฎคๅฐฑๆ˜ฏๅขž้‡ๆ›ดๆ–ฐ๏ผšๅชๆŠŠๆœฌๆฌกๆ•ด็†ๆˆๅŠŸ็š„ๆ–‡ไปถๅ†™ๅ…ฅ็ดขๅผ•๏ผŒไธไผš้‡ๆ–ฐๆ‰ซๆๆ•ดไธช็›ฎๆ ‡็›ฎๅฝ•ใ€‚ไธบๅ…ผๅฎน NASใ€WebDAV ๅ’Œ CloudDrive๏ผŒ็จ‹ๅบไผšๅ…ˆๆŠŠ library.db ๅคๅˆถๅˆฐ็ณป็ปŸไธดๆ—ถ็›ฎๅฝ•ๅฎŒๆˆ SQLite ไบ‹ๅŠก๏ผŒๅ†้กบๅบไธŠไผ ๅนถๆ›ฟๆข่ฟœ็จ‹ๆ•ฐๆฎๅบ“๏ผŒ้ฟๅ…ๅœจ่ฟœ็จ‹ๆ–‡ไปถไธŠ้šๆœบๅ†™ๅ…ฅใ€‚

aniorg \
  --source="/path/to/new-downloads" \
  --target="/path/to/anime" \
  --library-index

ๅฆ‚ๆžœไฝ ๆ‰‹ๅŠจๅพ€็›ฎๆ ‡็›ฎๅฝ•ๆทปๅŠ ใ€ๅˆ ้™คใ€็งปๅŠจไบ†ๆ–‡ไปถ๏ผŒๆˆ–่€…ๆƒณ้‡ๆ–ฐ็”Ÿๆˆๆ•ดไธช็ดขๅผ•๏ผŒไฝฟ็”จ --rebuild-library-indexใ€‚ๅฆ‚ๆžœๅชๆƒณๆ‰ซๆ็Žฐๆœ‰ target ่€Œไธๆ•ด็†ไปปไฝ•ๆ–ฐๆ–‡ไปถ๏ผŒ่ฎฉ --source ๆŒ‡ๅ‘ไธ€ไธชๅญ˜ๅœจ็š„็ฉบ็›ฎๅฝ•๏ผš

# ่ฃธ็ดขๅผ•๏ผšไธ่”็ฝ‘ใ€ไธไธ‹่ฝฝๅ›พ็‰‡
aniorg \
  --source="/path/to/empty" \
  --target="/path/to/anime" \
  --library-index \
  --rebuild-library-index

# MiruPlay ๆˆๅ“ๅบ“๏ผš่กฅๅ…ƒๆ•ฐๆฎๅ’Œ็ผบๅคฑๅ›พ็‰‡
aniorg \
  --source="/path/to/empty" \
  --target="/path/to/anime" \
  --mlip \
  --rebuild-library-index

--source ็›ฎๅฝ•ๅฟ…้กปๅญ˜ๅœจใ€‚็ฉบๆบไธไผš็งปๅŠจใ€ๅคๅˆถๆˆ–็กฌ้“พๆŽฅๅช’ไฝ“๏ผŒๅชไผšๆ‰ซๆ targetใ€‚--rebuild-library-index ๅฟ…้กปๅ’Œ --library-index ๆˆ– --mlip ไธ€่ตทไฝฟ็”จ๏ผ›ๅฆ‚ๆžœ source ไธๆ˜ฏ็ฉบ็›ฎๅฝ•๏ผŒๆœฌๆฌกๆˆๅŠŸๆ•ด็†็š„ๆ–ฐๆ–‡ไปถไนŸไผšๅŒ…ๅซๅœจ้‡ๅปบ็ป“ๆžœไธญใ€‚

ๅช้œ€่ฆๆŒ‰ๆ–ฐๅˆซๅๆˆ–ไพ›ๅบ”ๅ•†ๆ•ฐๆฎ้‡ๆ–ฐๅˆฎๅ‰Š็Žฐๆœ‰็ดขๅผ•ๆ—ถ๏ผŒไฝฟ็”จ --refresh-library-metadataใ€‚ๅฎƒไธ้œ€่ฆ --source๏ผŒๅชไปŽ library.db ่ฏปๅ–ๅช’ไฝ“่ทฏๅพ„ใ€้›†ๅทใ€ๅคงๅฐใ€mtimeใ€hash ๅ’Œ artwork ็ป‘ๅฎš๏ผŒไธ้€’ๅฝ’ๆžšไธพ target๏ผŒไนŸไธ่ฏปๅ–่ง†้ข‘ใ€‚่ฏฅๆจกๅผไผšๅผบๅˆถๅˆทๆ–ฐ AnimeAtlas ็ผ“ๅญ˜๏ผŒ้‡ๆ–ฐๅŒน้… Bangumi/ๅˆ†้›†ๅ…ƒๆ•ฐๆฎ๏ผ›็ผบๅคฑๆˆ–่ขซ --force-overwrite ่ฆ†็›–็š„ๅ›พ็‰‡ๆŒ‰ๆ˜Ž็กฎ่ทฏๅพ„ไธ‹่ฝฝ๏ผŒๅนถ็”ฑ็Žฐๆœ‰ artwork pack builder ๅ†™ๅ…ฅ tar/catalogใ€‚daemon organize job ้œ€่ฆ้กถๅฑ‚ confirmed=trueใ€‚

aniorg \
  --target="/path/to/anime" \
  --mlip \
  --refresh-library-metadata

็ป™ MiruPlay ๅขž้‡็”Ÿๆˆๆˆๅ“ๅบ“ๆ—ถ๏ผŒไฝฟ็”จ --mlip๏ผ›ๅฎƒ้ป˜่ฎคไธ‹่ฝฝ็ผบๅคฑๅ›พ็‰‡๏ผŒไฝ†ไธไผš็”Ÿๆˆ Kodi NFO๏ผš

aniorg \
  --source="/path/to/downloads" \
  --target="/path/to/anime" \
  --mlip

ๅฆ‚ๆžœ่ฟ˜ๆƒณ่กฅๅ…… TMDB ่ƒŒๆ™ฏๅ›พ๏ผŒๅฏไปฅ้ขๅค–ไผ ๅ…ฅ --tmdb-api-keyใ€‚

ๅฆ‚ๆžœๅŒๆ—ถๆƒณ็”Ÿๆˆ Kodi NFOใ€ๅ›พ็‰‡ๅ’Œ MLIP ็ดขๅผ•๏ผŒๅฏไปฅไธ€่ตทๅผ€ๅฏๅ…ƒๆ•ฐๆฎๅˆฎๅ‰Š๏ผš

aniorg \
  --source="/path/to/downloads" \
  --target="/path/to/anime" \
  --scrape-metadata \
  --tmdb-api-key="YOUR_TMDB_KEY" \
  --library-index

้ข„่งˆๆ—ถๅฏไปฅ็ป„ๅˆ --dry-runใ€‚ๆญคๆ—ถไธไผšๅˆ›ๅปบๆˆ–ไฟฎๆ”น library.db๏ผŒๅชไผšๆ‰“ๅฐๅฐ†ๆ‰ง่กŒๅˆๅง‹ๅŒ–ใ€ๅขž้‡ๆ›ดๆ–ฐ่ฟ˜ๆ˜ฏ้‡ๅปบ๏ผš

aniorg \
  --source="/path/to/downloads" \
  --target="/path/to/anime" \
  --library-index \
  --dry-run \
  --verbose

ๅฆ‚ๆžœไธไผ  --target๏ผŒ็›ฎๆ ‡็›ฎๅฝ•ๆฒฟ็”จ็Žฐๆœ‰่ง„ๅˆ™็ญ‰ไบŽ source๏ผŒๆ‰€ไปฅ็ดขๅผ•ไผšๅ†™ๅˆฐ <source>/library.dbใ€‚ๆ’ญๆ”พๅ™จ่ฏปๅ–ๆ—ถๅบ”ๆŠŠ media_file.path ๅฝ“ไฝœ็›ธๅฏน library.db ๆ‰€ๅœจ็›ฎๅฝ•็š„่ทฏๅพ„ๅค„็†๏ผŒ่ทฏๅพ„ๅˆ†้š”็ฌฆ็ปŸไธ€ไธบ /ใ€‚

-- ============================================================
-- Media Library Index Protocol (MLIP)
--
-- Version : 1
-- Storage : SQLite 3
--
-- ่ฎพ่ฎกๅŽŸๅˆ™๏ผš
-- 1. ไธๆ‰ซๆ็›ฎๅฝ•ๅณๅฏๆž„ๅปบๅช’ไฝ“ๅบ“
-- 2. ไธไพ่ต–ๅœจ็บฟๅˆฎๅ‰Š
-- 3. ๆ”ฏๆŒ้•ฟๆœŸๆ‰ฉๅฑ•
-- 4. ๆ‰€ๆœ‰ๆ•ฐๆฎๅ‡ๅฏ็”ฑๆ•ด็†ๅ™จ้‡ๆ–ฐ็”Ÿๆˆ
-- 5. ไธไฝฟ็”จ polymorphic association / JSON / EAV
-- ============================================================

PRAGMA foreign_keys = ON;

CREATE TABLE meta
(
    key     TEXT PRIMARY KEY,
    value   TEXT NOT NULL
);

-- meta keys:
-- schema = 3
-- protocol = MLIP
-- generator = AnimeOrganizer
-- generator_version = <cargo package version>
-- library_uuid = <uuid>
-- library_root = <canonical target path>
-- generated_at = <RFC3339 timestamp>

CREATE TABLE series
(
    id              INTEGER PRIMARY KEY,
    uuid            TEXT UNIQUE NOT NULL,
    title           TEXT NOT NULL,
    original_title  TEXT,
    sort_title      TEXT,
    summary         TEXT,
    year            INTEGER,

    -- series_type:
    -- 1 TV
    -- 2 Movie
    -- 3 OVA
    -- 4 ONA
    -- 5 SP
    series_type     INTEGER NOT NULL DEFAULT 1
);

CREATE INDEX idx_series_title ON series(title);

CREATE TABLE series_release_date
(
    series_id   INTEGER PRIMARY KEY,
    air_date    TEXT NOT NULL, -- YYYY-MM-DD when known

    FOREIGN KEY(series_id)
        REFERENCES series(id)
        ON DELETE CASCADE
);

CREATE TABLE episode
(
    id          INTEGER PRIMARY KEY,
    uuid        TEXT UNIQUE NOT NULL,
    series_id   INTEGER NOT NULL,
    season      INTEGER NOT NULL DEFAULT 1,
    episode     REAL NOT NULL,
    sort_order  REAL NOT NULL,
    title       TEXT,
    summary     TEXT,
    runtime     INTEGER, -- seconds

    FOREIGN KEY(series_id)
        REFERENCES series(id)
        ON DELETE CASCADE,

    UNIQUE(series_id, season, episode)
);

CREATE INDEX idx_episode_series ON episode(series_id);

CREATE TABLE media_file
(
    id              INTEGER PRIMARY KEY,
    episode_id      INTEGER NOT NULL,
    path            TEXT NOT NULL UNIQUE,
    size            INTEGER,
    modified_time   INTEGER,

    FOREIGN KEY(episode_id)
        REFERENCES episode(id)
        ON DELETE CASCADE
);

CREATE INDEX idx_media_path ON media_file(path);
CREATE INDEX idx_media_episode ON media_file(episode_id);

-- Required in MLIP v2. Each subtitle belongs to one concrete media file.
CREATE TABLE media_subtitle
(
    id              INTEGER PRIMARY KEY,
    media_file_id   INTEGER NOT NULL,
    path            TEXT NOT NULL,
    language        TEXT,
    title           TEXT,
    sort_order      INTEGER NOT NULL DEFAULT 0,

    FOREIGN KEY(media_file_id)
        REFERENCES media_file(id)
        ON DELETE CASCADE,

    UNIQUE(media_file_id, path)
);

CREATE INDEX idx_media_subtitle_file ON media_subtitle(media_file_id);

-- Required in MLIP v3. Extras belong directly to a series, never to a fake episode.
CREATE TABLE media_extra
(
    id              INTEGER PRIMARY KEY,
    uuid            TEXT UNIQUE NOT NULL,
    series_id       INTEGER NOT NULL,
    extra_kind      INTEGER NOT NULL, -- 1 OVA, 2 special, 3 NCOP, 4 NCED, 5 gallery
    ordinal         INTEGER NOT NULL,
    sort_order      INTEGER NOT NULL,
    title           TEXT NOT NULL,
    path            TEXT NOT NULL UNIQUE,
    size            INTEGER,
    modified_time   INTEGER,
    runtime         INTEGER, -- seconds

    FOREIGN KEY(series_id)
        REFERENCES series(id)
        ON DELETE CASCADE
);

CREATE INDEX idx_media_extra_series ON media_extra(series_id, extra_kind, sort_order);

CREATE TABLE series_artwork
(
    id              INTEGER PRIMARY KEY,
    series_id       INTEGER NOT NULL,

    -- artwork_kind:
    -- 1 poster
    -- 2 fanart
    -- 3 banner
    -- 4 logo
    -- 5 thumb
    -- 6 clearart
    -- 7 season_poster
    artwork_kind    INTEGER NOT NULL,
    path            TEXT NOT NULL,

    FOREIGN KEY(series_id)
        REFERENCES series(id)
        ON DELETE CASCADE,

    UNIQUE(series_id, artwork_kind, path)
);

CREATE INDEX idx_series_artwork_series ON series_artwork(series_id);

CREATE TABLE episode_artwork
(
    id              INTEGER PRIMARY KEY,
    episode_id      INTEGER NOT NULL,
    artwork_kind    INTEGER NOT NULL,
    path            TEXT NOT NULL,

    FOREIGN KEY(episode_id)
        REFERENCES episode(id)
        ON DELETE CASCADE,

    UNIQUE(episode_id, artwork_kind, path)
);

CREATE INDEX idx_episode_artwork_episode ON episode_artwork(episode_id);

CREATE TABLE genre
(
    id      INTEGER PRIMARY KEY,
    name    TEXT UNIQUE NOT NULL
);

CREATE TABLE series_genre
(
    series_id   INTEGER NOT NULL,
    genre_id    INTEGER NOT NULL,

    PRIMARY KEY(series_id, genre_id),

    FOREIGN KEY(series_id)
        REFERENCES series(id)
        ON DELETE CASCADE,

    FOREIGN KEY(genre_id)
        REFERENCES genre(id)
        ON DELETE CASCADE
);

CREATE TABLE series_external_id
(
    series_id   INTEGER NOT NULL,

    -- provider:
    -- 1 bangumi
    -- 2 tmdb
    -- 3 anidb
    provider    INTEGER NOT NULL,
    value       TEXT NOT NULL,

    PRIMARY KEY(series_id, provider, value),

    FOREIGN KEY(series_id)
        REFERENCES series(id)
        ON DELETE CASCADE
);

CREATE TABLE episode_external_id
(
    episode_id  INTEGER NOT NULL,
    provider    INTEGER NOT NULL,
    value       TEXT NOT NULL,

    PRIMARY KEY(episode_id, provider, value),

    FOREIGN KEY(episode_id)
        REFERENCES episode(id)
        ON DELETE CASCADE
);

CREATE TABLE capability
(
    name        TEXT PRIMARY KEY,
    enabled     INTEGER NOT NULL
);

-- v3 capabilities:
-- artwork = 1
-- genre = 1
-- external_id = 1
-- release_date = 1
-- people = 0
-- subtitle = 1
-- extra = 1
-- media_technical = 0
-- multi_file = 1

PRAGMA user_version = 3;

v2 ๆ–ฐๅขžๅฟ…้œ€่กจ media_subtitle๏ผŒๅนถๅฐ† subtitle capability ่ฎพไธบ 1ใ€‚ๆฏๆกๅญ—ๅน•ๅ…ณ่”ๅˆฐๅ…ทไฝ“ media_file๏ผ›ๆ•ด็†ๅ™จไผšๅŒๆญฅๅค„็†ไธŽ่ง†้ข‘ๅŒ็›ฎๅฝ•ใ€ๅŒ stem ๆˆ–ๅธฆ่ฏญ่จ€ๅŽ็ผ€็š„ .srtใ€.assใ€.ssaใ€.vtt ๆ–‡ไปถใ€‚.sub ๅ› ้œ€่ฆ้…ๅฏน .idx๏ผŒๆš‚ไธๆ”ฏๆŒใ€‚

v3 ๆ–ฐๅขžๅฟ…้œ€่กจ media_extra ๅ’Œ extra capabilityใ€‚ๅฎŒๆ•ด็›ฎๆ ‡ๆ‰ซๆไผšๆŠŠ OVAใ€NCOPใ€NCEDใ€Tokuten ๅ’Œ Images ๆ–‡ไปถไฝœไธบๆ‰€ๅฑžไฝœๅ“็š„ๆœฌๅœฐ็‰นๅ…ธ็ผ–็›ฎ๏ผ›BD menu ๆ–‡ไปถไปไผšๅฟฝ็•ฅใ€‚็‰นๅ…ธไธๅˆ›ๅปบไผช้€ ็š„ episode๏ผŒไนŸไธๅ‚ไธŽๆญฃ็‰‡้›†ๆ•ฐใ€‚ๅฏนๆ—ขๆœ‰ v1/v2 ๆ•ฐๆฎๅบ“ๆ‰ง่กŒๅ†™ๅ…ฅๆ—ถไผš่‡ชๅŠจๅ‡็บงไธบ v3ใ€‚

MLIP v4 ๆ˜ฏๅฝ“ๅ‰ writer ็š„้ป˜่ฎค่พ“ๅ‡บใ€‚ๅฎƒๆ–ฐๅขž artwork_pack ไธŽ artwork_asset๏ผŒๅฐ†ๅฏ้ชŒ่ฏ็š„ๅŽŸๅง‹ๅ›พ็‰‡ๅญ—่Š‚ไฟๅญ˜ๅˆฐไธๅฏๅ˜ใ€ๆœชๅŽ‹็ผฉ็š„ tar shards๏ผ›series_artwork ๅ’Œ episode_artwork ไฟ็•™็›ธๅฏน path fallback๏ผŒๅนถๅฏๅผ•็”จ asset_id ๅŠ binding ็บงๆฅๆบไฟกๆฏใ€‚writer ไผšๅ…ˆๅ‘ๅธƒๅนถๆ ก้ชŒ pack๏ผŒๅ†ๅ‘ๅธƒๅผ•็”จๅฎƒไปฌ็š„ library.dbใ€‚ๅฎŒๆ•ด้‡ๅปบไผš็”Ÿๆˆ v4๏ผ›ๅทฒๅฎกๆ ธไธ”ไธๅธŒๆœ›้‡ๆ–ฐ่งฃๆžๆ ‡้ข˜/ๅ…ƒๆ•ฐๆฎ็š„ v3 ๅบ“ๅฏ็”จไปฅไธ‹็ปดๆŠคๅทฅๅ…ทๅŽŸๆ ทๅ‡็บง๏ผš

cargo run --example migrate_mlip_v3_to_v4 -- "/path/to/anime"

๐ŸŽจ ๆ–‡ไปถๅ‘ฝๅๆ ผๅผ

ๆ”ฏๆŒ็š„ๆบๆ–‡ไปถๅๆ ผๅผ

[ๅ‘ๅธƒ็ป„] ๅŠจๆผซๅ็งฐ๏ผˆๅฏๅซๅญฃๅบฆ๏ผ‰ - ้›†ๆ•ฐ [ๆ ‡็ญพไฟกๆฏ].ๆ‰ฉๅฑ•ๅ

็คบไพ‹๏ผš

  • [ANi] ๅฆ–ๆ€ชๆ—…้คจ็‡Ÿๆฅญไธญ ่ฒณ - 07 [1080P][Baha][WEB-DL][AAC AVC][CHT].mp4
  • [SubsPlease] ้—ด่ฐ่ฟ‡ๅฎถๅฎถ - 12 [1080p].mkv
  • [EMBER] ่ฟ›ๅ‡ป็š„ๅทจไบบ The Final Season - 01 [1080p][Multiple Subtitle].avi

็›ฎๆ ‡ๆ–‡ไปถ็ป“ๆž„

ๅŠจๆผซๅ็งฐ๏ผˆๅซๅญฃๅบฆ๏ผ‰/
โ”œโ”€โ”€ Season 1/
โ”‚   โ”œโ”€โ”€ 01 [ๆ ‡็ญพไฟกๆฏ].ๆ‰ฉๅฑ•ๅ
โ”‚   โ””โ”€โ”€ 02 [ๆ ‡็ญพไฟกๆฏ].ๆ‰ฉๅฑ•ๅ
โ”œโ”€โ”€ Season 2/
โ”‚   โ”œโ”€โ”€ 01 [ๆ ‡็ญพไฟกๆฏ].ๆ‰ฉๅฑ•ๅ
โ”‚   โ””โ”€โ”€ ...
โ”œโ”€โ”€ tvshow.nfo
โ”œโ”€โ”€ poster.jpg
โ””โ”€โ”€ fanart.jpg

๐Ÿ”— ็กฌ้“พๆŽฅ่ฏดๆ˜Ž

็กฌ้“พๆŽฅๆ˜ฏๆŽจ่็š„ๆ•ด็†ๆ–นๅผ๏ผŒๅ…ทๆœ‰ไปฅไธ‹ไผ˜ๅŠฟ๏ผš

  • ้›ถ้ขๅค–็ฉบ้—ด: ไธๅ ็”จ้ขๅค–็ฃ็›˜็ฉบ้—ด
  • ๅฟซ้€Ÿๆ“ไฝœ: ๅ‡ ไนŽ็žฌ้—ดๅฎŒๆˆ
  • ๆ–‡ไปถๅŒๆญฅ: ๆบๆ–‡ไปถๅ’Œ็›ฎๆ ‡ๆ–‡ไปถๅ†…ๅฎนๅฎŒๅ…จๅŒๆญฅ

ไฝฟ็”จๆกไปถ

  1. ๅŒไธ€ๆ–‡ไปถ็ณป็ปŸ: ๆบๆ–‡ไปถๅ’Œ็›ฎๆ ‡ๅฟ…้กปๅœจๅŒไธ€ๅˆ†ๅŒบ/NASๅท
  2. ๆ–‡ไปถ็ณป็ปŸๆ”ฏๆŒ: ext4ใ€NTFSใ€APFS ็ญ‰ๅ‡ๆ”ฏๆŒ
  3. ๆƒ้™่ฆๆฑ‚: ้œ€่ฆๅฏนๆบๅ’Œ็›ฎๆ ‡็›ฎๅฝ•ๆœ‰ๅ†™ๅ…ฅๆƒ้™

่ทจ่ฎพๅค‡้”™่ฏฏ

ๅฆ‚ๆžœๆบๆ–‡ไปถๅ’Œ็›ฎๆ ‡ไธๅœจๅŒไธ€ๆ–‡ไปถ็ณป็ปŸ๏ผŒไผšๆ˜พ็คบ้”™่ฏฏ๏ผš

็กฌ้“พๆŽฅๅคฑ่ดฅ๏ผšๆบๆ–‡ไปถๅ’Œ็›ฎๆ ‡ๅฟ…้กปๅœจๅŒไธ€ๆ–‡ไปถ็ณป็ปŸ

ๆญคๆ—ถๅฏ้€‰ๆ‹ฉ๏ผš

  • ๅฐ†็›ฎๆ ‡็›ฎๅฝ•ๆ”นไธบไธŽๆบๆ–‡ไปถๅŒไธ€ๆ–‡ไปถ็ณป็ปŸ
  • ไฝฟ็”จๅคๅˆถๆจกๅผ (--mode=copy)๏ผŒๆˆ–้€š่ฟ‡ --fallback-on-link-failure=copy ่‡ชๅŠจๅ›ž้€€
  • ไฝฟ็”จ็งปๅŠจๆจกๅผ (--mode=move)๏ผŒๆˆ–้€š่ฟ‡ --fallback-on-link-failure=move ่‡ชๅŠจๅ›ž้€€

๐Ÿ”ง ๅˆฎๅ‰Šๅญๅ‘ฝไปค๏ผˆ้œ€ --features scraper๏ผ‰

# ๅˆฎๅ‰Š่ฟ‘ๆœŸๆ›ดๆ–ฐ
cargo run --features scraper -- scrape --days 7 --format json

# ๅŒน้…ๅˆซๅๆๆกˆ
cargo run --features scraper -- match --input scraped.json --format github

# ๆž„ๅปบ SQLite ๅˆซๅๅบ“
cargo run --features scraper -- build-db --output bangumi.db

# ไปŽ dump ๆๅ–ๅˆซๅ
cargo run --features scraper -- extract-aliases --download

# ๅˆๅนถๆ–ฐๅˆซๅๅˆฐๆ•ฐๆฎๅบ“
cargo run --features scraper -- merge-aliases --input new_aliases.json

# ๅบ”็”จๅŒน้…็š„ๅˆซๅๆๆกˆ
cargo run --features scraper -- apply-matches --input proposals.json

# ๅˆ›ๅปบๅˆซๅ่ฏทๆฑ‚ issue
cargo run --features scraper -- create-alias-issues --input uncertain.json --repo ModerRAS/anime-organizer

๐Ÿ“ก RSS ่ฎข้˜…็ฎก็†๏ผˆ้œ€ --features clouddrive๏ผ‰

# ๅˆ—ๅ‡บ่ฎข้˜…
aniorg rss --list-subscriptions

# ๆทปๅŠ ่ฎข้˜…
aniorg rss --add-subscription \
  --rss-url "https://example.com/rss" \
  --rss-target "/anime" \
  --rss-filter "720p"

# ๅ•ๆฌกๆ‰ง่กŒ
aniorg rss --single-shot \
  --clouddrive-url http://localhost:19798 \
  --rss-url "https://example.com/rss" \
  --rss-target "/anime"

# Daemon ๆจกๅผ๏ผˆๆŒ็ปญ็›‘ๆŽง๏ผ‰
aniorg rss --daemon \
  --clouddrive-url http://localhost:19798 \
  --rss-interval 300

่ฎค่ฏๆ”ฏๆŒไธค็งๆ–นๅผ๏ผš็›ดๆŽฅไผ  --clouddrive-token๏ผŒๆˆ–ไฝฟ็”จ --clouddrive-user + --clouddrive-pass ็™ปๅฝ•่Žทๅ–ไปค็‰Œใ€‚่ฎข้˜…ๅ’ŒๅŽป้‡็Šถๆ€้ป˜่ฎคไฟๅญ˜ๅœจ Windows ็š„ %LOCALAPPDATA%\anime-organizer\rss.dbใ€‚

โ˜๏ธ CloudDrive ่พ…ๅŠฉๅ‘ฝไปค๏ผˆ้œ€ --features clouddrive๏ผ‰

# ็›ดๆŽฅๆไบค magnet ๆˆ– torrent URL ๅˆฐ็ฆป็บฟไธ‹่ฝฝ
aniorg add-offline "magnet:?xt=urn:btih:..." \
  --target "/anime" \
  --clouddrive-url http://localhost:19798 \
  --clouddrive-token "YOUR_TOKEN"

# ๆต่งˆไบ‘็›˜็›ฎๅฝ•
aniorg list-folder "/anime" \
  --clouddrive-url http://localhost:19798 \
  --clouddrive-token "YOUR_TOKEN"

๐Ÿ’ก ไฝฟ็”จ็คบไพ‹

# ๆ•ด็†ไธ‹่ฝฝ็›ฎๅฝ•
aniorg --source="D:\Downloads\Anime"

# ๆ•ด็†ๅˆฐๆŒ‡ๅฎš็›ฎๅฝ•
aniorg -s "/home/user/Downloads" -t "/media/anime"

# ็กฌ้“พๆŽฅๆจกๅผ
aniorg -s "/home/user/Downloads" -m link -t "/mnt/anime"

# ๅคšๅญฃไฝœๅ“ๆŒ‰ Season ็›ฎๅฝ•ๆ•ด็†
aniorg -s "/path/to/downloads" -t "/path/to/anime" --season-mode

# ้ข„่งˆๅ˜ๆ›ดๅนถๆ˜พ็คบ่ฏฆ็ป†ๆ—ฅๅฟ—
aniorg -s "/path/to/downloads" --dry-run -v

# ๆŒ‡ๅฎšๆ–‡ไปถ็ฑปๅž‹
aniorg -s "/path/to/downloads" --include-ext="mp4,mkv"

# ไฝฟ็”จ่‡ชๅฎšไน‰ๅˆซๅๅบ“
aniorg -s "/path/to/downloads" --alias-file="./my-aliases.json"

# ๅผบๅˆถ่ฆ†็›–ๅทฒๆœ‰ NFO
aniorg -s "/path/to/downloads" --scrape-metadata --force-overwrite

English

๐Ÿ“– Project Description

anime-organizer (aniorg) is a command-line tool designed for anime collectors to automatically organize video files in download directories.

Core Features:

  • Auto-parse filenames to extract anime name, episode number, publisher info
  • Support hard link mode - organize files without using extra disk space
  • Generate Kodi-compatible NFO metadata files
  • Generate a MiruPlay-ready MLIP library.db with Bangumi metadata and artwork
  • Download poster and fanart images
  • RSS subscription and 115 cloud drive sync (requires clouddrive feature)

Use Cases:

  • Organize anime files in download directories
  • Automate anime media library management
  • Generate metadata for Kodi/Jellyfin/Plex media centers

๐Ÿš€ Features

  • Smart Parsing: Auto-recognize [Publisher] AnimeName - Episode [Tags].ext format
  • Flexible Organization: Restructure to AnimeName/Season N/Episode [Tags].ext
  • Multiple Modes: Support move, copy, and hard link operations
  • Metadata Scraping: Generate Kodi-compatible NFO files from Bangumi metadata
  • Artwork Download: Download anime posters from Bangumi first, use TMDB as a backup and fanart source, then AniDB as the final poster fallback
  • Alias Matching: Local bangumi.db aliases plus optional custom JSON overrides, with Bangumi title/search fallback
  • RSS Subscription: RSS auto-subscription and 115 cloud drive sync (requires clouddrive feature)
  • Cross-Platform: Support Windows, Linux, macOS
  • Portable Deployment: Single-file on most platforms; keep DirectML.dll beside aniorg.exe from the Windows x64 AniFileBERT release
  • High Performance: Native Rust implementation

๐Ÿ“ฅ Installation

Option 1: Download Pre-built Binary

Download from GitHub Releases. Windows x64 users should extract both aniorg.exe and DirectML.dll from the versioned ZIP and keep them in the same directory.

Option 2: Build from Source

git clone https://github.com/ModerRAS/anime-organizer.git
cd anime-organizer

# Default build (metadata feature enabled)
cargo build --release

# Full features
cargo build --release --features "scraper clouddrive torrent-scraper"

# Embedded AniFileBERT ONNX filename parser (CPU)
cargo build --release --features "anifilebert"

# AniFileBERT plus Windows DirectML (GPU; NPU can be selected explicitly)
cargo build --release --features "anifilebert-directml"

The compiled binary is located at target/release/aniorg. ANIORG_BERT_PROVIDER=cpu|auto|directml-gpu|directml-npu|directml-any controls the ONNX Runtime provider; ANIORG_DIRECTML_DEVICE_ID=0 pins a DirectML device. Without anifilebert-directml, the parser uses CPU. With it, the default is auto: try DirectML GPU first, then fall back to CPU. CPU threads can be tuned with ANIORG_ORT_INTRA_THREADS and ANIORG_ORT_INTER_THREADS; both default to 1. anifilebert-amd-npu remains as a compatibility alias for anifilebert-directml; VitisAI requires an additional ONNX Runtime provider package and is not part of the default build.

If your local Windows machine defaults to the GNU Rust toolchain, validate AniFileBERT/DirectML builds with the MSVC rustc explicitly. If ONNX Runtime fails during the local link step, point ORT_LIB_LOCATION at the extracted ORT directory and set ORT_PREFER_DYNAMIC_LINK=1 to use the import-lib/dll path.

Daemon and WebUI

On Windows, start the local daemon through its single entry point:

aniorg.exe --daemon

The WebUI and typed WebAPI listen only on http://127.0.0.1:32145/. One durable worker executes finite jobs serially, with daemon state stored in %LOCALAPPDATA%\anime-organizer\daemon.db. CloudDrive tokens and CloudDrive/WebDAV usernames and passwords rely on the current Windows user's ACL and are stored as plaintext in that local database; they are never returned by the API or stored in the browser. v1 is intended only for a trusted, single-user local machine.

RSS automatic organization keeps CloudDrive as the download/offline-task connection, while its organization target may independently use CloudDrive or WebDAV. Remote MLIP publication downloads uncached source media to a daemon temporary file for size and SHA-256 verification, updates library.db locally, then publishes it through a staged remote file, backup rename, and hash verification. Publication completes before any source mutation.

The storage_organize typed job supports copy and move between local directories, CloudDrive connections, and WebDAV connections. Same-connection operations prefer native COPY/MOVE; cross-endpoint moves stage, upload, verify size and SHA-256, publish final names, and only then delete source files. WebDAV supports standard file operations with optional Basic Auth but not magnet/offline download. Local hard links remain part of the existing organize job.

After a successful local move, empty source ancestors involved in that move are removed deepest-first while the source root and every non-empty directory are retained. New RSS subscriptions remove completed offline-task roots by default. The subscription detail page also provides preview and apply actions for recursively cleaning all empty directories below that subscription's source root. The root itself is retained, and cleanup is rejected while CloudDrive reports any init or downloading offline task.

๐ŸŽฏ Quick Start

# Hard link mode (default, zero extra space)
aniorg --source="/path/to/downloads"

# Preview mode
aniorg --source="/path/to/downloads" --dry-run --verbose

# Enable automatic fallback to copy when hard link fails
aniorg --source="/path/to/downloads" --fallback-on-link-failure=copy

# Organize multi-season releases into Season folders
aniorg --source="/path/to/downloads" --season-mode --target="/path/to/anime"

# Generate NFO files and artwork
aniorg --source="/path/to/downloads" --scrape-metadata

# Generate or update the MLIP library index in the target root
aniorg --source="/path/to/downloads" --target="/path/to/anime" --library-index

# Generate a MiruPlay-ready MLIP library with Bangumi metadata and posters
aniorg --source="/path/to/downloads" --target="/path/to/anime" --mlip

# Rebuild only the offline file index
aniorg --source="/path/to/empty" --target="/path/to/anime" --library-index --rebuild-library-index

# Rebuild a MiruPlay-ready library and download missing artwork
aniorg --source="/path/to/empty" --target="/path/to/anime" --mlip --rebuild-library-index

# Re-scrape metadata from the existing library.db without scanning media
aniorg --target="/path/to/anime" --mlip --refresh-library-metadata

๐Ÿ“‹ Arguments

Argument Short Type Required Default Description
--source -s string โœ… - Source directory path
--target -t string โŒ source Target root directory
--mode -m enum โŒ link Operation mode: move/copy/link
--dry-run bool โŒ false Preview only, no actual changes
--include-ext string โŒ mp4,mkv,... File extensions to process
--filename-parser enum โŒ rules Filename parser: rules, anifilebert, or auto (fall back to AniFileBERT after rules fail)
--verbose -v bool โŒ false Show detailed logs
--fallback-on-link-failure enum โŒ - Fallback when hard link fails: move or copy (disabled by default)
--season-mode / --ๅˆ†ๅญฃ bool โŒ false Group multi-season titles as Series/Season N/
--scrape-metadata / --ๅˆฎๅ‰Š bool โŒ false Enable Bangumi metadata scraping with optional TMDB artwork
--tmdb-api-key string โŒ - TMDB API key for backup posters and fanart
--alias-file string โŒ - Custom alias JSON file overriding same-name entries from local bangumi.db
--no-images bool โŒ false Skip Kodi/MLIP artwork downloads while retaining available text metadata
--no-episode-metadata bool โŒ false Skip Bangumi episode title, summary, and duration lookup
--force-overwrite bool โŒ false Overwrite existing NFO and image files
--bangumi-cache string โŒ system cache dir Cache for Bangumi Archive and AnimeAtlas SQLite; kept outside the media target by default
--metadata-source string โŒ - Local subject.jsonlines or its directory; explicit use stays offline and disables AnimeAtlas refresh
--library-index bool โŒ false Generate/update library.db in the target root
--mlip bool โŒ false Generate library.db, Bangumi metadata, and missing artwork without Kodi NFO
--rebuild-library-index bool โŒ false Full target rescan; with --mlip, also refresh metadata and download missing artwork
--refresh-library-metadata bool โŒ false With --mlip, re-match metadata using only the existing library.db; do not scan media, and pack new artwork into MLIP tar files
--probe-runtime bool โŒ false Use ffprobe to probe video duration and write episode.runtime in seconds
--help -h bool โŒ false Show help
--version -V bool โŒ false Show version

๐Ÿงพ Metadata Scraping

When --scrape-metadata is enabled, the tool will:

  • Prefer aliases from --alias-file JSON and a local alias database; when no local animeatlas.sqlite/bangumi.db is available, it downloads animeatlas.sqlite from the fixed AnimeAtlas release URL into the cache directory and falls back to the existing cache or Bangumi title/search matching if that download fails
  • Generate tvshow.nfo in the series root
  • Generate per-episode *.nfo files beside organized videos in Season N/
  • Download poster.jpg and seasonXX-poster.jpg from Bangumi first; when a TMDB API key is provided, TMDB is used as a poster backup and for fanart.jpg

The default cache is %LOCALAPPDATA%\anime-organizer\bangumi-cache on Windows (falling back to %APPDATA%) and $XDG_CACHE_HOME/anime-organizer/bangumi-cache or ~/.cache/anime-organizer/bangumi-cache on Linux/macOS. Override it with --bangumi-cache; the cache is not placed inside the media target by default.

Without --metadata-source, metadata modes refresh AnimeAtlas animeatlas.sqlite from its fixed release URL with a 24-hour TTL. The daemon also checks the cache hourly and refreshes it after expiry; failures keep the existing cache. An explicit --metadata-source selects local offline data and does not trigger AnimeAtlas downloads. A JSON --alias-file remains the highest-priority override.

The --alias-file JSON can reuse the object output format from extract-aliases, for example:

{
  "Frieren": {
    "bangumi_id": 444444,
    "name": "่‘ฌ้€ใฎใƒ•ใƒชใƒผใƒฌใƒณ",
    "tmdb_id": 209867,
    "anidb_id": 18597
  }
}

๐Ÿ—ƒ๏ธ MLIP Library Index

--library-index manages a fixed library.db in the target root. It only writes the file index: it does not fetch metadata or artwork. For MiruPlay, prefer --mlip; it writes Bangumi series and episode metadata and downloads missing poster.jpg and seasonXX-poster.jpg files into the physical media directory. Existing artwork is preserved unless --force-overwrite is set; --no-images skips downloads. Kodi NFO files are still generated only by --scrape-metadata.

A TMDB API key is optional and only adds backup poster/fanart coverage. When Bangumi episodes include duration_seconds, it is written to episode.runtime; pass --probe-runtime to use ffprobe and prefer actual local video duration. Runtime probing stays disabled by default to avoid reading every file on NAS, WebDAV, or cloud-backed libraries.

During a full target scan, an immediate Season N parent is authoritative. Flat season-one files, a Season 1 subdirectory, and later Season N directories may coexist; when a filename season conflicts with its directory, the directory wins. Artwork paths always follow the physical top-level media directory instead of creating a separate parser-derived directory.

The first run creates the database by scanning the full target directory after organization finishes:

aniorg \
  --source="/path/to/downloads" \
  --target="/path/to/anime" \
  --library-index

Later runs with the same command are incremental when library.db already exists: only files successfully organized in the current run are upserted. For NAS, WebDAV, and CloudDrive targets, library.db is copied to the system temp directory, updated locally, then uploaded and replaced sequentially instead of being randomly written in place.

aniorg \
  --source="/path/to/new-downloads" \
  --target="/path/to/anime" \
  --library-index

Use --rebuild-library-index when files were manually added, removed, or moved. To rebuild an existing target without organizing new media, point --source at an existing empty directory:

# Offline file index only
aniorg \
  --source="/path/to/empty" \
  --target="/path/to/anime" \
  --library-index \
  --rebuild-library-index

# MiruPlay-ready metadata and missing artwork
aniorg \
  --source="/path/to/empty" \
  --target="/path/to/anime" \
  --mlip \
  --rebuild-library-index

The source directory must exist. An empty source performs no move, copy, or hard-link operations; it only scans the target. --dry-run --library-index does not create or modify library.db; it only reports whether the command would initialize, incrementally update, or rebuild the index. media_file.path values are stored relative to the directory containing library.db and always use / separators.

Use --refresh-library-metadata when only aliases or provider metadata changed. It requires no --source: media paths, episode numbers, size, mtime, hashes, and artwork bindings come from the existing library.db; the target is not recursively enumerated and video bytes are never read. The mode force-refreshes the AnimeAtlas cache, re-resolves Bangumi and episode metadata, downloads missing or --force-overwrite artwork at explicit paths, and publishes those images through the existing artwork tar/catalog builder. A daemon organize job requires top-level confirmed=true.

aniorg \
  --target="/path/to/anime" \
  --mlip \
  --refresh-library-metadata

Matching .srt, .ass, .ssa, and .vtt sidecars are organized with their video and exported through the required MLIP v2 media_subtitle table. A sidecar must share the video stem or append a language-style suffix; .sub is excluded because VobSub requires a paired .idx.

MLIP v3 adds the required media_extra table. Full target scans classify OVA, NCOP, NCED, Tokuten, and Images videos as series-owned extras while ignoring Blu-ray menu videos. Extras never create fake episode rows or change the normal episode count. Existing v1/v2 databases migrate to v3 on the next write.

MLIP v4 is the current writer output. It adds artwork_pack and artwork_asset, storing verified original image bytes in immutable, uncompressed tar shards. series_artwork and episode_artwork retain relative path fallback and can reference an asset_id with binding-level provenance. Packs are published and verified before a library.db that references them. A full rebuild writes v4; an audited v3 library can be upgraded without re-resolving titles or metadata:

cargo run --example migrate_mlip_v3_to_v4 -- "/path/to/anime"

๐Ÿ”— Hard Link Notes

Hard linking is the recommended mode:

  • Zero Extra Space: No additional disk space used
  • Fast Operation: Almost instant
  • File Sync: Source and target share the same content

If hard linking fails due to cross-filesystem layouts or lack of support, you can opt in to automatic fallback via --fallback-on-link-failure=copy or --fallback-on-link-failure=move; otherwise, the failure is reported and the file is skipped.

Requirements:

  1. Source and target must be on the same filesystem
  2. Filesystem must support hard links (ext4, NTFS, APFS, etc.)
  3. Write permission required for both directories

๐Ÿ”ง Scraper Subcommands (requires --features scraper)

# Scrape recent updates
cargo run --features scraper -- scrape --days 7 --format json

# Match alias proposals
cargo run --features scraper -- match --input scraped.json --format github

# Build SQLite alias database
cargo run --features scraper -- build-db --output bangumi.db

# Extract aliases from dump
cargo run --features scraper -- extract-aliases --download

# Merge new aliases into database
cargo run --features scraper -- merge-aliases --input new_aliases.json

# Apply confident match proposals
cargo run --features scraper -- apply-matches --input proposals.json

# Create alias request issues
cargo run --features scraper -- create-alias-issues --input uncertain.json --repo ModerRAS/anime-organizer

๐Ÿ“ก RSS Subscription Management (requires --features clouddrive)

# List subscriptions
aniorg rss --list-subscriptions

# Add subscription
aniorg rss --add-subscription \
  --rss-url "https://example.com/rss" \
  --rss-target "/anime" \
  --rss-filter "720p"

# Single shot execution
aniorg rss --single-shot \
  --clouddrive-url http://localhost:19798 \
  --rss-url "https://example.com/rss" \
  --rss-target "/anime"

# Daemon mode (continuous monitoring)
aniorg rss --daemon \
  --clouddrive-url http://localhost:19798 \
  --rss-interval 300

Authentication supports either --clouddrive-token or --clouddrive-user + --clouddrive-pass. Subscription and dedupe state is stored in %LOCALAPPDATA%\anime-organizer\rss.db on Windows.

โ˜๏ธ CloudDrive Helper Commands (requires --features clouddrive)

# Submit a magnet or torrent URL directly to offline download
aniorg add-offline "magnet:?xt=urn:btih:..." \
  --target "/anime" \
  --clouddrive-url http://localhost:19798 \
  --clouddrive-token "YOUR_TOKEN"

# Browse a cloud folder
aniorg list-folder "/anime" \
  --clouddrive-url http://localhost:19798 \
  --clouddrive-token "YOUR_TOKEN"

๐Ÿงฒ Torrent Scraping (requires --features torrent-scraper)

# Scrape DMHY torrent titles
aniorg torrent-scrape --source dmhy --output dmhy_titles.txt

# Scrape Nyaa torrent titles
aniorg torrent-scrape --source nyaa --query "anime" --output nyaa_titles.txt

# Scrape both sources
aniorg torrent-scrape --source all --pages 3 --output all_titles.txt

๐Ÿ› ๏ธ Development

# Run tests
cargo test

# Run with verbose output
cargo run -- --source="/path/to/downloads" --verbose

# Build release binary
cargo build --release

# Build with all features
cargo build --release --features "scraper clouddrive torrent-scraper"

License

AGPL-3.0 License - see LICENSE for details.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages