Page 1 of 1

Combine 2 expressions and execute either one depending on file name ?

Posted: 07 Jan 2019, 00:00
by madmiddle
I have used the for many years but only recently started to learnt how powerful it really is. So firstly thank you for all the time you put into it, it's much appreciated. Secondly thank you to the community as they have provided a lot of answers without me having to register.

I have not been able to find an answer as i'm not entirely sure of what to search for so sorry for the vague title.

I'll to put it as simply as possible I would like to join the follow 2 expressions into 1 expression and then rename the file according to what is in the original file name:

Code: Select all

/Volumes/video/Film/{n.replaceFirst(/^(?i)(The|A|An)\s(.+)/, /$2, $1/).replaceAll(/[:]/, " - ").replaceAll(/[?]/, "")} ({y}).{vf}.{source}.{vc}.{ac}
/Volumes/video/Film/{n.replaceFirst(/^(?i)(The|A|An)\s(.+)/, /$2, $1/).replaceAll(/[:]/, " - ").replaceAll(/[?]/, "")} ({y}).{vf}.{source}.{vc}.{ac}-x0r
If the original file has a 'x0r' in it then i would like the bottom one to be used and anything else the top one.

As I said before I am only just finding out the real power of this app but need some guidance, I don't even know if the code I have entered above is the most efficient way of doing it either.

I have the up to date paid for app from the Mac app store if that makes any difference.

Thank you for your time

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 07 Jan 2019, 01:14
by madmiddle
I think I have found the answer, I need to use an IF statement. Can you use a IF with an AND condition ? for example IF it has a 1 AND 2 AND 3 in the filename ? I will probably be interested in how to use the OR function as well.

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 07 Jan 2019, 13:08
by rednoah
The easiest solution is to just match that keyword from the original file name:

Code: Select all

{'-'+fn.match(/x0r/)}
This will either give you "-x0r" if x0r is in the file name, or nothing.

So this will do:

Code: Select all

{n.sortName('$2, $1').colon(' - ').replace('?', '')} ({y}).{vf}.{source}.{vc}.{ac}{'-'+fn.match(/x0r/)}

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 07 Jan 2019, 15:07
by madmiddle
rednoah wrote: 07 Jan 2019, 13:08 The easiest solution is to just match that keyword from the original file name:

Code: Select all

{'-'+fn.match(/x0r/)}
This will either give you "-x0r" if x0r is in the file name, or nothing.

So this will do:

Code: Select all

{n.sortName('$2, $1').colon(' - ').replace('?', '')} ({y}).{vf}.{source}.{vc}.{ac}{'-'+fn.match(/x0r/)}
Thats awesome cheers fella.

I upload them to my server the folder being /Volumes/video/To be sorted and then either /Film/ or /Kids Films/ folder (i use this as a holding folder till i have the time to sit down and run Filebot through all the files). When uploaded they then go into /Volumes/Video and then either /Film/ or /Kids Films/ folders again.

Am I able to use an OR function checking the source folder to then rename and place them into the other folder? I think I need to use f.dir.dir.name but i'm really struggling to get it to work.

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 07 Jan 2019, 16:10
by rednoah
You can do that as well of course:

Code: Select all

{f =~ /Kids.Films/ ? 'Kids Films' : 'Films'}
Does the original path contains "Kids Films"? If yes, yield "Kids Films", otherwise yield "Films".

You can use that {...} expression in your format wherever you want.


e.g.

Code: Select all

/Volumes/Video/{f =~ /Kids.Films/ ? 'Kids Films' : 'Films'}/{n.sortName('$2, $1').colon(' - ').replace('?', '')} ({y}).{vf}.{source}.{vc}.{ac}{'-'+fn.match(/x0r/)}

Alternatively, code like {f[1..3]} (path components 1 to 3) can give you bits and pieces of the current path, so you can reuse them for the destination path.

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 07 Jan 2019, 18:28
by madmiddle
rednoah wrote: 07 Jan 2019, 16:10 You can do that as well of course:

