Page 3 of 3

Re: How about sharing our format expressions?

Posted: 28 Sep 2018, 20:13
by ChefGregS
I don't use MusicBrainz....sorry.

Greg

Re: How about sharing our format expressions?

Posted: 01 Oct 2018, 01:29
by DevXen
Hey, Thanks for your message, I apologize it took so long to reply, i've been busy with a new job with crazy hours, and had no idea i had a message... I believe this is my latest picard script. I don't really have time to go through and explain all that it does. but it's amazing. I made it for me and how I wanted it. so it'll separate by genre, band, album, disc. (disc name). it'll add extra info to the song as available. (demo, etc) separate soundtracks, various, etc. if an album has more than half of the songs but not a complete album it'll move them to the [unfinished albums] folder. if it has less than 5 songs, they go to the misc folder. Also i didn't realize at the time i had to backup my Variables when it backed up my script. and that PC crashed. so you'll have to go setup the variables it needs. which i'd assume it'll give you errors if they aren't there. I haven't had time to go in and figure those out. as i'm at the moment using a much much simpler script to get my google music songs organized. after i'm done with that i'll go back to this one to finish organizing my main collection. but I wouldn't count on it being anytime soon.


Newest Working version: Separates Incomplete Albums and Misc songs & reads Album/Bonus from album folder

Code: Select all

$set(title,$replace(%title%,...,…))
$set(album,$replace(%album%,...,…))
$set(artist,$replace(%artist%,...,…))
$set(albumartist,$replace(%albumartist%,...,…))
$if(%originaldate%,$set(date,%originaldate%))
$set(filename,%_filename%)
$set(foldername,%_dirname%)

$if($in(%title%,Live),$set(_misctype,Live))
$if($in(%title%,Demo),$set(_misctype,Demos))
$if($in(%title%,Acoustic),$set(_misctype,Acoustic))
$if($in(%title%,Unplugged),$set(_misctype,Acoustic))
$if($in(%title%,Remix),$set(_misctype,Remixes))

$if($in($lower(%_dirname%),album),$if($not(%discsubtitle%),$set(disctitle,Album)))
$if($in(%_dirname%,Bonus),$if($not(%discsubtitle%),$set(disctitle,Bonus Disc)))


$if($gte($matchedtracks(),$div(%totaltracks%,2)),$set(_miscorincomplete,Incomplete),$set(_miscorincomplete,Misc))
$if($gte($matchedtracks(),%totaltracks%),$unset(_miscorincomplete) $unset(_misctype))
$if($lte($sub(%totaltracks%,$matchedtracks()),1),$set(_numberofmissingtracks,$sub(%totaltracks%,$matchedtracks())$unset(_pluaralmissingtracks)))
$if($gt($sub(%totaltracks%,$matchedtracks()),1),$set(_numberofmissingtracks,$sub(%totaltracks%,$matchedtracks())$set(_pluaralmissingtracks,s)))


$if($in(%album%,Tribute),$set(_tribute,Tributes))
$if($in(%album%,tribute),$set(_tribute,Tributes))

$if($eq(%releasetype%,compilation),$set(releasetype,[Compilation Albums]))
$if($eq(%releasetype%,remix),$set(releasetype,[Remixes]) $set(tributetype,[Remixes]))



$if($eq(%releasetype%,soundtrack),$set(releasetype,[Soundtracks]))

$if($eq(%releasetype%,album),$set(releasetype,[Studio Albums]))
$if($eq(%releasetype%,live),$set(releasetype,[Live Albums]))
$if($eq(%releasetype%,single),$set(releasetype,[Singles]))
$if($eq(%releasetype%,ep),$set(releasetype,[EPs]))

$if(%_releasecomment%, $set(_releasecomment,\(%_releasecomment%\)),$noop())
$if($and($eq(%releasecountry%,JP),$not($in(%_releasecomment%,Japan))),$set(_releasecomment,%_releasecomment% \(Japan Import\)))
$if($and($eq(%releasecountry%,RU),$not($in(%_releasecomment%,Russia))),$set(_releasecomment,%_releasecomment% \(Russian Import\)))
$if($and($eq(%releasecountry%,XE),$not($in(%_releasecomment%,Europe))),$set(_releasecomment,%_releasecomment% \(European Import\)))
$if($and($eq(%releasecountry%,AU),$not($in(%_releasecomment%,Australia))),$set(_releasecomment,%_releasecomment% \(Australian Import\)))
$if($and($eq(%releasecountry%,DE),$not($in(%_releasecomment%,German))),$set(_releasecomment,%_releasecomment% \(German Import\)))
$if($and($eq(%releasecountry%,FI),$not($in(%_releasecomment%,Finland))),$set(_releasecomment,%_releasecomment% \(Finland Import\)))
$if($and($eq(%releasecountry%,FR),$not($in(%_releasecomment%,France))),$set(_releasecomment,%_releasecomment% \(France Import\)))



$if($in(%album%, Punk ),$set(tributetype,Punk))
$if($in(%album%, Rock ),$set(tributetype,Rock))
$if($in(%album%, Metal ),$set(tributetype,Metal))
$if($in(%album%, Bluegrass ),$set(tributetype,Bluegrass))
$if($in(%album%, Acoustic ),$set(tributetype,[Acoustic]))
$if($in(%album%,Gothic Acoustic),$set(tributetype,[Gothic Acoustic Series]))
$if($in(%album%,Pickin' On ),$set(tributetype,[Pickin' On Series]))
$if($in(%album%, Industrial ),$set(tributetype,Industrial))
$if($in(%album%, Techno ),$set(tributetype,Techno))
$if($in(%album%,Tribute),$set(_tribute,Tributes))
$if($in(%album%, Quartet ),$set(tributetype,[String Quartet Series]))
$if($in(%album%,Remix),$set(tributetype,[Remixes]))

