From c4aa744605d078f8ea5aa801e452df539cab7613 Mon Sep 17 00:00:00 2001 From: softworkz Date: Sun, 1 Nov 2015 19:24:45 +0100 Subject: Fix exception when episode title is null Sometimes TheTVDb does not have episode. This caused an exception in EpisodeFileOrganizer --- .../FileOrganization/EpisodeFileOrganizer.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs') diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index e36813d11..ef226a934 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -504,7 +504,15 @@ namespace MediaBrowser.Server.Implementations.FileOrganization private string GetEpisodeFileName(string sourcePath, string seriesName, int seasonNumber, int episodeNumber, int? endingEpisodeNumber, string episodeTitle, TvFileOrganizationOptions options, int? maxLength) { seriesName = _fileSystem.GetValidFilename(seriesName).Trim(); - episodeTitle = _fileSystem.GetValidFilename(episodeTitle).Trim(); + + if (episodeTitle == null) + { + episodeTitle = string.Empty; + } + else + { + episodeTitle = _fileSystem.GetValidFilename(episodeTitle).Trim(); + } var sourceExtension = (Path.GetExtension(sourcePath) ?? string.Empty).TrimStart('.'); -- cgit v1.2.3 From 182f1da03e668fe7b99113fc88721fa95bf18ad7 Mon Sep 17 00:00:00 2001 From: softworkz Date: Sun, 10 Jan 2016 06:19:19 +0100 Subject: Added OmdbEpisodeProvider as an alternative source for series episodes This new episode provider implementation does not bulk-download or cache episode data. It is only meant to be a backup source for situations where media is not recognized by the default provider (TheTvDb). --- .../Configuration/ServerConfiguration.cs | 3 +- .../MediaBrowser.Providers.csproj | 1 + MediaBrowser.Providers/Omdb/OmdbItemProvider.cs | 46 ++++++++++- MediaBrowser.Providers/TV/OmdbEpisodeProvider.cs | 89 ++++++++++++++++++++++ .../FileOrganization/EpisodeFileOrganizer.cs | 13 +++- 5 files changed, 144 insertions(+), 8 deletions(-) create mode 100644 MediaBrowser.Providers/TV/OmdbEpisodeProvider.cs (limited to 'MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs') diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 08f7f89e3..f6eb0ba74 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -565,7 +565,7 @@ namespace MediaBrowser.Model.Configuration Type = ImageType.Thumb } }, - DisabledMetadataFetchers = new []{ "TheMovieDb" } + DisabledMetadataFetchers = new []{ "The Open Movie Database", "TheMovieDb" } }, new MetadataOptions(0, 1280) @@ -586,6 +586,7 @@ namespace MediaBrowser.Model.Configuration Type = ImageType.Primary } }, + DisabledMetadataFetchers = new []{ "The Open Movie Database" }, DisabledImageFetchers = new []{ "TheMovieDb" } } }; diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 7478b2738..89bed8849 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -177,6 +177,7 @@ + diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs index efcc76e69..ea9d14534 100644 --- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs @@ -60,12 +60,18 @@ namespace MediaBrowser.Providers.Omdb public async Task> GetSearchResults(ItemLookupInfo searchInfo, string type, CancellationToken cancellationToken) { bool isSearch = false; + var episodeSearchInfo = searchInfo as EpisodeInfo; var list = new List(); var imdbId = searchInfo.GetProviderId(MetadataProviders.Imdb); - var url = "http://www.omdbapi.com/?plot=short&r=json"; + var url = "http://www.omdbapi.com/?plot=full&r=json"; + if (type == "episode" && episodeSearchInfo != null) + { + episodeSearchInfo.SeriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out imdbId); + } + var name = searchInfo.Name; var year = searchInfo.Year; @@ -95,6 +101,18 @@ namespace MediaBrowser.Providers.Omdb url += "&i=" + imdbId; } + if (type == "episode") + { + if (searchInfo.IndexNumber.HasValue) + { + url += string.Format(CultureInfo.InvariantCulture, "&Episode={0}", searchInfo.IndexNumber); + } + if (searchInfo.ParentIndexNumber.HasValue) + { + url += string.Format(CultureInfo.InvariantCulture, "&Season={0}", searchInfo.ParentIndexNumber); + } + } + using (var stream = await _httpClient.Get(new HttpRequestOptions { Url = url, @@ -124,10 +142,20 @@ namespace MediaBrowser.Providers.Omdb foreach (var result in resultList) { - var item = new RemoteSearchResult(); + var item = new RemoteSearchResult + { + IndexNumber = searchInfo.IndexNumber, + Name = result.Title, + ParentIndexNumber = searchInfo.ParentIndexNumber, + ProviderIds = searchInfo.ProviderIds, + SearchProviderName = Name + }; + + if (episodeSearchInfo != null && episodeSearchInfo.IndexNumberEnd.HasValue) + { + item.IndexNumberEnd = episodeSearchInfo.IndexNumberEnd.Value; + } - item.SearchProviderName = Name; - item.Name = result.Title; item.SetProviderId(MetadataProviders.Imdb, result.imdbID); int parsedYear; @@ -137,6 +165,13 @@ namespace MediaBrowser.Providers.Omdb item.ProductionYear = parsedYear; } + DateTime released; + if (!string.IsNullOrEmpty(result.Released) + && DateTime.TryParse(result.Released, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out released)) + { + item.PremiereDate = released; + } + if (!string.IsNullOrWhiteSpace(result.Poster) && !string.Equals(result.Poster, "N/A", StringComparison.OrdinalIgnoreCase)) { item.ImageUrl = result.Poster; @@ -267,6 +302,8 @@ namespace MediaBrowser.Providers.Omdb public string Year { get; set; } public string Rated { get; set; } public string Released { get; set; } + public string Season { get; set; } + public string Episode { get; set; } public string Runtime { get; set; } public string Genre { get; set; } public string Director { get; set; } @@ -281,6 +318,7 @@ namespace MediaBrowser.Providers.Omdb public string imdbRating { get; set; } public string imdbVotes { get; set; } public string imdbID { get; set; } + public string seriesID { get; set; } public string Type { get; set; } public string Response { get; set; } } diff --git a/MediaBrowser.Providers/TV/OmdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/OmdbEpisodeProvider.cs new file mode 100644 index 000000000..5a920c37f --- /dev/null +++ b/MediaBrowser.Providers/TV/OmdbEpisodeProvider.cs @@ -0,0 +1,89 @@ +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Providers; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Providers.Omdb; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Providers.TV +{ + class OmdbEpisodeProvider : + IRemoteMetadataProvider, + IHasOrder + { + private readonly IJsonSerializer _jsonSerializer; + private readonly IHttpClient _httpClient; + private OmdbItemProvider _itemProvider; + + public OmdbEpisodeProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogger logger, ILibraryManager libraryManager) + { + _jsonSerializer = jsonSerializer; + _httpClient = httpClient; + _itemProvider = new OmdbItemProvider(jsonSerializer, httpClient, logger, libraryManager); + } + + public Task> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken) + { + return _itemProvider.GetSearchResults(searchInfo, "episode", cancellationToken); + } + + public async Task> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken) + { + var result = new MetadataResult + { + Item = new Episode() + }; + + var imdbId = info.GetProviderId(MetadataProviders.Imdb); + if (string.IsNullOrWhiteSpace(imdbId)) + { + imdbId = await GetEpisodeImdbId(info, cancellationToken).ConfigureAwait(false); + } + + if (!string.IsNullOrEmpty(imdbId)) + { + result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); + result.HasMetadata = true; + + await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); + } + + return result; + } + + private async Task GetEpisodeImdbId(EpisodeInfo info, CancellationToken cancellationToken) + { + var results = await GetSearchResults(info, cancellationToken).ConfigureAwait(false); + var first = results.FirstOrDefault(); + return first == null ? null : first.GetProviderId(MetadataProviders.Imdb); + } + + public int Order + { + get + { + // After TheTvDb + return 1; + } + } + + public string Name + { + get { return "The Open Movie Database"; } + } + + public Task GetImageResponse(string url, CancellationToken cancellationToken) + { + return _itemProvider.GetImageResponse(url, cancellationToken); + } + } +} diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index ef226a934..7c803793a 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -427,11 +427,18 @@ namespace MediaBrowser.Server.Implementations.FileOrganization }, cancellationToken).ConfigureAwait(false); var episode = searchResults.FirstOrDefault(); + + string episodeName = string.Empty; if (episode == null) { - _logger.Warn("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); - return null; + var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); + _logger.Warn(msg); + //throw new Exception(msg); + } + else + { + episodeName = episode.Name; } var newPath = GetSeasonFolderPath(series, seasonNumber, options); @@ -449,7 +456,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization // Remove additional 4 chars to prevent PathTooLongException for downloaded subtitles (eg. filename.ext.eng.srt) maxFilenameLength -= 4; - var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber, episodeNumber, endingEpisodeNumber, episode.Name, options, maxFilenameLength); + var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber, episodeNumber, endingEpisodeNumber, episodeName, options, maxFilenameLength); if (string.IsNullOrEmpty(episodeFileName)) { -- cgit v1.2.3 From 9fbb304c475d10fd238c16cbbab9a81ebdea0593 Mon Sep 17 00:00:00 2001 From: softworkz Date: Sun, 10 Jan 2016 06:56:32 +0100 Subject: Allow Auto-Organize to succeed even if episode title cannot be determined --- .../FileOrganization/EpisodeFileOrganizer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs') diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 7c803793a..c27d266c3 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -512,7 +512,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { seriesName = _fileSystem.GetValidFilename(seriesName).Trim(); - if (episodeTitle == null) + if (string.IsNullOrEmpty(episodeTitle)) { episodeTitle = string.Empty; } -- cgit v1.2.3 From 0d3c8b8711d863a8c9fed3daaf3c941500458113 Mon Sep 17 00:00:00 2001 From: Luke Date: Mon, 18 Jan 2016 00:30:50 -0500 Subject: auto-organize by date --- .../FileOrganization/EpisodeFileOrganizer.cs | 161 +++++++++++++++------ 1 file changed, 114 insertions(+), 47 deletions(-) (limited to 'MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs') diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index c27d266c3..26392f5a9 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -74,42 +74,52 @@ namespace MediaBrowser.Server.Implementations.FileOrganization if (!string.IsNullOrEmpty(seriesName)) { - var season = episodeInfo.SeasonNumber; - - result.ExtractedSeasonNumber = season; - - if (season.HasValue) - { - // Passing in true will include a few extra regex's - var episode = episodeInfo.EpisodeNumber; - - result.ExtractedEpisodeNumber = episode; - - if (episode.HasValue) - { - _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, season, episode); - - var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber; - - result.ExtractedEndingEpisodeNumber = endingEpisodeNumber; - - await OrganizeEpisode(path, seriesName, season.Value, episode.Value, endingEpisodeNumber, options, overwriteExisting, result, cancellationToken).ConfigureAwait(false); - } - else - { - var msg = string.Format("Unable to determine episode number from {0}", path); - result.Status = FileSortingStatus.Failure; - result.StatusMessage = msg; - _logger.Warn(msg); - } - } - else - { - var msg = string.Format("Unable to determine season number from {0}", path); - result.Status = FileSortingStatus.Failure; - result.StatusMessage = msg; - _logger.Warn(msg); - } + var seasonNumber = episodeInfo.SeasonNumber; + + result.ExtractedSeasonNumber = seasonNumber; + + // Passing in true will include a few extra regex's + var episodeNumber = episodeInfo.EpisodeNumber; + + result.ExtractedEpisodeNumber = episodeNumber; + + var premiereDate = episodeInfo.IsByDate ? + new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) : + (DateTime?)null; + + if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue)) + { + if (episodeInfo.IsByDate) + { + _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value); + } + else + { + _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber); + } + + var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber; + + result.ExtractedEndingEpisodeNumber = endingEpisodeNumber; + + await OrganizeEpisode(path, + seriesName, + seasonNumber, + episodeNumber, + endingEpisodeNumber, + premiereDate, + options, + overwriteExisting, + result, + cancellationToken).ConfigureAwait(false); + } + else + { + var msg = string.Format("Unable to determine episode number from {0}", path); + result.Status = FileSortingStatus.Failure; + result.StatusMessage = msg; + _logger.Warn(msg); + } } else { @@ -141,14 +151,32 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId)); - await OrganizeEpisode(result.OriginalPath, series, request.SeasonNumber, request.EpisodeNumber, request.EndingEpisodeNumber, options, true, result, cancellationToken).ConfigureAwait(false); + await OrganizeEpisode(result.OriginalPath, + series, + request.SeasonNumber, + request.EpisodeNumber, + request.EndingEpisodeNumber, + null, + options, + true, + result, + cancellationToken).ConfigureAwait(false); await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false); return result; } - private Task OrganizeEpisode(string sourcePath, string seriesName, int seasonNumber, int episodeNumber, int? endingEpiosdeNumber, TvFileOrganizationOptions options, bool overwriteExisting, FileOrganizationResult result, CancellationToken cancellationToken) + private Task OrganizeEpisode(string sourcePath, + string seriesName, + int? seasonNumber, + int? episodeNumber, + int? endingEpiosdeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + bool overwriteExisting, + FileOrganizationResult result, + CancellationToken cancellationToken) { var series = GetMatchingSeries(seriesName, result); @@ -161,15 +189,33 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return Task.FromResult(true); } - return OrganizeEpisode(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, options, overwriteExisting, result, cancellationToken); + return OrganizeEpisode(sourcePath, + series, + seasonNumber, + episodeNumber, + endingEpiosdeNumber, + premiereDate, + options, + overwriteExisting, + result, + cancellationToken); } - private async Task OrganizeEpisode(string sourcePath, Series series, int seasonNumber, int episodeNumber, int? endingEpiosdeNumber, TvFileOrganizationOptions options, bool overwriteExisting, FileOrganizationResult result, CancellationToken cancellationToken) + private async Task OrganizeEpisode(string sourcePath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpiosdeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + bool overwriteExisting, + FileOrganizationResult result, + CancellationToken cancellationToken) { _logger.Info("Sorting file {0} into series {1}", sourcePath, series.Path); // Proceed to sort the file - var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, options, cancellationToken).ConfigureAwait(false); + var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options, cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(newPath)) { @@ -278,8 +324,18 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } - private List GetOtherDuplicatePaths(string targetPath, Series series, int seasonNumber, int episodeNumber, int? endingEpisodeNumber) + private List GetOtherDuplicatePaths(string targetPath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpisodeNumber) { + // TODO: Support date-naming? + if (!seasonNumber.HasValue || episodeNumber.HasValue) + { + return new List (); + } + var episodePaths = series.GetRecursiveChildren() .OfType() .Where(i => @@ -408,7 +464,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization /// The ending episode number. /// The options. /// System.String. - private async Task GetNewPath(string sourcePath, Series series, int seasonNumber, int episodeNumber, int? endingEpisodeNumber, TvFileOrganizationOptions options, CancellationToken cancellationToken) + private async Task GetNewPath(string sourcePath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpisodeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + CancellationToken cancellationToken) { var episodeInfo = new EpisodeInfo { @@ -417,7 +480,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization MetadataCountryCode = series.GetPreferredMetadataCountryCode(), MetadataLanguage = series.GetPreferredMetadataLanguage(), ParentIndexNumber = seasonNumber, - SeriesProviderIds = series.ProviderIds + SeriesProviderIds = series.ProviderIds, + PremiereDate = premiereDate }; var searchResults = await _providerManager.GetRemoteSearchResults(new RemoteSearchQuery @@ -439,9 +503,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization else { episodeName = episode.Name; - } + } + + seasonNumber = seasonNumber ?? episode.ParentIndexNumber; + episodeNumber = episodeNumber ?? episode.IndexNumber; - var newPath = GetSeasonFolderPath(series, seasonNumber, options); + var newPath = GetSeasonFolderPath(series, seasonNumber.Value, options); // MAX_PATH - trailing charachter - drive component: 260 - 1 - 3 = 256 // Usually newPath would include the drive component, but use 256 to be sure @@ -456,7 +523,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization // Remove additional 4 chars to prevent PathTooLongException for downloaded subtitles (eg. filename.ext.eng.srt) maxFilenameLength -= 4; - var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber, episodeNumber, endingEpisodeNumber, episodeName, options, maxFilenameLength); + var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber.Value, episodeNumber.Value, endingEpisodeNumber, episodeName, options, maxFilenameLength); if (string.IsNullOrEmpty(episodeFileName)) { -- cgit v1.2.3 From ce813c40c9f32521a15f0397c63e103e4ffefc9e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 28 Jan 2016 13:29:41 -0500 Subject: don't organize episode if series has no provider ids --- .../FileOrganization/EpisodeFileOrganizer.cs | 225 +++++++++++---------- 1 file changed, 117 insertions(+), 108 deletions(-) (limited to 'MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs') diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 26392f5a9..ae40ed6b5 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -76,50 +76,50 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { var seasonNumber = episodeInfo.SeasonNumber; - result.ExtractedSeasonNumber = seasonNumber; - - // Passing in true will include a few extra regex's - var episodeNumber = episodeInfo.EpisodeNumber; - - result.ExtractedEpisodeNumber = episodeNumber; - - var premiereDate = episodeInfo.IsByDate ? - new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) : - (DateTime?)null; - - if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue)) - { - if (episodeInfo.IsByDate) - { - _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value); - } - else - { - _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber); - } - - var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber; - - result.ExtractedEndingEpisodeNumber = endingEpisodeNumber; - - await OrganizeEpisode(path, - seriesName, - seasonNumber, - episodeNumber, - endingEpisodeNumber, - premiereDate, - options, - overwriteExisting, - result, - cancellationToken).ConfigureAwait(false); - } - else - { - var msg = string.Format("Unable to determine episode number from {0}", path); - result.Status = FileSortingStatus.Failure; - result.StatusMessage = msg; - _logger.Warn(msg); - } + result.ExtractedSeasonNumber = seasonNumber; + + // Passing in true will include a few extra regex's + var episodeNumber = episodeInfo.EpisodeNumber; + + result.ExtractedEpisodeNumber = episodeNumber; + + var premiereDate = episodeInfo.IsByDate ? + new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) : + (DateTime?)null; + + if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue)) + { + if (episodeInfo.IsByDate) + { + _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value); + } + else + { + _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber); + } + + var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber; + + result.ExtractedEndingEpisodeNumber = endingEpisodeNumber; + + await OrganizeEpisode(path, + seriesName, + seasonNumber, + episodeNumber, + endingEpisodeNumber, + premiereDate, + options, + overwriteExisting, + result, + cancellationToken).ConfigureAwait(false); + } + else + { + var msg = string.Format("Unable to determine episode number from {0}", path); + result.Status = FileSortingStatus.Failure; + result.StatusMessage = msg; + _logger.Warn(msg); + } } else { @@ -151,32 +151,32 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId)); - await OrganizeEpisode(result.OriginalPath, - series, - request.SeasonNumber, - request.EpisodeNumber, - request.EndingEpisodeNumber, - null, - options, - true, - result, - cancellationToken).ConfigureAwait(false); + await OrganizeEpisode(result.OriginalPath, + series, + request.SeasonNumber, + request.EpisodeNumber, + request.EndingEpisodeNumber, + null, + options, + true, + result, + cancellationToken).ConfigureAwait(false); await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false); return result; } - private Task OrganizeEpisode(string sourcePath, - string seriesName, - int? seasonNumber, - int? episodeNumber, - int? endingEpiosdeNumber, - DateTime? premiereDate, - TvFileOrganizationOptions options, - bool overwriteExisting, - FileOrganizationResult result, - CancellationToken cancellationToken) + private Task OrganizeEpisode(string sourcePath, + string seriesName, + int? seasonNumber, + int? episodeNumber, + int? endingEpiosdeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + bool overwriteExisting, + FileOrganizationResult result, + CancellationToken cancellationToken) { var series = GetMatchingSeries(seriesName, result); @@ -189,33 +189,42 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return Task.FromResult(true); } - return OrganizeEpisode(sourcePath, - series, - seasonNumber, - episodeNumber, - endingEpiosdeNumber, - premiereDate, - options, - overwriteExisting, - result, - cancellationToken); + if (!series.ProviderIds.Any()) + { + var msg = string.Format("Series has not yet been identified: {0}. If you just added the series, please run a library scan or use the identify feature to identify it.", seriesName); + result.Status = FileSortingStatus.Failure; + result.StatusMessage = msg; + _logger.Warn(msg); + return Task.FromResult(true); + } + + return OrganizeEpisode(sourcePath, + series, + seasonNumber, + episodeNumber, + endingEpiosdeNumber, + premiereDate, + options, + overwriteExisting, + result, + cancellationToken); } - private async Task OrganizeEpisode(string sourcePath, - Series series, - int? seasonNumber, - int? episodeNumber, - int? endingEpiosdeNumber, - DateTime? premiereDate, - TvFileOrganizationOptions options, - bool overwriteExisting, - FileOrganizationResult result, - CancellationToken cancellationToken) + private async Task OrganizeEpisode(string sourcePath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpiosdeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + bool overwriteExisting, + FileOrganizationResult result, + CancellationToken cancellationToken) { _logger.Info("Sorting file {0} into series {1}", sourcePath, series.Path); // Proceed to sort the file - var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options, cancellationToken).ConfigureAwait(false); + var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options, cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(newPath)) { @@ -324,17 +333,17 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } - private List GetOtherDuplicatePaths(string targetPath, - Series series, - int? seasonNumber, - int? episodeNumber, - int? endingEpisodeNumber) + private List GetOtherDuplicatePaths(string targetPath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpisodeNumber) { - // TODO: Support date-naming? - if (!seasonNumber.HasValue || episodeNumber.HasValue) - { - return new List (); - } + // TODO: Support date-naming? + if (!seasonNumber.HasValue || episodeNumber.HasValue) + { + return new List(); + } var episodePaths = series.GetRecursiveChildren() .OfType() @@ -464,14 +473,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization /// The ending episode number. /// The options. /// System.String. - private async Task GetNewPath(string sourcePath, - Series series, - int? seasonNumber, - int? episodeNumber, - int? endingEpisodeNumber, - DateTime? premiereDate, - TvFileOrganizationOptions options, - CancellationToken cancellationToken) + private async Task GetNewPath(string sourcePath, + Series series, + int? seasonNumber, + int? episodeNumber, + int? endingEpisodeNumber, + DateTime? premiereDate, + TvFileOrganizationOptions options, + CancellationToken cancellationToken) { var episodeInfo = new EpisodeInfo { @@ -481,7 +490,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization MetadataLanguage = series.GetPreferredMetadataLanguage(), ParentIndexNumber = seasonNumber, SeriesProviderIds = series.ProviderIds, - PremiereDate = premiereDate + PremiereDate = premiereDate }; var searchResults = await _providerManager.GetRemoteSearchResults(new RemoteSearchQuery @@ -491,7 +500,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization }, cancellationToken).ConfigureAwait(false); var episode = searchResults.FirstOrDefault(); - + string episodeName = string.Empty; if (episode == null) @@ -503,10 +512,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization else { episodeName = episode.Name; - } + } - seasonNumber = seasonNumber ?? episode.ParentIndexNumber; - episodeNumber = episodeNumber ?? episode.IndexNumber; + seasonNumber = seasonNumber ?? episode.ParentIndexNumber; + episodeNumber = episodeNumber ?? episode.IndexNumber; var newPath = GetSeasonFolderPath(series, seasonNumber.Value, options); -- cgit v1.2.3 From e906bdc06e2c2b047cd424b6b4e071e999f34ae6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jan 2016 13:29:09 -0500 Subject: don't organize with unknown episode name --- .../FileOrganization/EpisodeFileOrganizer.cs | 24 +++++++++------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs') diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index ae40ed6b5..e15ce27e0 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -189,15 +189,6 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return Task.FromResult(true); } - if (!series.ProviderIds.Any()) - { - var msg = string.Format("Series has not yet been identified: {0}. If you just added the series, please run a library scan or use the identify feature to identify it.", seriesName); - result.Status = FileSortingStatus.Failure; - result.StatusMessage = msg; - _logger.Warn(msg); - return Task.FromResult(true); - } - return OrganizeEpisode(sourcePath, series, seasonNumber, @@ -471,7 +462,9 @@ namespace MediaBrowser.Server.Implementations.FileOrganization /// The season number. /// The episode number. /// The ending episode number. + /// The premiere date. /// The options. + /// The cancellation token. /// System.String. private async Task GetNewPath(string sourcePath, Series series, @@ -501,17 +494,20 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var episode = searchResults.FirstOrDefault(); - string episodeName = string.Empty; - if (episode == null) { var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); _logger.Warn(msg); - //throw new Exception(msg); + return null; } - else + + var episodeName = episode.Name; + + if (string.IsNullOrWhiteSpace(episodeName)) { - episodeName = episode.Name; + var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); + _logger.Warn(msg); + return null; } seasonNumber = seasonNumber ?? episode.ParentIndexNumber; -- cgit v1.2.3 From fc6d22a81b2c2da171b7e76168c8bc07cf7ec53a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Jan 2016 23:54:55 -0500 Subject: update episode organizer --- .../FileOrganization/EpisodeFileOrganizer.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs') diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index e15ce27e0..73cc5ab01 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -503,12 +503,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var episodeName = episode.Name; - if (string.IsNullOrWhiteSpace(episodeName)) - { - var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); - _logger.Warn(msg); - return null; - } + //if (string.IsNullOrWhiteSpace(episodeName)) + //{ + // var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber); + // _logger.Warn(msg); + // return null; + //} seasonNumber = seasonNumber ?? episode.ParentIndexNumber; episodeNumber = episodeNumber ?? episode.IndexNumber; @@ -584,7 +584,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { seriesName = _fileSystem.GetValidFilename(seriesName).Trim(); - if (string.IsNullOrEmpty(episodeTitle)) + if (string.IsNullOrWhiteSpace(episodeTitle)) { episodeTitle = string.Empty; } -- cgit v1.2.3 From 3a868e28b3e3d9f0a13fc38c680047010d627b0f Mon Sep 17 00:00:00 2001 From: softworkz Date: Wed, 23 Sep 2015 06:12:46 +0200 Subject: Auto-Organize: Added feature to remember/persist series matching in manual organization dialog #2 When a filename cannot be auto-matched to an existing series name, the organization must be performed manually. Unfortunately not just once, but again and again for each episode coming in. This change proposes a simple but solid method to optionally persist the matching condition from within the manual organization dialog. This approach will make Emby "learn" how to organize files in the future without user interaction. --- .../Library/FileOrganizationService.cs | 44 ++++++++++++++ .../FileOrganization/IFileOrganizationService.cs | 14 +++++ .../MediaBrowser.Model.Portable.csproj | 3 + .../MediaBrowser.Model.net35.csproj | 3 + .../FileOrganization/AutoOrganizeOptions.cs | 8 +++ .../FileOrganization/SmartMatchInfo.cs | 19 ++++++ MediaBrowser.Model/MediaBrowser.Model.csproj | 1 + .../FileOrganization/EpisodeFileOrganizer.cs | 69 ++++++++++++++++++---- .../FileOrganization/Extensions.cs | 4 ++ .../FileOrganization/FileOrganizationService.cs | 57 ++++++++++++++++-- .../FileOrganization/OrganizerScheduledTask.cs | 12 ++-- .../FileOrganization/TvFolderOrganizer.cs | 12 ++-- .../MediaBrowser.WebDashboard.csproj | 9 +++ 13 files changed, 228 insertions(+), 27 deletions(-) create mode 100644 MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs (limited to 'MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs') diff --git a/MediaBrowser.Api/Library/FileOrganizationService.cs b/MediaBrowser.Api/Library/FileOrganizationService.cs index 29a982629..a08cc099e 100644 --- a/MediaBrowser.Api/Library/FileOrganizationService.cs +++ b/MediaBrowser.Api/Library/FileOrganizationService.cs @@ -74,6 +74,34 @@ namespace MediaBrowser.Api.Library public bool RememberCorrection { get; set; } } + [Route("/Library/FileOrganizationSmartMatch", "GET", Summary = "Gets smart match entries")] + public class GetSmartMatchInfos : IReturn> + { + /// + /// Skips over a given number of items within the results. Use for paging. + /// + /// The start index. + [ApiMember(Name = "StartIndex", Description = "Optional. The record index to start at. All items with a lower index will be dropped from the results.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? StartIndex { get; set; } + + /// + /// The maximum number of items to return + /// + /// The limit. + [ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? Limit { get; set; } + } + + [Route("/Library/FileOrganizationSmartMatch/{Id}/Delete", "POST", Summary = "Deletes a smart match entry")] + public class DeleteSmartMatchEntry + { + [ApiMember(Name = "Id", Description = "Item ID", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public string Id { get; set; } + + [ApiMember(Name = "MatchString", Description = "SmartMatch String", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] + public string MatchString { get; set; } + } + [Authenticated(Roles = "Admin")] public class FileOrganizationService : BaseApiService { @@ -130,5 +158,21 @@ namespace MediaBrowser.Api.Library Task.WaitAll(task); } + + public object Get(GetSmartMatchInfos request) + { + var result = _iFileOrganizationService.GetSmartMatchInfos(new FileOrganizationResultQuery + { + Limit = request.Limit, + StartIndex = request.StartIndex + }); + + return ToOptimizedSerializedResultUsingCache(result); + } + + public void Post(DeleteSmartMatchEntry request) + { + _iFileOrganizationService.DeleteSmartMatchEntry(request.Id, request.MatchString); + } } } diff --git a/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs b/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs index ff22b0cdc..8d7f4e117 100644 --- a/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs +++ b/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs @@ -67,5 +67,19 @@ namespace MediaBrowser.Controller.FileOrganization /// The cancellation token. /// Task. Task SaveResult(FileOrganizationResult result, CancellationToken cancellationToken); + + /// + /// Returns a list of smart match entries + /// + /// The query. + /// IEnumerable{SmartMatchInfo}. + QueryResult GetSmartMatchInfos(FileOrganizationResultQuery query); + + /// + /// Deletes a smart match entry. + /// + /// Item Id. + /// The match string to delete. + void DeleteSmartMatchEntry(string Id, string matchString); } } diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index b8c64b643..cea13f86e 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -668,6 +668,9 @@ FileOrganization\FileSortingStatus.cs + + FileOrganization\SmartMatchInfo.cs + FileOrganization\TvFileOrganizationOptions.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index e74468eff..6c484ffc9 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -633,6 +633,9 @@ FileOrganization\FileSortingStatus.cs + + FileOrganization\SmartMatchInfo.cs + FileOrganization\TvFileOrganizationOptions.cs diff --git a/MediaBrowser.Model/FileOrganization/AutoOrganizeOptions.cs b/MediaBrowser.Model/FileOrganization/AutoOrganizeOptions.cs index ae701ea68..071897b51 100644 --- a/MediaBrowser.Model/FileOrganization/AutoOrganizeOptions.cs +++ b/MediaBrowser.Model/FileOrganization/AutoOrganizeOptions.cs @@ -1,4 +1,5 @@  +using System.Collections.Generic; namespace MediaBrowser.Model.FileOrganization { public class AutoOrganizeOptions @@ -9,9 +10,16 @@ namespace MediaBrowser.Model.FileOrganization /// The tv options. public TvFileOrganizationOptions TvOptions { get; set; } + /// + /// Gets or sets a list of smart match entries. + /// + /// The smart match entries. + public List SmartMatchInfos { get; set; } + public AutoOrganizeOptions() { TvOptions = new TvFileOrganizationOptions(); + SmartMatchInfos = new List(); } } } diff --git a/MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs b/MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs new file mode 100644 index 000000000..808c0b006 --- /dev/null +++ b/MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs @@ -0,0 +1,19 @@ + +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Model.FileOrganization +{ + public class SmartMatchInfo + { + public Guid Id { get; set; } + public string Name { get; set; } + public FileOrganizerType OrganizerType { get; set; } + public List MatchStrings { get; set; } + + public SmartMatchInfo() + { + MatchStrings = new List(); + } + } +} diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index db278baa1..a5191192c 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -137,6 +137,7 @@ + diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 73cc5ab01..a952b60d5 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -46,12 +46,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization public Task OrganizeEpisodeFile(string path, CancellationToken cancellationToken) { - var options = _config.GetAutoOrganizeOptions().TvOptions; + var options = _config.GetAutoOrganizeOptions(); return OrganizeEpisodeFile(path, options, false, cancellationToken); } - public async Task OrganizeEpisodeFile(string path, TvFileOrganizationOptions options, bool overwriteExisting, CancellationToken cancellationToken) + public async Task OrganizeEpisodeFile(string path, AutoOrganizeOptions options, bool overwriteExisting, CancellationToken cancellationToken) { _logger.Info("Sorting file {0}", path); @@ -110,6 +110,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization premiereDate, options, overwriteExisting, + false, result, cancellationToken).ConfigureAwait(false); } @@ -145,7 +146,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return result; } - public async Task OrganizeWithCorrection(EpisodeFileOrganizationRequest request, TvFileOrganizationOptions options, CancellationToken cancellationToken) + public async Task OrganizeWithCorrection(EpisodeFileOrganizationRequest request, AutoOrganizeOptions options, CancellationToken cancellationToken) { var result = _organizationService.GetResult(request.ResultId); @@ -159,6 +160,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization null, options, true, + request.RememberCorrection, result, cancellationToken).ConfigureAwait(false); @@ -173,12 +175,13 @@ namespace MediaBrowser.Server.Implementations.FileOrganization int? episodeNumber, int? endingEpiosdeNumber, DateTime? premiereDate, - TvFileOrganizationOptions options, + AutoOrganizeOptions options, bool overwriteExisting, + bool rememberCorrection, FileOrganizationResult result, CancellationToken cancellationToken) { - var series = GetMatchingSeries(seriesName, result); + var series = GetMatchingSeries(seriesName, result, options); if (series == null) { @@ -197,6 +200,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization premiereDate, options, overwriteExisting, + rememberCorrection, result, cancellationToken); } @@ -207,15 +211,18 @@ namespace MediaBrowser.Server.Implementations.FileOrganization int? episodeNumber, int? endingEpiosdeNumber, DateTime? premiereDate, - TvFileOrganizationOptions options, + AutoOrganizeOptions options, bool overwriteExisting, + bool rememberCorrection, FileOrganizationResult result, CancellationToken cancellationToken) { _logger.Info("Sorting file {0} into series {1}", sourcePath, series.Path); + var originalExtractedSeriesString = result.ExtractedName; + // Proceed to sort the file - var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options, cancellationToken).ConfigureAwait(false); + var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options.TvOptions, cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(newPath)) { @@ -234,7 +241,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization if (!overwriteExisting) { - if (options.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath)) + if (options.TvOptions.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath)) { _logger.Info("File {0} already copied to new path {1}, stopping organization", sourcePath, newPath); result.Status = FileSortingStatus.SkippedExisting; @@ -251,7 +258,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } - PerformFileSorting(options, result); + PerformFileSorting(options.TvOptions, result); if (overwriteExisting) { @@ -285,6 +292,31 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } } + + if (rememberCorrection) + { + SaveSmartMatchString(originalExtractedSeriesString, series, options); + } + } + + private void SaveSmartMatchString(string matchString, Series series, AutoOrganizeOptions options) + { + SmartMatchInfo info = options.SmartMatchInfos.Find(i => i.Id == series.Id); + + if (info == null) + { + info = new SmartMatchInfo(); + info.Id = series.Id; + info.OrganizerType = FileOrganizerType.Episode; + info.Name = series.Name; + options.SmartMatchInfos.Add(info); + } + + if (!info.MatchStrings.Contains(matchString, StringComparer.OrdinalIgnoreCase)) + { + info.MatchStrings.Add(matchString); + _config.SaveAutoOrganizeOptions(options); + } } private void DeleteLibraryFile(string path, bool renameRelatedFiles, string targetPath) @@ -435,7 +467,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } - private Series GetMatchingSeries(string seriesName, FileOrganizationResult result) + private Series GetMatchingSeries(string seriesName, FileOrganizationResult result, AutoOrganizeOptions options) { var parsedName = _libraryManager.ParseName(seriesName); @@ -445,13 +477,28 @@ namespace MediaBrowser.Server.Implementations.FileOrganization result.ExtractedName = nameWithoutYear; result.ExtractedYear = yearInName; - return _libraryManager.RootFolder.GetRecursiveChildren(i => i is Series) + var series = _libraryManager.RootFolder.GetRecursiveChildren(i => i is Series) .Cast() .Select(i => NameUtils.GetMatchScore(nameWithoutYear, yearInName, i)) .Where(i => i.Item2 > 0) .OrderByDescending(i => i.Item2) .Select(i => i.Item1) .FirstOrDefault(); + + if (series == null) + { + SmartMatchInfo info = options.SmartMatchInfos.Where(e => e.MatchStrings.Contains(seriesName, StringComparer.OrdinalIgnoreCase)).FirstOrDefault(); + + if (info != null) + { + series = _libraryManager.RootFolder.GetRecursiveChildren(i => i is Series) + .Cast() + .Where(i => i.Id == info.Id) + .FirstOrDefault(); + } + } + + return series ?? new Series(); } /// diff --git a/MediaBrowser.Server.Implementations/FileOrganization/Extensions.cs b/MediaBrowser.Server.Implementations/FileOrganization/Extensions.cs index e43ab3665..c560152db 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/Extensions.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/Extensions.cs @@ -10,6 +10,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { return manager.GetConfiguration("autoorganize"); } + public static void SaveAutoOrganizeOptions(this IConfigurationManager manager, AutoOrganizeOptions options) + { + manager.SaveConfiguration("autoorganize", options); + } } public class AutoOrganizeOptionsFactory : IConfigurationFactory diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs index 839a85adb..3dd6a9be0 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs @@ -11,6 +11,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using System; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; @@ -96,9 +97,9 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return _repo.Delete(resultId); } - private TvFileOrganizationOptions GetTvOptions() + private AutoOrganizeOptions GetAutoOrganizeptions() { - return _config.GetAutoOrganizeOptions().TvOptions; + return _config.GetAutoOrganizeOptions(); } public async Task PerformOrganization(string resultId) @@ -113,7 +114,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager, _libraryMonitor, _providerManager); - await organizer.OrganizeEpisodeFile(result.OriginalPath, GetTvOptions(), true, CancellationToken.None) + await organizer.OrganizeEpisodeFile(result.OriginalPath, GetAutoOrganizeptions(), true, CancellationToken.None) .ConfigureAwait(false); } @@ -127,7 +128,55 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager, _libraryMonitor, _providerManager); - await organizer.OrganizeWithCorrection(request, GetTvOptions(), CancellationToken.None).ConfigureAwait(false); + await organizer.OrganizeWithCorrection(request, GetAutoOrganizeptions(), CancellationToken.None).ConfigureAwait(false); + } + + public QueryResult GetSmartMatchInfos(FileOrganizationResultQuery query) + { + if (query == null) + { + throw new ArgumentNullException("query"); + } + + var options = GetAutoOrganizeptions(); + + var items = options.SmartMatchInfos.Skip(query.StartIndex ?? 0).Take(query.Limit ?? Int32.MaxValue); + + return new QueryResult() + { + Items = items.ToArray(), + TotalRecordCount = items.Count() + }; + } + + public void DeleteSmartMatchEntry(string IdString, string matchString) + { + Guid Id; + + if (!Guid.TryParse(IdString, out Id)) + { + throw new ArgumentNullException("Id"); + } + + if (string.IsNullOrEmpty(matchString)) + { + throw new ArgumentNullException("matchString"); + } + + var options = GetAutoOrganizeptions(); + + SmartMatchInfo info = options.SmartMatchInfos.Find(i => i.Id == Id); + + if (info != null && info.MatchStrings.Contains(matchString)) + { + info.MatchStrings.Remove(matchString); + if (info.MatchStrings.Count == 0) + { + options.SmartMatchInfos.Remove(info); + } + + _config.SaveAutoOrganizeOptions(options); + } } } } diff --git a/MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs b/MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs index f1fe5539f..ace3b5af7 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs @@ -50,17 +50,17 @@ namespace MediaBrowser.Server.Implementations.FileOrganization get { return "Library"; } } - private TvFileOrganizationOptions GetTvOptions() + private AutoOrganizeOptions GetAutoOrganizeOptions() { - return _config.GetAutoOrganizeOptions().TvOptions; + return _config.GetAutoOrganizeOptions(); } public async Task Execute(CancellationToken cancellationToken, IProgress progress) { - if (GetTvOptions().IsEnabled) + if (GetAutoOrganizeOptions().TvOptions.IsEnabled) { await new TvFolderOrganizer(_libraryManager, _logger, _fileSystem, _libraryMonitor, _organizationService, _config, _providerManager) - .Organize(GetTvOptions(), cancellationToken, progress).ConfigureAwait(false); + .Organize(GetAutoOrganizeOptions(), cancellationToken, progress).ConfigureAwait(false); } } @@ -74,12 +74,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization public bool IsHidden { - get { return !GetTvOptions().IsEnabled; } + get { return !GetAutoOrganizeOptions().TvOptions.IsEnabled; } } public bool IsEnabled { - get { return GetTvOptions().IsEnabled; } + get { return GetAutoOrganizeOptions().TvOptions.IsEnabled; } } public bool IsActivityLogged diff --git a/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs index 3e5296639..c3fde2c1e 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs @@ -38,7 +38,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization private bool EnableOrganization(FileSystemMetadata fileInfo, TvFileOrganizationOptions options) { - var minFileBytes = options.MinFileSizeMb * 1024 * 1024; + var minFileBytes = options.TvOptions.MinFileSizeMb * 1024 * 1024; try { @@ -52,9 +52,9 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return false; } - public async Task Organize(TvFileOrganizationOptions options, CancellationToken cancellationToken, IProgress progress) + public async Task Organize(AutoOrganizeOptions options, CancellationToken cancellationToken, IProgress progress) { - var watchLocations = options.WatchLocations.ToList(); + var watchLocations = options.TvOptions.WatchLocations.ToList(); var eligibleFiles = watchLocations.SelectMany(GetFilesToOrganize) .OrderBy(_fileSystem.GetCreationTimeUtc) @@ -76,7 +76,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization try { - var result = await organizer.OrganizeEpisodeFile(file.FullName, options, options.OverwriteExistingEpisodes, cancellationToken).ConfigureAwait(false); + var result = await organizer.OrganizeEpisodeFile(file.FullName, options, options.TvOptions.OverwriteExistingEpisodes, cancellationToken).ConfigureAwait(false); if (result.Status == FileSortingStatus.Success && !processedFolders.Contains(file.DirectoryName, StringComparer.OrdinalIgnoreCase)) { processedFolders.Add(file.DirectoryName); @@ -100,7 +100,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization foreach (var path in processedFolders) { - var deleteExtensions = options.LeftOverFileExtensionsToDelete + var deleteExtensions = options.TvOptions.LeftOverFileExtensionsToDelete .Select(i => i.Trim().TrimStart('.')) .Where(i => !string.IsNullOrEmpty(i)) .Select(i => "." + i) @@ -111,7 +111,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization DeleteLeftOverFiles(path, deleteExtensions); } - if (options.DeleteEmptyFolders) + if (options.TvOptions.DeleteEmptyFolders) { if (!IsWatchFolder(path, watchLocations)) { diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 165792291..489574717 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -101,6 +101,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -281,6 +287,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 0e49ccfd077bf114a2a663249d81a2891c46639d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 7 Feb 2016 00:15:26 -0500 Subject: update smart match feature --- .../FileOrganization/AutoOrganizeOptions.cs | 5 ++--- .../FileOrganization/SmartMatchInfo.cs | 9 +++------ .../FileOrganization/EpisodeFileOrganizer.cs | 21 +++++++++++++-------- .../FileOrganization/FileOrganizationService.cs | 19 ++++++++++++------- 4 files changed, 30 insertions(+), 24 deletions(-) (limited to 'MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs') diff --git a/MediaBrowser.Model/FileOrganization/AutoOrganizeOptions.cs b/MediaBrowser.Model/FileOrganization/AutoOrganizeOptions.cs index 071897b51..830d55bf5 100644 --- a/MediaBrowser.Model/FileOrganization/AutoOrganizeOptions.cs +++ b/MediaBrowser.Model/FileOrganization/AutoOrganizeOptions.cs @@ -1,5 +1,4 @@  -using System.Collections.Generic; namespace MediaBrowser.Model.FileOrganization { public class AutoOrganizeOptions @@ -14,12 +13,12 @@ namespace MediaBrowser.Model.FileOrganization /// Gets or sets a list of smart match entries. /// /// The smart match entries. - public List SmartMatchInfos { get; set; } + public SmartMatchInfo[] SmartMatchInfos { get; set; } public AutoOrganizeOptions() { TvOptions = new TvFileOrganizationOptions(); - SmartMatchInfos = new List(); + SmartMatchInfos = new SmartMatchInfo[]{}; } } } diff --git a/MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs b/MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs index 808c0b006..a6bc66e49 100644 --- a/MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs +++ b/MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs @@ -1,19 +1,16 @@  -using System; -using System.Collections.Generic; - namespace MediaBrowser.Model.FileOrganization { public class SmartMatchInfo { - public Guid Id { get; set; } + public string Id { get; set; } public string Name { get; set; } public FileOrganizerType OrganizerType { get; set; } - public List MatchStrings { get; set; } + public string[] MatchStrings { get; set; } public SmartMatchInfo() { - MatchStrings = new List(); + MatchStrings = new string[] { }; } } } diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index a952b60d5..dcce91c31 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -301,20 +301,25 @@ namespace MediaBrowser.Server.Implementations.FileOrganization private void SaveSmartMatchString(string matchString, Series series, AutoOrganizeOptions options) { - SmartMatchInfo info = options.SmartMatchInfos.Find(i => i.Id == series.Id); + var seriesIdString = series.Id.ToString("N"); + SmartMatchInfo info = options.SmartMatchInfos.FirstOrDefault(i => string.Equals(i.Id, seriesIdString)); if (info == null) { info = new SmartMatchInfo(); - info.Id = series.Id; + info.Id = series.Id.ToString("N"); info.OrganizerType = FileOrganizerType.Episode; info.Name = series.Name; - options.SmartMatchInfos.Add(info); + var list = options.SmartMatchInfos.ToList(); + list.Add(info); + options.SmartMatchInfos = list.ToArray(); } if (!info.MatchStrings.Contains(matchString, StringComparer.OrdinalIgnoreCase)) { - info.MatchStrings.Add(matchString); + var list = info.MatchStrings.ToList(); + list.Add(matchString); + info.MatchStrings = list.ToArray(); _config.SaveAutoOrganizeOptions(options); } } @@ -487,14 +492,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization if (series == null) { - SmartMatchInfo info = options.SmartMatchInfos.Where(e => e.MatchStrings.Contains(seriesName, StringComparer.OrdinalIgnoreCase)).FirstOrDefault(); + SmartMatchInfo info = options.SmartMatchInfos.FirstOrDefault(e => e.MatchStrings.Contains(seriesName, StringComparer.OrdinalIgnoreCase)); if (info != null) { - series = _libraryManager.RootFolder.GetRecursiveChildren(i => i is Series) + series = _libraryManager.RootFolder + .GetRecursiveChildren(i => i is Series) .Cast() - .Where(i => i.Id == info.Id) - .FirstOrDefault(); + .FirstOrDefault(i => string.Equals(i.Id.ToString("N"), info.Id)); } } diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs index 3dd6a9be0..ce388bd8e 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs @@ -140,12 +140,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var options = GetAutoOrganizeptions(); - var items = options.SmartMatchInfos.Skip(query.StartIndex ?? 0).Take(query.Limit ?? Int32.MaxValue); + var items = options.SmartMatchInfos.Skip(query.StartIndex ?? 0).Take(query.Limit ?? Int32.MaxValue).ToArray(); return new QueryResult() { - Items = items.ToArray(), - TotalRecordCount = items.Count() + Items = items, + TotalRecordCount = options.SmartMatchInfos.Length }; } @@ -165,14 +165,19 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var options = GetAutoOrganizeptions(); - SmartMatchInfo info = options.SmartMatchInfos.Find(i => i.Id == Id); + SmartMatchInfo info = options.SmartMatchInfos.FirstOrDefault(i => string.Equals(i.Id, IdString)); if (info != null && info.MatchStrings.Contains(matchString)) { - info.MatchStrings.Remove(matchString); - if (info.MatchStrings.Count == 0) + var list = info.MatchStrings.ToList(); + list.Remove(matchString); + info.MatchStrings = list.ToArray(); + + if (info.MatchStrings.Length == 0) { - options.SmartMatchInfos.Remove(info); + var infos = options.SmartMatchInfos.ToList(); + infos.Remove(info); + options.SmartMatchInfos = infos.ToArray(); } _config.SaveAutoOrganizeOptions(options); -- cgit v1.2.3 From 865524da65e13392f2fda94b0c3d9e7c873480e3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 11 Feb 2016 15:09:01 -0500 Subject: fix GetOtherDuplicatePaths --- .../FileOrganization/EpisodeFileOrganizer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs') diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index dcce91c31..6509b016a 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -368,7 +368,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization int? endingEpisodeNumber) { // TODO: Support date-naming? - if (!seasonNumber.HasValue || episodeNumber.HasValue) + if (!seasonNumber.HasValue || !episodeNumber.HasValue) { return new List(); } -- cgit v1.2.3 From 59c9081f4b25b96f7cc9203a319ad19328651772 Mon Sep 17 00:00:00 2001 From: softworkz Date: Mon, 8 Feb 2016 02:25:10 +0100 Subject: Auto-Organize - Feature to remember/persist series matching in manual organization dialog: Changed to match against plain library name inste --- .../FileOrganization/IFileOrganizationService.cs | 4 ++-- MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs | 4 ++-- .../FileOrganization/EpisodeFileOrganizer.cs | 9 ++++----- .../FileOrganization/FileOrganizationService.cs | 10 ++++------ 4 files changed, 12 insertions(+), 15 deletions(-) (limited to 'MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs') diff --git a/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs b/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs index 8d7f4e117..daa670d83 100644 --- a/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs +++ b/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs @@ -78,8 +78,8 @@ namespace MediaBrowser.Controller.FileOrganization /// /// Deletes a smart match entry. /// - /// Item Id. + /// Item name. /// The match string to delete. - void DeleteSmartMatchEntry(string Id, string matchString); + void DeleteSmartMatchEntry(string ItemName, string matchString); } } diff --git a/MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs b/MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs index a6bc66e49..28c99b89b 100644 --- a/MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs +++ b/MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs @@ -3,8 +3,8 @@ namespace MediaBrowser.Model.FileOrganization { public class SmartMatchInfo { - public string Id { get; set; } - public string Name { get; set; } + public string ItemName { get; set; } + public string DisplayName { get; set; } public FileOrganizerType OrganizerType { get; set; } public string[] MatchStrings { get; set; } diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 6509b016a..bbbdcd4b3 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -301,15 +301,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization private void SaveSmartMatchString(string matchString, Series series, AutoOrganizeOptions options) { - var seriesIdString = series.Id.ToString("N"); - SmartMatchInfo info = options.SmartMatchInfos.FirstOrDefault(i => string.Equals(i.Id, seriesIdString)); + SmartMatchInfo info = options.SmartMatchInfos.FirstOrDefault(i => string.Equals(i.ItemName, series.Name)); if (info == null) { info = new SmartMatchInfo(); - info.Id = series.Id.ToString("N"); + info.ItemName = series.Name; info.OrganizerType = FileOrganizerType.Episode; - info.Name = series.Name; + info.DisplayName = series.Name; var list = options.SmartMatchInfos.ToList(); list.Add(info); options.SmartMatchInfos = list.ToArray(); @@ -499,7 +498,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization series = _libraryManager.RootFolder .GetRecursiveChildren(i => i is Series) .Cast() - .FirstOrDefault(i => string.Equals(i.Id.ToString("N"), info.Id)); + .FirstOrDefault(i => string.Equals(i.Name, info.ItemName)); } } diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs index ce388bd8e..cf1387b0e 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs @@ -149,13 +149,11 @@ namespace MediaBrowser.Server.Implementations.FileOrganization }; } - public void DeleteSmartMatchEntry(string IdString, string matchString) + public void DeleteSmartMatchEntry(string itemName, string matchString) { - Guid Id; - - if (!Guid.TryParse(IdString, out Id)) + if (string.IsNullOrEmpty(itemName)) { - throw new ArgumentNullException("Id"); + throw new ArgumentNullException("itemName"); } if (string.IsNullOrEmpty(matchString)) @@ -165,7 +163,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var options = GetAutoOrganizeptions(); - SmartMatchInfo info = options.SmartMatchInfos.FirstOrDefault(i => string.Equals(i.Id, IdString)); + SmartMatchInfo info = options.SmartMatchInfos.FirstOrDefault(i => string.Equals(i.ItemName, itemName)); if (info != null && info.MatchStrings.Contains(matchString)) { -- cgit v1.2.3 From 4f5a659111b1e3953ea8618d1b8d16a2c7e3f081 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 12 Feb 2016 20:50:44 -0500 Subject: use ignorecase --- .../FileOrganization/EpisodeFileOrganizer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs') diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index bbbdcd4b3..9d43dabcd 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -301,7 +301,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization private void SaveSmartMatchString(string matchString, Series series, AutoOrganizeOptions options) { - SmartMatchInfo info = options.SmartMatchInfos.FirstOrDefault(i => string.Equals(i.ItemName, series.Name)); + SmartMatchInfo info = options.SmartMatchInfos.FirstOrDefault(i => string.Equals(i.ItemName, series.Name, StringComparison.OrdinalIgnoreCase)); if (info == null) { @@ -498,7 +498,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization series = _libraryManager.RootFolder .GetRecursiveChildren(i => i is Series) .Cast() - .FirstOrDefault(i => string.Equals(i.Name, info.ItemName)); + .FirstOrDefault(i => string.Equals(i.Name, info.ItemName, StringComparison.OrdinalIgnoreCase)); } } -- cgit v1.2.3