Skip to content

Como organizar os arquivos?

Shoko possui um renamer padrao o WebAOM e usando o plugin LuaRenamer, cheguei nesse resultado

Para alcancar o resultado que eu queria, usei o LuaRenamer e chamei meus scripts de Shoko Group Structure (SGS):

Para quando temos varios packs em um grupo
Accel World/
├── 2012 - Accel World
|   ├── Extras
|   │   └── ...
│   ├── [#AnimeNSK]_Accel_World_-_01_[Blu-Ray_1280x720]_[10Bit]_(B132587A).mkv
│   ├── ...
│   └── [#AnimeNSK]_Accel_World_-_24_Final_[Blu-Ray_1280x720]_[10Bit]_(5FE38641).mkv
├── 2012 - Accel World OVA
│   ├── ...
│   └── [#AnimeNSK]_Accel_World_-_OVA_[Blu-Ray_1280x720]_[10Bit]_(6E91377B).mkv
└── Movies
    └── [#AnimeNSK]_Accel_World_Infinite_Burst_[BD_1920x1080]_[HEVC_10Bit]_(E30ACB16).mkv
Para quando temos 1 unico pack (11 eyes tem um final extra quando saiu em disco)
11 Eyes/
├── Extras
│   └── [#AnimeNSK]_11eyes_-_13_Final_[Blu-Ray_1280x720_H264+AAC]_(5D0D8E0E).mkv
├── ...
└── [#AnimeNSK]_11eyes_-_12_[Blu-Ray_1280x720_H264+AAC]_(CBF8F9E9).mkv

Primeiro eu gastei um bom tempo e usei a forma SGS - Mover&Renamer, porem de tempos em tempos eu esbarrava em casos que nao nao me agradavam sendo:

  • Fonte do AniDB diferentente do sub HDTV != BluRay, que ficava bem estranho quando todos os outros estavam corretoss..
  • Arquivo associado ao epsodio errado, ex Arquivo era o EP2 mas quem subiu colocou EP3 e ai ficava sendo reconhecido como duplicado, porem olhando o nome original e o contudo deu pra ver que nao era, para resolver eh preciso ir no anidb pedir e passar infos do fansub q provem a associacao errada (Muito role para pouco resultado)

Foi ai que resolvi apenas mexer com as pastas e deixar os nomes originais ficando com o SGS - Mover as vagtagens sao:

  • Mantenho tudo organizado da forma q eu prefiro (o jellyfin vai usar oq o shokofin repassar, entao isso nao afeta nada)
  • E mais facil saber se o duplicado e real ou erro de quem subiu
  • Facilita voltar a ficar de seed, pois o nome original esta mantido

Existem casos que precisam ser tratados manualmente, pois os arquivos estao relacionados a dois packs diferentes por ser uma re-exibicao com epsodios a mais

lua
-- special case: files with multiple relations
if anime.id and (anime.id == 3651 or anime.id == 6367) then
  subfolder = ("%s - %s"):format(2009, "Suzumiya Haruhi no Yuuutsu")
  group.name = "Suzumiya Haruhi no Yuuutsu"
end

Quando uma serie era sozinha e agora tem um segundo pack no grupo (temprada ou parte II) e preciso rodar o renamer(qualquer versao) nela novamente para que fique na estrutura certa ex

# Sozinha
└── Fate/Zero
    ├── [#AnimeNSK]_Fate_Zero_-_01_[Blu-Ray_1280x720]_(3ACB2773).mkv
    └── [#AnimeNSK]_Fate_Zero_-_13_Final_[Blu-Ray_1280x720]_(B3848E17).mkv

# Apos adicionar a parte II
└── Fate/Zero
    ├── 2012 - Fate/Zero
    │   ├── [#AnimeNSK]_Fate_Zero_-_14_[Blu-Ray_1280x720]_[10Bit]_(276ED68B).mkv
    │   └── [#AnimeNSK]_Fate_Zero_-_25_Final_[Blu-Ray_1280x720]_[10Bit]_(40C9DB72).mkv
    ├── [#AnimeNSK]_Fate_Zero_-_01_[Blu-Ray_1280x720]_(3ACB2773).mkv
    └── [#AnimeNSK]_Fate_Zero_-_13_Final_[Blu-Ray_1280x720]_(B3848E17).mkv

# Apos rodar novamente
└── Fate/Zero
    ├── 2011 - Fate/Zero
    │   ├── [#AnimeNSK]_Fate_Zero_-_01_[Blu-Ray_1280x720]_(3ACB2773).mkv
    │   └── [#AnimeNSK]_Fate_Zero_-_13_Final_[Blu-Ray_1280x720]_(B3848E17).mkv
    └── 2012 - Fate/Zero
        ├── [#AnimeNSK]_Fate_Zero_-_14_[Blu-Ray_1280x720]_[10Bit]_(276ED68B).mkv
        └── [#AnimeNSK]_Fate_Zero_-_25_Final_[Blu-Ray_1280x720]_[10Bit]_(40C9DB72).mkv

Scripts

SGS - Mover
lua
-- SGS - Mover

-- # Multiple packs inside group output
-- Accel World/
-- ├── 2012 - Accel World
-- |   ├── Extras
-- |   │   └── ...
-- │   ├── [#AnimeNSK]_Accel_World_-_01_[Blu-Ray_1280x720]_[10Bit]_(B132587A).mkv
-- │   ├── ...
-- │   └── [#AnimeNSK]_Accel_World_-_24_Final_[Blu-Ray_1280x720]_[10Bit]_(5FE38641).mkv
-- ├── 2012 - Accel World OVA
-- │   ├── ...
-- │   └── [#AnimeNSK]_Accel_World_-_OVA_[Blu-Ray_1280x720]_[10Bit]_(6E91377B).mkv
-- └── Movies
--     └── [#AnimeNSK]_Accel_World_Infinite_Burst_[BD_1920x1080]_[HEVC_10Bit]_(E30ACB16).mkv
-- # Single pack output
-- 11 Eyes/
-- ├── Extras
-- │   └── [#AnimeNSK]_11eyes_-_13_Final_[Blu-Ray_1280x720_H264+AAC]_(5D0D8E0E).mkv
-- ├── ...
-- └── [#AnimeNSK]_11eyes_-_12_[Blu-Ray_1280x720_H264+AAC]_(CBF8F9E9).mkv

-- Set defaults
remove_illegal_chars = false
replace_illegal_chars = true
use_existing_anime_location = false

-- Manged Folder
destination = "anime"

local maxnamelen = 70
local spacechar = " "
local animename = anime.preferredname
local episodelanguage = Language.English

local shortanimename = nil
if anime.titles then
  for _, v in ipairs(anime.titles) do
    if
    v.type == "Short"
    and v.name
    and (v.language == episodelanguage or v.language == "Romaji")
    then
      shortanimename = v.name
    end
  end
end

local truncatedanimename = animename:truncate(maxnamelen):gsub(' %(.*%)', '')
-- if name is at max lenght then use shortname
if #animename >= maxnamelen and shortanimename then
  truncatedanimename = shortanimename
end

-- put year in front so folder are sorted by year
subfolder = ("%s - %s")
  :format(anime.airdate.year, truncatedanimename)

-- special case: files with multiple relations
if anime.id and (anime.id == 3651 or anime.id == 6367) then
  subfolder = ("%s - %s"):format(2009, "Suzumiya Haruhi no Yuuutsu")
  group.name = "Suzumiya Haruhi no Yuuutsu"
end

-- group dirs based on numer structure
local episodenumber = episode_numbers(math.max(#tostring(anime.episodecounts[episode.type]), 2))
if #groups == 1 and #groups[1].animes > 1 then
  if episodenumber:match("^[S|C|T|O]") then
    subfolder = { group.name, subfolder, "Extras" }
  elseif anime.type == AnimeType.Movie then
    subfolder = { group.name, "Movies" }
  else
    subfolder = { group.name, subfolder }
  end
else
  if episodenumber:match("^[S|C|T|O]") then
    subfolder = { group.name, "Extras" }
  else
    subfolder = { group.name }
  end
end

-- remover prefixos antigos, nao acho q vale mais a pena usar
filename = file.name:gsub("%[Unknown%]", ''):gsub("%[noGroup%]", ''):gsub("%[notanidb%]", '')
SGS - Mover&Renamer
lua
-- Shoko Group Structure

-- This script has 2 stages
-- 1 - Move manually linked files keeping original filenames, but add prefix [notanidb]
-- 2 - If found anidb relations, rename files to normalize name structure

remove_illegal_chars = false
replace_illegal_chars = true
use_existing_anime_location = false -- Allows files in Destination import folders to be moved when a group previously had 1 series.

-- Manged Folder
destination = "anime"

local maxnamelen = 70
local spacechar = " "
local animename = anime.preferredname
local episodelanguage = Language.English

-- Part 1
--
-- Accel World
-- ├── Accel World
-- │   └── [notanidb][#AnimeNSK]_Accel_World_-_01_[Blu-Ray_1280x720]_[10Bit]_(B132587A).mkv
-- ├── Accel World OVA
-- │   └── [notanidb][#AnimeNSK]_Accel_World_-_OVA_[Blu-Ray_1280x720]_[10Bit]_(6E91377B).mkv
-- └── Movies
--     └── [notanidb][#AnimeNSK]_Accel_World_Infinite_Burst_[BD_1920x1080]_[HEVC_10Bit]_(E30ACB16).mkv

local shortanimename = nil
if anime.titles then
  for _, v in ipairs(anime.titles) do
    if
    v.type == "Short"
    and v.name
    and (v.language == episodelanguage or v.language == "Romaji")
    then
      shortanimename = v.name
    end
  end
end

local truncatedanimename = animename:truncate(maxnamelen):gsub(' %(.*%)', '')
-- if name is at max lenght then use shortname
if #animename >= maxnamelen and shortanimename then
  truncatedanimename = shortanimename
end

-- put year in front so folder are sorted by year
subfolder = ("%s - %s")
  :format(anime.airdate.year, truncatedanimename)

-- special case: files with multiple relations
if anime.id and (anime.id == 3651 or anime.id == 6367) then
  subfolder = ("%s - %s"):format(2009, "Suzumiya Haruhi no Yuuutsu")
  group.name = "Suzumiya Haruhi no Yuuutsu"
end

-- group dirs based on numer structure
local episodenumber = episode_numbers(math.max(#tostring(anime.episodecounts[episode.type]), 2))
if episodenumber:match("^[S|C|T|O]") then
  subfolder = { group.name, "Extras" }
  if #groups == 1 and #groups[1].animes > 1 then
    subfolder = { group.name, subfolder, "Extras" }
  end
elseif anime.type == AnimeType.Movie then
  subfolder = { group.name, "Movies" }
elseif #groups == 1 and #groups[1].animes > 1 then
  subfolder = { group.name, subfolder }
else
  subfolder = group.name
end

-- not found in anidb, just add prefix to know its not in anidb
if not file.anidb or not file.anidb.releasegroup then
  local function starts_with(str, start)
    return str:sub(1, #start) == start
  end

  if not starts_with(file.name, '[notanidb]') then
    filename = '[notanidb]' .. file.name
  end

  return
end

-- Part 2
--
-- Accel World
-- ├── Accel World
-- │   └── [ANSK] Accel World - 01 [BluRay 720p H264 10bit] [AAC 2.0] (B132587A).mkv
-- ├── Accel World OVA
-- │   └── [ANSK] Accel World OVA - 01 [BluRay 720p H264 10bit] [AAC 2.0] (6E91377B).mkv
-- └── Movies
--     └── [ANSK] Accel World: Infinite Burst [BluRay 1080p HEVC 10bit] [AAC 2.0] (E30ACB16).mkv

-- Anidb release group keys exist before trying to access them (they may be nil)
local releasegroup = (file.anidb.releasegroup.shortname or file.anidb.releasegroup.name)

-- Check if anidb and if file version is greater than 1
local fileversion = ""
if (file.anidb and file.anidb.version > 1) then
  fileversion = " v" .. file.anidb.version
end

local videoinfo = table.concat({
  file.anidb and (file.anidb.source or ""):gsub('BluRay', 'BD'),
  file.media.video.res or "",
  file.media.video.codec or "",
  file.media.video.bitdepth and file.media.video.bitdepth .. "bit" or "",
}, " "):cleanspaces(spacechar)

-- get first audioinfo
local audioinfo = table.concat({
  file.media.audio[1].codec or "",
  file.media.audio[1].channels or "",
}, " "):cleanspaces(spacechar)

local crchash = ""
-- CRC can be null if disabled in Shoko settings, so need to check it
if file.hashes.crc then
  crchash = file.hashes.crc
end

-- clean generic names
local truncatedepisodename = (episode:getname(episodelanguage) or "")
    :gsub("Complete Movie", '')
    :gsub("Episode", '')
    :gsub("OVA", '')
    :gsub("Part 1:", '')
    :gsub("Part 2:", '')
    :gsub("Part 3:", '')
    :gsub("TV Special", '')
    :cleanspaces(spacechar)
    :truncate(maxnamelen)

if anime.type == AnimeType.Movie then
  -- map numbers to romam (common in movies)
  local title = ""
  local epnmap = {
    ["01"] = "I",
    ["02"] = "II",
    ["03"] = "III",
    ["04"] = "IV",
    ["05"] = "V",
    ["06"] = "VI",
    ["07"] = "VII",
    ["08"] = "VIII",
    ["09"] = "IX",
    ["10"] = "X",
  }

  -- build title
  if (#episodenumber > 1 and #truncatedepisodename > 1) then
    title = " " .. (epnmap[episodenumber] or episodenumber) .. ". " .. truncatedepisodename
  end

  filename = string.format(
    "[%s] %s %s [%s] [%s] (%s)",
    releasegroup,
    truncatedanimename,
    title,
    videoinfo,
    audioinfo,
    crchash
  ):cleanspaces(spacechar)
else
  -- comment if you want to keep epname
  truncatedepisodename = ""

  filename = string.format(
    "[%s] %s - %s %s [%s] [%s] (%s)",
    releasegroup,
    truncatedanimename,
    episodenumber .. fileversion,
    truncatedepisodename,
    videoinfo,
    audioinfo,
    crchash
  ):cleanspaces(spacechar)
end