$if($in(%album%,Symphonic),$set(_tribute,Tributes))
$if($in(%album%,Symphonic),$set(tributetype,[Symphonic]))


$if($in(%album%, Lullaby Renditions),$set(_tribute,Tributes))
$if($in(%album%, Lullaby Renditions),$set(tributetype,[Lullaby Renditions]))

$if($in(%album%, Piano ),$set(_tribute,Tributes))
$if($in(%album%, Piano ),$set(tributetype,[Piano Series]))

$if($not(%tributetype%),$set(tributetype,[Various Artists]))



$if($in(%releasetype%,[Soundtracks]),$set(_tribute,Soundtracks)$unset(tributetype))


$replace($replace($replace($replace($replace($replace($replace($replace($replace(

$if($eq(%compilation%,1),

$if(%_tribute%,[%_tribute%]/
$if(%tributetype%,%tributetype%)/
$if(%date%, [$left(%date%,4)]) - %album%
$if(%_releasecomment%, %_releasecomment%)
$if($and($ne(%totaldiscs%,1),$not($in(%totaldiscs%,1))),\(%totaldiscs% Disc Set\),$noop())
$if($gt(%totaldiscs%,1),/Disc $num(%discnumber%,2)
$if(%discsubtitle%, - \(%discsubtitle%\)))/
$num(%tracknumber%,2) - %artist% - %title%
$if(%discsubtitle%,\(%discsubtitle%\)))

$if($eq(%albumartist%,Various Artists),
$if($not(%_tribute%),Various Artists/%releasetype%/
$if(%date%, [$left(%date%,4)]) - %album%
$if(%_releasecomment%, %_releasecomment%)
$if($and($ne(%totaldiscs%,1),$not($in(%totaldiscs%,1))),\(%totaldiscs% Disc Set\),$noop())
$if($gt(%totaldiscs%,1),/Disc $num(%discnumber%,2)
$if(%discsubtitle%, - \(%discsubtitle%\)))/
$num(%tracknumber%,2) - %artist% - %title%
$if(%discsubtitle%,\(%discsubtitle%\))))

$if($not($eq(%albumartist%,Various Artists)),
$if($not(%_tribute%),Various Artists/%releasetype%/
$if(%date%, [$left(%date%,4)]) - %album%
$if(%_releasecomment%, %_releasecomment%)
$if($and($ne(%totaldiscs%,1),$not($in(%totaldiscs%,1))),\(%totaldiscs% Disc Set\),$noop())
$if($gt(%totaldiscs%,1),/Disc $num(%discnumber%,2)
$if(%discsubtitle%, - \(%discsubtitle%\)))/
$num(%tracknumber%,2) - %artist% - %title%
$if(%discsubtitle%,\(%discsubtitle%\)))))

,*,[x]),?,),:, -),",'),_, ),|, ),<,[),>,]), , )


$replace($replace($replace($replace($replace($replace($replace($replace($replace(

$if($not($eq(%compilation%,1)),
$if(%_tribute%,[%_tribute%]/
$if(%tributetype%,%tributetype%)/
$if(%date%, [$left(%date%,4)]) - %album%$if($ne(%originalyear%,$left(%date%,4)),
$if(%originalyear%, \(%originalyear% Reissue\)))
$if(%_releasecomment%, %_releasecomment%)
$if($and($ne(%totaldiscs%,1),$not($in(%totaldiscs%,1))),\(%totaldiscs% Discs\),$noop())
$if($gt(%totaldiscs%,1),/Disc $num(%discnumber%,2)
$if(%discsubtitle%, - \(%discsubtitle%\)))/
%artist% - $num(%tracknumber%,2) - %title%
$if(%discsubtitle%,\(%discsubtitle%\)))

$if($not(%_tribute%),
$if(%_miscorincomplete%,
$if($eq(%_miscorincomplete%,Misc),
$if2(%grouping%,Unknown)/$if2(%genre%,Unknown)/
$if2(%albumartistsort%,%artistsort%,%albumartist%,%artist%)/
$if(%_misctype%,[%_misctype%]/,[Misc]/)
%artist% -$if(%album%, %album% -) $num(%tracknumber%,2) - %title%)

$if($eq(%_miscorincomplete%,Incomplete),
$if2(%grouping%,Unknown)/$if2(%genre%,Unknown)/
$if2(%albumartistsort%,%artistsort%,%albumartist%,%artist%)/
$if(%_miscorincomplete%, [Incomplete Albums]/)
$if(%date%, [$left(%date%,4)]) - %album% $if(%_numberofmissingtracks%, \($num(%_numberofmissingtracks%,2) Track$if(%_pluaralmissingtracks%,%_pluaralmissingtracks%) Missing\))
$if($ne(%originalyear%,$left(%date%,4)),
$if(%originalyear%, \(%originalyear% Reissue\)))
$if(%_releasecomment%, %_releasecomment%)
$if($and($ne(%totaldiscs%,1),$not($in(%totaldiscs%,1))),\(%totaldiscs% Discs\),$noop())
$if($gt(%totaldiscs%,1),/Disc $num(%discnumber%,2)
$if(%discsubtitle%, - \(%discsubtitle%\)))/
%artist% - $num(%tracknumber%,2) - %title%
$if(%discsubtitle%,\(%discsubtitle%\)))))

$if($not(%_miscorincomplete%),
$if2(%grouping%,Unknown)/$if2(%genre%,Unknown)/
$if2(%albumartistsort%,%artistsort%,%albumartist%,%artist%)/
$if(%releasetype%, %releasetype%/)
$if(%date%, [$left(%date%,4)]) - %album%
$if($ne(%originalyear%,$left(%date%,4)),
$if(%originalyear%, \(%originalyear% Reissue\)))
$if(%_releasecomment%, %_releasecomment%)
$if($and($ne(%totaldiscs%,1),$not($in(%totaldiscs%,1))),\(%totaldiscs% Discs\),$noop())
$if($gt(%totaldiscs%,1),/Disc $num(%discnumber%,2) $if(%disctitle%, - \(%disctitle%\))
$if(%discsubtitle%, - \(%discsubtitle%\)))/
%artist% - $num(%tracknumber%,2) - %title%
$if(%discsubtitle%,\(%discsubtitle%\))))

,*,[x]),?,),:, -),",'),_, ),|, ),<,[),>,]), , )

Re: How about sharing our format expressions?

Posted: 19 Oct 2018, 14:34
by iAmKoinu
Hey there! Been using Filebot for a few months now, and thought I'd share the expressions I have for my collection! :D They're on the simpler side, but it gets the job done for me :)

All of mine are based off of different drives.

Movies:
F:/Movies/{n.lowerTrail().colon(' - ')} ({y})/{n.lowerTrail().colon(' - ')}.[{d.format('MMM-dd-yyyy')}]
Example:
F:/Movies/The Greatest Showman (2017)/The Greatest Showman.[Dec-08-2017].mkv


TV Series:
G:/Shows/n.lowerTrail().colon(' - ')} ({y})/Season {s.pad(2)}/{n.colon(' - ').lowerTrail()}.{y}.{s00e00}.{t.colon(' - ').lowerTrail()}.[{airdate.format('MMM-dd-yyyy')}]
Example:
G:/Shows/How I Met Your Mother (2005)/Season 01/How I Met Your Mother.2005.S01E01.Pilot.[Sep-19-2005].mkv


Anime (I keep my anime in the same directory as my series, because I have them in the same category on Plex.. just easier that way :D ):
G:/Shows/n.lowerTrail().colon(' - ')} ({y})/Season {s.pad(2)}/{n.colon(' - ').lowerTrail()}.{y}.{s00e00}.#{absolute.pad(4)}.{t.colon(' - ').lowerTrail()}.[{airdate.format('MMM-dd-yyyy')}]
Example:
G:/Shows/My Hero Academia (2016)/Season 01/My Hero Academia.2016.S01E01.#0001.Izuku Midoriya Origin.{Apr-03-2016].mkv


As you can see, I like having the series name in the filename itself because I'm weird haha.

Also, the only real difference between TV Series and Anime is that the Anime expression has an added "absolute" numbering added to the filename. I like knowing the episode number, and the S00E00 is for plex :)
I also added a pad of 4 to the absolute numbering, because One Piece is getting up there almost to 1000 episodes, so I just went ahead and made all of the anime absolute numbering with a pad of 4 :)

Anyway, hope this helped some of y'all! :)

Re: How about sharing our format expressions?

Posted: 27 Apr 2019, 17:02
by snaporaz
I have a simple renaming scheme to organize movies in folders. It distinguishes english names and "foreign" latin and non-latin names:

Code: Select all

{y}/{primaryTitle}{if (n != primaryTitle) {primaryTitle.isLatin() ? " (${n})" : " (${primaryTitle.ascii()}) (${n})"}}/{fn}
Like this:

1993/Short Cuts/Short Cuts.1993.720p.BluRay.AVC-mfcorrea.mkv

1997/Abre los ojos (Open Your Eyes)/Open.Your.Eyes.1997.BluRay.720p.x264.AC3-CMCT.mkv

2018/万引き家族 (wan yinki jia zu) (Shoplifters)/shoplifters.2018.limited.720p.bluray.x264-cadaver.mkv



The only trouble is the non-standard transliteration from non-latin names...
but I can't find an automatic way of applying a correct identifier in String.transliterate(identifier) based on the correct language.

Re: How about sharing our format expressions?

Posted: 06 Jun 2019, 07:48
by devster
Just an update on formats I'm using, you can now find them here: https://github.com/devster31/filebot-scripts
It includes movie, series, and anime formats as being currently used, however it also has a very small script which can generate them from mustache templates and partials written in javascript, a qBittorrent and transmission post-processing script (in bash and WIP in python), and a few other junk scripts (mostly useless).
Enjoy.

Re: How about sharing our format expressions?

Posted: 26 Aug 2019, 23:03
by 9000aalborg
Hi guys

Major noob here :-/

I am trying to use nothinghere's script.
And I am too new to the forums to write nothinghere a personal message
But I would use the script, BUT without the period between the words in the name ( for example "in.the.name.of the.rose). I would rather have "In the name of the rose"

Can anyone help me to change that in the movie and tv-episode scripts ?

Thanks.
\Lars (major noob from Denmark)

nothinghere wrote:
13 Jul 2014, 18:57
The ones I am using. Major thanks to Ithiel and Rednoah for some of the parts.

Movies:

Code: Select all

{norm={it.upperInitial().lowerTrail().replaceTrailingBrackets().replaceAll(/\u0022/, '\'').replaceAll(/[:|]/, '.').replaceAll(/\?/, '!').replaceAll(/[*\s\.,]+/, '.').replaceAll(/\b[IiVvXx]+\b/, { it.upper() }).replaceAll(/[0-9](th|nd|rd)/, { it.lower() })};isLatin = {java.text.Normalizer.normalize(it, java.text.Normalizer.Form.NFD).replaceAll(/\p{InCombiningDiacriticalMarks}+/, '') ==~ /^\p{InBasicLatin}+$/}; isLatin(info.OriginalName) ? norm(info.OriginalName) : norm(primaryTitle) }.({y}){if(isLatin(info.OriginalName) && info.OriginalName != primaryTitle && !(info.SpokenLanguages[0] ==~ /(sv|da|no)/)) '.'+ norm(primaryTitle) }{'.'+vf}{'.'+source}{fn.contains('3D') || fn.contains('3-D') ? '.3D':''}{'.'+fn.replace(/(?i)\.DC\./, '.directors.cut.').replaceAll(/director\'?s|theatrical|ultimate/,'$0.Cut').matchAll(/UNCENSORED|UNRATED|REMASTERED|EXTENDED|UNCUT|DIRECTOR\'?S.CUT|THEATRICAL.CUT|ULTIMATE.CUT|FINAL.CUT|SPECIAL.EDITION/)*.upperInitial()*.lowerTrail().sort().join('.')}{'.'+fn.matchAll(/PROPER|REPACK/)*.upper().sort().join('.')}{'.'+vc.replace('Microsoft', 'VC-1')}{'.'+ac.replace('MPEG Audio', 'MP3')}{audio.FormatProfile =~ /MA Core/ ? '-HD.MA' : ''}{audio.FormatProfile =~ /ES/ ? '-ES' : ''}{audio.FormatProfile =~ /Pro/ ? '-Pro' : ''}{'.'+af.replace('8 6ch', '7.1').replace('7 6ch', '6.1').replace('6ch', '5.1').replace('3ch', '2.1').replace('2ch','2.0').replace('1ch','1.0')}{def g = c{group}; def m = c{fn.match(/(?:(?<=[-])[a-z0-9]+$)|(?:^[a-z0-9]+(?=[-]))/)}; if(g==null && m!=null) return '-'+m.replace(/^tpz$/, 'TOPAZ'); if(g!=null && m!=null && m.lower()!=g.lower()) return '-'+m.replace(/^tpz$/, 'TOPAZ'); if(g!=null) return '-'+g;}
I am using the original title if it the alphabet used is latin based. If the original title is not the same as the english title, and the first spoken language is not Swedish, Norwegian or Danish I will add the English title as part of the filename. This way I can keep the original titles which I prefer, but still have a chance to find them/connect them to the English titles most commonly used when talking to people. The Nordic stuff is because I live there so I know which movies they are.
If you want to use the format but don't want the special hack for Nordic stuff remove the text: "&& !(info.SpokenLanguages[0] ==~ /(sv|da|no)/)"
The audio/movie codecs are hacked a bit to be named by their real/common names instead of the ones defined by mediainfo. I.e. DTS-HD MA, MP3, VC-1 instead of DTS MA Core, MPEG Audio and Microsoft respectively.

Examples:
Kôkaku.Kidôtai.2.0.(2008).Ghost.In.The.Shell.2.0.720p.REPACK.x264.DTS.5.1-timeshift.mkv // Latin characters but added english name
Jagten.(2012).1080p.BluRay.x264.DTS-HD.MA-GRYM.mkv // Original name only, primary language is Danish
My.Sassy.Girl.(2001).720p.BluRay.x264.AC3.5.1-EbP.mkv // Actual name is 엽기적인 그녀, or transliterated to Yeopgijeogin Geunyeo
I would have loved to figure out how to keep the transliterated names, but using {transliterate(info.OriginalTitle)}did not work perfectly, which meant a bunch of titles missed when doing searched.
For my sassy girl the transliteration was something like Yeobgi-jeogin Geunyeo or the like, which is really close, but far away to miss some lookups.

NOTE: I do not care for multipart files so I do not support them. I rip my movies as single files without any splits.



Series is a bit simpler as I only care about the name we get from TheTVDB (I have long since abandoned any hope that they'll change their mind and structure series as they were intended instead of simply how they where broadcasted):

Code: Select all

{n}/{episode.special ? 'Specials' : 'Season '+s}/{norm={it.upperInitial().lowerTrail().replaceTrailingBrackets().replaceAll(/\u0022/, '\'').replaceAll(/[:|]/, '.').replaceAll(/\?/, '!').replaceAll(/[*\s\.]+/, '.').replaceAll(/\b[IiVvXx]+\b/, { it.upper() }).replaceAll(/[0-9](th|nd|rd)/, { it.lower() })};norm(n) }.{episode.special ? 'S00E'+special.pad(2) : s00e00}.{norm(t)}{'.'+vf}{'.'+source}{'.'+fn.matchAll(/PROPER|REPACK/)*.upper().sort().join('.')}{'.'+vc.replace('Microsoft', 'VC-1')}{'.'+ac.replace('MPEG Audio', 'MP3')}{audio.FormatProfile =~ /MA Core/ ? '-HD.MA' : ''}{audio.FormatProfile =~ /ES/ ? '-ES' : ''}{audio.FormatProfile =~ /Pro/ ? '-Pro' : ''}{'.'+af.replace('8 6ch', '7.1').replace('7 6ch', '6.1').replace('6ch', '5.1').replace('3ch', '2.1').replace('2ch','2.0').replace('1ch','1.0')}{def g = c{group}; def m = c{fn.match(/(?:(?<=[-])[a-z0-9]+$)|(?:^[a-z0-9]+(?=[-]))/)}; if(g==null && m!=null) return '-'+m.replace(/^tpz$/, 'TOPAZ'); if(g!=null && m!=null && m.lower()!=g.lower()) return '-'+m.replace(/^tpz$/, 'TOPAZ'); if(g!=null) return '-'+g;}
NOTE: I do not pad the season numbering (i.e. I use Season 1, Season 2 instead of Season 01, Season 02).
Specials end up in a /Specials folder instead. Same thing for video/audio as movies have.

Examples:
Coupling\Season 1\Coupling.S01E01.Flushed.360p.DVDRip.x264.AAC.mkv
Doctor Horrible's Sing-Along Blog\Season 1\Doctor.Horrible's.Sing-Along.Blog.S01E01.Act.I.1080p.BluRay.x264.DTS-DIMENSION.mkv


If anyone wants to copy my thing entirely the script I use to sort everything is:

Code: Select all

filebot -script fn:amc "x:/downloads" --log-file d:\amc-run.log --output "//nas/" --action move --conflict skip -non-strict --def clean=y --def "movieFormat=Movies/{norm={it.upperInitial().lowerTrail().replaceTrailingBrackets().replaceAll(/\u0022/, '\'').replaceAll(/[:|]/, '.').replaceAll(/\?/, '!').replaceAll(/[*\s\.,]+/, '.').replaceAll(/\b[IiVvXx]+\b/, { it.upper() }).replaceAll(/[0-9](th|nd|rd)/, { it.lower() })};isLatin = {java.text.Normalizer.normalize(it, java.text.Normalizer.Form.NFD).replaceAll(/\p{InCombiningDiacriticalMarks}+/, '') ==~ /^\p{InBasicLatin}+$/}; isLatin(info.OriginalName) ? norm(info.OriginalName) : norm(primaryTitle) }.({y}){if(isLatin(info.OriginalName) && info.OriginalName != primaryTitle && !(info.SpokenLanguages[0] ==~ /(sv|da|no)/)) '.'+ norm(primaryTitle) }{'.'+vf}{'.'+source}{fn.contains('3D') || fn.contains('3-D') ? '.3D':''}{'.'+fn.replace(/(?i)\.DC\./, '.directors.cut.').replaceAll(/director\'?s|theatrical|ultimate/,'$0.Cut').matchAll(/UNCENSORED|UNRATED|REMASTERED|EXTENDED|UNCUT|DIRECTOR\'?S.CUT|THEATRICAL.CUT|ULTIMATE.CUT|FINAL.CUT|SPECIAL.EDITION/)*.upperInitial()*.lowerTrail().sort().join('.')}{'.'+fn.matchAll(/PROPER|REPACK/)*.upper().sort().join('.')}{'.'+vc.replace('Microsoft', 'VC-1')}{'.'+ac.replace('MPEG Audio', 'MP3')}{audio.FormatProfile =~ /MA Core/ ? '-HD.MA' : ''}{audio.FormatProfile =~ /ES/ ? '-ES' : ''}{audio.FormatProfile =~ /Pro/ ? '-Pro' : ''}{'.'+af.replace('8 6ch', '7.1').replace('7 6ch', '6.1').replace('6ch', '5.1').replace('3ch', '2.1').replace('2ch','2.0').replace('1ch','1.0')}{def g = c{group}; def m = c{fn.match(/(?:(?<=[-])[a-z0-9]+$)|(?:^[a-z0-9]+(?=[-]))/)}; if(g==null && m!=null) return '-'+m.replace(/^tpz$/, 'TOPAZ'); if(g!=null && m!=null && m.lower()!=g.lower()) return '-'+m.replace(/^tpz$/, 'TOPAZ'); if(g!=null) return '-'+g;}" --def "seriesFormat=TV Shows/{n}/{episode.special ? 'Specials' : 'Season '+s}/{norm={it.upperInitial().lowerTrail().replaceTrailingBrackets().replaceAll(/\u0022/, '\'').replaceAll(/[:|]/, '.').replaceAll(/\?/, '!').replaceAll(/[*\s\.]+/, '.').replaceAll(/\b[IiVvXx]+\b/, { it.upper() }).replaceAll(/[0-9](th|nd|rd)/, { it.lower() })};norm(n) }.{episode.special ? 'S00E'+special.pad(2) : s00e00}.{norm(t)}{'.'+vf}{'.'+source}{'.'+fn.matchAll(/PROPER|REPACK/)*.upper().sort().join('.')}{'.'+vc.replace('Microsoft', 'VC-1')}{'.'+ac.replace('MPEG Audio', 'MP3')}{audio.FormatProfile =~ /MA Core/ ? '-HD.MA' : ''}{audio.FormatProfile =~ /ES/ ? '-ES' : ''}{audio.FormatProfile =~ /Pro/ ? '-Pro' : ''}{'.'+af.replace('8 6ch', '7.1').replace('7 6ch', '6.1').replace('6ch', '5.1').replace('3ch', '2.1').replace('2ch','2.0').replace('1ch','1.0')}{def g = c{group}; def m = c{fn.match(/(?:(?<=[-])[a-z0-9]+$)|(?:^[a-z0-9]+(?=[-]))/)}; if(g==null && m!=null) return '-'+m.replace(/^tpz$/, 'TOPAZ'); if(g!=null && m!=null && m.lower()!=g.lower()) return '-'+m.replace(/^tpz$/, 'TOPAZ'); if(g!=null) return '-'+g;}"
NOTE: Remember to update the paths to your series/movies and downloads.
Paste everything into a file called amc.cmd or something and double click it to run it.

Re: How about sharing our format expressions?

Posted: 31 Aug 2019, 03:35
by Liquidbings
TV

Code: Select all

I:/TV/{n}{' '+any{"[$certification]"}{"["+$imdb.certification+"]" }.replaceAll('N A','').replaceAll(/^ \d+$/, 'PG-$0')}{" [$rating" + "★]"}/{regular ? 'Season ' + s.pad(1) : 'Specials'}/
{
	def space = call{' '};
	
	def dir_root = 'I/TV/'+
	call{hd.matches(/(?i)SD/) ? '480p-720p/' : ' '}+
	call{hd.matches(/(?i)HD/) ? '720p-1080p/' : ' '}+
	call{hd.matches(/(?i)UHD/) ? '4k/' : ' '};
	// Main Title e.g.
	// 1408 (2007) (Director's Cut) 1080p HD Blu-ray non-HDR x264 DTS5.1ch_SiNNERS
	// 300 (2007) 720p HD BRRip non-HDR x265 DTS 5.1ch_ESiR
	// Deadpool (2016) 2160p UHD WEB-DL non-HDR AVC DTS-HD MA 7.1ch_DDR
	// Deadpool 2 (2018) (Super Duper Cut) 2160p UHD Blu-ray REMUX HDR10bit ATEME TrueHD Atmos 13Obj 7.1ch_EPSiLON
	def main_title = call{n}+
	space + call{s00e00}+
	space + '-'+
	space + call{t}+
	space + call{fn.matches(/(?i).+\b25th.+?anniv.+/) ? '(25th Anniv. Edition)' : ' '}+
	space + call{fn.matches(/(?i).+\b\(limited\b.*?\).+/) ? '(Limited Edition)' : ' '}+
	space + call{fn.matches(/(?i).+\b\(uncut\b.*?\).+/) ? '(Uncut)' : ' '}+
	space + call{fn.matches(/(?i).+\bcollector.+?s.+?edition\b.+/) ? '(Collector\'s Edition)' : ' '}+
	space + call{fn.matches(/(?i).+\bdirect.+?cut\b.+/) ? '(Director\'s Cut)' : ' '}+
	space + call{fn.matches(/(?i).+\bextended.+?\b.+/) ? '(Extended)' : ' '}+
	space + call{fn.matches(/(?i).+\bextended.+?edit\b.+/) ? '(Extended Edition)' : ' '}+
	space + call{fn.matches(/(?i).+\bimax\b.+/) ? '(IMAX Edition)' : ' '}+
	space + call{fn.matches(/(?i).+\blimited\b.+/) ? '(Limited)' : ' '}+
	space + call{fn.matches(/(?i).+\bremastered\b.+/) ? '(Remastered)' : ' '}+
	space + call{fn.matches(/(?i).+\bsuper.+duper.+cut\b.+/) ? '(Super Duper Cut)' : ' '}+
	space + call{fn.matches(/(?i).+\btheatrical\b.+/) ? '(Theatrical)' : ' '}+
	space + call{fn.matches(/(?i).+\bunrated\b.+/) ? '(Unrated)' : ' '}+
	space + call{any{fn.match(/\([^\()+?[^\d]+?\)\s*/)} {' '}{' '}}+
	space + '['+ call{self.vf ? self.vf : self.hpi}+
	space + call{hd}+
	space + call{source.matches(/(?i)blu.*ray/) ? 'BluRay' : {source} ?: 'WEB-DL'}+
	space + call{fn.matches(/(?i).+\bremux\b.+/) ? 'REMUX' : ' '}+
	space + call{fn.matches(/(?i).+\bwebrip\b.+/) ? 'WEBRip' : ' '}+
	space + call{fn.matches(/(?i).+\bhevc.+?\b.+/) ? '(x265)' : ' '}+
	space + call{fn.matches(/(?i).+\bx265\b.+/) ? '(x265)' : ' '}+
	space + call{fn.matches(/(?i).+\b264\b.+/) ? '(x264)' : ' '}+
	// Only calls {hdr} if it's not SD else non-HDR
	space + call{if (hd =~ 'HD') {any{hdr + bitdepth + 'bit'}{'non-HDR'}}}+
	space + call{vc}+
	space +
	// Call audio
	// Thread here where I got the base code: https://www.filebot.net/forums/viewtopic.php?f=5&t=5285
	call {
		def mCFP =
		[
		'AAC LC SBR PS' : 'AAC',
		'AAC LC SBR' : 'AAC',
		'AAC LC' : 'AAC',
		'AC 3 Dep' : 'E-AC3',
		'AC 3' : 'AC3',
		'DTS 96 24' : 'DTS 96-24',
		'DTS ES XBR' : 'DTS-HD HRA',
		'DTS ES XLL' : 'DTS-HD MA',
		'DTS ES XXCH XBR' : 'DTS-HD HRA',
		'DTS ES XXCH XLL' : 'DTS-HD MA',
		'DTS ES XXCH' : 'DTS-ES',
		'DTS ES' : 'DTS-ES',
		'DTS XBR' : 'DTS-HD HRA',
		'DTS XLL X' : 'DTS X',
		'DTS XLL' : 'DTS-HD MA',
		'DTS' : 'DTS',
		'E AC 3 JOC' : 'EAC3 Atmos',
		'E AC 3' : 'EAC3',
		'MLP FBA 16 ch' : 'TrueHD Atmos',
		'MLP FBA' : 'TrueHD',
		'MP3' : 'MP3',
		'MPEG Audio' : 'MP2',
		'PCM' : 'PCM'
		];
		def audioClean = { it.replaceAll(/[\p{Pd}\p{Space}]/, ' ').replaceAll(/\p{Space}{2,}/, ' ').slash(' ') };
		def channelClean = { it.replaceAll(/Debug.+|Object\sBased\s?\/?|(\d+)?\sobjects\s\/\s|0.(?=\d.\d)|20/).replaceAll(/6/,'5.1').replaceAll(/8/,'7.1') };
		def audioCollection = audio.collect
		{ au ->
			def channels = any{ channelClean(au['ChannelPositionsString2'])}{ channelClean(au['ChannelsOriginal'])}{ channelClean(au['Channels']) };
			def dynChannel = {au['NumberOfDynamicObjects'] + 'Obj'};
			def ch = channels.tokenize('\\/').take(3)*.toDouble().inject(0, { a, b -> a + b }).findAll { it > 0 }.max().toString() + 'ch';
			def codec = audioClean(any{ au['CodecID/Hint'] }{ au['Format'] });
			def format_profile = { ( au['Format_AdditionalFeatures'] != null) ? audioClean(au['Format_AdditionalFeatures']) : '' };
			def combined = allOf{codec}{format_profile}.join(' ');
			def stream = allOf { mCFP.get(combined, 'UNKNOWN_FORMAT--'+combined+'--') } { dynChannel } { ch };
		};
		return audioCollection[0].join( ' ' )
		} +
		'_'+
		// Group
		call{any{"$group"}{fn.match(/(?<=[_-])[^\s_-]+?$/)}{'NA'}.replaceAll(/[-_\[\]]\s*|\.\w{3}$/, '')};
		// Language
		def lang = call{any{'.'+lang}{lang}}+{fn.matches(/(?i).+sdh.+/) ? '_SDH' : ''}{any{fn.match(/(?i)\(foreignpartsonly\)/)}{''}};
		// Extension
		def ext = call{'.'+ext};
		// Call all the bindings to create the result
		(call(main_title).replace(':', ';') + call(lang)).replaceAll(/null/,'')
	}[{runtime} Min]
Movies

Code: Select all

I:/Movies/{n}{' '+any{"[$certification]"}{"["+$imdb.certification+"]" }.replaceAll('N A','').replaceAll(/^ \d+$/, 'PG-$0')}{" [$rating" + "★]"}/
{
	def space = call{' '};
	
	def dir_root = 'I/Movies/'+
	call{hd.matches(/(?i)SD/) ? '480p-720p/' : ' '}+
	call{hd.matches(/(?i)HD/) ? '720p-1080p/' : ' '}+
	call{hd.matches(/(?i)UHD/) ? '4k/' : ' '};
	// Main Title e.g.
	// 1408 (2007) (Director's Cut) 1080p HD Blu-ray non-HDR x264 DTS5.1ch_SiNNERS
	// 300 (2007) 720p HD BRRip non-HDR x265 DTS 5.1ch_ESiR
	// Deadpool (2016) 2160p UHD WEB-DL non-HDR AVC DTS-HD MA 7.1ch_DDR
	// Deadpool 2 (2018) (Super Duper Cut) 2160p UHD Blu-ray REMUX HDR10bit ATEME TrueHD Atmos 13Obj 7.1ch_EPSiLON
	def main_title = call{n}+
	space + call{fn.matches(/(?i).+\b25th.+?anniv.+/) ? '(25th Anniv. Edition)' : ' '}+
	space + call{fn.matches(/(?i).+\b\(limited\b.*?\).+/) ? '(Limited Edition)' : ' '}+
	space + call{fn.matches(/(?i).+\b\(uncut\b.*?\).+/) ? '(Uncut)' : ' '}+
	space + call{fn.matches(/(?i).+\bcollector.+?s.+?edition\b.+/) ? '(Collector\'s Edition)' : ' '}+
	space + call{fn.matches(/(?i).+\bdirect.+?cut\b.+/) ? '(Director\'s Cut)' : ' '}+
	space + call{fn.matches(/(?i).+\bextended.+?\b.+/) ? '(Extended)' : ' '}+
	space + call{fn.matches(/(?i).+\bextended.+?edit\b.+/) ? '(Extended Edition)' : ' '}+
	space + call{fn.matches(/(?i).+\bimax\b.+/) ? '(IMAX Edition)' : ' '}+
	space + call{fn.matches(/(?i).+\blimited\b.+/) ? '(Limited)' : ' '}+
	space + call{fn.matches(/(?i).+\bremastered\b.+/) ? '(Remastered)' : ' '}+
	space + call{fn.matches(/(?i).+\bsuper.+duper.+cut\b.+/) ? '(Super Duper Cut)' : ' '}+
	space + call{fn.matches(/(?i).+\btheatrical\b.+/) ? '(Theatrical)' : ' '}+
	space + call{fn.matches(/(?i).+\bunrated\b.+/) ? '(Unrated)' : ' '}+
	space + call{any{fn.match(/\([^\()+?[^\d]+?\)\s*/)} {' '}{' '}}+
	space + '['+ call{self.vf ? self.vf : self.hpi}+
	space + call{hd}+
	space + call{source.matches(/(?i)blu.*ray/) ? 'BluRay' : {source} ?: 'WEB-DL'}+
	space + call{fn.matches(/(?i).+\bremux\b.+/) ? 'REMUX' : ' '}+
	space + call{fn.matches(/(?i).+\bwebrip\b.+/) ? 'WEBRip' : ' '}+
	space + call{fn.matches(/(?i).+\bhevc.+?\b.+/) ? '(x265)' : ' '}+
	space + call{fn.matches(/(?i).+\bx265\b.+/) ? '(x265)' : ' '}+
	space + call{fn.matches(/(?i).+\b264\b.+/) ? '(x264)' : ' '}+
	// Only calls {hdr} if it's not SD else non-HDR
	space + call{if (hd =~ 'HD') {any{hdr + bitdepth + 'bit'}{'non-HDR'}}}+
	space + call{vc}+
	space +
	// Call audio
	// Thread here where I got the base code: https://www.filebot.net/forums/viewtopic.php?f=5&t=5285
	call {
		def mCFP =
		[
		'AAC LC SBR PS' : 'AAC',
		'AAC LC SBR' : 'AAC',
		'AAC LC' : 'AAC',
		'AC 3 Dep' : 'E-AC3',
		'AC 3' : 'AC3',
		'DTS 96 24' : 'DTS 96-24',
		'DTS ES XBR' : 'DTS-HD HRA',
		'DTS ES XLL' : 'DTS-HD MA',
		'DTS ES XXCH XBR' : 'DTS-HD HRA',
		'DTS ES XXCH XLL' : 'DTS-HD MA',
		'DTS ES XXCH' : 'DTS-ES',
		'DTS ES' : 'DTS-ES',
		'DTS XBR' : 'DTS-HD HRA',
		'DTS XLL X' : 'DTS X',
		'DTS XLL' : 'DTS-HD MA',
		'DTS' : 'DTS',
		'E AC 3 JOC' : 'EAC3 Atmos',
		'E AC 3' : 'EAC3',
		'MLP FBA 16 ch' : 'TrueHD Atmos',
		'MLP FBA' : 'TrueHD',
		'MP3' : 'MP3',
		'MPEG Audio' : 'MP2',
		'PCM' : 'PCM'
		];
		def audioClean = { it.replaceAll(/[\p{Pd}\p{Space}]/, ' ').replaceAll(/\p{Space}{2,}/, ' ').slash(' ') };
		def channelClean = { it.replaceAll(/Debug.+|Object\sBased\s?\/?|(\d+)?\sobjects\s\/\s|0.(?=\d.\d)|20/).replaceAll(/6/,'5.1').replaceAll(/8/,'7.1') };
		def audioCollection = audio.collect
		{ au ->
			def channels = any{ channelClean(au['ChannelPositionsString2'])}{ channelClean(au['ChannelsOriginal'])}{ channelClean(au['Channels']) };
			def dynChannel = {au['NumberOfDynamicObjects'] + 'Obj'};
			def ch = channels.tokenize('\\/').take(3)*.toDouble().inject(0, { a, b -> a + b }).findAll { it > 0 }.max().toString() + 'ch';
			def codec = audioClean(any{ au['CodecID/Hint'] }{ au['Format'] });
			def format_profile = { ( au['Format_AdditionalFeatures'] != null) ? audioClean(au['Format_AdditionalFeatures']) : '' };
			def combined = allOf{codec}{format_profile}.join(' ');
			def stream = allOf { mCFP.get(combined, 'UNKNOWN_FORMAT--'+combined+'--') } { dynChannel } { ch };
		};
		return audioCollection[0].join( ' ' )
		} +
		'_'+
		space+
		// Group
		call{any{"$group"}{fn.match(/(?<=[_-])[^\s_-]+?$/)}{'NA'}.replaceAll(/[-_\[\]]\s*|\.\w{3}$/, '')};
		// Language
		def lang = call{any{'.'+lang}{lang}}+{fn.matches(/(?i).+sdh.+/) ? '_SDH' : ''}{any{fn.match(/(?i)\(foreignpartsonly\)/)}{''}};
		// Extension
		def ext = call{'.'+ext};
		// Call all the bindings to create the result
		(call(main_title).replace(':', ';') + call(lang)).replaceAll(/null/,'')
	}[{runtime} Min]
Hello everyone hope all are well! Very new to all this but I think I have read every page I could and deciphered everything as best I can with my current knowledge.
I took Stephen147's code and modified what I could to output what I was looking for. I had lost everything I did over the last month or so this evening somehow, but was able to rebuild roughly what I had. I believe anway.

Please take a gander and let me know if anyone see's anything that could be cleaned up or fixed as I honestly dont know what a good portion of this stuff does aside from giving me the results I'm looking for lol

I pretty much wanted something that would give me the standard title and season folders with a special for extras/specials
Then tell me the video formats, where it is sourced from, weather it is a remux, what it is encoded to, if it has HDR, then the sound format and channels etc, followed by how long the episode is.

So basically:
Before:
D:/MakeMkv/The.Handmaids.Tale.S03E07.Under.His.Eye.1080p.HULU.WEBRip.AAC2.0.H264/The.Handmaids.Tale.S03E07.Under.His.Eye.1080p.HULU.WEB-DL.AAC2.0.H.264-NTb
After
I:/TV/The Handmaid's Tale [TV-MA] [8.9★]/Season 3/The Handmaid's Tale S03E07 - Under His Eye [1080p HD WEB-DL non-HDR AVC AAC 2.0ch_NTb[55 Min]

Before:
D:/MakeMkv/Rick and Morty S01 Season 1 1080p TrueHD [MAX Quality]/S01E02.Lawnmower.Dog.mkv
After:
I:/TV/Rick and Morty [TV-MA] [9.3★]/Season 1/Rick and Morty S01E02 - Lawnmower Dog [1080p HD non-HDR Microsoft TrueHD 5.1ch_NA[25 Min]

Before:
D:/MakeMkv/Stranger.Things.S01.2160p.BluRay.REMUX.HEVC.DD5.1-FGT/Stranger.Things.S01E01.Chapter.One.The.Vanishing.Of.Will.Byers.2160p.BluRay.REMUX.HEVC.DD5.1-FGT
After:
I:/TV/Stranger Things [TV-14] [9.2★]/Season 1/Stranger Things S01E01 - Chapter One; The Vanishing of Will Byers [2160p UHD BluRay REMUX (x265) non-HDR ATEME AC3 5.1ch_FGT[50 Min]

Re: How about sharing our format expressions?

Posted: 08 Sep 2019, 17:25
by Liquidbings
Things I can't seem to get quite right is I want it to

1. replace x265 or hevc with (X265)
2. replace x264 with (X264)

with what I have there it works sometimes and other times I have x265 and (X265) also on the same line

Re: How about sharing our format expressions?

Posted: 08 Sep 2019, 18:31
by kim
you only add tag if in filename

Code: Select all

	space + call{fn.matches(/(?i).+\bhevc.+?\b.+/) ? '(x265)' : ' '}+
	space + call{fn.matches(/(?i).+\bx265\b.+/) ? '(x265)' : ' '}+
	space + call{fn.matches(/(?i).+\b264\b.+/) ? '(x264)' : ' '}+

try something like this:

Code: Select all

{'(' + any{vc.match(/x26[45]/)}{vc} + ')'}