Giter VIP home page Giter VIP logo

luarenamer's Introduction

LuaRenamer

Installation

  1. Download the latest release
  2. Unzip the files into destination
    • (Windows) C:\ProgramData\ShokoServer\plugins
    • (Docker) wherever the container location /home/shoko/.shoko/Shoko.CLI/plugins is mounted
  3. Restart Shoko Server
  4. (Optional) Install VS Code and the Lua extension to edit your script. The extension uses LuaCATS annotations
  5. Follow instructions in the next section to add your script

Usage

With Shoko Desktop

  1. Open Shoko Desktop
  2. Navigate to Utilities/File Renaming
  3. Use the Default script or create a new one and set the type of the script to LuaRenamer in the drop-down menu
  4. (Optional) Open the lua subfolder of the extracted plugin in VS Code
  5. Create a script
  6. Paste the script in the text box in Shoko Desktop
  7. Add the files you wish to rename
  8. Test your script before renaming by pressing Preview. (There is no preview for file moving, only renaming)
  9. Pressing Rename does not move files by default, the checkbox to move must also be checked
  10. Save your script

Linux/Without Shoko Desktop

  1. Copy/download the linux scripts
  2. (Optional) Open the lua subfolder of the extracted plugin in VS Code
  3. Create a script
  4. Preview the results with the preview script ./preview_rename_script.sh <script filename> [# results]
  5. Add your script to Shoko with the add script ./add_rename_script.sh <script filename>
  6. If you want to rename and move all existing files use the rename script ./rename_and_move_all.sh <script name>

Renaming on Import

If you wish to rename/move your files on import you must do two things:

  1. Set Rename/Move On Import to true in Shoko settings
  2. Ensure your script is saved with the run on import setting true
    1. Check that it is the only script with the setting enabled

Script Writing

VS Code + the Lua extension is recommended for script editing.
The script environment utilizes LuaCATS annotations, allowing the extension to provide type linting.

The Environment

The lua environment is sandboxed, removing operations from standard libraries such as io, and os. See BaseEnv in LuaContext.
The script is run in a fresh environment for every file.
Only the output variables defined in env.lua will have any effect outside of the script.

  • env.lua*: The starting environment, output variable values will change renaming/moving behaviour
  • defs.lua*: Table definitions available from Shoko
  • enums.lua*: Enumeration definitions
  • lualinq.lua: A modified utility library (original, docs) that adds functional query methods similar to LINQ
  • utils.lua: Additional utility functions can be defined here

* This file is not executed, it serves as documentation/annotations

Script Settings

In addition to the filename, destination and subfolder output variables, these variables affect the result of your script.

  • use_existing_anime_location If true, the subfolder with the most files of the same anime is reused if one exists. This takes precedence over the subfolder set in the script (default: false)
  • replace_illegal_chars If true, replaces all illegal path characters in subfolder and file name with alternatives. See ReplaceMap in Utils.cs (default: false)
  • remove_illegal_chars If true, removes all illegal path characters in subfolder and file name. If false, illegal characters are replaced with underscores or replaced if replace_illegal_chars is true. (default: false)
  • skip_rename If true, the result of running the script is discarded when renaming. (default: false)
  • skip_move If true, the result of running the script is discarded when moving. (default: false)

Notes for File Moving

Import folders are only valid destination candidates if they exist and have either the 'Destination' or 'Both' Drop Type. Using use_existing_anime_location allows for an import folder with 'Excluded' drop type to be picked. This may change in the future.
Destination defaults to the nearest (to the file) valid import folder.
Destination is set via:

  • Import folder name (string)
  • Server folder path (string)
  • Import folder reference (selected from 'importfolders' array)

If destination set via path, it is matched to import folder path with converted directory seperators but no other special handling (relative path or expansion).

Subfolder defaults to the anime title in your preferred language.
Subfolder is set via:

  • Subfolder name (string)
  • Path segments (array-table, e.g. {"parent dir name", "subdir name", "..."})

If set via a string subfolder name, directory separators within the string are ignored or replaced depending on preference.
Also see use_existing_anime_location in Script Settings

The default script provides a sensible renaming template. Some variables may be customized at the top of the file, and can serve as a good base for your own script.

Common Questions/Scenarios

I want to split my collection across import folders

The easiest option is to set the destination by import folder name. Keep in mind the import folder must have the Destination or Both drop type. You may also specify the destination by the full path of the import folder on the server or by referencing it directly via importfolders.

if anime.restricted then
  destination = "hentai"
else
  destination = "anime"
end

I want to split my collection across subfolders

if anime.type == AnimeType.Movie then
    subfolder = { "Anime Movies", anime.preferredname }
else
    subfolder = { "Anime", anime.preferredname }
end

I want my anime to be grouped according to Shoko

Adding Shoko group name to subfolder path when there are multiple series in group.
Warning: adding new series to a group with one entry will not move the old series into a subfolder, so you should probably use this when batch renaming/moving existing series

if #groups == 1 and #groups[1].animes > 1 then
  subfolder = {groups[1].name, anime.preferredname}
end

I want to move/rename my anime collection into seasons

AniDB, Shoko's metadata provider does not have the concept of seasons. Therefore the metadata available cannot be cleanly mapped. I recommend using Shoko Metadata for Plex or Shokofin for Jellyfin as your client instead of depending on other metadata providers.

I want to hard link my files

Neither Shoko nor this plugin has the ability to create file links. I recommend creating any links before the file is processed by Shoko. Usually download clients have the option to run a script on download completion. You can create a script to link files to a Shoko drop source folder. Feel free to contact me if you need help with this.
Note: If you hard link your files you will need to create an import folder for each file system/volume used.

luarenamer's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

luarenamer's Issues

install on Docker

I have my ShokoServer on Docker (Manjaro Linux) and I use the Shoko Desktop app via Wine. I extracted the archive (linux version) to ~/.shoko/Shoko.CLI/plugin (inside ~/.shoko/Shoko.CLI/plugin/LuaRenamer is only lua subdirectory and files - no nested LuaRenamer directory). After restarting the server I opened Shoko Desktop, went to Utilities > File Renaming tab but there is no new renamer:
image

Investigate how subfolder paths are handled within Shoko

From first looks it's impossible to set an empty subfolder (immediate descendant of import folder).

Also check if there if there is a bug/vulnerability that allows user to set a subfolder that starts at root "/" or use relative paths "../"

Use episode updated event to run renamer

Currently, the renamer only runs on import and thats it. Due to that episodes with a title "Episode X" are not renamed to their actual name when/if it is eventually updated. It would be a nice addition to add an option to run the renamer whenever episode info is updated.

Hard to reproduce error on docker

Two users, Eclipse and kero_chan reported this error when renaming files.

17:50:20| SVR_VideoLocal_Place --- System.InvalidCastException: Unable to cast object of type 'NLua.LuaUserData' to type 'KeraLua.LuaFunction'.
   at NLua.Lua.GetFunction(String fullPath)
   at NLua.Lua.RegisterFunction(String path, Object target, MethodBase function)
   at LuaRenamer.LuaRenamer.CreateLuaEnv()
   at LuaRenamer.LuaRenamer.RunSandboxed(String code)
   at LuaRenamer.LuaRenamer.GetInfo()
   at LuaRenamer.LuaRenamer.GetFilename(RenameEventArgs args)
   at Shoko.Server.RenameFileHelper.GetFilename(SVR_VideoLocal_Place place, String scriptName) in /usr/src/app/source/Shoko.Server/Renamer/RenameFileHelper.cs:line 69
08:39:38| --- Trying to load /home/shoko/.shoko/Shoko.CLI/plugins/LuaRenamer/KeraLua.dll
Process terminated. A callback was made on a garbage collected delegate of type 'KeraLua!KeraLua.LuaFunction::Invoke'.
   at KeraLua.NativeMethods.lua_settable(IntPtr, Int32)
08:40:56| --- Trying to load /home/shoko/.shoko/Shoko.CLI/plugins/LuaRenamer/KeraLua.dll
            *Error: Unable to cast object of type 'NLua.LuaUserData' to type 'KeraLua.LuaFunction'.
            *Error: Unable to cast object of type 'NLua.LuaUserData' to type 'KeraLua.LuaFunction'.
            *Error: Unable to cast object of type 'NLua.LuaTable' to type 'KeraLua.LuaFunction'.
            *Error: Unable to cast object of type 'NLua.LuaUserData' to type 'KeraLua.LuaFunction'.
08:58:45| --- Trying to load /home/shoko/.shoko/Shoko.CLI/plugins/LuaRenamer/KeraLua.dll

Fix getname function

Source of error is from anime/episode getname lua function. (TitleFunction in LuaContext.cs)
Investigate possible changes in abstraction TitleType enum that causes this.

Error log from kero_chan#9048

13:22:26| SVR_VideoLocal_Place --- Error: The renamer returned an error on file: "/srv/Downloads/anime/[SubsPlease] Girls und Panzer das Finale - 03 (1080p) [EAD6892E].mkv"
            *Error: ...hoko/.shoko/Shoko.CLI/plugins/LuaRenamer/lua/lualinq.lua:434: attempt to compare number with nil
13:22:26| SVR_VideoLocal_Place --- Attempting to MOVE file: "/srv/Downloads/anime/[SubsPlease] Girls und Panzer das Finale - 03 (1080p) [EAD6892E].mkv"
13:22:27| SVR_VideoLocal_Place --- Could not find a valid destination: "/srv/Downloads/anime/[SubsPlease] Girls und Panzer das Finale - 03 (1080p) [EAD6892E].mkv"

Instructions for Linux

I managed to follow the install instructions for Linux and added the file to the .shoko/Shoko.CLI/plugins folder. But since I am on Linux, I could not follow the usage instructions entirely. Instead, I modified sample script.lua manually and saved it as my script.lua in the same folder. At this point I'm not sure anymore what my next step should be. Is sample script.lua the one that the renamer actually uses and should I not have created a new file? Or do I need to use a different name for it? Or add it to a configuration somewhere? I assume that Shoko Desktop does this for you, but I don't use that and it is not available on Linux. I'd appreciate some help with this.

In case you're curious about how I modified the sample script without Shoko Desktop. I basically removed all the logic and only kept the variables for the different parts that go into the filename. This allowed me to run it in an online runtime (JDoodle) so I could verify what the filename would be. This is the code that I used, maybe it'd be useful to add to the documentation somewhere (it could probably use better, more representative values for these variables).

local group = "[Fansub Group]"

local animename = "Isekai Anime"
animename = string.gsub(string.sub(animename, 0, 35), "%s+$", "") .. (#animename > 35 and "..." or "")

local episodename = "My First Day in Another World"
episodename = string.gsub(string.sub(episodename, 0, 35), "%s+$", "") .. (#episodename > 35 and "..." or "")

local episodenumber = "01"

local res = "1080p"
local codec = "AVC"
local bitdepth = "8bit"
local source = "HDD"

local fileinfo = "(" .. res .. " " .. codec .. " " .. bitdepth .. " " .. source .. ")"

local audiotag = "[AUDIOTAG]"
local subtag = "[SUBBED]"

local centag = "[UNCEN]"
local hashtag = "[deadbeef]"

local audios = "2.0"
local nametable = {group, animename, episodenumber, episodename, fileinfo, audiotag, subtag, centag, audios, hashtag}
filename = string.sub(table.concat(nametable, " "), 0, 120)

print(filename)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.