|
|
@ -136,8 +136,8 @@ namespace Emby.Naming.Common
|
|
|
|
|
|
|
|
|
|
|
|
CleanDateTimes = new[]
|
|
|
|
CleanDateTimes = new[]
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@"(.+[^_\,\.\(\)\[\]\-])[_\.\(\)\[\]\-](19\d{2}|20\d{2})([ _\,\.\(\)\[\]\-][^0-9]|).*(19\d{2}|20\d{2})*",
|
|
|
|
@"(.+[^_\,\.\(\)\[\]\-])[_\.\(\)\[\]\-](19[0-9]{2}|20[0-9]{2})([ _\,\.\(\)\[\]\-][^0-9]|).*(19[0-9]{2}|20[0-9]{2})*",
|
|
|
|
@"(.+[^_\,\.\(\)\[\]\-])[ _\.\(\)\[\]\-]+(19\d{2}|20\d{2})([ _\,\.\(\)\[\]\-][^0-9]|).*(19\d{2}|20\d{2})*"
|
|
|
|
@"(.+[^_\,\.\(\)\[\]\-])[ _\.\(\)\[\]\-]+(19[0-9]{2}|20[0-9]{2})([ _\,\.\(\)\[\]\-][^0-9]|).*(19[0-9]{2}|20[0-9]{2})*"
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
CleanStrings = new[]
|
|
|
|
CleanStrings = new[]
|
|
|
@ -277,7 +277,7 @@ namespace Emby.Naming.Common
|
|
|
|
// This isn't a Kodi naming rule, but the expression below causes false positives,
|
|
|
|
// This isn't a Kodi naming rule, but the expression below causes false positives,
|
|
|
|
// so we make sure this one gets tested first.
|
|
|
|
// so we make sure this one gets tested first.
|
|
|
|
// "Foo Bar 889"
|
|
|
|
// "Foo Bar 889"
|
|
|
|
new EpisodeExpression(@".*[\\\/](?![Ee]pisode)(?<seriesname>[\w\s]+?)\s(?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*[^\\\/x]*$")
|
|
|
|
new EpisodeExpression(@".*[\\\/](?![Ee]pisode)(?<seriesname>[\w\s]+?)\s(?<epnumber>[0-9]{1,3})(-(?<endingepnumber>[0-9]{2,3}))*[^\\\/x]*$")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
|
},
|
|
|
|
},
|
|
|
@ -300,32 +300,32 @@ namespace Emby.Naming.Common
|
|
|
|
// *** End Kodi Standard Naming
|
|
|
|
// *** End Kodi Standard Naming
|
|
|
|
|
|
|
|
|
|
|
|
// [bar] Foo - 1 [baz]
|
|
|
|
// [bar] Foo - 1 [baz]
|
|
|
|
new EpisodeExpression(@".*?(\[.*?\])+.*?(?<seriesname>[\w\s]+?)[-\s_]+(?<epnumber>\d+).*$")
|
|
|
|
new EpisodeExpression(@".*?(\[.*?\])+.*?(?<seriesname>[\w\s]+?)[-\s_]+(?<epnumber>[0-9]+).*$")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
|
},
|
|
|
|
},
|
|
|
|
new EpisodeExpression(@".*(\\|\/)[sS]?(?<seasonnumber>\d+)[xX](?<epnumber>\d+)[^\\\/]*$")
|
|
|
|
new EpisodeExpression(@".*(\\|\/)[sS]?(?<seasonnumber>[0-9]+)[xX](?<epnumber>[0-9]+)[^\\\/]*$")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
new EpisodeExpression(@".*(\\|\/)[sS](?<seasonnumber>\d+)[x,X]?[eE](?<epnumber>\d+)[^\\\/]*$")
|
|
|
|
new EpisodeExpression(@".*(\\|\/)[sS](?<seasonnumber>[0-9]+)[x,X]?[eE](?<epnumber>[0-9]+)[^\\\/]*$")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
new EpisodeExpression(@".*(\\|\/)(?<seriesname>((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d+))[^\\\/]*$")
|
|
|
|
new EpisodeExpression(@".*(\\|\/)(?<seriesname>((?![sS]?[0-9]{1,4}[xX][0-9]{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]+))[^\\\/]*$")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
new EpisodeExpression(@".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d+)[^\\\/]*$")
|
|
|
|
new EpisodeExpression(@".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>[0-9]{1,4})[xX\.]?[eE](?<epnumber>[0-9]+)[^\\\/]*$")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// "01.avi"
|
|
|
|
// "01.avi"
|
|
|
|
new EpisodeExpression(@".*[\\\/](?<epnumber>\d+)(-(?<endingepnumber>\d+))*\.\w+$")
|
|
|
|
new EpisodeExpression(@".*[\\\/](?<epnumber>[0-9]+)(-(?<endingepnumber>[0-9]+))*\.\w+$")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsOptimistic = true,
|
|
|
|
IsOptimistic = true,
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
@ -335,34 +335,34 @@ namespace Emby.Naming.Common
|
|
|
|
new EpisodeExpression(@"([0-9]+)-([0-9]+)"),
|
|
|
|
new EpisodeExpression(@"([0-9]+)-([0-9]+)"),
|
|
|
|
|
|
|
|
|
|
|
|
// "01 - blah.avi", "01-blah.avi"
|
|
|
|
// "01 - blah.avi", "01-blah.avi"
|
|
|
|
new EpisodeExpression(@".*(\\|\/)(?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*\s?-\s?[^\\\/]*$")
|
|
|
|
new EpisodeExpression(@".*(\\|\/)(?<epnumber>[0-9]{1,3})(-(?<endingepnumber>[0-9]{2,3}))*\s?-\s?[^\\\/]*$")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsOptimistic = true,
|
|
|
|
IsOptimistic = true,
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// "01.blah.avi"
|
|
|
|
// "01.blah.avi"
|
|
|
|
new EpisodeExpression(@".*(\\|\/)(?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*\.[^\\\/]+$")
|
|
|
|
new EpisodeExpression(@".*(\\|\/)(?<epnumber>[0-9]{1,3})(-(?<endingepnumber>[0-9]{2,3}))*\.[^\\\/]+$")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsOptimistic = true,
|
|
|
|
IsOptimistic = true,
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// "blah - 01.avi", "blah 2 - 01.avi", "blah - 01 blah.avi", "blah 2 - 01 blah", "blah - 01 - blah.avi", "blah 2 - 01 - blah"
|
|
|
|
// "blah - 01.avi", "blah 2 - 01.avi", "blah - 01 blah.avi", "blah 2 - 01 blah", "blah - 01 - blah.avi", "blah 2 - 01 - blah"
|
|
|
|
new EpisodeExpression(@".*[\\\/][^\\\/]* - (?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*[^\\\/]*$")
|
|
|
|
new EpisodeExpression(@".*[\\\/][^\\\/]* - (?<epnumber>[0-9]{1,3})(-(?<endingepnumber>[0-9]{2,3}))*[^\\\/]*$")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsOptimistic = true,
|
|
|
|
IsOptimistic = true,
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// "01 episode title.avi"
|
|
|
|
// "01 episode title.avi"
|
|
|
|
new EpisodeExpression(@"[Ss]eason[\._ ](?<seasonnumber>[0-9]+)[\\\/](?<epnumber>\d{1,3})([^\\\/]*)$")
|
|
|
|
new EpisodeExpression(@"[Ss]eason[\._ ](?<seasonnumber>[0-9]+)[\\\/](?<epnumber>[0-9]{1,3})([^\\\/]*)$")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsOptimistic = true,
|
|
|
|
IsOptimistic = true,
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// "Episode 16", "Episode 16 - Title"
|
|
|
|
// "Episode 16", "Episode 16 - Title"
|
|
|
|
new EpisodeExpression(@".*[\\\/][^\\\/]* (?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*[^\\\/]*$")
|
|
|
|
new EpisodeExpression(@".*[\\\/][^\\\/]* (?<epnumber>[0-9]{1,3})(-(?<endingepnumber>[0-9]{2,3}))*[^\\\/]*$")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsOptimistic = true,
|
|
|
|
IsOptimistic = true,
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
@ -625,17 +625,17 @@ namespace Emby.Naming.Common
|
|
|
|
AudioBookPartsExpressions = new[]
|
|
|
|
AudioBookPartsExpressions = new[]
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Detect specified chapters, like CH 01
|
|
|
|
// Detect specified chapters, like CH 01
|
|
|
|
@"ch(?:apter)?[\s_-]?(?<chapter>\d+)",
|
|
|
|
@"ch(?:apter)?[\s_-]?(?<chapter>[0-9]+)",
|
|
|
|
// Detect specified parts, like Part 02
|
|
|
|
// Detect specified parts, like Part 02
|
|
|
|
@"p(?:ar)?t[\s_-]?(?<part>\d+)",
|
|
|
|
@"p(?:ar)?t[\s_-]?(?<part>[0-9]+)",
|
|
|
|
// Chapter is often beginning of filename
|
|
|
|
// Chapter is often beginning of filename
|
|
|
|
@"^(?<chapter>\d+)",
|
|
|
|
"^(?<chapter>[0-9]+)",
|
|
|
|
// Part if often ending of filename
|
|
|
|
// Part if often ending of filename
|
|
|
|
@"(?<part>\d+)$",
|
|
|
|
"(?<part>[0-9]+)$",
|
|
|
|
// Sometimes named as 0001_005 (chapter_part)
|
|
|
|
// Sometimes named as 0001_005 (chapter_part)
|
|
|
|
@"(?<chapter>\d+)_(?<part>\d+)",
|
|
|
|
"(?<chapter>[0-9]+)_(?<part>[0-9]+)",
|
|
|
|
// Some audiobooks are ripped from cd's, and will be named by disk number.
|
|
|
|
// Some audiobooks are ripped from cd's, and will be named by disk number.
|
|
|
|
@"dis(?:c|k)[\s_-]?(?<chapter>\d+)"
|
|
|
|
@"dis(?:c|k)[\s_-]?(?<chapter>[0-9]+)"
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var extensions = VideoFileExtensions.ToList();
|
|
|
|
var extensions = VideoFileExtensions.ToList();
|
|
|
@ -675,16 +675,16 @@ namespace Emby.Naming.Common
|
|
|
|
|
|
|
|
|
|
|
|
MultipleEpisodeExpressions = new string[]
|
|
|
|
MultipleEpisodeExpressions = new string[]
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})((-| - )\d{1,4}[eExX](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)[sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3})((-| - )[0-9]{1,4}[eExX](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})((-| - )\d{1,4}[xX][eE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)[sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3})((-| - )[0-9]{1,4}[xX][eE](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})((-| - )?[xXeE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)[sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3})((-| - )?[xXeE](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})(-[xE]?[eE]?(?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)[sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3})(-[xE]?[eE]?(?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)(?<seriesname>((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3}))((-| - )\d{1,4}[xXeE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)(?<seriesname>((?![sS]?[0-9]{1,4}[xX][0-9]{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3}))((-| - )[0-9]{1,4}[xXeE](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)(?<seriesname>((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3}))((-| - )\d{1,4}[xX][eE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)(?<seriesname>((?![sS]?[0-9]{1,4}[xX][0-9]{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3}))((-| - )[0-9]{1,4}[xX][eE](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)(?<seriesname>((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3}))((-| - )?[xXeE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)(?<seriesname>((?![sS]?[0-9]{1,4}[xX][0-9]{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3}))((-| - )?[xXeE](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)(?<seriesname>((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3}))(-[xX]?[eE]?(?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)(?<seriesname>((?![sS]?[0-9]{1,4}[xX][0-9]{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3}))(-[xX]?[eE]?(?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d{1,3})((-| - )?[xXeE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>[0-9]{1,4})[xX\.]?[eE](?<epnumber>[0-9]{1,3})((-| - )?[xXeE](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
|
|
|
|
@".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d{1,3})(-[xX]?[eE]?(?<endingepnumber>\d{1,3}))+[^\\\/]*$"
|
|
|
|
@".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>[0-9]{1,4})[xX\.]?[eE](?<epnumber>[0-9]{1,3})(-[xX]?[eE]?(?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$"
|
|
|
|
}.Select(i => new EpisodeExpression(i)
|
|
|
|
}.Select(i => new EpisodeExpression(i)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsNamed = true
|
|
|
|
IsNamed = true
|
|
|
|