From 9c1ff4af6bcb16c890755452fbf1ad18df68770e Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Thu, 19 May 2011 20:47:07 -0700 Subject: [PATCH] initial stage of indexer refactoring. things compile. --- IISExpress/AppServer/applicationhost.config | 2 +- NzbDrone.Core.Test/QualityProfileTest.cs | 3 + NzbDrone.Core.Test/RootDirProviderTest.cs | 30 +++- NzbDrone.Core.Test/SyncProviderTest.cs | 23 --- NzbDrone.Core/Model/EpisodeParseResult.cs | 4 +- NzbDrone.Core/Model/IndexerType.cs | 16 -- NzbDrone.Core/NzbDrone.Core.csproj | 2 +- NzbDrone.Core/Providers/EpisodeProvider.cs | 95 ++++------ NzbDrone.Core/Providers/HistoryProvider.cs | 4 +- .../Providers/Indexer/IndexerProviderBase.cs | 162 ++---------------- .../Providers/Indexer/IsNeededProvider.cs | 113 ++++++++++++ .../Providers/Indexer/NewzbinProvider.cs | 13 +- .../Providers/Indexer/NzbMatrixProvider.cs | 12 +- .../Providers/Indexer/NzbsOrgProvider.cs | 12 +- .../Providers/Indexer/NzbsRUsProvider.cs | 15 +- NzbDrone.Core/Providers/RootDirProvider.cs | 38 +++- NzbDrone.Core/Providers/SabProvider.cs | 4 +- NzbDrone.Core/Providers/SeriesProvider.cs | 9 +- NzbDrone.Core/Providers/SyncProvider.cs | 36 +--- .../Controllers/AddSeriesController.cs | 2 +- NzbDrone/app.config | 2 +- 21 files changed, 249 insertions(+), 348 deletions(-) delete mode 100644 NzbDrone.Core/Model/IndexerType.cs create mode 100644 NzbDrone.Core/Providers/Indexer/IsNeededProvider.cs diff --git a/IISExpress/AppServer/applicationhost.config b/IISExpress/AppServer/applicationhost.config index 5f57e13ec..cef5c1125 100644 --- a/IISExpress/AppServer/applicationhost.config +++ b/IISExpress/AppServer/applicationhost.config @@ -145,7 +145,7 @@ - + diff --git a/NzbDrone.Core.Test/QualityProfileTest.cs b/NzbDrone.Core.Test/QualityProfileTest.cs index 484326cec..5a58933b2 100644 --- a/NzbDrone.Core.Test/QualityProfileTest.cs +++ b/NzbDrone.Core.Test/QualityProfileTest.cs @@ -58,6 +58,9 @@ namespace NzbDrone.Core.Test var series = Builder.CreateNew().Build(); series.QualityProfileId = profileId; + repo.Add(testProfile); + repo.Add(series); + var result = repo.All(); Assert.Count(1, result); diff --git a/NzbDrone.Core.Test/RootDirProviderTest.cs b/NzbDrone.Core.Test/RootDirProviderTest.cs index a74373b56..9c0e50228 100644 --- a/NzbDrone.Core.Test/RootDirProviderTest.cs +++ b/NzbDrone.Core.Test/RootDirProviderTest.cs @@ -1,7 +1,10 @@ -using System.Linq; +using System; +using System.Linq; using AutoMoq; using MbUnit.Framework; +using Moq; using NzbDrone.Core.Providers; +using NzbDrone.Core.Providers.Core; using NzbDrone.Core.Repository; using NzbDrone.Core.Test.Framework; using SubSonic.Repository; @@ -113,5 +116,30 @@ namespace NzbDrone.Core.Test Assert.AreEqual(1, rootDir.Id); Assert.AreEqual(path, rootDir.Path); } + + [Test] + public void None_existing_folder_returns_empty_list() + { + const string path = "d:\\bad folder"; + + var mocker = new AutoMoqer(); + mocker.GetMock(MockBehavior.Strict) + .Setup(m => m.FolderExists(path)).Returns(false); + + var result = mocker.Resolve().GetUnmappedFolders(path); + + Assert.IsNotNull(result); + Assert.IsEmpty(result); + + mocker.VerifyAllMocks(); + } + + [Test] + [ExpectedException(typeof(ArgumentException))] + public void empty_folder_path_throws() + { + var mocker = new AutoMoqer(); + mocker.Resolve().GetUnmappedFolders(""); + } } } \ No newline at end of file diff --git a/NzbDrone.Core.Test/SyncProviderTest.cs b/NzbDrone.Core.Test/SyncProviderTest.cs index 11c451224..9df079751 100644 --- a/NzbDrone.Core.Test/SyncProviderTest.cs +++ b/NzbDrone.Core.Test/SyncProviderTest.cs @@ -12,29 +12,6 @@ namespace NzbDrone.Core.Test // ReSharper disable InconsistentNaming public class SyncProviderTest : TestBase { - [Test] - public void None_existing_folder_returns_empty_list() - { - const string path = "d:\\bad folder"; - var mocker = new AutoMoqer(); - mocker.GetMock(MockBehavior.Strict) - .Setup(m => m.FolderExists(path)).Returns(false); - - var result = mocker.Resolve().GetUnmappedFolders(path); - - Assert.IsNotNull(result); - Assert.IsEmpty(result); - - mocker.VerifyAllMocks(); - } - - [Test] - [ExpectedException(typeof (ArgumentException))] - public void empty_folder_path_throws() - { - var mocker = new AutoMoqer(); - mocker.Resolve().GetUnmappedFolders(""); - } } } \ No newline at end of file diff --git a/NzbDrone.Core/Model/EpisodeParseResult.cs b/NzbDrone.Core/Model/EpisodeParseResult.cs index 4273534dc..6ea931ae3 100644 --- a/NzbDrone.Core/Model/EpisodeParseResult.cs +++ b/NzbDrone.Core/Model/EpisodeParseResult.cs @@ -7,11 +7,9 @@ namespace NzbDrone.Core.Model public class EpisodeParseResult { internal string CleanTitle { get; set; } - public int SeriesId { get; set; } - - public string FolderName { get; set; } internal int SeasonNumber { get; set; } + internal List Episodes { get; set; } internal string EpisodeTitle { get; set; } diff --git a/NzbDrone.Core/Model/IndexerType.cs b/NzbDrone.Core/Model/IndexerType.cs deleted file mode 100644 index 27427810c..000000000 --- a/NzbDrone.Core/Model/IndexerType.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace NzbDrone.Core.Model -{ - public enum IndexerType - { - Unknown = 0, - NzbsOrg = 1, - NzbMatrix = 2, - NzbsRus = 3, - Newzbin = 4 - } -} diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 9d844f434..d88ba4f5a 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -168,11 +168,11 @@ - + diff --git a/NzbDrone.Core/Providers/EpisodeProvider.cs b/NzbDrone.Core/Providers/EpisodeProvider.cs index 1b22294bd..ee2be5abe 100644 --- a/NzbDrone.Core/Providers/EpisodeProvider.cs +++ b/NzbDrone.Core/Providers/EpisodeProvider.cs @@ -27,6 +27,11 @@ namespace NzbDrone.Core.Providers { } + public virtual int AddEpisode(Episode episode) + { + return (Int32)_repository.Add(episode); + } + public virtual Episode GetEpisode(long id) { return _repository.Single(id); @@ -56,16 +61,6 @@ namespace NzbDrone.Core.Providers return _repository.Find(e => e.SeasonId == seasonId); } - public virtual IList GetEpisodeByParseResult(EpisodeParseResult parseResult) - { - var seasonEpisodes = _repository.All().Where(e => - e.SeriesId == parseResult.SeriesId && - e.SeasonNumber == parseResult.SeasonNumber).ToList(); - - //Has to be done separately since subsonic doesn't support contain method - return seasonEpisodes.Where(c => parseResult.Episodes.Contains(c.EpisodeNumber)).ToList(); - - } public virtual IList EpisodesWithoutFiles(bool includeSpecials) { @@ -80,73 +75,41 @@ namespace NzbDrone.Core.Providers /// /// Episode that needs to be checked /// - public virtual bool IsNeeded(EpisodeParseResult parsedReport) + public virtual bool IsNeeded(EpisodeParseResult parsedReport, Episode episodeInfo) { - //Todo: Fix this so it properly handles multi-epsiode releases (Currently as long as the first episode is needed we download it) - //Todo: for small releases this is less of an issue, but for Full Season Releases this could be an issue if we only need the first episode (or first few) - foreach (var episode in parsedReport.Episodes) + var file = episodeInfo.EpisodeFile; + + if (file != null) { - var episodeInfo = GetEpisode(parsedReport.SeriesId, parsedReport.SeasonNumber, episode); + Logger.Debug("Existing file is {0} proper:{1}", file.Quality, file.Proper); - if (episodeInfo == null) + //There will never be a time when the episode quality is less than what we have and we want it... ever.... I think. + if (file.Quality > parsedReport.Quality) { - Logger.Debug("Episode S{0:00}E{1:00} doesn't exist in db. adding it now.", parsedReport.SeasonNumber, episode); - //Todo: How do we want to handle this really? Episode could be released before information is on TheTvDB - //(Parks and Rec did this a lot in the first season, from experience) - //Keivan: Should automatically add the episode to db with minimal information. then update the description/title when available. - //Mark: Perhaps we should only add the epsiode if its the latest season, sometimes people name things completely wrong (duh!) - episodeInfo = new Episode - { - SeriesId = parsedReport.SeriesId, - AirDate = DateTime.Now.Date, - EpisodeNumber = episode, - SeasonNumber = parsedReport.SeasonNumber, - Title = String.Empty, - Overview = String.Empty, - Language = "en" - }; - - _repository.Add(episodeInfo); - + Logger.Trace("file has better quality. skipping"); + return false; } - var file = episodeInfo.EpisodeFile; - - if (file != null) + //If not null we need to see if this episode has the quality as the download (or if it is better) + if (file.Quality == parsedReport.Quality && file.Proper == parsedReport.Proper) { - Logger.Debug("File is {0} Proper:{1}", file.Quality, file.Proper); - - //There will never be a time when the episode quality is less than what we have and we want it... ever.... I think. - if (file.Quality > parsedReport.Quality) - { - Logger.Trace("file has better quality. skipping"); - continue; - } - - //If not null we need to see if this episode has the quality as the download (or if it is better) - if (file.Quality == parsedReport.Quality && file.Proper == parsedReport.Proper) - { - Logger.Trace("Same quality/proper. existing proper. skipping"); - continue; - } - - //Now we need to handle upgrades and actually pay attention to the Cut-off Value - if (file.Quality < parsedReport.Quality) - { - if (episodeInfo.Series.QualityProfile.Cutoff <= file.Quality) - { - Logger.Trace("Quality is past cut-off skipping."); - continue; - } - } + Logger.Trace("Same quality/proper. existing proper. skipping"); + return false; } - Logger.Debug("Episode {0} is needed", parsedReport); - return true; //If we get to this point and the file has not yet been rejected then accept it + //Now we need to handle upgrades and actually pay attention to the Cut-off Value + if (file.Quality < parsedReport.Quality) + { + if (episodeInfo.Series.QualityProfile.Cutoff <= file.Quality) + { + Logger.Trace("Quality is past cut-off skipping."); + return false; + } + } } - Logger.Debug("Episode {0} is not needed", parsedReport); - return false; + Logger.Debug("Episode {0} is needed", parsedReport); + return true; //If we get to this point and the file has not yet been rejected then accept it } public virtual void RefreshEpisodeInfo(int seriesId) diff --git a/NzbDrone.Core/Providers/HistoryProvider.cs b/NzbDrone.Core/Providers/HistoryProvider.cs index 1c7e12402..58aa914fd 100644 --- a/NzbDrone.Core/Providers/HistoryProvider.cs +++ b/NzbDrone.Core/Providers/HistoryProvider.cs @@ -50,8 +50,10 @@ namespace NzbDrone.Core.Providers { //Looks for the existence of this episode in History if (_repository.Exists(h => h.EpisodeId == episodeId && h.Quality == quality && h.IsProper == proper)) + { + Logger.Debug("Episode in History. ID:{0} Q:{1} Proper:{2}", episodeId, quality, proper); return true; - + } Logger.Debug("Episode not in History. ID:{0} Q:{1} Proper:{2}", episodeId, quality, proper); return false; } diff --git a/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs b/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs index dc84f4c8b..6cd4d16a1 100644 --- a/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs +++ b/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs @@ -1,14 +1,10 @@ using System; using System.Collections.Generic; -using System.IO; using System.Net; using System.ServiceModel.Syndication; -using System.Linq; using NLog; -using NzbDrone.Core.Helpers; using NzbDrone.Core.Model; using NzbDrone.Core.Providers.Core; -using NzbDrone.Core.Providers.ExternalNotification; using NzbDrone.Core.Repository; namespace NzbDrone.Core.Providers.Indexer @@ -16,33 +12,16 @@ namespace NzbDrone.Core.Providers.Indexer public abstract class IndexerProviderBase { protected readonly Logger _logger; - protected readonly ConfigProvider _configProvider; - protected readonly EpisodeProvider _episodeProvider; private readonly HttpProvider _httpProvider; + protected readonly ConfigProvider _configProvider; private readonly IndexerProvider _indexerProvider; - private readonly HistoryProvider _historyProvider; - protected readonly SeasonProvider _seasonProvider; - protected readonly SeriesProvider _seriesProvider; - protected readonly SabProvider _sabProvider; - protected readonly IEnumerable _externalNotificationProvider; - protected IndexerProviderBase(SeriesProvider seriesProvider, SeasonProvider seasonProvider, - EpisodeProvider episodeProvider, ConfigProvider configProvider, - HttpProvider httpProvider, IndexerProvider indexerProvider, - HistoryProvider historyProvider, SabProvider sabProvider, - IEnumerable externalNotificationProvider) + protected IndexerProviderBase(HttpProvider httpProvider, ConfigProvider configProvider, IndexerProvider indexerProvider) { - _seriesProvider = seriesProvider; - _seasonProvider = seasonProvider; - _episodeProvider = episodeProvider; - _configProvider = configProvider; _httpProvider = httpProvider; + _configProvider = configProvider; _indexerProvider = indexerProvider; - _historyProvider = historyProvider; - _sabProvider = sabProvider; - //Todo: IEnumerable yields no results for some reason, yet yields results in other classes - _externalNotificationProvider = externalNotificationProvider; _logger = LogManager.GetLogger(GetType().ToString()); } @@ -51,11 +30,6 @@ namespace NzbDrone.Core.Providers.Indexer /// public abstract string Name { get; } - /// - /// Gets a bool to determine if Backlog Searching is Supported - /// - public abstract bool SupportsBacklog { get; } - /// /// Gets the source URL for the feed /// @@ -80,10 +54,11 @@ namespace NzbDrone.Core.Providers.Indexer /// /// Fetches RSS feed and process each news item. /// - public List Fetch() + public List Fetch() { _logger.Debug("Fetching feeds from " + Settings.Name); - var exeptions = new List(); + + var result = new List(); foreach (var url in Urls) { @@ -98,11 +73,14 @@ namespace NzbDrone.Core.Providers.Indexer { try { - ProcessItem(item); + var parsedEpisode = ParseFeed(item); + if (parsedEpisode != null) + { + result.Add(parsedEpisode); + } } catch (Exception itemEx) { - exeptions.Add(itemEx); _logger.ErrorException("An error occurred while processing feed item", itemEx); } @@ -110,123 +88,24 @@ namespace NzbDrone.Core.Providers.Indexer } catch (Exception feedEx) { - exeptions.Add(feedEx); _logger.ErrorException("An error occurred while processing feed", feedEx); } } _logger.Info("Finished processing feeds from " + Settings.Name); - return exeptions; - } - - internal void ProcessItem(SyndicationItem feedItem) - { - _logger.Debug("Processing RSS feed item " + feedItem.Title.Text); - - var parseResult = ParseFeed(feedItem); - - if (parseResult != null && parseResult.SeriesId != 0) - { - if (!_seriesProvider.IsMonitored(parseResult.SeriesId)) - { - _logger.Debug("{0} is present in the DB but not tracked. skipping.", parseResult.CleanTitle); - return; - } - - if (!_seriesProvider.QualityWanted(parseResult.SeriesId, parseResult.Quality)) - { - _logger.Debug("Post doesn't meet the quality requirements [{0}]. skipping.", parseResult.Quality); - return; - } - - if (_seasonProvider.IsIgnored(parseResult.SeriesId, parseResult.SeasonNumber)) - { - _logger.Debug("Season {0} is currently set to ignore. skipping.", parseResult.SeasonNumber); - return; - } - - //Todo: How to handle full season files? Currently the episode list is completely empty for these releases - //Todo: Should we assume that the release contains all the episodes that belong to this season and add them from the DB? - - if (!_episodeProvider.IsNeeded(parseResult)) - { - _logger.Debug("Episode {0} is not needed. skipping.", parseResult); - return; - } - - var episodes = _episodeProvider.GetEpisodeByParseResult(parseResult); - - if (InHistory(episodes, parseResult, feedItem)) - { - return; - } - - parseResult.EpisodeTitle = episodes[0].Title; - var sabTitle = _sabProvider.GetSabTitle(parseResult); - - if (_sabProvider.IsInQueue(sabTitle)) - { - return; - } - - if (!_sabProvider.AddByUrl(NzbDownloadUrl(feedItem), sabTitle)) - { - _logger.Warn("Unable to add item to SAB queue. {0} {1}", NzbDownloadUrl(feedItem), sabTitle); - return; - } - - foreach (var episode in episodes) - { - _historyProvider.Add(new History - { - Date = DateTime.Now, - EpisodeId = episode.EpisodeId, - IsProper = parseResult.Proper, - NzbTitle = feedItem.Title.Text, - Quality = parseResult.Quality, - Indexer = Name - }); - } - - //Notify! - foreach (var notification in _externalNotificationProvider.Where(n => n.Settings.Enabled)) - { - notification.OnGrab(sabTitle); - } - } + return result; } /// - /// Parses the RSS feed item and. + /// Parses the RSS feed item /// /// RSS feed item to parse /// Detailed episode info public EpisodeParseResult ParseFeed(SyndicationItem item) { var episodeParseResult = Parser.ParseEpisodeInfo(item.Title.Text); - if (episodeParseResult == null) return null; - var seriesInfo = _seriesProvider.FindSeries(episodeParseResult.CleanTitle); - - if (seriesInfo == null) - { - var seriesId = SceneNameHelper.FindByName(episodeParseResult.CleanTitle); - - if (seriesId != 0) - seriesInfo = _seriesProvider.GetSeries(seriesId); - } - - if (seriesInfo != null) - { - episodeParseResult.SeriesId = seriesInfo.SeriesId; - episodeParseResult.FolderName = new DirectoryInfo(seriesInfo.Path).Name; ; - - episodeParseResult.CleanTitle = seriesInfo.Title; - return CustomParser(item, episodeParseResult); - } - - _logger.Debug("Unable to map {0} to any of series in database", episodeParseResult.CleanTitle); - return null; + return CustomParser(item, episodeParseResult); } /// @@ -246,18 +125,5 @@ namespace NzbDrone.Core.Providers.Indexer /// RSS Feed item to generate the link for /// Download link URL protected abstract string NzbDownloadUrl(SyndicationItem item); - - private bool InHistory(IList episodes, EpisodeParseResult parseResult, SyndicationItem feedItem) - { - foreach (var episode in episodes) - { - if (_historyProvider.Exists(episode.EpisodeId, parseResult.Quality, parseResult.Proper)) - { - _logger.Debug("Episode in history: {0}", feedItem.Title.Text); - return true; - } - } - return false; - } } } \ No newline at end of file diff --git a/NzbDrone.Core/Providers/Indexer/IsNeededProvider.cs b/NzbDrone.Core/Providers/Indexer/IsNeededProvider.cs new file mode 100644 index 000000000..f9068c6cd --- /dev/null +++ b/NzbDrone.Core/Providers/Indexer/IsNeededProvider.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using NLog; +using NzbDrone.Core.Helpers; +using NzbDrone.Core.Model; +using NzbDrone.Core.Repository; +using System.ServiceModel.Syndication; + +namespace NzbDrone.Core.Providers.Indexer +{ + public class IsNeededProvider + { + private readonly SeriesProvider _seriesProvider; + private readonly SeasonProvider _seasonProvider; + private readonly EpisodeProvider _episodeProvider; + private readonly HistoryProvider _historyProvider; + private readonly SabProvider _sabProvider; + + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + public IsNeededProvider(SeriesProvider seriesProvider, SeasonProvider seasonProvider, EpisodeProvider episodeProvider, HistoryProvider historyProvider, SabProvider sabProvider) + { + _seriesProvider = seriesProvider; + _seasonProvider = seasonProvider; + _episodeProvider = episodeProvider; + _historyProvider = historyProvider; + _sabProvider = sabProvider; + } + + + internal bool IsNeeded(EpisodeParseResult parseResult, Series series) + { + foreach (var episodeNumber in parseResult.Episodes) + { + //Todo: How to handle full season files? Currently the episode list is completely empty for these releases + //Todo: Should we assume that the release contains all the episodes that belong to this season and add them from the DB? + //Todo: Fix this so it properly handles multi-epsiode releases (Currently as long as the first episode is needed we download it) + //Todo: for small releases this is less of an issue, but for Full Season Releases this could be an issue if we only need the first episode (or first few) + + if (!series.Monitored) + { + Logger.Debug("{0} is present in the DB but not tracked. skipping.", parseResult.CleanTitle); + return false; + } + + if (!_seriesProvider.QualityWanted(series.SeriesId, parseResult.Quality)) + { + Logger.Debug("Post doesn't meet the quality requirements [{0}]. skipping.", parseResult.Quality); + return false; + } + + if (_seasonProvider.IsIgnored(series.SeriesId, parseResult.SeasonNumber)) + { + Logger.Debug("Season {0} is currently set to ignore. skipping.", parseResult.SeasonNumber); + return false; + } + + var episodeInfo = _episodeProvider.GetEpisode(series.SeriesId, parseResult.SeasonNumber, episodeNumber); + if (episodeInfo == null) + { + episodeInfo = _episodeProvider.GetEpisode(series.SeriesId, parseResult.AirDate); + } + //if still null we should add the temp episode + if (episodeInfo == null) + { + Logger.Debug("Episode {0} doesn't exist in db. adding it now.", parseResult); + episodeInfo = new Episode + { + SeriesId = series.SeriesId, + AirDate = DateTime.Now.Date, + EpisodeNumber = episodeNumber, + SeasonNumber = parseResult.SeasonNumber, + Title = parseResult.EpisodeTitle, + Overview = String.Empty, + Language = "en" + }; + + _episodeProvider.AddEpisode(episodeInfo); + } + + + if (!_episodeProvider.IsNeeded(parseResult, episodeInfo)) + { + Logger.Debug("Episode {0} is not needed. skipping.", parseResult); + return false; + } + + if (_historyProvider.Exists(episodeInfo.EpisodeId, parseResult.Quality, parseResult.Proper)) + { + Logger.Debug("Episode {0} is in history. skipping.", parseResult); + return false; + } + + parseResult.EpisodeTitle = episodeInfo.Title; + var sabTitle = _sabProvider.GetSabTitle(parseResult, new DirectoryInfo(series.Path).Name); + + if (_sabProvider.IsInQueue(sabTitle)) + { + Logger.Debug("Episode {0} is already in sab's queue. skipping.", parseResult); + return false; + } + + //Congragulations younge feed item! you have made it this far. you are truly special!!! + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/Providers/Indexer/NewzbinProvider.cs b/NzbDrone.Core/Providers/Indexer/NewzbinProvider.cs index 3e385710b..e35749d0d 100644 --- a/NzbDrone.Core/Providers/Indexer/NewzbinProvider.cs +++ b/NzbDrone.Core/Providers/Indexer/NewzbinProvider.cs @@ -9,13 +9,7 @@ namespace NzbDrone.Core.Providers.Indexer { public class NewzbinProvider : IndexerProviderBase { - public NewzbinProvider(SeriesProvider seriesProvider, SeasonProvider seasonProvider, - EpisodeProvider episodeProvider, ConfigProvider configProvider, - HttpProvider httpProvider, IndexerProvider indexerProvider, - HistoryProvider historyProvider, SabProvider sabProvider, IEnumerable externalNotificationProvider) - : base(seriesProvider, seasonProvider, episodeProvider, - configProvider, httpProvider, indexerProvider, historyProvider, - sabProvider, externalNotificationProvider) + public NewzbinProvider(HttpProvider httpProvider, ConfigProvider configProvider, IndexerProvider indexerProvider) : base(httpProvider, configProvider, indexerProvider) { } @@ -40,11 +34,6 @@ namespace NzbDrone.Core.Providers.Indexer get { return "Newzbin"; } } - public override bool SupportsBacklog - { - get { return false; } - } - protected override string NzbDownloadUrl(SyndicationItem item) { return item.Id + "/nzb"; diff --git a/NzbDrone.Core/Providers/Indexer/NzbMatrixProvider.cs b/NzbDrone.Core/Providers/Indexer/NzbMatrixProvider.cs index 1efdf070f..cdcb34ad3 100644 --- a/NzbDrone.Core/Providers/Indexer/NzbMatrixProvider.cs +++ b/NzbDrone.Core/Providers/Indexer/NzbMatrixProvider.cs @@ -11,13 +11,7 @@ namespace NzbDrone.Core.Providers.Indexer { public class NzbMatrixProvider : IndexerProviderBase { - public NzbMatrixProvider(SeriesProvider seriesProvider, SeasonProvider seasonProvider, - EpisodeProvider episodeProvider, ConfigProvider configProvider, - HttpProvider httpProvider, IndexerProvider indexerProvider, - HistoryProvider historyProvider, SabProvider sabProvider, IEnumerable externalNotificationProvider) - : base(seriesProvider, seasonProvider, episodeProvider, - configProvider, httpProvider, indexerProvider, historyProvider, - sabProvider, externalNotificationProvider) + public NzbMatrixProvider(HttpProvider httpProvider, ConfigProvider configProvider, IndexerProvider indexerProvider) : base(httpProvider, configProvider, indexerProvider) { } @@ -40,10 +34,6 @@ namespace NzbDrone.Core.Providers.Indexer get { return "NzbMatrix"; } } - public override bool SupportsBacklog - { - get { return true; } - } protected override string NzbDownloadUrl(SyndicationItem item) { diff --git a/NzbDrone.Core/Providers/Indexer/NzbsOrgProvider.cs b/NzbDrone.Core/Providers/Indexer/NzbsOrgProvider.cs index b1951ac24..44e76fdc6 100644 --- a/NzbDrone.Core/Providers/Indexer/NzbsOrgProvider.cs +++ b/NzbDrone.Core/Providers/Indexer/NzbsOrgProvider.cs @@ -10,13 +10,7 @@ namespace NzbDrone.Core.Providers.Indexer { public class NzbsOrgProvider : IndexerProviderBase { - public NzbsOrgProvider(SeriesProvider seriesProvider, SeasonProvider seasonProvider, - EpisodeProvider episodeProvider, ConfigProvider configProvider, - HttpProvider httpProvider, IndexerProvider indexerProvider, - HistoryProvider historyProvider, SabProvider sabProvider, IEnumerable externalNotificationProvider) - : base(seriesProvider, seasonProvider, episodeProvider, - configProvider, httpProvider, indexerProvider, historyProvider, - sabProvider, externalNotificationProvider) + public NzbsOrgProvider(HttpProvider httpProvider, ConfigProvider configProvider, IndexerProvider indexerProvider) : base(httpProvider, configProvider, indexerProvider) { } @@ -36,10 +30,6 @@ namespace NzbDrone.Core.Providers.Indexer get { return "Nzbs.org"; } } - public override bool SupportsBacklog - { - get { return false; } - } protected override string NzbDownloadUrl(SyndicationItem item) { diff --git a/NzbDrone.Core/Providers/Indexer/NzbsRUsProvider.cs b/NzbDrone.Core/Providers/Indexer/NzbsRUsProvider.cs index cde0cd431..dd296575c 100644 --- a/NzbDrone.Core/Providers/Indexer/NzbsRUsProvider.cs +++ b/NzbDrone.Core/Providers/Indexer/NzbsRUsProvider.cs @@ -10,13 +10,7 @@ namespace NzbDrone.Core.Providers.Indexer { public class NzbsRUsProvider : IndexerProviderBase { - public NzbsRUsProvider(SeriesProvider seriesProvider, SeasonProvider seasonProvider, - EpisodeProvider episodeProvider, ConfigProvider configProvider, - HttpProvider httpProvider, IndexerProvider indexerProvider, - HistoryProvider historyProvider, SabProvider sabProvider, IEnumerable externalNotificationProvider) - : base(seriesProvider, seasonProvider, episodeProvider, - configProvider, httpProvider, indexerProvider, historyProvider, - sabProvider, externalNotificationProvider) + public NzbsRUsProvider(HttpProvider httpProvider, ConfigProvider configProvider, IndexerProvider indexerProvider) : base(httpProvider, configProvider, indexerProvider) { } @@ -39,12 +33,7 @@ namespace NzbDrone.Core.Providers.Indexer get { return "NzbsRUs"; } } - public override bool SupportsBacklog - { - get { return false; } - } - - protected override string NzbDownloadUrl(SyndicationItem item) + protected override string NzbDownloadUrl(SyndicationItem item) { return item.Links[0].Uri.ToString(); } diff --git a/NzbDrone.Core/Providers/RootDirProvider.cs b/NzbDrone.Core/Providers/RootDirProvider.cs index 49b214391..9c1e1aee9 100644 --- a/NzbDrone.Core/Providers/RootDirProvider.cs +++ b/NzbDrone.Core/Providers/RootDirProvider.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using NLog; +using NzbDrone.Core.Providers.Core; using NzbDrone.Core.Repository; using SubSonic.Repository; @@ -9,10 +12,16 @@ namespace NzbDrone.Core.Providers public class RootDirProvider { private readonly IRepository _sonioRepo; + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + private readonly DiskProvider _diskProvider; + private readonly SeriesProvider _seriesProvider; - public RootDirProvider(IRepository sonicRepo) + + public RootDirProvider(IRepository sonicRepo, SeriesProvider seriesProvider, DiskProvider diskProvider) { _sonioRepo = sonicRepo; + _diskProvider = diskProvider; + _seriesProvider = seriesProvider; } #region IRootDirProvider @@ -42,6 +51,33 @@ namespace NzbDrone.Core.Providers return _sonioRepo.Single(rootDirId); } + public List GetUnmappedFolders(string path) + { + Logger.Debug("Generating list of unmapped folders"); + if (String.IsNullOrEmpty(path)) + throw new ArgumentException("Invalid path provided", "path"); + + var results = new List(); + + if (!_diskProvider.FolderExists(path)) + { + Logger.Debug("Path supplied does not exist: {0}", path); + return results; + } + + + foreach (string seriesFolder in _diskProvider.GetDirectories(path)) + { + var cleanPath = Parser.NormalizePath(new DirectoryInfo(seriesFolder).FullName); + + if (!_seriesProvider.SeriesPathExists(cleanPath)) + results.Add(cleanPath); + } + + Logger.Debug("{0} unmapped folders detected.", results.Count); + return results; + } + #endregion } } \ No newline at end of file diff --git a/NzbDrone.Core/Providers/SabProvider.cs b/NzbDrone.Core/Providers/SabProvider.cs index 418f756b2..e3e9c8610 100644 --- a/NzbDrone.Core/Providers/SabProvider.cs +++ b/NzbDrone.Core/Providers/SabProvider.cs @@ -92,7 +92,7 @@ namespace NzbDrone.Core.Providers _configProvider.SabPassword); } - public String GetSabTitle(EpisodeParseResult parseResult) + public String GetSabTitle(EpisodeParseResult parseResult, String folderName) { //Show Name - 1x01-1x02 - Episode Name //Show Name - 1x01 - Episode Name @@ -105,7 +105,7 @@ namespace NzbDrone.Core.Providers var epNumberString = String.Join("-", episodeString); - var result = String.Format("{0} - {1} - {2} [{3}]", parseResult.FolderName, epNumberString, parseResult.EpisodeTitle, parseResult.Quality); + var result = String.Format("{0} - {1} - {2} [{3}]", folderName, epNumberString, parseResult.EpisodeTitle, parseResult.Quality); if (parseResult.Proper) { diff --git a/NzbDrone.Core/Providers/SeriesProvider.cs b/NzbDrone.Core/Providers/SeriesProvider.cs index 18958712d..866bce749 100644 --- a/NzbDrone.Core/Providers/SeriesProvider.cs +++ b/NzbDrone.Core/Providers/SeriesProvider.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Text.RegularExpressions; using NLog; +using NzbDrone.Core.Helpers; using NzbDrone.Core.Providers.Core; using NzbDrone.Core.Repository; using NzbDrone.Core.Repository.Quality; @@ -108,8 +109,14 @@ namespace NzbDrone.Core.Providers public virtual Series FindSeries(string title) { - //TODO:Add series alias support here. if a series is not found in the repo should be tried using its aliases var normalizeTitle = Parser.NormalizeTitle(title); + + var seriesId = SceneNameHelper.FindByName(normalizeTitle); + if (seriesId != 0) + { + return GetSeries(seriesId); + } + return _repository.Single(s => s.CleanTitle == normalizeTitle); } diff --git a/NzbDrone.Core/Providers/SyncProvider.cs b/NzbDrone.Core/Providers/SyncProvider.cs index 70f353f4f..6da08c76f 100644 --- a/NzbDrone.Core/Providers/SyncProvider.cs +++ b/NzbDrone.Core/Providers/SyncProvider.cs @@ -11,41 +11,7 @@ namespace NzbDrone.Core.Providers { public class SyncProvider { - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - private readonly DiskProvider _diskProvider; - private readonly SeriesProvider _seriesProvider; - public SyncProvider(SeriesProvider seriesProvider, DiskProvider diskProvider) - { - _seriesProvider = seriesProvider; - _diskProvider = diskProvider; - } - - public List GetUnmappedFolders(string path) - { - Logger.Debug("Generating list of unmapped folders"); - if (String.IsNullOrEmpty(path)) - throw new ArgumentException("Invalid path provided", "path"); - - var results = new List(); - - if (!_diskProvider.FolderExists(path)) - { - Logger.Debug("Path supplied does not exist: {0}", path); - return results; - } - - - foreach (string seriesFolder in _diskProvider.GetDirectories(path)) - { - var cleanPath = Parser.NormalizePath(new DirectoryInfo(seriesFolder).FullName); - - if (!_seriesProvider.SeriesPathExists(cleanPath)) - results.Add(cleanPath); - } - - Logger.Debug("{0} unmapped folders detected.", results.Count); - return results; - } + } } \ No newline at end of file diff --git a/NzbDrone.Web/Controllers/AddSeriesController.cs b/NzbDrone.Web/Controllers/AddSeriesController.cs index cef67ebaa..1b2bf1723 100644 --- a/NzbDrone.Web/Controllers/AddSeriesController.cs +++ b/NzbDrone.Web/Controllers/AddSeriesController.cs @@ -72,7 +72,7 @@ namespace NzbDrone.Web.Controllers foreach (var folder in _rootFolderProvider.GetAll()) { - unmappedList.AddRange(_syncProvider.GetUnmappedFolders(folder.Path)); + unmappedList.AddRange(_rootFolderProvider.GetUnmappedFolders(folder.Path)); } return View(unmappedList); diff --git a/NzbDrone/app.config b/NzbDrone/app.config index 81d395705..19dd15844 100644 --- a/NzbDrone/app.config +++ b/NzbDrone/app.config @@ -4,6 +4,6 @@ - + \ No newline at end of file