Different Naming Scheme Depending On Extension

Running FileBot from the console, Groovy scripting, shell scripts, etc
Post Reply
gordian
Posts: 4
Joined: 28 Jan 2015, 17:11

Different Naming Scheme Depending On Extension

Post by gordian »

Before I dive into the nitty gritty of my post, I want to express my sincere gratitude for this great tool and the vast resources that are provided in this community :)
I have been using it for my GUI-assisted renaming tasks in one form or another for quite a while.
Now I want to finally get rid off an old shellscript I wrote years ago and use the FileBot CLI for my automated renaming tasks as well.


What I want to accomplish
  1. Rename files according to my preferences
  2. Use a different naming scheme depending on file extension; namely: move *.nfo and *.jpg files to a subdirectory, retaining their original filename
  3. Move files to folder x and create symlinks in folder y that point to the files in their new location
Due to my unfamiliarity with Groovy / Java I have been failing at the second task all evening :/
In order to contribute at least a little and give some background information, I'll post my basic naming scheme for tv series. It mainly consists of code snippets posted by rednoah, Igor and various other board users (thanks, guys :)) and some slight modifications to suit my taste. The aim was similar to Igor's: straight forward, clean naming, adhering relatively close to scene standards.

Code: Select all

{n.upperInitial().space('.').replaceAll(/[,()]+/).replaceAll(/\.-\./,'.')}.{s00e00}.{t.upperInitial().space('.').replacePart('Part.$1').replaceAll(/[`´‘’?]/, "'")}{"."+fn.matchAll(/unrated|uncut|extended/).join('.').lower().upperInitial()}{"."+fn.matchAll(/repack|proper|rerip|internal|repacked/).join('.').toUpperCase()}{'.'+vf.match(/720p|1080p/)}{".$source"}{"."+fn.matchAll(/DD5.1|AAC2.0/).join('.').toUpperCase()}{"."+vc.replaceAll(/AVC/, "H264")}{def g = c{group}; def m = c{fn.match(/(?:(?<=[-])\w+$)|(?:^\w+(?=[-]))/)}; if(g==null && m!=null) return "-$m"; if(g!=null) return "-$g"; if(g==null && m==null) return "-iND"}
I have been trying all evening to extend my naming scheme in order to handle various extensions differently, but I failed miserably. By now I think the most elegant solution would be to write/modify a FileBot script.
Here is how far I got in my naming scheme:

Code: Select all

{if (ext =~ /jpg|nfo/) return "nfos/${fn}"; else return "${n.upperInitial().space('.').replaceAll(/[,()]+/).replaceAll(/\.-\./,'.')}.${s00e00}.${t.upperInitial().space('.').replacePart('Part.$1').replaceAll(/[`´‘’?]/, "'")}"}
Once I use the matchAll function in the above expression, e.g. ${"."+fn.matchAll(/repack|proper|rerip|internal|repacked/)}, I run into trouble, as matchAll breaks if it does not find a matching pattern.
Now this was not the first time the thought occurred that there must be a more genteel solution to the task at hand than to write an overly complex naming scheme.. so before working around the issue and taking this sham any further all the while outing myself to be the biggest copy & paste & trial & error idiot on the planet, I wanted to ask how to do it right.

I am willing to work for my cake, but I would appreciate a push into the right direction :)
How would you experts go about solving the task outlined in #2 of my agenda?
Can it be done via naming scheme or do I have to get into scripting?

Once I get the naming based on extension sorted out, I will continue to pull out my hair regarding the creation of symlinks pointing to the moved files.
One step (and hair) at a time, though :D


Any help is appreciated.


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

Re: Different Naming Scheme Depending On Extension

Post by rednoah »

I guess you're on the right track. As long as FileBot matches the non-media files to the same Movie/Episode object you can use the normal format expression logic and just add some extra conditions based on the extension.

e.g. insert an /image/ folder into the output path:

Code: Select all

{ext == 'jpg' ? '/image/' : ''}
:idea: Please read the FAQ and How to Request Help.
gordian
Posts: 4
Joined: 28 Jan 2015, 17:11

Re: Different Naming Scheme Depending On Extension

Post by gordian »

Hi Noah,

Thank you for your interest/reply and sorry for posting another wall of text.
I had this project on hold until today due to an unexpected hospital stay.
Now that I am home and recovering I am trying to get back into the subject.

Using the ternary operator to insert a sub-directory depending on the file extension is certainly more elegant than my usage of an if else statement.
But it is not the part where I am struggling.
The problem is that I want to retain the original filename {fn} for the files I move into the sub-directory (jpg, nfo), but rename the remaining files according to my scheme.

My renaming scheme (see above) is so complex, that I can't seem to be able to use it sensibly within a statement.
E.g. if fn.matchAll does not find a pattern, it breaks the operation. If that happens within a statement, no value is returned. At least that is what I think is the issue.
Let me illustrate using a real world example:

