@ -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 < E xception > Fetch ( )
public List < E pisodeParseResult > 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 ;
}
}
}