Lua file renaming and moving plugin for Shoko. Uses Lua 5.4.
- Download the latest release
- Unzip the files into C:\ProgramData\ShokoServer\plugins (Windows) or /home/.shoko/Shoko.CLI/plugins (Linux/Docker)
- (Optional) You may COPY (not move) the lua sub-directory to a convenient location for script editing
- It is strongly recommened to install VS Code and the Lua extension to edit your script. The extension uses EmmyLua for annotations
- Follow instructions in the next section to add your script
- Open the lua folder under the directory you extracted, in VS Code
- Look at the sample script and the bottom of defs.lua to get an idea of available variables
- Create a new file or modify the sample script to fit your needs. NOTE: 'sample script.lua' is not read by the renamer, you must save it as a script within shoko, see next steps
- Open Shoko Desktop
- Navigate to Utilities/File Renaming
- Use the Default script or create a new one and set the type of the script to LuaRenamer in the drop-down menu
- Copy your script and paste it in the text box
- Test your script by adding files and clicking preview in the utility under the text box until you are satisfied
- Check run on import, and save the script (next to the script type drop-down)
- You may manually rename and move the files (if checked) of your collection in the utility
Destination defaults to the first destination folder it can find.
If destination is set, it must be set to the name(in shoko) of an import folder, or an import folder table, which are found in the importfolders array or file.importfolder for the current file's folder
The only destination folders settable by the renamer are import folders with Drop Type of Destination or Both.
Subfolder defaults to your preferred language anime title.
If subfolder is set, it must be set to an array-table of path segments () e.g. subfolder = {"parent dir name", "subdir name", "..."}
If 'use_existing_anime_location' is set to true, the last added file's location from the same anime will be used if it exists.
The lua environment is sandboxed, removing operations from standard libraries such as io, and os. See BaseEnv in NLuaSingleton.
Additionally, a modified version of lualinq from xanathar, licensed under the BSD 3 clause, has
been included for convenience. Original Documentation
See defs.lua for all exposed data definitions/structure available from shoko.
function rm_empty_str(table) return from(table):where(function (a) return a ~= "" end):toArray() end
local group = file.anidb and file.anidb.releasegroup and "[" .. (file.anidb.releasegroup.shortname or file.anidb.releasegroup.name) .. "]" or ""
local animename = anime:getname(Language.English) or anime:getname(Language.Romaji) or anime.preferredname
animename = string.gsub(string.sub(animename, 0, 35), "%s+$", "") .. (#animename > 35 and "..." or "")
local episodename = episode:getname(Language.English) or ""
episodename = string.gsub(string.sub(episodename, 0, 35), "%s+$", "") .. (#episodename > 35 and "..." or "")
local episodenumber = ""
if anime.type ~= AnimeType.Movie or not string.find(episodename, "Complete Movie") then
episodenumber = episode_numbers(2) .. (file.anidb and file.anidb.version > 1 and "v" .. file.anidb.version or "")
if #episodes > 1 or string.find(episodename, "Episode") then
episodename = ""
end
else
episodename = ""
end
local res = file.media.video.res or ""
local codec = file.media.video.codec or ""
local bitdepth = file.media.video.bitdepth and file.media.video.bitdepth ~= 8 and file.media.video.bitdepth .. "bit" or ""
local source = file.anidb and file.anidb.source or ""
local fileinfo = "(" .. table.concat(rm_empty_str{res, codec, bitdepth, source}, " ") .. ")"
local dublangs = from(file.anidb and file.anidb.media.dublanguages or from(file.media.audio):select("language"))
local sublangs = from(file.anidb and file.anidb.media.sublanguages or file.media.sublanguages)
local audiotag = dublangs:contains(Language.English) and (dublangs:contains(Language.Japanese) and "[DUAL-AUDIO]" or "[DUB]") or ""
local subtag = audiotag == "" and not sublangs:contains(Language.English) and "[RAW]" or ""
local centag = anime.restricted and file.anidb and (file.anidb.censored and "[CEN]" or "[UNCEN]") or ""
local hashtag = "[" .. file.hashes.crc .. "]"
local nametable = rm_empty_str{group, animename, episodenumber, episodename, fileinfo, audiotag, subtag, centag, hashtag}
filename = string.sub(table.concat(nametable, " "), 0, 120)
WIP