Merge branch 'rename-existing-folder' into develop

Tim Turner 8 years ago
commit a340bc4da3

@ -64,6 +64,11 @@ namespace NzbDrone.Common.Extensions
return childPath.Substring(parentPath.Length).Trim(Path.DirectorySeparatorChar); return childPath.Substring(parentPath.Length).Trim(Path.DirectorySeparatorChar);
} }
public static string GetRelativePathWithoutChildCheck(this string parentPath, string childPath)
{
return childPath.Substring(parentPath.Length).Trim(Path.DirectorySeparatorChar);
}
public static string GetParentPath(this string childPath) public static string GetParentPath(this string childPath)
{ {
var parentPath = childPath.TrimEnd('\\', '/'); var parentPath = childPath.TrimEnd('\\', '/');

@ -123,6 +123,17 @@ namespace NzbDrone.Core.Extras
// } // }
//} //}
// TODO
public void Handle(MovieFolderCreatedEvent message)
{
var movie = message.Movie;
foreach(var extraFileManager in _extraFileManagers)
{
//extraFileManager.CreateAfterMovieImport(movie, message.MovieFolder);
}
}
public void Handle(EpisodeFolderCreatedEvent message) public void Handle(EpisodeFolderCreatedEvent message)
{ {
var series = message.Series; var series = message.Series;

@ -116,6 +116,12 @@ namespace NzbDrone.Core.MediaFiles
_diskTransferService.TransferFile(movieFilePath, destinationFilePath, mode); _diskTransferService.TransferFile(movieFilePath, destinationFilePath, mode);
var oldMoviePath = new OsPath(movieFilePath).Directory.FullPath.TrimEnd(Path.DirectorySeparatorChar);
var newMoviePath = new OsPath(destinationFilePath).Directory.FullPath.TrimEnd(Path.DirectorySeparatorChar);
movie.Path = newMoviePath;
movieFile.RelativePath = movie.Path.GetRelativePath(destinationFilePath); movieFile.RelativePath = movie.Path.GetRelativePath(destinationFilePath);
_updateMovieFileService.ChangeFileDateForFile(movieFile, movie); _updateMovieFileService.ChangeFileDateForFile(movieFile, movie);
@ -132,6 +138,8 @@ namespace NzbDrone.Core.MediaFiles
_mediaFileAttributeService.SetFilePermissions(destinationFilePath); _mediaFileAttributeService.SetFilePermissions(destinationFilePath);
_diskProvider.DeleteFolder(oldMoviePath, true);
return movieFile; return movieFile;
} }
@ -144,6 +152,7 @@ namespace NzbDrone.Core.MediaFiles
{ {
var movieFolder = Path.GetDirectoryName(filePath); var movieFolder = Path.GetDirectoryName(filePath);
var rootFolder = new OsPath(movieFolder).Directory.FullPath; var rootFolder = new OsPath(movieFolder).Directory.FullPath;
var fileName = Path.GetFileName(filePath);
if (!_diskProvider.FolderExists(rootFolder)) if (!_diskProvider.FolderExists(rootFolder))
{ {
@ -156,7 +165,7 @@ namespace NzbDrone.Core.MediaFiles
if (!_diskProvider.FolderExists(movieFolder)) if (!_diskProvider.FolderExists(movieFolder))
{ {
CreateFolder(movieFolder); CreateFolder(movieFolder);
newEvent.SeriesFolder = movieFolder; newEvent.MovieFolder = movieFolder;
changed = true; changed = true;
} }

@ -71,8 +71,9 @@ namespace NzbDrone.Core.MediaFiles
{ {
MovieId = movie.Id, MovieId = movie.Id,
MovieFileId = file.Id, MovieFileId = file.Id,
ExistingPath = file.RelativePath, ExistingPath = movieFilePath,
NewPath = movie.Path.GetRelativePath(newPath) //NewPath = movie.Path.GetRelativePath(newPath)
NewPath = newPath
}; };
} }
@ -94,6 +95,7 @@ namespace NzbDrone.Core.MediaFiles
_movieFileMover.MoveMovieFile(movieFile, movie); _movieFileMover.MoveMovieFile(movieFile, movie);
_mediaFileService.Update(movieFile); _mediaFileService.Update(movieFile);
_movieService.UpdateMovie(movie);
renamed.Add(movieFile); renamed.Add(movieFile);
_logger.Debug("Renamed movie file: {0}", movieFile); _logger.Debug("Renamed movie file: {0}", movieFile);
@ -122,7 +124,7 @@ namespace NzbDrone.Core.MediaFiles
public void Execute(RenameMovieCommand message) public void Execute(RenameMovieCommand message)
{ {
_logger.Debug("Renaming all files for selected movie"); _logger.Debug("Renaming all files for selected movies");
var moviesToRename = _movieService.GetMovies(message.MovieIds); var moviesToRename = _movieService.GetMovies(message.MovieIds);
foreach(var movie in moviesToRename) foreach(var movie in moviesToRename)

@ -210,7 +210,7 @@ namespace NzbDrone.Core.Notifications
public void Handle(MovieDownloadedEvent message) public void Handle(MovieDownloadedEvent message)
{ {
var downloadMessage = new DownloadMessage(); var downloadMessage = new DownloadMessage();
downloadMessage.Message = GetMessage(message.Movie.Movie, message.Movie.Quality); downloadMessage.Message = GetMessage(message.Movie.Movie, message.Movie.Quality);
downloadMessage.Series = null; downloadMessage.Series = null;
downloadMessage.EpisodeFile = null; downloadMessage.EpisodeFile = null;
downloadMessage.MovieFile = message.MovieFile; downloadMessage.MovieFile = message.MovieFile;

@ -17,7 +17,7 @@ namespace NzbDrone.Core.Notifications.Plex
public interface IPlexServerProxy public interface IPlexServerProxy
{ {
List<PlexSection> GetTvSections(PlexServerSettings settings); List<PlexSection> GetTvSections(PlexServerSettings settings);
List<PlexSection> GetMovieSections(PlexServerSettings settings); List<PlexSection> GetMovieSections(PlexServerSettings settings);
void Update(int sectionId, PlexServerSettings settings); void Update(int sectionId, PlexServerSettings settings);
void UpdateSeries(int metadataId, PlexServerSettings settings); void UpdateSeries(int metadataId, PlexServerSettings settings);
string Version(PlexServerSettings settings); string Version(PlexServerSettings settings);
@ -81,12 +81,12 @@ namespace NzbDrone.Core.Notifications.Plex
return Json.Deserialize<PlexMediaContainerLegacy>(response.Content) return Json.Deserialize<PlexMediaContainerLegacy>(response.Content)
.Sections .Sections
.Where(d => d.Type == "movie") .Where(d => d.Type == "movie")
.Select(s => new PlexSection .Select(s => new PlexSection
{ {
Id = s.Id, Id = s.Id,
Language = s.Language, Language = s.Language,
Locations = s.Locations, Locations = s.Locations,
Type = s.Type Type = s.Type
}) })
.ToList(); .ToList();
} }

@ -86,8 +86,8 @@ namespace NzbDrone.Core.Notifications.Slack
}; };
NotifySlack(payload); NotifySlack(payload);
} }
public override void OnRename(Series series) public override void OnRename(Series series)
{ {
var payload = new SlackPayload var payload = new SlackPayload

@ -1,324 +1,349 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using NLog; using NLog;
using NzbDrone.Common.Cache; using NzbDrone.Common.Cache;
using NzbDrone.Common.EnsureThat; using NzbDrone.Common.EnsureThat;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Organizer namespace NzbDrone.Core.Organizer
{ {
public interface IBuildFileNames public interface IBuildFileNames
{ {
string BuildFileName(List<Episode> episodes, Series series, EpisodeFile episodeFile, NamingConfig namingConfig = null); string BuildFileName(List<Episode> episodes, Series series, EpisodeFile episodeFile, NamingConfig namingConfig = null);
string BuildFileName(Movie movie, MovieFile movieFile, NamingConfig namingConfig = null); string BuildFileName(Movie movie, MovieFile movieFile, NamingConfig namingConfig = null);
string BuildFilePath(Movie movie, string fileName, string extension); string BuildFilePath(Movie movie, string fileName, string extension);
string BuildFilePath(Series series, int seasonNumber, string fileName, string extension); string BuildFilePath(Series series, int seasonNumber, string fileName, string extension);
string BuildSeasonPath(Series series, int seasonNumber); string BuildSeasonPath(Series series, int seasonNumber);
BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec); BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec);
string GetSeriesFolder(Series series, NamingConfig namingConfig = null); string GetSeriesFolder(Series series, NamingConfig namingConfig = null);
string GetSeasonFolder(Series series, int seasonNumber, NamingConfig namingConfig = null); string GetSeasonFolder(Series series, int seasonNumber, NamingConfig namingConfig = null);
string GetMovieFolder(Movie movie, NamingConfig namingConfig = null); string GetMovieFolder(Movie movie, NamingConfig namingConfig = null);
} }
public class FileNameBuilder : IBuildFileNames public class FileNameBuilder : IBuildFileNames
{ {
private readonly INamingConfigService _namingConfigService; private readonly INamingConfigService _namingConfigService;
private readonly IQualityDefinitionService _qualityDefinitionService; private readonly IQualityDefinitionService _qualityDefinitionService;
private readonly ICached<EpisodeFormat[]> _episodeFormatCache; private readonly ICached<EpisodeFormat[]> _episodeFormatCache;
private readonly ICached<AbsoluteEpisodeFormat[]> _absoluteEpisodeFormatCache; private readonly ICached<AbsoluteEpisodeFormat[]> _absoluteEpisodeFormatCache;
private readonly Logger _logger; private readonly Logger _logger;
private static readonly Regex TitleRegex = new Regex(@"\{(?<prefix>[- ._\[(]*)(?<token>(?:[a-z0-9]+)(?:(?<separator>[- ._]+)(?:[a-z0-9]+))?)(?::(?<customFormat>[a-z0-9]+))?(?<suffix>[- ._)\]]*)\}", private static readonly Regex TitleRegex = new Regex(@"\{(?<prefix>[- ._\[(]*)(?<token>(?:[a-z0-9]+)(?:(?<separator>[- ._]+)(?:[a-z0-9]+))?)(?::(?<customFormat>[a-z0-9]+))?(?<suffix>[- ._)\]]*)\}",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex EpisodeRegex = new Regex(@"(?<episode>\{episode(?:\:0+)?})", private static readonly Regex EpisodeRegex = new Regex(@"(?<episode>\{episode(?:\:0+)?})",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex TagsRegex = new Regex(@"(?<tags>\{tags(?:\:0+)?})", private static readonly Regex TagsRegex = new Regex(@"(?<tags>\{tags(?:\:0+)?})",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex SeasonRegex = new Regex(@"(?<season>\{season(?:\:0+)?})", private static readonly Regex SeasonRegex = new Regex(@"(?<season>\{season(?:\:0+)?})",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex AbsoluteEpisodeRegex = new Regex(@"(?<absolute>\{absolute(?:\:0+)?})", private static readonly Regex AbsoluteEpisodeRegex = new Regex(@"(?<absolute>\{absolute(?:\:0+)?})",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static readonly Regex SeasonEpisodePatternRegex = new Regex(@"(?<separator>(?<=})[- ._]+?)?(?<seasonEpisode>s?{season(?:\:0+)?}(?<episodeSeparator>[- ._]?[ex])(?<episode>{episode(?:\:0+)?}))(?<separator>[- ._]+?(?={))?", public static readonly Regex SeasonEpisodePatternRegex = new Regex(@"(?<separator>(?<=})[- ._]+?)?(?<seasonEpisode>s?{season(?:\:0+)?}(?<episodeSeparator>[- ._]?[ex])(?<episode>{episode(?:\:0+)?}))(?<separator>[- ._]+?(?={))?",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static readonly Regex AbsoluteEpisodePatternRegex = new Regex(@"(?<separator>(?<=})[- ._]+?)?(?<absolute>{absolute(?:\:0+)?})(?<separator>[- ._]+?(?={))?", public static readonly Regex AbsoluteEpisodePatternRegex = new Regex(@"(?<separator>(?<=})[- ._]+?)?(?<absolute>{absolute(?:\:0+)?})(?<separator>[- ._]+?(?={))?",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static readonly Regex AirDateRegex = new Regex(@"\{Air(\s|\W|_)Date\}", RegexOptions.Compiled | RegexOptions.IgnoreCase); public static readonly Regex AirDateRegex = new Regex(@"\{Air(\s|\W|_)Date\}", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static readonly Regex SeriesTitleRegex = new Regex(@"(?<token>\{(?:Series)(?<separator>[- ._])(Clean)?Title\})", public static readonly Regex SeriesTitleRegex = new Regex(@"(?<token>\{(?:Series)(?<separator>[- ._])(Clean)?Title\})",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static readonly Regex MovieTitleRegex = new Regex(@"(?<token>\{((?:(Movie|Original))(?<separator>[- ._])(Clean)?Title(The)?)\})", public static readonly Regex MovieTitleRegex = new Regex(@"(?<token>\{((?:(Movie|Original))(?<separator>[- ._])(Clean)?Title(The)?)\})",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex FileNameCleanupRegex = new Regex(@"([- ._])(\1)+", RegexOptions.Compiled); private static readonly Regex FileNameCleanupRegex = new Regex(@"([- ._])(\1)+", RegexOptions.Compiled);
private static readonly Regex TrimSeparatorsRegex = new Regex(@"[- ._]$", RegexOptions.Compiled); private static readonly Regex TrimSeparatorsRegex = new Regex(@"[- ._]$", RegexOptions.Compiled);
private static readonly Regex ScenifyRemoveChars = new Regex(@"(?<=\s)(,|<|>|\/|\\|;|:|'|""|\||`|~|!|\?|@|$|%|^|\*|-|_|=){1}(?=\s)|('|:|\?|,)(?=(?:(?:s|m)\s)|\s|$)|(\(|\)|\[|\]|\{|\})", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex ScenifyRemoveChars = new Regex(@"(?<=\s)(,|<|>|\/|\\|;|:|'|""|\||`|~|!|\?|@|$|%|^|\*|-|_|=){1}(?=\s)|('|:|\?|,)(?=(?:(?:s|m)\s)|\s|$)|(\(|\)|\[|\]|\{|\})", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex ScenifyReplaceChars = new Regex(@"[\/]", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex ScenifyReplaceChars = new Regex(@"[\/]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
//TODO: Support Written numbers (One, Two, etc) and Roman Numerals (I, II, III etc) //TODO: Support Written numbers (One, Two, etc) and Roman Numerals (I, II, III etc)
private static readonly Regex MultiPartCleanupRegex = new Regex(@"(?:\(\d+\)|(Part|Pt\.?)\s?\d+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex MultiPartCleanupRegex = new Regex(@"(?:\(\d+\)|(Part|Pt\.?)\s?\d+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly char[] EpisodeTitleTrimCharacters = new[] { ' ', '.', '?' }; private static readonly char[] EpisodeTitleTrimCharacters = new[] { ' ', '.', '?' };
public FileNameBuilder(INamingConfigService namingConfigService, public FileNameBuilder(INamingConfigService namingConfigService,
IQualityDefinitionService qualityDefinitionService, IQualityDefinitionService qualityDefinitionService,
ICacheManager cacheManager, ICacheManager cacheManager,
Logger logger) Logger logger)
{ {
_namingConfigService = namingConfigService; _namingConfigService = namingConfigService;
_qualityDefinitionService = qualityDefinitionService; _qualityDefinitionService = qualityDefinitionService;
//_movieFormatCache = cacheManager.GetCache<MovieFormat>(GetType(), "movieFormat"); //_movieFormatCache = cacheManager.GetCache<MovieFormat>(GetType(), "movieFormat");
_episodeFormatCache = cacheManager.GetCache<EpisodeFormat[]>(GetType(), "episodeFormat"); _episodeFormatCache = cacheManager.GetCache<EpisodeFormat[]>(GetType(), "episodeFormat");
_absoluteEpisodeFormatCache = cacheManager.GetCache<AbsoluteEpisodeFormat[]>(GetType(), "absoluteEpisodeFormat"); _absoluteEpisodeFormatCache = cacheManager.GetCache<AbsoluteEpisodeFormat[]>(GetType(), "absoluteEpisodeFormat");
_logger = logger; _logger = logger;
} }
public string BuildFileName(List<Episode> episodes, Series series, EpisodeFile episodeFile, NamingConfig namingConfig = null) public string BuildFileName(List<Episode> episodes, Series series, EpisodeFile episodeFile, NamingConfig namingConfig = null)
{ {
if (namingConfig == null) if (namingConfig == null)
{ {
namingConfig = _namingConfigService.GetConfig(); namingConfig = _namingConfigService.GetConfig();
} }
if (!namingConfig.RenameEpisodes) if (!namingConfig.RenameEpisodes)
{ {
return GetOriginalTitle(episodeFile); return GetOriginalTitle(episodeFile);
} }
if (namingConfig.StandardEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Standard) if (namingConfig.StandardEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Standard)
{ {
throw new NamingFormatException("Standard episode format cannot be empty"); throw new NamingFormatException("Standard episode format cannot be empty");
} }
if (namingConfig.DailyEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Daily) if (namingConfig.DailyEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Daily)
{ {
throw new NamingFormatException("Daily episode format cannot be empty"); throw new NamingFormatException("Daily episode format cannot be empty");
} }
if (namingConfig.AnimeEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Anime) if (namingConfig.AnimeEpisodeFormat.IsNullOrWhiteSpace() && series.SeriesType == SeriesTypes.Anime)
{ {
throw new NamingFormatException("Anime episode format cannot be empty"); throw new NamingFormatException("Anime episode format cannot be empty");
} }
var pattern = namingConfig.StandardEpisodeFormat; var pattern = namingConfig.StandardEpisodeFormat;
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance); var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
episodes = episodes.OrderBy(e => e.SeasonNumber).ThenBy(e => e.EpisodeNumber).ToList(); episodes = episodes.OrderBy(e => e.SeasonNumber).ThenBy(e => e.EpisodeNumber).ToList();
if (series.SeriesType == SeriesTypes.Daily) if (series.SeriesType == SeriesTypes.Daily)
{ {
pattern = namingConfig.DailyEpisodeFormat; pattern = namingConfig.DailyEpisodeFormat;
} }
if (series.SeriesType == SeriesTypes.Anime && episodes.All(e => e.AbsoluteEpisodeNumber.HasValue)) if (series.SeriesType == SeriesTypes.Anime && episodes.All(e => e.AbsoluteEpisodeNumber.HasValue))
{ {
pattern = namingConfig.AnimeEpisodeFormat; pattern = namingConfig.AnimeEpisodeFormat;
} }
pattern = AddSeasonEpisodeNumberingTokens(pattern, tokenHandlers, episodes, namingConfig); pattern = AddSeasonEpisodeNumberingTokens(pattern, tokenHandlers, episodes, namingConfig);
pattern = AddAbsoluteNumberingTokens(pattern, tokenHandlers, series, episodes, namingConfig); pattern = AddAbsoluteNumberingTokens(pattern, tokenHandlers, series, episodes, namingConfig);
AddSeriesTokens(tokenHandlers, series); AddSeriesTokens(tokenHandlers, series);
AddEpisodeTokens(tokenHandlers, episodes); AddEpisodeTokens(tokenHandlers, episodes);
AddEpisodeFileTokens(tokenHandlers, episodeFile); AddEpisodeFileTokens(tokenHandlers, episodeFile);
AddQualityTokens(tokenHandlers, series, episodeFile); AddQualityTokens(tokenHandlers, series, episodeFile);
AddMediaInfoTokens(tokenHandlers, episodeFile); AddMediaInfoTokens(tokenHandlers, episodeFile);
var fileName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim(); var fileName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim();
fileName = FileNameCleanupRegex.Replace(fileName, match => match.Captures[0].Value[0].ToString()); fileName = FileNameCleanupRegex.Replace(fileName, match => match.Captures[0].Value[0].ToString());
fileName = TrimSeparatorsRegex.Replace(fileName, string.Empty); fileName = TrimSeparatorsRegex.Replace(fileName, string.Empty);
return fileName; return fileName;
} }
public string BuildFileName(Movie movie, MovieFile movieFile, NamingConfig namingConfig = null) public string BuildFileName(Movie movie, MovieFile movieFile, NamingConfig namingConfig = null)
{ {
if (namingConfig == null) if (namingConfig == null)
{ {
namingConfig = _namingConfigService.GetConfig(); namingConfig = _namingConfigService.GetConfig();
} }
if (!namingConfig.RenameEpisodes) if (!namingConfig.RenameEpisodes)
{ {
return GetOriginalTitle(movieFile); return GetOriginalTitle(movieFile);
} }
//TODO: Update namingConfig for Movies! var pattern = namingConfig.StandardMovieFormat;
var pattern = namingConfig.StandardMovieFormat; var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
AddMovieTokens(tokenHandlers, movie);
AddMovieTokens(tokenHandlers, movie); AddReleaseDateTokens(tokenHandlers, movie.Year);
AddReleaseDateTokens(tokenHandlers, movie.Year); //In case we want to separate the year AddImdbIdTokens(tokenHandlers, movie.ImdbId);
AddImdbIdTokens(tokenHandlers, movie.ImdbId); AddQualityTokens(tokenHandlers, movie, movieFile);
AddQualityTokens(tokenHandlers, movie, movieFile); AddMediaInfoTokens(tokenHandlers, movieFile);
AddMediaInfoTokens(tokenHandlers, movieFile); AddMovieFileTokens(tokenHandlers, movieFile);
AddMovieFileTokens(tokenHandlers, movieFile); AddTagsTokens(tokenHandlers, movieFile);
AddTagsTokens(tokenHandlers, movieFile);
var fileName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim();
var fileName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim(); fileName = FileNameCleanupRegex.Replace(fileName, match => match.Captures[0].Value[0].ToString());
fileName = FileNameCleanupRegex.Replace(fileName, match => match.Captures[0].Value[0].ToString()); fileName = TrimSeparatorsRegex.Replace(fileName, string.Empty);
fileName = TrimSeparatorsRegex.Replace(fileName, string.Empty);
return fileName;
return fileName; }
}
public string BuildFilePath(Series series, int seasonNumber, string fileName, string extension)
public string BuildFilePath(Series series, int seasonNumber, string fileName, string extension) {
{ Ensure.That(extension, () => extension).IsNotNullOrWhiteSpace();
Ensure.That(extension, () => extension).IsNotNullOrWhiteSpace();
var path = BuildSeasonPath(series, seasonNumber);
var path = BuildSeasonPath(series, seasonNumber);
return Path.Combine(path, fileName + extension);
return Path.Combine(path, fileName + extension); }
}
public string BuildFilePath(Movie movie, string fileName, string extension)
public string BuildFilePath(Movie movie, string fileName, string extension) {
Ensure.That(extension, () => extension).IsNotNullOrWhiteSpace();
var path = BuildMoviePath(movie);
return Path.Combine(path, fileName + extension);
}
public string BuildMoviePath(Movie movie)
{ {
Ensure.That(extension, () => extension).IsNotNullOrWhiteSpace();
var path = movie.Path; var path = movie.Path;
var directory = new DirectoryInfo(path).Name;
return Path.Combine(path, fileName + extension); var parentDirectoryPath = new DirectoryInfo(path).Parent.FullName;
} var namingConfig = _namingConfigService.GetConfig();
public string BuildSeasonPath(Series series, int seasonNumber) var movieFile = movie.MovieFile;
{
var path = series.Path; var pattern = namingConfig.MovieFolderFormat;
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
if (series.SeasonFolder)
{ AddMovieTokens(tokenHandlers, movie);
if (seasonNumber == 0) AddReleaseDateTokens(tokenHandlers, movie.Year);
{ AddImdbIdTokens(tokenHandlers, movie.ImdbId);
path = Path.Combine(path, "Specials"); AddQualityTokens(tokenHandlers, movie, movieFile);
} AddMediaInfoTokens(tokenHandlers, movieFile);
else AddMovieFileTokens(tokenHandlers, movieFile);
{
var seasonFolder = GetSeasonFolder(series, seasonNumber); var directoryName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim();
directoryName = FileNameCleanupRegex.Replace(directoryName, match => match.Captures[0].Value[0].ToString());
seasonFolder = CleanFileName(seasonFolder); directoryName = TrimSeparatorsRegex.Replace(directoryName, string.Empty);
path = Path.Combine(path, seasonFolder); return Path.Combine(parentDirectoryPath, directoryName);
} }
}
public string BuildSeasonPath(Series series, int seasonNumber)
return path; {
} var path = series.Path;
public BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec) if (series.SeasonFolder)
{ {
return new BasicNamingConfig(); //For now let's be lazy if (seasonNumber == 0)
{
var episodeFormat = GetEpisodeFormat(nameSpec.StandardEpisodeFormat).LastOrDefault(); path = Path.Combine(path, "Specials");
}
if (episodeFormat == null) else
{ {
return new BasicNamingConfig(); var seasonFolder = GetSeasonFolder(series, seasonNumber);
}
seasonFolder = CleanFileName(seasonFolder);
var basicNamingConfig = new BasicNamingConfig
{ path = Path.Combine(path, seasonFolder);
Separator = episodeFormat.Separator, }
NumberStyle = episodeFormat.SeasonEpisodePattern }
};
return path;
var titleTokens = TitleRegex.Matches(nameSpec.StandardEpisodeFormat); }
foreach (Match match in titleTokens) public BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec)
{ {
var separator = match.Groups["separator"].Value; return new BasicNamingConfig(); //For now let's be lazy
var token = match.Groups["token"].Value;
var episodeFormat = GetEpisodeFormat(nameSpec.StandardEpisodeFormat).LastOrDefault();
if (!separator.Equals(" "))
{ if (episodeFormat == null)
basicNamingConfig.ReplaceSpaces = true; {
} return new BasicNamingConfig();
}
if (token.StartsWith("{Series", StringComparison.InvariantCultureIgnoreCase))
{ var basicNamingConfig = new BasicNamingConfig
basicNamingConfig.IncludeSeriesTitle = true; {
} Separator = episodeFormat.Separator,
NumberStyle = episodeFormat.SeasonEpisodePattern
if (token.StartsWith("{Episode", StringComparison.InvariantCultureIgnoreCase)) };
{
basicNamingConfig.IncludeEpisodeTitle = true; var titleTokens = TitleRegex.Matches(nameSpec.StandardEpisodeFormat);
}
foreach (Match match in titleTokens)
if (token.StartsWith("{Quality", StringComparison.InvariantCultureIgnoreCase)) {
{ var separator = match.Groups["separator"].Value;
basicNamingConfig.IncludeQuality = true; var token = match.Groups["token"].Value;
}
} if (!separator.Equals(" "))
{
return basicNamingConfig; basicNamingConfig.ReplaceSpaces = true;
} }
public string GetSeriesFolder(Series series, NamingConfig namingConfig = null) if (token.StartsWith("{Series", StringComparison.InvariantCultureIgnoreCase))
{ {
if (namingConfig == null) basicNamingConfig.IncludeSeriesTitle = true;
{ }
namingConfig = _namingConfigService.GetConfig();
} if (token.StartsWith("{Episode", StringComparison.InvariantCultureIgnoreCase))
{
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance); basicNamingConfig.IncludeEpisodeTitle = true;
}
AddSeriesTokens(tokenHandlers, series);
if (token.StartsWith("{Quality", StringComparison.InvariantCultureIgnoreCase))
return CleanFolderName(ReplaceTokens(namingConfig.SeriesFolderFormat, tokenHandlers, namingConfig)); {
} basicNamingConfig.IncludeQuality = true;
}
public string GetSeasonFolder(Series series, int seasonNumber, NamingConfig namingConfig = null) }
{
if (namingConfig == null) return basicNamingConfig;
{ }
namingConfig = _namingConfigService.GetConfig();
} public string GetSeriesFolder(Series series, NamingConfig namingConfig = null)
{
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance); if (namingConfig == null)
{
AddSeriesTokens(tokenHandlers, series); namingConfig = _namingConfigService.GetConfig();
AddSeasonTokens(tokenHandlers, seasonNumber); }
return CleanFolderName(ReplaceTokens(namingConfig.SeasonFolderFormat, tokenHandlers, namingConfig)); var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
}
AddSeriesTokens(tokenHandlers, series);
public string GetMovieFolder(Movie movie, NamingConfig namingConfig = null)
{ return CleanFolderName(ReplaceTokens(namingConfig.SeriesFolderFormat, tokenHandlers, namingConfig));
if(namingConfig == null) }
{
namingConfig = _namingConfigService.GetConfig(); public string GetSeasonFolder(Series series, int seasonNumber, NamingConfig namingConfig = null)
} {
if (namingConfig == null)
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance); {
namingConfig = _namingConfigService.GetConfig();
AddMovieTokens(tokenHandlers, movie); }
AddReleaseDateTokens(tokenHandlers, movie.Year);
AddImdbIdTokens(tokenHandlers, movie.ImdbId); var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
return CleanFolderName(ReplaceTokens(namingConfig.MovieFolderFormat, tokenHandlers, namingConfig)); AddSeriesTokens(tokenHandlers, series);
} AddSeasonTokens(tokenHandlers, seasonNumber);
public static string CleanTitle(string title) return CleanFolderName(ReplaceTokens(namingConfig.SeasonFolderFormat, tokenHandlers, namingConfig));
{ }
title = title.Replace("&", "and");
title = ScenifyReplaceChars.Replace(title, " "); public string GetMovieFolder(Movie movie, NamingConfig namingConfig = null)
title = ScenifyRemoveChars.Replace(title, string.Empty); {
if(namingConfig == null)
return title; {
} namingConfig = _namingConfigService.GetConfig();
}
var tokenHandlers = new Dictionary<string, Func<TokenMatch, string>>(FileNameBuilderTokenEqualityComparer.Instance);
AddMovieTokens(tokenHandlers, movie);
AddReleaseDateTokens(tokenHandlers, movie.Year);
AddImdbIdTokens(tokenHandlers, movie.ImdbId);
return CleanFolderName(ReplaceTokens(namingConfig.MovieFolderFormat, tokenHandlers, namingConfig));
}
public static string CleanTitle(string title)
{
title = title.Replace("&", "and");
title = ScenifyReplaceChars.Replace(title, " ");
title = ScenifyRemoveChars.Replace(title, string.Empty);
return title;
}
public static string TitleThe(string title) public static string TitleThe(string title)
{ {

@ -74,6 +74,19 @@ module.exports = Marionette.Layout.extend({
var file = movie.model.get("movieFile"); var file = movie.model.get("movieFile");
this.filesCollection.add(file); this.filesCollection.add(file);
//this.listenTo(this.releaseCollection, 'sync', this._showSearchResults); //this.listenTo(this.releaseCollection, 'sync', this._showSearchResults);
this.listenTo(this.model, 'change', function(model, options) {
if (options && options.changeSource === 'signalr') {
this._refresh(movie);
}
});
},
_refresh : function(movie) {
this.filesCollection = new FilesCollection();
var file = movie.model.get("movieFile");
this.filesCollection.add(file);
this.onShow();
}, },
onShow : function() { onShow : function() {

@ -9,6 +9,7 @@ module.exports = Marionette.ItemView.extend({
//var type = this.model.get('seriesType'); //var type = this.model.get('seriesType');
return { return {
rename : this.naming.get('renameEpisodes'), rename : this.naming.get('renameEpisodes'),
folderFormat: this.naming.get('movieFolderFormat'),
format : this.naming.get('standardMovieFormat') format : this.naming.get('standardMovieFormat')
}; };
}, },

@ -1,3 +1,4 @@
{{#if rename}} {{#if rename}}
Folder Naming pattern: {{folderFormat}}<br>
Naming pattern: {{format}} Naming pattern: {{format}}
{{/if}} {{/if}}

@ -9,7 +9,7 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="alert alert-info"> <div class="alert alert-info">
<div class="path-info x-path-info">All paths are relative to: <strong>{{path}}</strong></div> <div class="path-info x-path-info">Your movie may be moved; see the paths below</div>
<div class="x-format-region"></div> <div class="x-format-region"></div>
</div> </div>

Loading…
Cancel
Save