mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
Added: A Huge Cleanup of old Series Code. (Let's pray nothing breaks :P) (#2589)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
@@ -10,21 +10,16 @@ using NzbDrone.Common.EnsureThat;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Movies;
|
||||
|
||||
namespace NzbDrone.Core.Organizer
|
||||
{
|
||||
public interface IBuildFileNames
|
||||
{
|
||||
string BuildFileName(List<Episode> episodes, Series series, EpisodeFile episodeFile, NamingConfig namingConfig = null);
|
||||
string BuildFileName(Movie movie, MovieFile movieFile, NamingConfig namingConfig = null);
|
||||
string BuildFilePath(Movie movie, string fileName, string extension);
|
||||
string BuildFilePath(Series series, int seasonNumber, string fileName, string extension);
|
||||
string BuildMoviePath(Movie movie, NamingConfig namingConfig = null);
|
||||
string BuildSeasonPath(Series series, int seasonNumber);
|
||||
BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec);
|
||||
string GetSeriesFolder(Series series, NamingConfig namingConfig = null);
|
||||
string GetSeasonFolder(Series series, int seasonNumber, NamingConfig namingConfig = null);
|
||||
string GetMovieFolder(Movie movie, NamingConfig namingConfig = null);
|
||||
}
|
||||
|
||||
@@ -89,64 +84,6 @@ namespace NzbDrone.Core.Organizer
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public string BuildFileName(List<Episode> episodes, Series series, EpisodeFile episodeFile, NamingConfig namingConfig = null)
|
||||
{
|
||||
if (namingConfig == null)
|
||||
{
|
||||
namingConfig = _namingConfigService.GetConfig();
|
||||
}
|
||||
|
||||
if (!namingConfig.RenameEpisodes)
|
||||
{
|
||||
return GetOriginalTitle(episodeFile);
|
||||
}
|
||||
|
||||
if (namingConfig.StandardEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Standard)
|
||||
{
|
||||
throw new NamingFormatException("Standard episode format cannot be empty");
|
||||
}
|
||||
|
||||
if (namingConfig.DailyEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Daily)
|
||||
{
|
||||
throw new NamingFormatException("Daily episode format cannot be empty");
|
||||
}
|
||||
|
||||
if (namingConfig.AnimeEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Anime)
|
||||
{
|
||||
throw new NamingFormatException("Anime episode format cannot be empty");
|
||||
}
|
||||
|
||||
var pattern = namingConfig.StandardEpisodeFormat;
|
||||
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
|
||||
|
||||
episodes = episodes.OrderBy(e => e.SeasonNumber).ThenBy(e => e.EpisodeNumber).ToList();
|
||||
|
||||
if (series.SeriesType == SeriesTypes.Daily)
|
||||
{
|
||||
pattern = namingConfig.DailyEpisodeFormat;
|
||||
}
|
||||
|
||||
if (series.SeriesType == SeriesTypes.Anime && episodes.All(e => e.AbsoluteEpisodeNumber.HasValue))
|
||||
{
|
||||
pattern = namingConfig.AnimeEpisodeFormat;
|
||||
}
|
||||
|
||||
pattern = AddSeasonEpisodeNumberingTokens(pattern, tokenHandlers, episodes, namingConfig);
|
||||
pattern = AddAbsoluteNumberingTokens(pattern, tokenHandlers, series, episodes, namingConfig);
|
||||
|
||||
AddSeriesTokens(tokenHandlers, series);
|
||||
AddEpisodeTokens(tokenHandlers, episodes);
|
||||
AddEpisodeFileTokens(tokenHandlers, episodeFile);
|
||||
AddQualityTokens(tokenHandlers, series, episodeFile);
|
||||
AddMediaInfoTokens(tokenHandlers, episodeFile);
|
||||
|
||||
var fileName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim();
|
||||
fileName = FileNameCleanupRegex.Replace(fileName, match => match.Captures[0].Value[0].ToString());
|
||||
fileName = TrimSeparatorsRegex.Replace(fileName, string.Empty);
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public string BuildFileName(Movie movie, MovieFile movieFile, NamingConfig namingConfig = null)
|
||||
{
|
||||
if (namingConfig == null)
|
||||
@@ -177,15 +114,6 @@ namespace NzbDrone.Core.Organizer
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public string BuildFilePath(Series series, int seasonNumber, string fileName, string extension)
|
||||
{
|
||||
Ensure.That(extension, () => extension).IsNotNullOrWhiteSpace();
|
||||
|
||||
var path = BuildSeasonPath(series, seasonNumber);
|
||||
|
||||
return Path.Combine(path, fileName + extension);
|
||||
}
|
||||
|
||||
public string BuildFilePath(Movie movie, string fileName, string extension)
|
||||
{
|
||||
Ensure.That(extension, () => extension).IsNotNullOrWhiteSpace();
|
||||
@@ -245,104 +173,52 @@ namespace NzbDrone.Core.Organizer
|
||||
return Path.Combine(parentDirectoryPath, directoryName);
|
||||
}
|
||||
|
||||
public string BuildSeasonPath(Series series, int seasonNumber)
|
||||
{
|
||||
var path = series.Path;
|
||||
|
||||
if (series.SeasonFolder)
|
||||
{
|
||||
if (seasonNumber == 0)
|
||||
{
|
||||
path = Path.Combine(path, "Specials");
|
||||
}
|
||||
else
|
||||
{
|
||||
var seasonFolder = GetSeasonFolder(series, seasonNumber);
|
||||
|
||||
seasonFolder = CleanFileName(seasonFolder);
|
||||
|
||||
path = Path.Combine(path, seasonFolder);
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec)
|
||||
{
|
||||
return new BasicNamingConfig(); //For now let's be lazy
|
||||
|
||||
var episodeFormat = GetEpisodeFormat(nameSpec.StandardEpisodeFormat).LastOrDefault();
|
||||
//var episodeFormat = GetEpisodeFormat(nameSpec.StandardMovieFormat).LastOrDefault();
|
||||
|
||||
if (episodeFormat == null)
|
||||
{
|
||||
return new BasicNamingConfig();
|
||||
}
|
||||
//if (episodeFormat == null)
|
||||
//{
|
||||
// return new BasicNamingConfig();
|
||||
//}
|
||||
|
||||
var basicNamingConfig = new BasicNamingConfig
|
||||
{
|
||||
Separator = episodeFormat.Separator,
|
||||
NumberStyle = episodeFormat.SeasonEpisodePattern
|
||||
};
|
||||
//var basicNamingConfig = new BasicNamingConfig
|
||||
//{
|
||||
// Separator = episodeFormat.Separator,
|
||||
// NumberStyle = episodeFormat.SeasonEpisodePattern
|
||||
//};
|
||||
|
||||
var titleTokens = TitleRegex.Matches(nameSpec.StandardEpisodeFormat);
|
||||
//var titleTokens = TitleRegex.Matches(nameSpec.StandardMovieFormat);
|
||||
|
||||
foreach (Match match in titleTokens)
|
||||
{
|
||||
var separator = match.Groups["separator"].Value;
|
||||
var token = match.Groups["token"].Value;
|
||||
//foreach (Match match in titleTokens)
|
||||
//{
|
||||
// var separator = match.Groups["separator"].Value;
|
||||
// var token = match.Groups["token"].Value;
|
||||
|
||||
if (!separator.Equals(" "))
|
||||
{
|
||||
basicNamingConfig.ReplaceSpaces = true;
|
||||
}
|
||||
// if (!separator.Equals(" "))
|
||||
// {
|
||||
// basicNamingConfig.ReplaceSpaces = true;
|
||||
// }
|
||||
|
||||
if (token.StartsWith("{Series", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
basicNamingConfig.IncludeSeriesTitle = true;
|
||||
}
|
||||
// if (token.StartsWith("{Series", StringComparison.InvariantCultureIgnoreCase))
|
||||
// {
|
||||
// basicNamingConfig.IncludeSeriesTitle = true;
|
||||
// }
|
||||
|
||||
if (token.StartsWith("{Episode", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
basicNamingConfig.IncludeEpisodeTitle = true;
|
||||
}
|
||||
// if (token.StartsWith("{Episode", StringComparison.InvariantCultureIgnoreCase))
|
||||
// {
|
||||
// basicNamingConfig.IncludeEpisodeTitle = true;
|
||||
// }
|
||||
|
||||
if (token.StartsWith("{Quality", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
basicNamingConfig.IncludeQuality = true;
|
||||
}
|
||||
}
|
||||
// if (token.StartsWith("{Quality", StringComparison.InvariantCultureIgnoreCase))
|
||||
// {
|
||||
// basicNamingConfig.IncludeQuality = true;
|
||||
// }
|
||||
//}
|
||||
|
||||
return basicNamingConfig;
|
||||
}
|
||||
|
||||
public string GetSeriesFolder(Series series, NamingConfig namingConfig = null)
|
||||
{
|
||||
if (namingConfig == null)
|
||||
{
|
||||
namingConfig = _namingConfigService.GetConfig();
|
||||
}
|
||||
|
||||
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
|
||||
|
||||
AddSeriesTokens(tokenHandlers, series);
|
||||
|
||||
return CleanFolderName(ReplaceTokens(namingConfig.SeriesFolderFormat, tokenHandlers, namingConfig));
|
||||
}
|
||||
|
||||
public string GetSeasonFolder(Series series, int seasonNumber, NamingConfig namingConfig = null)
|
||||
{
|
||||
if (namingConfig == null)
|
||||
{
|
||||
namingConfig = _namingConfigService.GetConfig();
|
||||
}
|
||||
|
||||
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
|
||||
|
||||
AddSeriesTokens(tokenHandlers, series);
|
||||
AddSeasonTokens(tokenHandlers, seasonNumber);
|
||||
|
||||
return CleanFolderName(ReplaceTokens(namingConfig.SeasonFolderFormat, tokenHandlers, namingConfig));
|
||||
//return basicNamingConfig;
|
||||
}
|
||||
|
||||
public string GetMovieFolder(Movie movie, NamingConfig namingConfig = null)
|
||||
@@ -429,136 +305,6 @@ namespace NzbDrone.Core.Organizer
|
||||
return CleanFileName(name);
|
||||
}
|
||||
|
||||
private void AddSeriesTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Series series)
|
||||
{
|
||||
tokenHandlers["{Series Title}"] = m => series.Title;
|
||||
tokenHandlers["{Series CleanTitle}"] = m => CleanTitle(series.Title);
|
||||
}
|
||||
|
||||
private string AddSeasonEpisodeNumberingTokens(string pattern, Dictionary<string, Func<TokenMatch, string>> tokenHandlers, List<Episode> episodes, NamingConfig namingConfig)
|
||||
{
|
||||
var episodeFormats = GetEpisodeFormat(pattern).DistinctBy(v => v.SeasonEpisodePattern).ToList();
|
||||
|
||||
int index = 1;
|
||||
foreach (var episodeFormat in episodeFormats)
|
||||
{
|
||||
var seasonEpisodePattern = episodeFormat.SeasonEpisodePattern;
|
||||
string formatPattern;
|
||||
|
||||
switch ((MultiEpisodeStyle)namingConfig.MultiEpisodeStyle)
|
||||
{
|
||||
case MultiEpisodeStyle.Duplicate:
|
||||
formatPattern = episodeFormat.Separator + episodeFormat.SeasonEpisodePattern;
|
||||
seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.Repeat:
|
||||
formatPattern = episodeFormat.EpisodeSeparator + episodeFormat.EpisodePattern;
|
||||
seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.Scene:
|
||||
formatPattern = "-" + episodeFormat.EpisodeSeparator + episodeFormat.EpisodePattern;
|
||||
seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.Range:
|
||||
formatPattern = "-" + episodeFormat.EpisodePattern;
|
||||
seasonEpisodePattern = FormatRangeNumberTokens(seasonEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.PrefixedRange:
|
||||
formatPattern = "-" + episodeFormat.EpisodeSeparator + episodeFormat.EpisodePattern;
|
||||
seasonEpisodePattern = FormatRangeNumberTokens(seasonEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
//MultiEpisodeStyle.Extend
|
||||
default:
|
||||
formatPattern = "-" + episodeFormat.EpisodePattern;
|
||||
seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
}
|
||||
|
||||
var token = string.Format("{{Season Episode{0}}}", index++);
|
||||
pattern = pattern.Replace(episodeFormat.SeasonEpisodePattern, token);
|
||||
tokenHandlers[token] = m => seasonEpisodePattern;
|
||||
}
|
||||
|
||||
AddSeasonTokens(tokenHandlers, episodes.First().SeasonNumber);
|
||||
|
||||
if (episodes.Count > 1)
|
||||
{
|
||||
tokenHandlers["{Episode}"] = m => episodes.First().EpisodeNumber.ToString(m.CustomFormat) + "-" + episodes.Last().EpisodeNumber.ToString(m.CustomFormat);
|
||||
}
|
||||
else
|
||||
{
|
||||
tokenHandlers["{Episode}"] = m => episodes.First().EpisodeNumber.ToString(m.CustomFormat);
|
||||
}
|
||||
|
||||
return pattern;
|
||||
}
|
||||
|
||||
private string AddAbsoluteNumberingTokens(string pattern, Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Series series, List<Episode> episodes, NamingConfig namingConfig)
|
||||
{
|
||||
var absoluteEpisodeFormats = GetAbsoluteFormat(pattern).DistinctBy(v => v.AbsoluteEpisodePattern).ToList();
|
||||
|
||||
int index = 1;
|
||||
foreach (var absoluteEpisodeFormat in absoluteEpisodeFormats)
|
||||
{
|
||||
if (series.SeriesType != SeriesTypes.Anime)
|
||||
{
|
||||
pattern = pattern.Replace(absoluteEpisodeFormat.AbsoluteEpisodePattern, "");
|
||||
continue;
|
||||
}
|
||||
|
||||
var absoluteEpisodePattern = absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
string formatPattern;
|
||||
|
||||
switch ((MultiEpisodeStyle)namingConfig.MultiEpisodeStyle)
|
||||
{
|
||||
|
||||
case MultiEpisodeStyle.Duplicate:
|
||||
formatPattern = absoluteEpisodeFormat.Separator + absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.Repeat:
|
||||
var repeatSeparator = absoluteEpisodeFormat.Separator.Trim().IsNullOrWhiteSpace() ? " " : absoluteEpisodeFormat.Separator.Trim();
|
||||
|
||||
formatPattern = repeatSeparator + absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.Scene:
|
||||
formatPattern = "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.Range:
|
||||
case MultiEpisodeStyle.PrefixedRange:
|
||||
formatPattern = "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
var eps = new List<Episode> { episodes.First() };
|
||||
|
||||
if (episodes.Count > 1) eps.Add(episodes.Last());
|
||||
|
||||
absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, eps);
|
||||
break;
|
||||
|
||||
//MultiEpisodeStyle.Extend
|
||||
default:
|
||||
formatPattern = "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
}
|
||||
|
||||
var token = string.Format("{{Absolute Pattern{0}}}", index++);
|
||||
pattern = pattern.Replace(absoluteEpisodeFormat.AbsoluteEpisodePattern, token);
|
||||
tokenHandlers[token] = m => absoluteEpisodePattern;
|
||||
}
|
||||
|
||||
return pattern;
|
||||
}
|
||||
|
||||
private void AddMovieTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Movie movie)
|
||||
{
|
||||
tokenHandlers["{Movie Title}"] = m => movie.Title;
|
||||
@@ -584,33 +330,6 @@ namespace NzbDrone.Core.Organizer
|
||||
tokenHandlers["{IMDb Id}"] = m => $"{imdbId}";
|
||||
}
|
||||
|
||||
private void AddSeasonTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, int seasonNumber)
|
||||
{
|
||||
tokenHandlers["{Season}"] = m => seasonNumber.ToString(m.CustomFormat);
|
||||
}
|
||||
|
||||
private void AddEpisodeTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, List<Episode> episodes)
|
||||
{
|
||||
if (!episodes.First().AirDate.IsNullOrWhiteSpace())
|
||||
{
|
||||
tokenHandlers["{Air Date}"] = m => episodes.First().AirDate.Replace('-', ' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
tokenHandlers["{Air Date}"] = m => "Unknown";
|
||||
}
|
||||
|
||||
tokenHandlers["{Episode Title}"] = m => GetEpisodeTitle(episodes, "+");
|
||||
tokenHandlers["{Episode CleanTitle}"] = m => CleanTitle(GetEpisodeTitle(episodes, "and"));
|
||||
}
|
||||
|
||||
private void AddEpisodeFileTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, EpisodeFile episodeFile)
|
||||
{
|
||||
tokenHandlers["{Original Title}"] = m => GetOriginalTitle(episodeFile);
|
||||
tokenHandlers["{Original Filename}"] = m => GetOriginalFileName(episodeFile);
|
||||
tokenHandlers["{Release Group}"] = m => episodeFile.ReleaseGroup ?? m.DefaultValue("Radarr");
|
||||
}
|
||||
|
||||
private void AddMovieFileTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, MovieFile episodeFile)
|
||||
{
|
||||
tokenHandlers["{Original Title}"] = m => GetOriginalTitle(episodeFile);
|
||||
@@ -619,18 +338,6 @@ namespace NzbDrone.Core.Organizer
|
||||
tokenHandlers["{Release Group}"] = m => episodeFile.ReleaseGroup ?? m.DefaultValue("Radarr");
|
||||
}
|
||||
|
||||
private void AddQualityTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Series series, EpisodeFile episodeFile)
|
||||
{
|
||||
var qualityTitle = _qualityDefinitionService.Get(episodeFile.Quality.Quality).Title;
|
||||
var qualityProper = GetQualityProper(series, episodeFile.Quality);
|
||||
var qualityReal = GetQualityReal(series, episodeFile.Quality);
|
||||
|
||||
tokenHandlers["{Quality Full}"] = m => String.Format("{0} {1} {2}", qualityTitle, qualityProper, qualityReal);
|
||||
tokenHandlers["{Quality Title}"] = m => qualityTitle;
|
||||
tokenHandlers["{Quality Proper}"] = m => qualityProper;
|
||||
tokenHandlers["{Quality Real}"] = m => qualityReal;
|
||||
}
|
||||
|
||||
private void AddQualityTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Movie movie, MovieFile movieFile)
|
||||
{
|
||||
if (movieFile?.Quality?.Quality == null)
|
||||
@@ -652,110 +359,6 @@ namespace NzbDrone.Core.Organizer
|
||||
tokenHandlers["{Quality Real}"] = m => qualityReal;
|
||||
}
|
||||
|
||||
private void AddMediaInfoTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, EpisodeFile episodeFile)
|
||||
{
|
||||
if (episodeFile.MediaInfo == null) return;
|
||||
|
||||
string videoCodec;
|
||||
switch (episodeFile.MediaInfo.VideoCodec)
|
||||
{
|
||||
case "AVC":
|
||||
if (episodeFile.SceneName.IsNotNullOrWhiteSpace() && Path.GetFileNameWithoutExtension(episodeFile.SceneName).Contains("h264"))
|
||||
{
|
||||
videoCodec = "h264";
|
||||
}
|
||||
else
|
||||
{
|
||||
videoCodec = "x264";
|
||||
}
|
||||
break;
|
||||
|
||||
case "V_MPEGH/ISO/HEVC":
|
||||
if (episodeFile.SceneName.IsNotNullOrWhiteSpace() && Path.GetFileNameWithoutExtension(episodeFile.SceneName).Contains("h265"))
|
||||
{
|
||||
videoCodec = "h265";
|
||||
}
|
||||
else
|
||||
{
|
||||
videoCodec = "x265";
|
||||
}
|
||||
break;
|
||||
|
||||
case "MPEG-2 Video":
|
||||
videoCodec = "MPEG2";
|
||||
break;
|
||||
|
||||
default:
|
||||
videoCodec = episodeFile.MediaInfo.VideoCodec;
|
||||
break;
|
||||
}
|
||||
|
||||
string audioCodec;
|
||||
switch (episodeFile.MediaInfo.AudioFormat)
|
||||
{
|
||||
case "AC-3":
|
||||
audioCodec = "AC3";
|
||||
break;
|
||||
|
||||
case "E-AC-3":
|
||||
audioCodec = "EAC3";
|
||||
break;
|
||||
|
||||
case "MPEG Audio":
|
||||
if (episodeFile.MediaInfo.AudioProfile == "Layer 3")
|
||||
{
|
||||
audioCodec = "MP3";
|
||||
}
|
||||
else
|
||||
{
|
||||
audioCodec = episodeFile.MediaInfo.AudioFormat;
|
||||
}
|
||||
break;
|
||||
|
||||
case "DTS":
|
||||
audioCodec = episodeFile.MediaInfo.AudioFormat;
|
||||
break;
|
||||
|
||||
default:
|
||||
audioCodec = episodeFile.MediaInfo.AudioFormat;
|
||||
break;
|
||||
}
|
||||
|
||||
var mediaInfoAudioLanguages = GetLanguagesToken(episodeFile.MediaInfo.AudioLanguages);
|
||||
if (!mediaInfoAudioLanguages.IsNullOrWhiteSpace())
|
||||
{
|
||||
mediaInfoAudioLanguages = string.Format("[{0}]", mediaInfoAudioLanguages);
|
||||
}
|
||||
|
||||
if (mediaInfoAudioLanguages == "[EN]")
|
||||
{
|
||||
mediaInfoAudioLanguages = string.Empty;
|
||||
}
|
||||
|
||||
var mediaInfoSubtitleLanguages = GetLanguagesToken(episodeFile.MediaInfo.Subtitles);
|
||||
if (!mediaInfoSubtitleLanguages.IsNullOrWhiteSpace())
|
||||
{
|
||||
mediaInfoSubtitleLanguages = string.Format("[{0}]", mediaInfoSubtitleLanguages);
|
||||
}
|
||||
|
||||
var videoBitDepth = episodeFile.MediaInfo.VideoBitDepth > 0 ? episodeFile.MediaInfo.VideoBitDepth.ToString() : string.Empty;
|
||||
var audioChannels = episodeFile.MediaInfo.FormattedAudioChannels > 0 ?
|
||||
episodeFile.MediaInfo.FormattedAudioChannels.ToString("F1", CultureInfo.InvariantCulture) :
|
||||
string.Empty;
|
||||
|
||||
tokenHandlers["{MediaInfo Video}"] = m => videoCodec;
|
||||
tokenHandlers["{MediaInfo VideoCodec}"] = m => videoCodec;
|
||||
tokenHandlers["{MediaInfo VideoBitDepth}"] = m => videoBitDepth;
|
||||
|
||||
tokenHandlers["{MediaInfo Audio}"] = m => audioCodec;
|
||||
tokenHandlers["{MediaInfo AudioCodec}"] = m => audioCodec;
|
||||
tokenHandlers["{MediaInfo AudioChannels}"] = m => audioChannels;
|
||||
|
||||
tokenHandlers["{MediaInfo Simple}"] = m => string.Format("{0} {1}", videoCodec, audioCodec);
|
||||
|
||||
tokenHandlers["{MediaInfo Full}"] = m => string.Format("{0} {1}{2} {3}", videoCodec, audioCodec, mediaInfoAudioLanguages, mediaInfoSubtitleLanguages);
|
||||
}
|
||||
|
||||
private void AddMediaInfoTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, MovieFile movieFile)
|
||||
{
|
||||
if (movieFile.MediaInfo == null) return;
|
||||
@@ -964,48 +567,6 @@ namespace NzbDrone.Core.Organizer
|
||||
return replacementText;
|
||||
}
|
||||
|
||||
private string FormatNumberTokens(string basePattern, string formatPattern, List<Episode> episodes)
|
||||
{
|
||||
var pattern = string.Empty;
|
||||
|
||||
for (int i = 0; i < episodes.Count; i++)
|
||||
{
|
||||
var patternToReplace = i == 0 ? basePattern : formatPattern;
|
||||
|
||||
pattern += EpisodeRegex.Replace(patternToReplace, match => ReplaceNumberToken(match.Groups["episode"].Value, episodes[i].EpisodeNumber));
|
||||
}
|
||||
|
||||
return ReplaceSeasonTokens(pattern, episodes.First().SeasonNumber);
|
||||
}
|
||||
|
||||
private string FormatAbsoluteNumberTokens(string basePattern, string formatPattern, List<Episode> episodes)
|
||||
{
|
||||
var pattern = string.Empty;
|
||||
|
||||
for (int i = 0; i < episodes.Count; i++)
|
||||
{
|
||||
var patternToReplace = i == 0 ? basePattern : formatPattern;
|
||||
|
||||
pattern += AbsoluteEpisodeRegex.Replace(patternToReplace, match => ReplaceNumberToken(match.Groups["absolute"].Value, episodes[i].AbsoluteEpisodeNumber.Value));
|
||||
}
|
||||
|
||||
return ReplaceSeasonTokens(pattern, episodes.First().SeasonNumber);
|
||||
}
|
||||
|
||||
private string FormatRangeNumberTokens(string seasonEpisodePattern, string formatPattern, List<Episode> episodes)
|
||||
{
|
||||
var eps = new List<Episode> { episodes.First() };
|
||||
|
||||
if (episodes.Count > 1) eps.Add(episodes.Last());
|
||||
|
||||
return FormatNumberTokens(seasonEpisodePattern, formatPattern, eps);
|
||||
}
|
||||
|
||||
private string ReplaceSeasonTokens(string pattern, int seasonNumber)
|
||||
{
|
||||
return SeasonRegex.Replace(pattern, match => ReplaceNumberToken(match.Groups["season"].Value, seasonNumber));
|
||||
}
|
||||
|
||||
private string ReplaceNumberToken(string token, int value)
|
||||
{
|
||||
var split = token.Trim('{', '}').Split(':');
|
||||
@@ -1026,46 +587,6 @@ namespace NzbDrone.Core.Organizer
|
||||
}).ToArray());
|
||||
}
|
||||
|
||||
private AbsoluteEpisodeFormat[] GetAbsoluteFormat(string pattern)
|
||||
{
|
||||
return _absoluteEpisodeFormatCache.Get(pattern, () => AbsoluteEpisodePatternRegex.Matches(pattern).OfType<Match>()
|
||||
.Select(match => new AbsoluteEpisodeFormat
|
||||
{
|
||||
Separator = match.Groups["separator"].Value.IsNotNullOrWhiteSpace() ? match.Groups["separator"].Value : "-",
|
||||
AbsoluteEpisodePattern = match.Groups["absolute"].Value
|
||||
}).ToArray());
|
||||
}
|
||||
|
||||
private string GetEpisodeTitle(List<Episode> episodes, string separator)
|
||||
{
|
||||
separator = string.Format(" {0} ", separator.Trim());
|
||||
|
||||
if (episodes.Count == 1)
|
||||
{
|
||||
return episodes.First().Title.TrimEnd(EpisodeTitleTrimCharacters);
|
||||
}
|
||||
|
||||
var titles = episodes.Select(c => c.Title.TrimEnd(EpisodeTitleTrimCharacters))
|
||||
.Select(CleanupEpisodeTitle)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
if (titles.All(t => t.IsNullOrWhiteSpace()))
|
||||
{
|
||||
titles = episodes.Select(c => c.Title.TrimEnd(EpisodeTitleTrimCharacters))
|
||||
.Distinct()
|
||||
.ToList();
|
||||
}
|
||||
|
||||
return string.Join(separator, titles);
|
||||
}
|
||||
|
||||
private string CleanupEpisodeTitle(string title)
|
||||
{
|
||||
//this will remove (1),(2) from the end of multi part episodes.
|
||||
return MultiPartCleanupRegex.Replace(title, string.Empty).Trim();
|
||||
}
|
||||
|
||||
private string GetQualityProper(Movie movie, QualityModel quality)
|
||||
{
|
||||
if (quality.Revision.Version > 1)
|
||||
@@ -1076,31 +597,6 @@ namespace NzbDrone.Core.Organizer
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
private string GetQualityProper(Series series, QualityModel quality)
|
||||
{
|
||||
if (quality.Revision.Version > 1)
|
||||
{
|
||||
if (series.SeriesType == SeriesTypes.Anime)
|
||||
{
|
||||
return "v" + quality.Revision.Version;
|
||||
}
|
||||
|
||||
return "Proper";
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
private string GetQualityReal(Series series, QualityModel quality)
|
||||
{
|
||||
if (quality.Revision.Real > 0)
|
||||
{
|
||||
return "REAL";
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private string GetQualityReal(Movie movie, QualityModel quality)
|
||||
{
|
||||
if (quality.Revision.Real > 0)
|
||||
@@ -1111,26 +607,6 @@ namespace NzbDrone.Core.Organizer
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private string GetOriginalTitle(EpisodeFile episodeFile)
|
||||
{
|
||||
if (episodeFile.SceneName.IsNullOrWhiteSpace())
|
||||
{
|
||||
return GetOriginalFileName(episodeFile);
|
||||
}
|
||||
|
||||
return episodeFile.SceneName;
|
||||
}
|
||||
|
||||
private string GetOriginalFileName(EpisodeFile episodeFile)
|
||||
{
|
||||
if (episodeFile.RelativePath.IsNullOrWhiteSpace())
|
||||
{
|
||||
return Path.GetFileNameWithoutExtension(episodeFile.Path);
|
||||
}
|
||||
|
||||
return Path.GetFileNameWithoutExtension(episodeFile.RelativePath);
|
||||
}
|
||||
|
||||
private string GetOriginalTitle(MovieFile episodeFile)
|
||||
{
|
||||
if (episodeFile.SceneName.IsNullOrWhiteSpace())
|
||||
@@ -1183,4 +659,4 @@ namespace NzbDrone.Core.Organizer
|
||||
Range = 4,
|
||||
PrefixedRange = 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user