User defined Variables/Bindings in format string

Any questions? Need some help?
Post Reply
SonOfDiablo
Posts: 26
Joined: 11 Feb 2019, 10:11

User defined Variables/Bindings in format string

Post by SonOfDiablo » 06 Mar 2020, 20:50

Hello,

I just encountered an issue where a show is given the wrong year (because of an inconsistency on TheTVDB) and I'm trying to figure out the best solution to the problem.

right now this is my format pattern:

Code: Select all

{csv('D:/Film/filter.csv').get(n.lower()).split(';')[1] ?: 'New'}/Shows/{n} ({csv('D:/Film/filter.csv').get(n.lower()).split(';')[0] ?: '????'})/Season {s.pad(2)}/{n.upperInitial().space('.')}.{S00E00}.{t.upperInitial().space('.')}
filter.csv looks like this:

Code: Select all

Show Name;2008;RootPath1
Show Name2;1997;RootPath1
Show Name3;2011;RootPath2
...
What I really want is to make the csv call a variable, something like:

Code: Select all

string[] ShowInfo = D:/Film/filter.csv').get(n.lower()).split(';') ?: ['????','New']
That way I could reuse the values instead of reading the csv file twice, ending up with the following pattern:

Code: Select all

{ShowInfo[1]}/Shows/{n} ({ShowInfo[0])/Season {s.pad(2)}/{n.upperInitial().space('.')}.{S00E00}.{t.upperInitial().space('.')}
Is this at all possible?

kim
Power User
Posts: 898
Joined: 15 May 2014, 16:17

Re: User defined Variables/Bindings in format string

Post by kim » 07 Mar 2020, 01:42

You can only reuse IF within same {}

Code: Select all

{def a = 'b' + 'c'; a + 'd' + a + 'e'}

User avatar
rednoah
The Source
Posts: 17864
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: User defined Variables/Bindings in format string

Post by rednoah » 07 Mar 2020, 05:14

You can only use variables, conditionals, etc inside {GroovyCode} sections.


:idea: Depending on your use case, you might want to consider using a single {...} expression for your entire code and just have that yield the path you want. If your format is heavy on code and logic, then this will make things more easy and intuitive.


e.g.

Code: Select all

Movies/{
[ allOf {ny}
        { allOf {vf}
                {group}
        }
, allOf {ny}
        {'CD'+pi}
        {lang}
]*.findResults { 
    if (it) it.toString()
              .replaceAll(/[!?.]+$/)
              .asciiQuotes()
}*.join(' ')
  .join('/')
}
:idea: Please read the FAQ and How to Request Help.

SonOfDiablo
Posts: 26
Joined: 11 Feb 2019, 10:11

Re: User defined Variables/Bindings in format string

Post by SonOfDiablo » 07 Mar 2020, 09:44

rednoah wrote:
07 Mar 2020, 05:14
You can only use variables, conditionals, etc inside {GroovyCode} sections.


:idea: Depending on your use case, you might want to consider using a single {...} expression for your entire code and just have that yield the path you want. If your format is heavy on code and logic, then this will make things more easy and intuitive.
Oh I did not know that was an option...
Thank you very much Rednoah!

I have now gotten to this format code, might need to clean it up a bit more at some point, but it's way better than before!

Code: Select all

{
    def ShowInfo = csv('D:/Film/filter.csv').get(n.lower()).split(';') ?: ['????','New'];
    def pattern = '%s/Shows/%s (%s)/Season %s/%s.%s.%s';
    String.format(pattern,ShowInfo[1],n,ShowInfo[0],s.pad(2),n.upperInitial().space('.'),S00E00,t.upperInitial().space('.'))
}

SonOfDiablo
Posts: 26
Joined: 11 Feb 2019, 10:11

Re: User defined Variables/Bindings in format string

Post by SonOfDiablo » 07 Mar 2020, 10:53

However I have run into an issue...

When calling filebot from the command line (Powershell Core 6 on Windows) it works just fine, however when calling filebot from TotalCommander (Like I have been doing for years now, without issues) I get the following error message:

Code: Select all

Rename episodes using [TheTVDB]
Autoo-detected query: [Murdoch Mysteries]
Fetching episode data for [Murdoch Mysteries]
Fetching episode data for [The Murdoch Mysteries (2004)]
Apply filter [!readLines('D:/Film/Filebot_Excludes.txt').contains(n)] on [350] items
[MOVE] from [D:\Film\Out\Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv] to [D:\Film\Out\Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv\Shows\Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv (Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv)\Season Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv\Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv.Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv.Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv.mkv]
[MOVE] Failure: java.nio.file.NoSuchFileException: D:\Film\Out\Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv\Shows
Processed 0 files
D:\Film\Out\Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv\Shows
java.nio.file.NoSuchFileException: D:\Film\Out\Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv\Shows
    at net.filebot.util.FileUtilities.resolveDestination(FileUtilities.java:122)
    at net.filebot.util.FileUtilities.moveRename(FileUtilities.java:65)
    at net.filebot.StandardRenameAction$1.rename(StandardRenameAction.java:25)
    at net.filebot.cli.CmdlineOperations.renameAll(CmdlineOperations.java:640)
    at net.filebot.cli.CmdlineOperations.renameSeries(CmdlineOperations.java:251)
    at net.filebot.cli.CmdlineOperations.rename(CmdlineOperations.java:97)
    at net.filebot.cli.ArgumentProcessor.runCommand(ArgumentProcessor.java:124)
    at net.filebot.cli.ArgumentProcessor.run(ArgumentProcessor.java:33)
    at net.filebot.Main.main(Main.java:132)
(There might be typos, I had to copy it all by hand from a recording since the window closed before I could see anything)

The full command run by hand:

Code: Select all

filebot -rename "D:\Film\Out\Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv" --db TheTVDB -non-strict --filter "!readLines('D:/Film/Filebot_Excludes.txt').contains(n)" --log FINE --format "{ def ShowInfo = csv('D:/Film/filter.csv').get(n.lower()).split(';') ?: ['????','New']; def pattern = '%s/Shows/%s (%s)/Season %s/%s.%s.%s'; String.format(pattern,ShowInfo[1],n,ShowInfo[0],s.pad(2),n.upperInitial().space('.'),S00E00,t.upperInitial().space('.')) }"
What is run from TotalCommander:

Code: Select all

Command: filebot
Parameters: -rename %P%S --db TheTVDB -non-strict --filter "!readLines('D:/Film/Filebot_Excludes.txt').contains(n)" --log FINE --format "{ def ShowInfo = csv('D:/Film/filter.csv').get(n.lower()).split(';') ?: ['????','New']; def pattern = '%s/Shows/%s (%s)/Season %s/%s.%s.%s'; String.format(pattern,ShowInfo[1],n,ShowInfo[0],s.pad(2),n.upperInitial().space('.'),S00E00,t.upperInitial().space('.')) }"
(%P%S gets expanded to the path and filename of the selected file(s), so in this case would be D:\Film\Out\Murdoch.Mysteries.S13E12.Fox.Hunt.1080p.DDP2.0.H.264-TEST.mkv)


Would you have any ideas as to what could be causing this issue?
As mentioned, I have been using the same method of calling FileBot through TotalCommander for years without any issues and the previous format worked aswell.

Code: Select all

-rename %P%S --db TheTVDB -non-strict --filter "!readLines('D:/Film/Filebot_Excludes.txt').contains(n)" --log FINE --format "{csv('D:/Film/filter.csv').get(n.lower()).split(';')[1] ?: 'New'}/Shows/{n} ({csv('D:/Film/filter.csv').get(n.lower()).split(';')[0] ?: '????'})/Season {s.pad(2)}/{n.upperInitial().space('.')}.{S00E00}.{t.upperInitial().space('.')}"

User avatar
rednoah
The Source
Posts: 17864
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: User defined Variables/Bindings in format string

Post by rednoah » 07 Mar 2020, 13:08

You can use external *.groovy files, instead of passing code inline on the command-line. The latter is possible, but difficult to do correctly, because you will find that different tools, PowerShell, CMD, bash, TC, etc all have their peculiarities when you start trying to passing in complex multi-line argument values.


:idea: Please read Cmdline and Argument Passing for details.


:idea: Use the @file syntax for reading command-line arguments from external text files.
:idea: Please read the FAQ and How to Request Help.

SonOfDiablo
Posts: 26
Joined: 11 Feb 2019, 10:11

Re: User defined Variables/Bindings in format string

Post by SonOfDiablo » 07 Mar 2020, 13:51

That worked thanks!

Though I do have one question (just out of curiosity) in the @file syntax post you show this example:

Code: Select all

Movies/{
[ allOf {ny}
        { allOf {vf}
                {group}
        }
, allOf {ny}
        {'CD'+pi}
        {lang}
]*.findResults { 
    if (it) it.toString()
              .replaceAll(/[!?.]+$/)
              .asciiQuotes()
}*.join(' ')
  .join('/')
}
Which is used with the AMC script.
I'm just wondering if it's possible to not encapsulate the script content in curly-brackets and keeping it on one line, like this:

Code: Select all

{def ShowInfo = csv('D:/Film/filter.csv').get(n.lower()).split(';') ?: ['????','New'];def pattern = '%s/Shows/%s (%s)/Season %s/%s.%s.%s';String.format(pattern,ShowInfo[1],n,ShowInfo[0],s.pad(2),n.upperInitial().space('.'),S00E00,t.upperInitial().space('.'))}
but split it up like so:

Code: Select all

{
    def ShowInfo = csv('D:/Film/filter.csv').get(n.lower()).split(';') ?: ['????','New'];
    def pattern = '%s/Shows/%s (%s)/Season %s/%s.%s.%s';
    String.format(pattern,ShowInfo[1],n,ShowInfo[0],s.pad(2),n.upperInitial().space('.'),S00E00,t.upperInitial().space('.'))
}
I have tried that and without the curly brackets at the start and end, but sadly didn't work.

Is that at all possible with the -rename option or would I have to introduce an actual script (AMC or custom) to accomplish this?

User avatar
rednoah
The Source
Posts: 17864
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: User defined Variables/Bindings in format string

Post by rednoah » 07 Mar 2020, 14:17

{...} are necessary for FileBot Format syntax. FileBot Format syntax does not care about newlines. The Groovy code inside {...} does care about newlines, but that's just syntax. Any multi-line Groovy code can be expressed in a single line. I guess it's mostly a matter of replacing newline with ; semicolon.


You can also evaluate Groovy code dynamically if that helps:
viewtopic.php?f=5&t=10839
:idea: Please read the FAQ and How to Request Help.

SonOfDiablo
Posts: 26
Joined: 11 Feb 2019, 10:11

Re: User defined Variables/Bindings in format string

Post by SonOfDiablo » 07 Mar 2020, 14:37

After a bit of reading I thought Evaluate(...) as file seemed to be the best option for what I want, however I'm getting the following error message:

Code: Select all

Expression yields empty value: No signature of method: TVFormat.csv() is applicable for argument types: (String) values: [D:/Film/filter.csv]
I guess I have to explicitly state the class containing csv, however I can't seem to track down that bit of info.

User avatar
rednoah
The Source
Posts: 17864
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: User defined Variables/Bindings in format string

Post by rednoah » 07 Mar 2020, 15:14

Strange. Works for me.

Are you using FileBot r7205 (latest beta) or above?
viewtopic.php?t=1609
:idea: Please read the FAQ and How to Request Help.

SonOfDiablo
Posts: 26
Joined: 11 Feb 2019, 10:11

Re: User defined Variables/Bindings in format string

Post by SonOfDiablo » 07 Mar 2020, 15:18

I'm using the Microsoft Store version (which is currently on v4.8.5 (r6224))

User avatar
rednoah
The Source
Posts: 17864
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: User defined Variables/Bindings in format string

Post by rednoah » 07 Mar 2020, 15:45

Sorry, looks like my previous answers don't apply yet. It'll work with upcoming releases though. Looks like you'll have to go with a different solution if you need a solution right now.
:idea: Please read the FAQ and How to Request Help.

SonOfDiablo
Posts: 26
Joined: 11 Feb 2019, 10:11

Re: User defined Variables/Bindings in format string

Post by SonOfDiablo » 07 Mar 2020, 15:52

Oh, fair enough. I'm just gonna wait it out then.

Thank you for all the assistance though, greatly appreciated!

Post Reply