Jellyfin compatible naming scheme : particularities

Any questions? Need some help?
Post Reply
smellycheese
Posts: 12
Joined: 27 Sep 2025, 23:12

Jellyfin compatible naming scheme : particularities

Post by smellycheese »

Hi,

Following main thread (Jellyfin compatible naming scheme) here is first part of the main idea named "particularities"

I'm looking to keep following terms (if exist) on original filename :
3D, REMASTERED, EXTENDED, THEATRiCAL, DiRECTORS.CUT, UNRATED, UNCUT, PROPER, iNTERNAL, LiMiTED, REPACK, PROPER, CuSTOM, Open.Matte, COMPLETE, SPECIAL.EDITION, RATED, CRiTERiON, Cannes.Cut, FESTiVAL, XXth.Anniversary.Edition ( where XX could be any number), ULTiMATE.DiRECTORS.CUT, 3D, HDR, DV

Some/most of them are known with {tags} but is it the proper way to mix it with some other special pattern matching for other or considering a whole list by special pattern matching?

Importance thing is also to respect type case as described above, if that's not currently true in original filename it must be fixed in new filename.

Thank in advance
User avatar
rednoah
The Source
Posts: 24412
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Jellyfin compatible naming scheme : particularities

Post by rednoah »

Alright, so lets say we want to copy along the following tags from the original file name:

Code: Select all

3D
REMASTERED
EXTENDED
THEATRiCAL
DiRECTORS.CUT
UNRATED
UNCUT
PROPER
iNTERNAL
LiMiTED
REPACK
PROPER
CuSTOM
Open.Matte
COMPLETE
SPECIAL.EDITION
RATED
CRiTERiON
Cannes.Cut
FESTiVAL
XXth.Anniversary.Edition
ULTiMATE.DiRECTORS.CUT
3D
HDR
DV

:idea: The match information from the file path would be the easy solution:

Format: Select all

{ fn.matchAll(/3D|REMASTERED|EXTENDED|THEATRiCAL|DiRECTORS.CUT|UNRATED|UNCUT|PROPER|iNTERNAL|LiMiTED|REPACK|PROPER|CuSTOM|Open.Matte|COMPLETE|SPECIAL.EDITION|RATED|CRiTERiON|Cannes.Cut|FESTiVAL|[0-9]{1,2}th.Anniversary.Edition|ULTiMATE.DiRECTORS.CUT|3D|HDR|DV/) }


:idea: If we then wanted to combine the results of { tags } and { fn.matchAll(...) } then the code will get a little bit more complex:

Format: Select all

{ 
	list
	{ tags }
	{ fn.matchAll(/3D|REMASTERED|EXTENDED|THEATRiCAL|DiRECTORS.CUT|UNRATED|UNCUT|PROPER|iNTERNAL|LiMiTED|REPACK|PROPER|CuSTOM|Open.Matte|COMPLETE|SPECIAL.EDITION|RATED|CRiTERiON|Cannes.Cut|FESTiVAL|[0-9]{1,2}th.Anniversary.Edition|ULTiMATE.DiRECTORS.CUT|3D|HDR|DV/) }
	.toSorted().joiningDistinct(', ', '[', ']')
}


smellycheese wrote: 27 Sep 2025, 23:27 - particularities (if multiples exist, sort them alphabetically if possible) : 3D, REMASTERED, EXTENDED, THEATRiCAL, DiRECTORS.CUT, UNRATED, UNCUT, PROPER, iNTERNAL, LiMiTED, REPACK, PROPER, CuSTOM, Open.Matte, COMPLETE, SPECIAL.EDITION, RATED, CRiTERiON, Cannes.Cut, FESTiVAL, XXth.Anniversary.Edition ( where XX could be any number), ULTiMATE.DiRECTORS.CUT, 3D, HDR, DV
particularities must respect type case as described above, if that's not currently true in original filename it must be fixed in new filename.
If we also want to normalize the custom tags, i.e. THEATRICAL ➔ THEATRiCAL, then we need to go back to the drawing board, since fn.match() / fn.matchAll() just copy & paste from the original file name.

:arrow: Now things get a little bit complex:

Format: Select all

{
	def pattern = /3D|REMASTERED|EXTENDED|THEATRiCAL|DiRECTORS.CUT|UNRATED|UNCUT|PROPER|iNTERNAL|LiMiTED|REPACK|PROPER|CuSTOM|Open.Matte|COMPLETE|SPECIAL.EDITION|RATED|CRiTERiON|Cannes.Cut|FESTiVAL|ULTiMATE.DiRECTORS.CUT|3D|HDR|DV/
	def mapping = pattern.tokenize('|').collectEntries{ [it, it] }

	fn.matchAll(pattern)*.match(mapping)
}
** The list of custom tags could be read from a file. See Read external CSV / TSV / JSON / XML files for details. Let me know if you want the code for that.


:!: Now we also find that we have to separate the [0-9]{1,2}th.Anniversary.Edition bit into a separate piece of code, as the pattern isn't also the normalized value here, we have to use a different approach for this specific pattern:

Format: Select all

{
	fn.match(/([0-9]{1,2})th.Anniversary.Edition/) + ' Anniversary Edition'
}
:idea: Please read the FAQ and How to Request Help.
Post Reply