How about sharing our format expressions?

All about user-defined episode / movie format expressions
AbedlaPaille
Posts: 101
Joined: 12 Apr 2020, 04:02

Re: How about sharing our format expressions?

Post by AbedlaPaille »

Abed Movies

Code: Select all

E:/{fn =~ /3D/ ? 'Films 3D' : 'Films'}/{norm = {it.upperInitial().replaceTrailingBrackets().replaceAll(/[`´‘’ʻ""“”]/, "'").replaceAll(/[:|]/, " - ").replaceAll(/[?]/, "!").replaceAll(/[*\s]+/, " ").replaceAll(/\b[IiVvXx]+\b/, { it.upper() }).replaceAll(/\b[0-9](?i:th|nd|rd)\b/, { it.lower() })}; {info.OriginalLanguage != /en/ ? norm(n) : norm(primaryTitle)}}{info.OriginalName != n && ! (info.OriginalLanguage ==~ /(en|fr)/) ? ' ('+norm(primaryTitle)+')' :""}{fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':""} ({y}){' ['+vf.match(/720[pP]|1080[pP]/)+']'}{video.CodecID =~ /hev1|hevc|HEVC/ ? ' [HEVC]' : ''}/{info.OriginalLanguage != /en/ ? norm(n) : norm(primaryTitle)}{info.OriginalName != n && ! (info.OriginalLanguage ==~ /(en|fr)/) ? ' ('+norm(primaryTitle)+')' :""}{fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':""} ({y}){' [' + fn.matchAll(/UNCENSORED|UNRATED|REMASTERED|EXTENDED|UNCUT|DIRECTOR\'?S[ ._-]CUT|THEATRICAL[ ._-]CUT|ULTIMATE[ ._-]CUT|FINAL[ ._-]CUT|SPECIAL[ ._-]EDITION/)*.upper().sort().join(' ').replaceAll(/[.]/, " ") + ']'}{' ['+vs.match(/BluRay/)+']'}{' ['+vf.match(/720[pP]|1080[pP]/)+']'}{video.CodecID =~ /hev1|hevc|HEVC/ ? ' [HEVC]' : ''}{if (bitdepth == 10) ' [10bit]'}{if (af == (/6ch/)) ' [5.1]'}{" CD$pi"}{'.'+lang}{if (dc > 1) " ($di)"}
  • All movies are in preferred language French except English ones -> English
  • Adds original title if it's neither an english nor french movie
  • Retains quality if 720p/1080p / Retains source if BluRay / Retains bitdepth if 10bit / Retains codec if HEVC / Retains af if 6ch (prints 5.1)
  • Deals with multiple subtitles in same language by adding (1), (2), (3)
  • Retains movie tags like remastered, extended, 3D
  • Special folder for 3D movies
  • Invalid characters replacement
Examples
E:/Films/E.T. The Extra-Terrestrial (1982) [1080p]/E.T. The Extra-Terrestrial (1982) [BluRay] [1080p] [5.1]
E:/Films/Entre Les Murs (2008)/Entre Les Murs (2008)
E:/Films/Four Weddings And A Funeral (1994) [1080p] [HEVC]/Four Weddings And A Funeral (1994) [REMASTERED] [BluRay] [1080p] [HEVC] [10bit] [5.1]
E:/Films/Four Weddings And A Funeral (1994) [1080p] [HEVC]/Four Weddings And A Funeral (1994) [REMASTERED] [BluRay] [1080p] [HEVC] [10bit] [5.1].eng (1)
E:/Films/Four Weddings And A Funeral (1994) [1080p] [HEVC]/Four Weddings And A Funeral (1994) [REMASTERED] [BluRay] [1080p] [HEVC] [10bit] [5.1].eng (2)
E:/Films 3D/How To Train Your Dragon 3D (2010) [1080p]/How To Train Your Dragon 3D (2010) [BluRay] [1080p] [5.1]
Still trying to figure out having collections and movies with a single expression
Don't know how to make custom collections like Pixar, Ghibli, MCU
Haven't managed to transliterate asian titles
jebbe
Posts: 8
Joined: 25 Dec 2017, 04:54

Re: How about sharing our format expressions?

Post by jebbe »

Code: Select all

{['F:', 'G:', 'I:', 'J:', 'L:', 'V:', 'W:', 'Y:'].collect{ (it+'/Movies') as File }.sort{ a, b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()} ({vf})\{n} ({y}){' ['+fn.replaceAll(/(?i)directors|theatrical|ultimate/,'$0 Cut').matchAll(/OPEN.MATTE|UNRATED|REMASTERED|EXTENDED|UNCUT|DIRECTORS.CUT|THEATRICAL.CUT|ULTIMATE.CUT|SPECIAL.EDITION/).join('][').upperInitial().lowerTrail()+']'} [{vf}] [{ac}{fn.match("-HD.MA.")+af}]/{n} ({y}) {vc}{" (CD$pi)"}{' '+lang}
Here is what I use and am still trying to figure out how to make it so if it finds Open.Matte or Special.Edition in the title and places it in the title, it removes the . between the two words. I can of course do it manually but unsure how to do this with the code. Most of what I use is pieces of many of peoples code here that I've Frankensteined together for my needs.
Baradhur
Posts: 10
Joined: 12 Jan 2016, 12:24

Re: How about sharing our format expressions?

Post by Baradhur »

Here is mine. I've used that one for 2 years now an all my libraries are organized following thing. My model is simple and represents exactly what I need.

Movies

Base format is

Code: Select all

Movie Categorie\Name in french (year) - (director) (VO name if different from french) [Languages] [Resolution, video code, audio codec]
Script

Code: Select all

Films/renamed/{any{genres[0]}{"Unknown"}}/ 
{any{localize.fr.n}{n}}
{(pn >= 2) ? " cd$pi" : ""} 
{"($y)"} 
- {"($director)"} 
{localize.fr.n == primaryTitle ? "" : "(${primaryTitle})"}
{"[${fn.lower().match(/- fr|- vostfr|- multi|\[fr\]|\[vostfr\]|\[multi\]|multi|vostfr/).replace('- ', '')}]"} 
{allOf{"$vf"}{"$vc"}{"$ac"}}
Before

Code: Select all

The.Invisible.Man.2020.MULTi.TRUEFRENCH.1080p.HDLight.x264.AC3-EXTREME.mkv
After

Code: Select all

renamed\Thriller\Invisible Man (2020) - (Leigh Whannell) (The Invisible Man) [multi] [1080p, x264, AC3]

Series
base format is

Code: Select all

TV show\TV Show Season Number\TV Show - SxE - Episode name [languages] [resolution] [codes]
Script

Code: Select all

Renamed/{n}/{n} Saison {s.pad(2)}/{n} - {sxe} - {t} {"[vostfr]"} {"[$vf]"} {allOf{"$vc"}{"$ac"}}
Before

Code: Select all

Brooklyn.Nine-Nine.S07E01.MULTi.720p.WEB.H264-CiELOS.mkv
After

Code: Select all

Renamed\Brooklyn Nine-Nine\Brooklyn Nine-Nine Saison 07\Brooklyn Nine-Nine - 7x01 - Manhunter [vostfr] [720p] [AVC, AAC].mkv
xaeiou
Posts: 15
Joined: 22 Oct 2019, 06:24

Re: How about sharing our format expressions?

Post by xaeiou »

Here is my format expression replacing characters illegal on the Windows filesystem with similar looking unicode characters. I don't use Windows, but I do share files from my Linux NAS via samba - this format is necessary for the samba clients to see the filenames correctly, otherwise they will be truncated to 8 character DOS format and are usually impossible to recognise.

It's also possible to have the fileserver make this translation, but I prefer to have filebot do it during renaming then I never have to worry about it again.

This expression includes a prefix with all the replaced characters so you can see how they look on your system font.

Thanks to rednoah for helping me simplify the syntax for this expression.

Code: Select all

'<>:"/\\|?*'.replace(
	'<' : '﹤',
	'>' : '﹥',
	':' : 'ː',
	'"' : '“',
	'/' : '⁄',
	'|' : '⼁',
	'?' : '?',
	'*' : '﹡',
	'\\': '∖'
)
WhatTimeDayPlace
Posts: 15
Joined: 05 Aug 2021, 09:42

Re: How about sharing our format expressions?

Post by WhatTimeDayPlace »

Movies with localized title + original and alternative titles

I want to keep movie files
  • in a Plex-compatible format
  • with the localized title leading.
  • In addition the original title should be added in square brackets.
  • If the local title is equal to the original title, then the original title can be dropped.
  • Alternative titles are desirable, too, but only local ones. I don't want all alternative titles world-wide.
In my case "local" is German. So desired example outcomes look like this:
  • Verfluchtes Amsterdam (1988) [Amsterdamned]
  • Wer Gewalt sät... (1971) [Straw Dogs]
  • Lost in Space (1998)
  • Dark Planet / Rebellion (2009) [Obitaemyy Ostrov. Skhvatka, The Inhabited Island 2 / Rebellion]
I lack rule programming skills. Thankfully @rednoah provided the following, which works well for me:

Code: Select all

{ny} { allOf{ primaryTitle }{ localize.en.n }.joiningDistinct(', ', '[', ']'){ n.contains(it) ? null : it } }
Issues I still see are mostly related to shortcomings in TMDB. So that is not related to FileBot or the formatting rule.

The original thread is here: viewtopic.php?f=6&t=12755
SnakeBonD
Posts: 1
Joined: 23 Jan 2022, 15:09

Re: How about sharing our format expressions?

Post by SnakeBonD »

Hi,
For my first message, I would like to thank the FileBot developers for this application, as well as all members of this forum for their sharing of examples. ;)
I spent a lot of time in this forum, because there are many ideas to find a solution for each way to rename media files. :idea:

Here is the way I rename my media files:

MOVIES:
For movies I wanted to classify them in the following order:
By studio (Marvel, Disney, Dreamworks, etc.), by Collection or by genre/
the title of the movie in my language, then in the original language if existing, the year, rating, if audio is not french and have subtitle = [VOSTFR] not subtitle=[VO], resolution and audio channels.

exemple:
_MOVIES\COLLECTION\JAMES─BOND─007\Goldeneye [1995] [6.9★] [tt0113189][HD][5.1].mkv
_MOVIES\GENRE\Action\Sky Hunter [2017] (空天猎) [7.2★] [tt6908536][VO][SD][5.1].mkv
_MOVIES\STUDIO\MARVEL\Avengers L'ère D'ultron [2015] (Avengers Age Of Ultron) [7.3★] [tt2395427][VOSTFR][Full HD][5.1].mkv

Code: Select all

/_MOVIES/
{any
	{ 
	info.productionCompanies*.match(
		/Marvel/ : 'STUDIO/MARVEL',
		/Lucasfilm/ : 'STUDIO/STAR─WARS',
		/DC / : 'STUDIO/DC─COMICS',
		/Disney/ : 'STUDIO/DISNEY',
		/Pixar/ : 'STUDIO/PIXAR',
		/Dreamworks/ : 'STUDIO/DREAMWORKS',
		/Studio Ghibli/ : 'STUDIO/STUDIO─GHIBLI'
		).find()
	}	
	
	{ 'COLLECTION/'+collection
	.replaceFirst(/^(?i)(The)\s(.+)/, /$2, $1/)
	.replaceFirst(/^(?i)(Collection of the)\s(.+)/, /$2 Collection/)
	.replaceAll(/ - Saga/, "")
	.replaceAll(/ Collection/, "")
	.replaceAll(/Saga Collection/, "")
	.replaceAll(/[`´‘’ʻ""“”]/, "'")
	.replaceAll(/[:*?"<>|?]/)
	.replaceAll(/[*\s]+/, "─")
	.upper()
	}
	
	{
	def genreOrder = ['Anilation': 1, 'Comedy': 2, 'Horror': 3, 'Science-Fiction': 4, 'Adventure': 5, 'Romance': 6, 'Drama': 7, 'Action': 8].withDefault{ 100 }
	'GENRE/'+genres.toSorted{ genreOrder[it] }[0]
	}
}/

{
	norm = {
		it
		.upperInitial()
		.lowerTrail()
		.replaceTrailingBrackets()
		.replaceAll(/[`´‘’ʻ""“”]/, "'")
		.replaceAll(/[:*?"<>|?]/)
		.replaceAll(':', 'ː')
		.replaceAll(/[?]/, "?")
	}
	; norm(n)
} 
[{y}] 
{if (norm(n) != norm(primaryTitle)) ' ('+norm(primaryTitle)+')'} 
{" ["+rating+"★]"}
{" ["+imdbid+"]"}
{'fr' in text.language ? '[VOSTFR]' : 'VO'}
{vf == /2160p/ ? '[4K]' : vf =~ /1080p/ ? '[Full HD]' : vf =~ /720p/ ? '[HD]' : '[SD]'}[{channels}]
TV SHOW:

For the Series, I classified them by the name of the series + year + number of seasons + number of episodes /
Sub folders with 1 folder by season + number episodes /
Title Serie + Name Episode + if audio is not french and have subtitle = [VOSTFR] not subtitle=[VO], resolution and audio channels.

exemple:
_SERIES\L'AGENCE TOUS RISQUES [1983] [5 Saison, 98 Episodes]\The A-Team [Saison 05-13 épisodes]\L'Agence Tous Risques [1983] - S05E01 - Dishpan Man [SD][2.0].mp4

Code: Select all

/_SERIES/
{
	norm = {
		it
		.upper()
		.replaceTrailingBrackets()
		.replaceAll(/[`´‘’ʻ""“”]/, "'")
		.replaceAll(/[:*?"<>|?]/)
		.replaceAll(':', 'ː')
		.replaceAll(/[?]/, "?")
		.replaceAll(/[*\s]+/, " ")
	}; norm(n)
} [{y}] [{episodelist.season.max()} Saison, {episodelist.count{ it.episode }} Episodes]/
/{localize.english.n.replaceAll(/[!?.]+$/).replaceAll(/[`´‘’ʻ""“”]/, "'").replaceAll(/[:*?"<>|?]/).upperInitial().replaceTrailingBrackets().lowerTrail().replacePart(', Part $1')} 
[Saison {s.pad(2)}-{episodelist.count{ it.episode && it.season == s }} épisodes]/

{
	norm = {
		it
		.upperInitial()
		.replaceTrailingBrackets()
		.replaceAll(/[`´‘’ʻ""“”]/, "'")
		.replaceAll(/[:*?"<>|?]/)
		.replaceAll(':', 'ː')
		.replaceAll(/[?]/, "?")
		.replaceAll(/[*\s]+/, " ")
	}; norm(n)
} [{y}] 

- {s00e00} - {localize.english.t.replaceAll(/[!?.]+$/).replaceAll(/[`´‘’ʻ""“”]/, "'").replaceAll(/[:*?"<>|?]/).lowerTrail().replacePart(', Part $1')} 
{'fr' in text.language ? '[VOSTFR]' : '[VO]'}
{vf == /2160p/ ? '[4K]' : vf =~ /1080p/ ? '[Full HD]' : vf =~ /720p/ ? '[HD]' : '[SD]'}[{channels}]
MUSIC:
For the music I treat them before with musicbrainz, then with mp3tag, then with Filebot.
I classify them in files according to:
File Format (if MP3 -> _MP3 _) / Genre (if no kind -> _No_Genre _) / Artist / Album / Artist - Title [Bitrate] .ext

exemple:
_MUSIC\_MP3_\_NO_GENRE_\ACDC\Acdc - Tnt [128 kbps].mp3
_MUSIC\_MP3_\SERTANEJO\LEANDRO E LEONARDO\TE AMO DEMAIS\Leandro E Leonardo - 002 - Tudo Me Lembra Você [192 kb s].mp3
_MUSIC\_FLAC_\HEAVY METAL\METALLICA\ONE OF 282\Metallica - 001 - Of Wolf And Man [1 048 kb s].flac

Code: Select all

/_MUSIC/{'_'+ext.upper()+'_'}/
{any
	{genre
	.tokenize(',')
	.first()
	.replace(':' : 'ː')
	.replaceAll(/[`´‘’ʻ""“”]/, "")
	.replaceAll(/[.:*?"<>|?]/)
	.replaceAll(/&/,"and")
	.replaceAll(/#/,"number")
	.replaceTrailingBrackets()
	.lowerTrail()
	.upper()
	}
	{'_NO_GENRE_'}
}/
{
	artist
	.replace(':' : 'ː')
	.replaceAll(/[`´‘’ʻ""“”]/, "")
	.replaceAll(/[.:*?"<>|?]/)
	.replaceAll(/&/,"and")
	.replaceAll(/#/,"number")
	.replaceTrailingBrackets()
	.lowerTrail()
	.upper()
}/

{
	album
	.replaceAll(/&/,"and")
	.replaceAll(/#/,"number")
	.replace(':' : 'ː')
	.replaceAll(/[`´‘’ʻ""“”]/, "")
	.replaceAll(/[.:*?"<>|?]/)
	.replaceTrailingBrackets()
	.lowerTrail()
	.upper()
}
/
{
	artist
	.replace(':' : 'ː')
	.replaceAll(/[`´‘’ʻ""“”]/, "")
	.replaceAll(/[.:*?"<>|?]/)
	.replaceAll(/&/,"and")
	.replaceAll(/#/,"number")
	.replaceTrailingBrackets()
	.lowerTrail()
	.upperInitial()
}
{any
	//{media.'part/position_total' == null ? null : '/CD ' + media.'part/position'}
	{' - '+pi.pad(3)+' - '}
	{' - '}
}

{
	t
	.replace(':' : 'ː')
	.replaceAll(/[`´‘’ʻ""“”]/, "")
	.replaceAll(/[.:*?"<>|?]/)
	.replaceAll(/&/,"and")
	.replaceAll(/#/,"number")
	.replaceTrailingBrackets()
	.lowerTrail()
	.upperInitial()
} 
[{audio[0].bitratestring.replace('/', 'p')}]
Last edited by SnakeBonD on 23 Jan 2022, 16:10, edited 1 time in total.
Post Reply