Code: Select all

{f =~ /Kids.Films/ ? 'Kids Films' : 'Films'}
Does the original path contains "Kids Films"? If yes, yield "Kids Films", otherwise yield "Films".

You can use that {...} expression in your format wherever you want.


e.g.

Code: Select all

/Volumes/Video/{f =~ /Kids.Films/ ? 'Kids Films' : 'Films'}/{n.sortName('$2, $1').colon(' - ').replace('?', '')} ({y}).{vf}.{source}.{vc}.{ac}{'-'+fn.match(/x0r/)}

Alternatively, code like {f[1..3]} (path components 1 to 3) can give you bits and pieces of the current path, so you can reuse them for the destination path.
ah bloody hell it's a similar format to visual basic to me so if i wanted to add a third part to it then it would look like this:

Code: Select all

/Volumes/Video/{f =~ /Kids.Films/ ? 'Kids Films' : f =~ /Stand.Up.Comedy/ ? 'Stand Up Comedy' : 'Film'}/{n.sortName('$2, $1').colon(' - ').replace('?', '')} ({y}).{vf}.{source}.{vc}.{ac}{'-'+fn.match(/x0r/)}
?

so the only thing left for me to try a figure out is the AND function:

It's for a separate naming project but I need to find all the files that are 720p AND x264 AND BluRay as the source, is that with the double == ?

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 07 Jan 2019, 18:38
by rednoah
Yes, the ternary operator is quite common in programming languages:
http://groovy-lang.org/operators.html#_ternary_operator

Groovy used Java / C style && and || for AND and OR:
http://groovy-lang.org/operators.html#_ ... _operators

Checking if 2 string values are equal is indeed == in Groovy as well (same as Java).

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 08 Jan 2019, 01:52
by madmiddle
rednoah wrote: 07 Jan 2019, 18:38 Yes, the ternary operator is quite common in programming languages:
http://groovy-lang.org/operators.html#_ternary_operator

Groovy used Java / C style && and || for AND and OR:
http://groovy-lang.org/operators.html#_ ... _operators

Checking if 2 string values are equal is indeed == in Groovy as well (same as Java).
Top banana. Thanks for the info.

So I have come up with the following code:

Code: Select all

{if (vf == '720p' && source == 'BluRay' && vc == 'x264' && ac == 'AC3') 'Yes' }
this currently works for all the files that meet that criteria but for the life of me I can not add the 'false/everything else' into this expression. I thought I might need to add the '?' and then separate the true and false statement with a colon:

Code: Select all

{if (vf == '720p' && source == 'BluRay' && vc == 'x264' && ac == 'AC3') ? 'Yes' : 'No' }
but with various tries I have failed. I think I am painfully close.


EDIT:

Got it sort of. For the majority of files this code works perfectly:

Code: Select all

{if (vf == '720p' && source == 'BluRay' && vc == 'x264' && ac == 'AC3') 'Yes' else 'No'}
up until it finds a file with the source missing then i get this error message in the New Names Window for the affected file:

Code: Select all

[Expression yields empty value: Binding "source": undefined]
I can only assume that I gets stuck in the code when it has a Null as the source when it is expecting a value, rather than getting to the end for the 'No'. is there a IFERROR type code i can add to it ?

This is basically where I would like to end up but my infuriating lack of coding is just pushing it that far away:

Code: Select all

{if (vf == '720p' && source == 'BluRay' && vc == 'x264' && ac == 'AC3')  {n.sortName('$2, $1').colon(' - ').replace('?', '')} ({y}).{vf}.{source}.{vc}.{ac}-x0r}  else  Null }
I just want it to find the ones that meet the 3 items in the code a rename them only them files and leave the rest alone.

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 08 Jan 2019, 03:44
by rednoah
Here's some information of why your whole {...} expression fails just because {source} is undefined:
viewtopic.php?f=5&t=1895

An easy fix would be doing this, catching all errors and defaulting to null as return value:

Code: Select all

