mirror of https://github.com/Radarr/Radarr
initial stage of indexer refactoring. things compile.
This commit is contained in:
parent
7d7b37be5b
commit
9c1ff4af6b
|
@ -145,7 +145,7 @@
|
|||
<virtualDirectory path="/" physicalPath="%NZBDRONE_PATH%\NZBDrone.Web" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:8989:" />
|
||||
<binding protocol="http" bindingInformation="*:8980:" />
|
||||
</bindings>
|
||||
</site>
|
||||
<siteDefaults>
|
||||
|
|
|
@ -58,6 +58,9 @@ namespace NzbDrone.Core.Test
|
|||
var series = Builder<Series>.CreateNew().Build();
|
||||
series.QualityProfileId = profileId;
|
||||
|
||||
repo.Add(testProfile);
|
||||
repo.Add(series);
|
||||
|
||||
var result = repo.All<Series>();
|
||||
|
||||
Assert.Count(1, result);
|
||||
|
|
|
@ -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<DiskProvider>(MockBehavior.Strict)
|
||||
.Setup(m => m.FolderExists(path)).Returns(false);
|
||||
|
||||
var result = mocker.Resolve<RootDirProvider>().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<RootDirProvider>().GetUnmappedFolders("");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<DiskProvider>(MockBehavior.Strict)
|
||||
.Setup(m => m.FolderExists(path)).Returns(false);
|
||||
|
||||
var result = mocker.Resolve<SyncProvider>().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<SyncProvider>().GetUnmappedFolders("");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<int> Episodes { get; set; }
|
||||
|
||||
internal string EpisodeTitle { get; set; }
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -168,11 +168,11 @@
|
|||
<Compile Include="Instrumentation\NlogWriter.cs" />
|
||||
<Compile Include="Model\ConnectionInfoModel.cs" />
|
||||
<Compile Include="Model\ExternalNotificationType.cs" />
|
||||
<Compile Include="Model\IndexerType.cs" />
|
||||
<Compile Include="Model\LanguageType.cs" />
|
||||
<Compile Include="Model\SabnzbdInfoModel.cs" />
|
||||
<Compile Include="Providers\ExternalNotification\ExternalNotificationProviderBase.cs" />
|
||||
<Compile Include="Providers\ExternalNotification\XbmcNotificationProvider.cs" />
|
||||
<Compile Include="Providers\Indexer\IsNeededProvider.cs" />
|
||||
<Compile Include="Providers\Indexer\SyndicationFeedXmlReader.cs" />
|
||||
<Compile Include="Providers\AutoConfigureProvider.cs" />
|
||||
<Compile Include="Providers\Indexer\NzbMatrixProvider.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<Episode>(id);
|
||||
|
@ -56,16 +61,6 @@ namespace NzbDrone.Core.Providers
|
|||
return _repository.Find<Episode>(e => e.SeasonId == seasonId);
|
||||
}
|
||||
|
||||
public virtual IList<Episode> GetEpisodeByParseResult(EpisodeParseResult parseResult)
|
||||
{
|
||||
var seasonEpisodes = _repository.All<Episode>().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<Episode> EpisodesWithoutFiles(bool includeSpecials)
|
||||
{
|
||||
|
@ -80,73 +75,41 @@ namespace NzbDrone.Core.Providers
|
|||
/// </summary>
|
||||
/// <param name = "parsedReport">Episode that needs to be checked</param>
|
||||
/// <returns></returns>
|
||||
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)
|
||||
|
|
|
@ -50,8 +50,10 @@ namespace NzbDrone.Core.Providers
|
|||
{
|
||||
//Looks for the existence of this episode in History
|
||||
if (_repository.Exists<History>(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;
|
||||
}
|
||||
|
|
|
@ -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<ExternalNotificationProviderBase> _externalNotificationProvider;
|
||||
|
||||
protected IndexerProviderBase(SeriesProvider seriesProvider, SeasonProvider seasonProvider,
|
||||
EpisodeProvider episodeProvider, ConfigProvider configProvider,
|
||||
HttpProvider httpProvider, IndexerProvider indexerProvider,
|
||||
HistoryProvider historyProvider, SabProvider sabProvider,
|
||||
IEnumerable<ExternalNotificationProviderBase> 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
|
|||
/// </summary>
|
||||
public abstract string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a bool to determine if Backlog Searching is Supported
|
||||
/// </summary>
|
||||
public abstract bool SupportsBacklog { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source URL for the feed
|
||||
/// </summary>
|
||||
|
@ -80,10 +54,11 @@ namespace NzbDrone.Core.Providers.Indexer
|
|||
/// <summary>
|
||||
/// Fetches RSS feed and process each news item.
|
||||
/// </summary>
|
||||
public List<Exception> Fetch()
|
||||
public List<EpisodeParseResult> Fetch()
|
||||
{
|
||||
_logger.Debug("Fetching feeds from " + Settings.Name);
|
||||
var exeptions = new List<Exception>();
|
||||
|
||||
var result = new List<EpisodeParseResult>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the RSS feed item and.
|
||||
/// Parses the RSS feed item
|
||||
/// </summary>
|
||||
/// <param name = "item">RSS feed item to parse</param>
|
||||
/// <returns>Detailed episode info</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -246,18 +125,5 @@ namespace NzbDrone.Core.Providers.Indexer
|
|||
/// <param name = "item">RSS Feed item to generate the link for</param>
|
||||
/// <returns>Download link URL</returns>
|
||||
protected abstract string NzbDownloadUrl(SyndicationItem item);
|
||||
|
||||
private bool InHistory(IList<Episode> 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<ExternalNotificationProviderBase> 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";
|
||||
|
|
|
@ -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<ExternalNotificationProviderBase> 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)
|
||||
{
|
||||
|
|
|
@ -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<ExternalNotificationProviderBase> 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)
|
||||
{
|
||||
|
|
|
@ -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<ExternalNotificationProviderBase> 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();
|
||||
}
|
||||
|
|
|
@ -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<RootDir>(rootDirId);
|
||||
}
|
||||
|
||||
public List<String> 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<String>();
|
||||
|
||||
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
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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<Series>(s => s.CleanTitle == normalizeTitle);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<String> 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<String>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
<supportedRuntime version="v4.0" />
|
||||
</startup>
|
||||
<appSettings>
|
||||
<add key="port" value="8989" />
|
||||
<add key="port" value="8980" />
|
||||
</appSettings>
|
||||
</configuration>
|
Loading…
Reference in New Issue