mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
1st pass at Movie Naming
Parser is failing on the sample
This commit is contained in:
@@ -24,7 +24,7 @@ namespace NzbDrone.Core.Organizer
|
||||
BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec);
|
||||
string GetSeriesFolder(Series series, NamingConfig namingConfig = null);
|
||||
string GetSeasonFolder(Series series, int seasonNumber, NamingConfig namingConfig = null);
|
||||
string GetMovieFolder(Movie movie);
|
||||
string GetMovieFolder(Movie movie, NamingConfig namingConfig = null);
|
||||
}
|
||||
|
||||
public class FileNameBuilder : IBuildFileNames
|
||||
@@ -79,6 +79,7 @@ namespace NzbDrone.Core.Organizer
|
||||
{
|
||||
_namingConfigService = namingConfigService;
|
||||
_qualityDefinitionService = qualityDefinitionService;
|
||||
//_movieFormatCache = cacheManager.GetCache<MovieFormat>(GetType(), "movieFormat");
|
||||
_episodeFormatCache = cacheManager.GetCache<EpisodeFormat[]>(GetType(), "episodeFormat");
|
||||
_absoluteEpisodeFormatCache = cacheManager.GetCache<AbsoluteEpisodeFormat[]>(GetType(), "absoluteEpisodeFormat");
|
||||
_logger = logger;
|
||||
@@ -154,52 +155,20 @@ namespace NzbDrone.Core.Organizer
|
||||
return GetOriginalTitle(movieFile);
|
||||
}
|
||||
|
||||
/*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;
|
||||
//TODO: Update namingConfig for Movies!
|
||||
var pattern = namingConfig.StandardMovieFormat;
|
||||
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);
|
||||
AddMovieTokens(tokenHandlers, movie);
|
||||
//AddReleaseDateTokens(tokenHandlers, movie.Year); //In case we want to separate the year
|
||||
AddQualityTokens(tokenHandlers, movie, movieFile);
|
||||
AddMediaInfoTokens(tokenHandlers, movieFile);
|
||||
|
||||
var fileName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim();
|
||||
fileName = FileNameCleanupRegex.Replace(fileName, match => match.Captures[0].Value[0].ToString());
|
||||
fileName = TrimSeparatorsRegex.Replace(fileName, string.Empty);*/
|
||||
fileName = TrimSeparatorsRegex.Replace(fileName, string.Empty);
|
||||
|
||||
//TODO: Update namingConfig for Movies!
|
||||
|
||||
return GetOriginalTitle(movieFile);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public string BuildFilePath(Series series, int seasonNumber, string fileName, string extension)
|
||||
@@ -318,9 +287,18 @@ namespace NzbDrone.Core.Organizer
|
||||
return CleanFolderName(ReplaceTokens(namingConfig.SeasonFolderFormat, tokenHandlers, namingConfig));
|
||||
}
|
||||
|
||||
public string GetMovieFolder(Movie movie)
|
||||
public string GetMovieFolder(Movie movie, NamingConfig namingConfig = null)
|
||||
{
|
||||
return CleanFolderName(movie.Title);
|
||||
if(namingConfig == null)
|
||||
{
|
||||
namingConfig = _namingConfigService.GetConfig();
|
||||
}
|
||||
|
||||
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
|
||||
|
||||
AddMovieTokens(tokenHandlers, movie);
|
||||
|
||||
return CleanFolderName(ReplaceTokens(namingConfig.MovieFolderFormat, tokenHandlers, namingConfig));
|
||||
}
|
||||
|
||||
public static string CleanTitle(string title)
|
||||
@@ -484,6 +462,17 @@ namespace NzbDrone.Core.Organizer
|
||||
return pattern;
|
||||
}
|
||||
|
||||
private void AddMovieTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Movie movie)
|
||||
{
|
||||
tokenHandlers["{Movie Title}"] = m => movie.Title;
|
||||
tokenHandlers["{Movie CleanTitle}"] = m => CleanTitle(movie.Title);
|
||||
}
|
||||
|
||||
private void AddReleaseDateTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, int releaseYear)
|
||||
{
|
||||
tokenHandlers["{Release Year}"] = m => string.Format("({0})", releaseYear.ToString()); //Do I need m.CustomFormat?
|
||||
}
|
||||
|
||||
private void AddSeasonTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, int seasonNumber)
|
||||
{
|
||||
tokenHandlers["{Season}"] = m => seasonNumber.ToString(m.CustomFormat);
|
||||
@@ -523,6 +512,18 @@ namespace NzbDrone.Core.Organizer
|
||||
tokenHandlers["{Quality Real}"] = m => qualityReal;
|
||||
}
|
||||
|
||||
private void AddQualityTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Movie movie, MovieFile movieFile)
|
||||
{
|
||||
var qualityTitle = _qualityDefinitionService.Get(movieFile.Quality.Quality).Title;
|
||||
var qualityProper = GetQualityProper(movie, movieFile.Quality);
|
||||
var qualityReal = GetQualityReal(movie, movieFile.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 AddMediaInfoTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, EpisodeFile episodeFile)
|
||||
{
|
||||
if (episodeFile.MediaInfo == null) return;
|
||||
@@ -627,6 +628,110 @@ namespace NzbDrone.Core.Organizer
|
||||
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;
|
||||
|
||||
string videoCodec;
|
||||
switch (movieFile.MediaInfo.VideoCodec)
|
||||
{
|
||||
case "AVC":
|
||||
if (movieFile.SceneName.IsNotNullOrWhiteSpace() && Path.GetFileNameWithoutExtension(movieFile.SceneName).Contains("h264"))
|
||||
{
|
||||
videoCodec = "h264";
|
||||
}
|
||||
else
|
||||
{
|
||||
videoCodec = "x264";
|
||||
}
|
||||
break;
|
||||
|
||||
case "V_MPEGH/ISO/HEVC":
|
||||
if (movieFile.SceneName.IsNotNullOrWhiteSpace() && Path.GetFileNameWithoutExtension(movieFile.SceneName).Contains("h265"))
|
||||
{
|
||||
videoCodec = "h265";
|
||||
}
|
||||
else
|
||||
{
|
||||
videoCodec = "x265";
|
||||
}
|
||||
break;
|
||||
|
||||
case "MPEG-2 Video":
|
||||
videoCodec = "MPEG2";
|
||||
break;
|
||||
|
||||
default:
|
||||
videoCodec = movieFile.MediaInfo.VideoCodec;
|
||||
break;
|
||||
}
|
||||
|
||||
string audioCodec;
|
||||
switch (movieFile.MediaInfo.AudioFormat)
|
||||
{
|
||||
case "AC-3":
|
||||
audioCodec = "AC3";
|
||||
break;
|
||||
|
||||
case "E-AC-3":
|
||||
audioCodec = "EAC3";
|
||||
break;
|
||||
|
||||
case "MPEG Audio":
|
||||
if (movieFile.MediaInfo.AudioProfile == "Layer 3")
|
||||
{
|
||||
audioCodec = "MP3";
|
||||
}
|
||||
else
|
||||
{
|
||||
audioCodec = movieFile.MediaInfo.AudioFormat;
|
||||
}
|
||||
break;
|
||||
|
||||
case "DTS":
|
||||
audioCodec = movieFile.MediaInfo.AudioFormat;
|
||||
break;
|
||||
|
||||
default:
|
||||
audioCodec = movieFile.MediaInfo.AudioFormat;
|
||||
break;
|
||||
}
|
||||
|
||||
var mediaInfoAudioLanguages = GetLanguagesToken(movieFile.MediaInfo.AudioLanguages);
|
||||
if (!mediaInfoAudioLanguages.IsNullOrWhiteSpace())
|
||||
{
|
||||
mediaInfoAudioLanguages = string.Format("[{0}]", mediaInfoAudioLanguages);
|
||||
}
|
||||
|
||||
if (mediaInfoAudioLanguages == "[EN]")
|
||||
{
|
||||
mediaInfoAudioLanguages = string.Empty;
|
||||
}
|
||||
|
||||
var mediaInfoSubtitleLanguages = GetLanguagesToken(movieFile.MediaInfo.Subtitles);
|
||||
if (!mediaInfoSubtitleLanguages.IsNullOrWhiteSpace())
|
||||
{
|
||||
mediaInfoSubtitleLanguages = string.Format("[{0}]", mediaInfoSubtitleLanguages);
|
||||
}
|
||||
|
||||
var videoBitDepth = movieFile.MediaInfo.VideoBitDepth > 0 ? movieFile.MediaInfo.VideoBitDepth.ToString() : string.Empty;
|
||||
var audioChannels = movieFile.MediaInfo.FormattedAudioChannels > 0 ?
|
||||
movieFile.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 string GetLanguagesToken(string mediaInfoLanguages)
|
||||
{
|
||||
List<string> tokens = new List<string>();
|
||||
@@ -806,6 +911,16 @@ namespace NzbDrone.Core.Organizer
|
||||
return MultiPartCleanupRegex.Replace(title, string.Empty).Trim();
|
||||
}
|
||||
|
||||
private string GetQualityProper(Movie movie, QualityModel quality)
|
||||
{
|
||||
if (quality.Revision.Version > 1)
|
||||
{
|
||||
return "Proper";
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
private string GetQualityProper(Series series, QualityModel quality)
|
||||
{
|
||||
if (quality.Revision.Version > 1)
|
||||
@@ -831,6 +946,16 @@ namespace NzbDrone.Core.Organizer
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private string GetQualityReal(Movie movie, QualityModel quality)
|
||||
{
|
||||
if (quality.Revision.Real > 0)
|
||||
{
|
||||
return "REAL";
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private string GetOriginalTitle(EpisodeFile episodeFile)
|
||||
{
|
||||
if (episodeFile.SceneName.IsNullOrWhiteSpace())
|
||||
|
Reference in New Issue
Block a user