any{source}{null}
e.g.

Code: Select all

{vf == '720p' && any{source}{null} == 'BluRay' && vc == 'x264' && ac == 'AC3' ? 'Yes' : 'No'}
You can turn this around as well, to explicitly handle the error case:

Code: Select all

{any{vf == '720p' && source == 'BluRay' && vc == 'x264' && ac == 'AC3' ? 'Yes' : 'No'}{'Error'}}

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 08 Jan 2019, 15:06
by madmiddle
rednoah wrote: 08 Jan 2019, 03:44 Here's some information of why your whole {...} expression fails just because {source} is undefined:
viewtopic.php?f=5&t=1895

An easy fix would be doing this, catching all errors and defaulting to null as return value:

Code: Select all

any{source}{null}
e.g.

Code: Select all

{vf == '720p' && any{source}{null} == 'BluRay' && vc == 'x264' && ac == 'AC3' ? 'Yes' : 'No'}
You can turn this around as well, to explicitly handle the error case:

Code: Select all

{any{vf == '720p' && source == 'BluRay' && vc == 'x264' && ac == 'AC3' ? 'Yes' : 'No'}{'Error'}}
cheers fella for all your help but even after reading hundreds of posts, adjusting the code several times to try and get it to work I'm really struggling with the syntax of this:

Code: Select all