This works:

Code: Select all

C:/Some.Path/{n.upperInitial().space('.').replaceAll(/[,()]+/).replaceAll(/\.-\./,'.')}/{ext =~ /jpg|nfo/ ? "nfos/${fn}" : "${n.upperInitial().space('.').replaceAll(/[,()]+/).replaceAll(/\.-\./,'.')}.${s00e00}.${t.upperInitial().space('.').replacePart('Part.$1').replaceAll(/[`´‘’?]/, "'")}"}
This does not work (if the file extension is not jpg or nfo and the filename does not contain one of these expressions repack|proper|rerip|internal|repacked it fails with ScriptException: java.lang.Exception: Pattern not found):

Code: Select all

C:/Some.Path/{n.upperInitial().space('.').replaceAll(/[,()]+/).replaceAll(/\.-\./,'.')}/{ext =~ /jpg|nfo/ ? "nfos/${fn}" : "${n.upperInitial().space('.').replaceAll(/[,()]+/).replaceAll(/\.-\./,'.')}.${s00e00}.${t.upperInitial().space('.').replacePart('Part.$1').replaceAll(/[`´‘’?]/, "'")}${"."+fn.matchAll(/repack|proper|rerip|internal|repacked/)}"}

So this is basically what I want to do:
Move nfo and jpg files to

Code: Select all

{n}/nfos/{fn}

and move all other files to

Code: Select all

{n}/{n.upperInitial().space('.').replaceAll(/[,()]+/).replaceAll(/\.-\./,'.')}.{s00e00}.{t.upperInitial().space('.').replacePart('Part.$1').replaceAll(/[`´‘’?]/, "'")}{"."+fn.matchAll(/unrated|uncut|extended/).join('.').lower().upperInitial()}{"."+fn.matchAll(/repack|proper|rerip|internal|repacked/).join('.').toUpperCase()}{'.'+vf.match(/720p|1080p/)}{".$source"}{"."+fn.matchAll(/DD5.1|AAC2.0/).join('.').toUpperCase()}{"."+vc.replaceAll(/AVC/, "H264")}{def g = c{group}; def m = c{fn.match(/(?:(?<=[-])\w+$)|(?:^\w+(?=[-]))/)}; if(g==null && m!=null) return "-$m"; if(g!=null) return "-$g"; if(g==null && m==null) return "-iND"}
Is this even possible using the normal format expression logic or am I wasting my time?


Thanks again & best regards,
gordian
User avatar
rednoah
The Source
Posts: 23931
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Different Naming Scheme Depending On Extension

Post by rednoah »

I guess this is a bit tricky since you have 2 completely different formats in one expression.

If you're struggling with matchAll you can use c{...} or any{...}{...} to catch/ignore the Exception thrown by matchAll that would normally unwind the top {...} block. The allOf{...}{...} helper might be handy as well. See stickies for details. ;)

Regardings two formats in one, it's probably best to put everything into one {...} code block.

Food for Thought:

Code: Select all

{ if (ext =~ /nfo/) { n+'/nfos/'+fn } else { n+'/'+episode } }
:idea: Please read the FAQ and How to Request Help.
gordian
Posts: 4
Joined: 28 Jan 2015, 17:11

Re: Different Naming Scheme Depending On Extension

Post by gordian »

Thank you very much for your assistance, rednoah.
You are my personal hero and you made my day! :)
You truly are The Source :D

If anyone else is struggling to achieve something similar, here is my n00bish solution (I am sure a pro could solve it way more elegant.. but - so far - it works flawlessly):

Code: Select all

Some.Path/{n.upperInitial().space('.').replaceAll(/[,()]+/).replaceAll(/\.-\./,'.')}{ if (ext =~ /nfo|jpg/) { '/nfos/'+fn } else { '/'+"${allOf {n.upperInitial().space('.').replaceAll(/[,()]+/).replaceAll(/\.-\./,'.')}{s00e00}{t.upperInitial().space('.').replacePart('Part.$1').replaceAll(/[`´‘’?]/, "'")}{fn.matchAll(/unrated|uncut|extended/).join('.').lower().upperInitial()}{fn.matchAll(/repack|proper|rerip|internal|repacked/).join('.').toUpperCase()}{vf.match(/720p|1080p/)}{source}{fn.matchAll(/DD5.1|AAC2.0/).join('.').toUpperCase()}{vc.replaceAll(/AVC/, "H264")} join('.')}${def g = c{group}; def m = c{fn.match(/(?:(?<=[-])\w+$)|(?:^\w+(?=[-]))/)}; if(g==null && m!=null) return "-$m"; if(g!=null) return "-$g"; if(g==null && m==null) return "-iND"}" } }

Tomorrow I will tackle the symlink part of my objective.
Though I think the easiest solution would probably be to use your AMC script and it's exec function.
Post Reply