{if (vf == '720p' && any{source}{Null} == 'BluRay' && vc == 'x264' && ac == 'AC3')  {n.sortName('$2, $1').colon(' - ').replace('?', '')} {({y}).{vf}.{source}.{vc}.{ac}-x0r}  else  {n.sortName('$2, $1').colon(' - ').replace('?', '')} {({y}).{vf}.{source}.{vc}.{ac} }
it just doesn't like the part after the name for some reason. with my very limited knowledge i know it works on it's own but not in this case. because it's separate does it think it should be the false statement ?


I don't think anybody else has done it with me searching through the forum.

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 08 Jan 2019, 15:46
by rednoah
1.
Fixing & Rewriting your format like so makes it more clear what's going on:

Code: Select all

{n.sortName('$2, $1').colon(' - ').replace('?', '')} ({y})
.{vf}.{any{source}{'NoSource'}}.{vc}.{ac}
{if (vf == '720p' && any{source}{null} == 'BluRay' && vc == 'x264' && ac == 'AC3') '-x0r'}

2.
Here's some information on how it works:
viewtopic.php?f=5&t=1895

TL;DR The outermost {...} encapsulate Groovy code. Everything within the outermost {...} is Groovy code, which itself may use { and } for code block and closure, which has completely different semantic meaning from the output most {...} which simply encapsulate Groovy code.

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 08 Jan 2019, 16:14
by madmiddle
rednoah wrote: 08 Jan 2019, 15:46 1.
Fixing & Rewriting your format like so makes it more clear what's going on:

Code: Select all

{n.sortName('$2, $1').colon(' - ').replace('?', '')} ({y})
.{vf}.{any{source}{'NoSource'}}.{vc}.{ac}
{if (vf == '720p' && any{source}{null} == 'BluRay' && vc == 'x264' && ac == 'AC3') '-x0r'}

2.
Here's some information on how it works:
viewtopic.php?f=5&t=1895

TL;DR The outermost {...} encapsulate Groovy code. Everything within the outermost {...} is Groovy code, which itself may use { and } for code block and closure, which has completely different semantic meaning from the output most {...} which simply encapsulate Groovy code.
OH FFS is looks so simple when you see the answer. Thank you for all your help :D :D

If I need to clarify some small tweaks should i come back to this post or start a new one ?

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 08 Jan 2019, 16:19
by rednoah
Up to you. If it’s very related, reuse. If it’s very distinct, new thread.

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 14 Jan 2019, 23:50
by madmiddle
rednoah wrote: 08 Jan 2019, 16:19 Up to you. If it’s very related, reuse. If it’s very distinct, new thread.
Been tinkering ever since with looking at other peoples code and I am nearly there with the following:

Code: Select all

/Volumes/video/
{f =~ /Christmas/ ? 'Christmas' : f =~ /Kids.Movies/ ? 'Kids Movies' : f =~ /Music.Concerts/ ? 'Music Concerts' : f =~ /Stand.Up.Comedy/ ? 'Stand Up Comedy' : 'Movies' }/
{n.replaceFirst(/^(?i)(The|A|An)\s(.+)/, /$2, $1/).colon(' - ').replaceAll(/[?]/, "")} 
[{y}{any{' - ' +info.certifications.GB}{ null }}] 
[{vf} {any{"$source"}{null}} {vc} {ac} {af}] 
{" [$group]"}
now with the 'info,certifications.GB' if the UK certification is there, I would like the year and the rating to be displayed like this as part of the filename, [2009 - 12] and then when it is not present to only show the year ie this [2009] but I can't seem to get the not/null working as it displays [2009 - null] I can only assume it is showing the error for getting the cert and not even got to the second part. any ideas ?

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 15 Jan 2019, 03:04
by rednoah
This should do:

Code: Select all

{def c = info.certifications.GB; if (c) ' - ' + c}

:idea: any{}{} unfortunately doesn't work here because the certifications map doesn't throw an error but return null for non-existing keys, and any{}{} doesn't work for ' - ' + null because that returns ' - null' which any{}{} accepts as valid value (non-null / non-Empty-String).

Actually, this might work too, because String.concat() should throw an error when passing in a null argument:

Code: Select all

{' - '.concat(info.certifications.GB)}

Re: Combine 2 expressions and execute either one depending on file name ?

Posted: 15 Jan 2019, 10:20
by madmiddle
rednoah wrote: 15 Jan 2019, 03:04
Actually, this might work too, because String.concat() should throw an error when passing in a null argument:

Code: Select all

{' - '.concat(info.certifications.GB)}
This works perfectly thank you:

Code: Select all

/Volumes/video/
{f =~ /Christmas/ ? 'Christmas' : f =~ /Kids.Movies/ ? 'Kids Movies' : f =~ /Music.Concerts/ ? 'Music Concerts' : f =~ /Stand.Up.Comedy/ ? 'Stand Up Comedy' : 'Movies' }/
{n.replaceFirst(/^(?i)(The|A|An)\s(.+)/, /$2, $1/).colon(' - ').replaceAll(/[?]/, "")} 
[{y}{' - '.concat(info.certifications.GB)}] 
[{vf} {any{"$source"}{null}} {vc}  

{def ChannelString = any{(0.0+audio.'ChannelPositionsString2'*.replaceAll(/Object\sBased\s\/|0.(?=\d.\d)/, '')*.split(' / ')*.collect{ it.split('/')*.toBigDecimal().sum() }*.max().max()).toString()}{channels};
def codecSubVersion = any{audio.any{ a -> call{a.FormatProfile} =~ 'HRA' } ? '.HRA' : null}
{audio.any{ a -> call{a.FormatProfile} =~ 'X / MA / Core' } ? '.X' : null}
{audio.any{ a -> call{a.FormatProfile} =~ 'MA / Core' } ? '.MA' : null}
{audio.any{ a -> call{a.FormatProfile} =~ 'ES Matrix / Core' } ? '-ES' : null}{null};
def codecVersion = any{audio.Codec.join().match(/DTS-HD/)+codecSubVersion+'.'+audio.Codec.join().match(/TrueHD/)}
{audio.Codec.join().match(/DTS-HD/)+codecSubVersion}
{audio.Codec.join().match(/TrueHD/)}
{audio.Codec.join().match(/DTS/)+codecSubVersion.replaceAll(/null/)}{ac}} {any{ChannelString}{channels}}]{" [$group]"} 
{" ["+actors.take(3).join(', ')+"]"}{any{" ("+imdb.genres.take(3).join(', ')+")"}{" ["+genres.take(3).join(', ')+"]"}}