RssItemProcessingProvider will now handle full series NZBs.
This commit is contained in:
parent
fd06987331
commit
1076b3ab58
|
@ -0,0 +1,15 @@
|
||||||
|
using NzbDrone.Core.Repository.Quality;
|
||||||
|
using SubSonic.SqlGeneration.Schema;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Model
|
||||||
|
{
|
||||||
|
public class SeasonModel
|
||||||
|
{
|
||||||
|
public string SeriesTitle { get; set; }
|
||||||
|
public int SeriesId { get; set; }
|
||||||
|
public int SeasonNumber { get; set; }
|
||||||
|
public QualityTypes Quality { get; set; }
|
||||||
|
public long Size { get; set; }
|
||||||
|
public bool Proper { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using NzbDrone.Core.Repository.Quality;
|
||||||
|
using SubSonic.SqlGeneration.Schema;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Model
|
||||||
|
{
|
||||||
|
public class SeasonParseResult
|
||||||
|
{
|
||||||
|
internal string SeriesTitle { get; set; }
|
||||||
|
internal int SeasonNumber { get; set; }
|
||||||
|
internal int Year { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("Series:{0} Season:{1}", SeriesTitle, SeasonNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -166,6 +166,8 @@
|
||||||
<Compile Include="Instrumentation\SubsonicTarget.cs" />
|
<Compile Include="Instrumentation\SubsonicTarget.cs" />
|
||||||
<Compile Include="Instrumentation\ExceptioneerTarget.cs" />
|
<Compile Include="Instrumentation\ExceptioneerTarget.cs" />
|
||||||
<Compile Include="Instrumentation\NlogWriter.cs" />
|
<Compile Include="Instrumentation\NlogWriter.cs" />
|
||||||
|
<Compile Include="Model\SeasonModel.cs" />
|
||||||
|
<Compile Include="Model\SeasonParseResult.cs" />
|
||||||
<Compile Include="Model\EpisodeParseResult.cs" />
|
<Compile Include="Model\EpisodeParseResult.cs" />
|
||||||
<Compile Include="Model\EpisodeModel.cs" />
|
<Compile Include="Model\EpisodeModel.cs" />
|
||||||
<Compile Include="Model\EpisodeRenameModel.cs" />
|
<Compile Include="Model\EpisodeRenameModel.cs" />
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace NzbDrone.Core.Providers
|
||||||
{
|
{
|
||||||
//This interface will contain methods to process individual RSS Feed Items (Queue if wanted)
|
//This interface will contain methods to process individual RSS Feed Items (Queue if wanted)
|
||||||
|
|
||||||
bool DownloadIfWanted(NzbInfoModel nzb, Indexer indexer);
|
void DownloadIfWanted(NzbInfoModel nzb, Indexer indexer);
|
||||||
string GetTitleFix(List<EpisodeParseResult> episodes, int seriesId);
|
string GetTitleFix(List<EpisodeParseResult> episodes, int seriesId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
using NzbDrone.Core.Repository;
|
using NzbDrone.Core.Repository;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Providers
|
namespace NzbDrone.Core.Providers
|
||||||
|
@ -6,6 +7,7 @@ namespace NzbDrone.Core.Providers
|
||||||
public interface ISeasonProvider
|
public interface ISeasonProvider
|
||||||
{
|
{
|
||||||
Season GetSeason(int seasonId);
|
Season GetSeason(int seasonId);
|
||||||
|
Season GetSeason(int seriesId, int seasonNumber);
|
||||||
List<Season> GetSeasons(int seriesId);
|
List<Season> GetSeasons(int seriesId);
|
||||||
Season GetLatestSeason(int seriesId);
|
Season GetLatestSeason(int seriesId);
|
||||||
void EnsureSeason(int seriesId, int seasonId, int seasonNumber);
|
void EnsureSeason(int seriesId, int seasonId, int seasonNumber);
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace NzbDrone.Core.Providers
|
||||||
|
|
||||||
#region IRssItemProcessingProvider Members
|
#region IRssItemProcessingProvider Members
|
||||||
|
|
||||||
public bool DownloadIfWanted(NzbInfoModel nzb, Indexer indexer)
|
public void DownloadIfWanted(NzbInfoModel nzb, Indexer indexer)
|
||||||
{
|
{
|
||||||
//Do we want this item?
|
//Do we want this item?
|
||||||
try
|
try
|
||||||
|
@ -48,7 +48,7 @@ namespace NzbDrone.Core.Providers
|
||||||
if (nzb.IsPassworded())
|
if (nzb.IsPassworded())
|
||||||
{
|
{
|
||||||
Logger.Debug("Skipping Passworded Report {0}", nzb.Title);
|
Logger.Debug("Skipping Passworded Report {0}", nzb.Title);
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var episodeParseResults = Parser.ParseEpisodeInfo(nzb.Title);
|
var episodeParseResults = Parser.ParseEpisodeInfo(nzb.Title);
|
||||||
|
@ -56,24 +56,26 @@ namespace NzbDrone.Core.Providers
|
||||||
if (episodeParseResults.Count() > 0)
|
if (episodeParseResults.Count() > 0)
|
||||||
{
|
{
|
||||||
ProcessStandardItem(nzb, indexer, episodeParseResults);
|
ProcessStandardItem(nzb, indexer, episodeParseResults);
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Todo: Try to handle Season X style naming
|
//Handles Full Season NZBs
|
||||||
|
var seasonParsedResult = Parser.ParseSeasonInfo(nzb.Title);
|
||||||
|
|
||||||
if (episodeParseResults.Count() < 1)
|
if (seasonParsedResult != null)
|
||||||
{
|
{
|
||||||
Logger.Debug("Unsupported Title: {0}", nzb.Title);
|
//ProcessFullSeasonItem
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.Debug("Unsupported Title: {0}", nzb.Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Error("Unsupported Title: {0}", nzb.Title);
|
Logger.Error("Unsupported Title: {0}", nzb.Title);
|
||||||
Logger.ErrorException("Error Parsing NZB: " + ex.Message, ex);
|
Logger.ErrorException("Error Parsing/Processing NZB: " + ex.Message, ex);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetTitleFix(List<EpisodeParseResult> episodes, int seriesId)
|
public string GetTitleFix(List<EpisodeParseResult> episodes, int seriesId)
|
||||||
|
@ -157,39 +159,19 @@ namespace NzbDrone.Core.Providers
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//If their is more than one episode in this NZB check to see if it has been added as a single NZB
|
|
||||||
|
|
||||||
//Do we want to download the NZB Directly or Send to SABnzbd?
|
|
||||||
|
|
||||||
nzb.TitleFix = GetTitleFix(episodeParseResults, series.SeriesId); //Get the TitleFix so we can use it later
|
nzb.TitleFix = GetTitleFix(episodeParseResults, series.SeriesId); //Get the TitleFix so we can use it later
|
||||||
nzb.TitleFix = String.Format("{0} [{1}]", nzb.TitleFix, nzb.Quality); //Add Quality to the titleFix
|
nzb.TitleFix = String.Format("{0} [{1}]", nzb.TitleFix, nzb.Quality); //Add Quality to the titleFix
|
||||||
|
|
||||||
if (Convert.ToBoolean(_configProvider.GetValue("UseBlackHole", true, true)))
|
if (Convert.ToBoolean(_configProvider.GetValue("UseBlackHole", true, true)))
|
||||||
{
|
{
|
||||||
var path = _configProvider.GetValue("BlackholeDirectory", String.Empty, true);
|
if (DownloadNzb(nzb))
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(path))
|
|
||||||
{
|
|
||||||
//Use the NZBDrone root Directory + /NZBs
|
|
||||||
//path = CentralDispatch.StartupPath + "NZBs";
|
|
||||||
path = @"C:\Test\NZBs";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_diskProvider.FolderExists(path))
|
|
||||||
{
|
|
||||||
var filename = path + Path.DirectorySeparatorChar + nzb.TitleFix + ".nzb";
|
|
||||||
|
|
||||||
if (_httpProvider.DownloadFile(nzb.Link.ToString(), filename))
|
|
||||||
AddToHistory(episodeParseResults, series, nzb, indexer);
|
AddToHistory(episodeParseResults, series, nzb, indexer);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
|
||||||
Logger.Error("Blackhole Directory doesn't exist, not saving NZB: '{0}'", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Send it to SABnzbd
|
//Send it to SABnzbd
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//Only need to do this check if it contains more than one episode (because we already checked individually before)
|
||||||
if (episodeParseResults.Count > 1)
|
if (episodeParseResults.Count > 1)
|
||||||
{
|
{
|
||||||
if (_sabProvider.IsInQueue(nzb.TitleFix))
|
if (_sabProvider.IsInQueue(nzb.TitleFix))
|
||||||
|
@ -199,7 +181,126 @@ namespace NzbDrone.Core.Providers
|
||||||
if (indexer.IndexerName != "Newzbin")
|
if (indexer.IndexerName != "Newzbin")
|
||||||
{
|
{
|
||||||
if (AddByUrl(nzb))
|
if (AddByUrl(nzb))
|
||||||
|
AddToHistory(episodeParseResults, series, nzb, indexer);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
{
|
{
|
||||||
|
//Send to SAB using Newzbin ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessFullSeasonItem(NzbInfoModel nzb, Indexer indexer, SeasonParseResult seasonParseResult)
|
||||||
|
{
|
||||||
|
//Will try to match via NormalizeTitle, if that fails it will look for a scene name and do a lookup for your shows
|
||||||
|
var series = _seriesProvider.FindSeries(seasonParseResult.SeriesTitle);
|
||||||
|
|
||||||
|
if (series == null)
|
||||||
|
{
|
||||||
|
//If we weren't able to find a title using the clean name, lets try again looking for a scene name
|
||||||
|
|
||||||
|
var sceneId = SceneNameHelper.FindByName(seasonParseResult.SeriesTitle);
|
||||||
|
|
||||||
|
if (sceneId != 0)
|
||||||
|
series = _seriesProvider.GetSeries(sceneId);
|
||||||
|
|
||||||
|
if (series == null)
|
||||||
|
{
|
||||||
|
Logger.Debug("Show is not being watched: {0}", seasonParseResult.SeriesTitle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Debug("Show is being watched: {0}", series.Title);
|
||||||
|
|
||||||
|
nzb.Proper = Parser.ParseProper(nzb.Title);
|
||||||
|
nzb.Quality = Parser.ParseQuality(nzb.Title);
|
||||||
|
|
||||||
|
if (!_seriesProvider.QualityWanted(series.SeriesId, nzb.Quality))
|
||||||
|
{
|
||||||
|
Logger.Info("Quality [{0}] is not wanted for: {1}", nzb.Quality, series.Title);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var season = _seasonProvider.GetSeason(series.SeriesId, seasonParseResult.SeasonNumber);
|
||||||
|
|
||||||
|
if (season == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_seasonProvider.IsIgnored(season.SeriesId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Check to see if this is an upgrade for all our files
|
||||||
|
|
||||||
|
var episodesWithoutFiles = season.Episodes.Where(e => e.EpisodeFileId == 0);
|
||||||
|
|
||||||
|
var downloadWholeSeason = false;
|
||||||
|
|
||||||
|
if (season.Episodes.Count() == episodesWithoutFiles.Count())
|
||||||
|
{
|
||||||
|
//We don't have any episodes for this season, so as it stands right now we need the entire NZB
|
||||||
|
//Download!
|
||||||
|
downloadWholeSeason = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var episodesNeeded = season.Episodes.Count;
|
||||||
|
|
||||||
|
foreach (var episode in season.Episodes)
|
||||||
|
{
|
||||||
|
var episodeModel = new EpisodeModel();
|
||||||
|
episodeModel.Proper = nzb.Proper;
|
||||||
|
episodeModel.SeriesId = series.SeriesId;
|
||||||
|
episodeModel.SeriesTitle = series.Title;
|
||||||
|
episodeModel.Quality = nzb.Quality;
|
||||||
|
episodeModel.SeasonNumber = episode.SeasonNumber;
|
||||||
|
episodeModel.EpisodeNumber = episode.EpisodeNumber;
|
||||||
|
|
||||||
|
if (!_episodeProvider.IsNeeded(episodeModel))
|
||||||
|
{
|
||||||
|
downloadWholeSeason = false;
|
||||||
|
episodesNeeded--; //Decrement the number of downloads we need, used if we want to replace all existing episodes if this will upgrade over X% of files
|
||||||
|
break; //We only want to download this NZB if ALL episodes can be upgraded by this Season NZB
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downloadWholeSeason)
|
||||||
|
{
|
||||||
|
//Do the final check to ensure we should download this NZB
|
||||||
|
|
||||||
|
if (Convert.ToBoolean(_configProvider.GetValue("UseBlackHole", true, true)))
|
||||||
|
{
|
||||||
|
if (DownloadNzb(nzb))
|
||||||
|
{
|
||||||
|
var episodeParseResults = new List<EpisodeParseResult>();
|
||||||
|
episodeParseResults.AddRange(
|
||||||
|
season.Episodes.Select(
|
||||||
|
e =>
|
||||||
|
new EpisodeParseResult {EpisodeNumber = e.EpisodeNumber, SeasonNumber = e.SeasonNumber}));
|
||||||
|
|
||||||
|
AddToHistory(episodeParseResults, series, nzb, indexer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Send it to SABnzbd
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_sabProvider.IsInQueue(nzb.TitleFix))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (indexer.IndexerName != "Newzbin")
|
||||||
|
{
|
||||||
|
if (AddByUrl(nzb))
|
||||||
|
{
|
||||||
|
var episodeParseResults = new List<EpisodeParseResult>();
|
||||||
|
episodeParseResults.AddRange(
|
||||||
|
season.Episodes.Select(
|
||||||
|
e =>
|
||||||
|
new EpisodeParseResult { EpisodeNumber = e.EpisodeNumber, SeasonNumber = e.SeasonNumber }));
|
||||||
|
|
||||||
AddToHistory(episodeParseResults, series, nzb, indexer);
|
AddToHistory(episodeParseResults, series, nzb, indexer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,10 +308,13 @@ namespace NzbDrone.Core.Providers
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//AddById(episodeParseResults, series, nzb, indexer);
|
//Send to SAB using Newzbin ID
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Possibly grab the whole season if a certain % of the season is missing, rather than for 1 or 2 episodes
|
||||||
|
throw new NotImplementedException("NzbDrone is currently not able to handle downloadinga whole season when less than a whole season it missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool AddByUrl(NzbInfoModel nzb)
|
private bool AddByUrl(NzbInfoModel nzb)
|
||||||
|
@ -246,5 +350,28 @@ namespace NzbDrone.Core.Providers
|
||||||
_historyProvider.Insert(history);
|
_historyProvider.Insert(history);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool DownloadNzb(NzbInfoModel nzb)
|
||||||
|
{
|
||||||
|
var path = _configProvider.GetValue("BlackholeDirectory", String.Empty, true);
|
||||||
|
|
||||||
|
if (String.IsNullOrEmpty(path))
|
||||||
|
{
|
||||||
|
//Use the NZBDrone root Directory + /NZBs
|
||||||
|
//path = CentralDispatch.StartupPath + "NZBs";
|
||||||
|
path = @"C:\Test\NZBs";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_diskProvider.FolderExists(path))
|
||||||
|
{
|
||||||
|
var filename = path + Path.DirectorySeparatorChar + nzb.TitleFix + ".nzb";
|
||||||
|
|
||||||
|
if (_httpProvider.DownloadFile(nzb.Link.ToString(), filename))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Error("Blackhole Directory doesn't exist, not saving NZB: '{0}'", path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,8 +92,6 @@ namespace NzbDrone.Core.Providers
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
using NzbDrone.Core.Repository;
|
using NzbDrone.Core.Repository;
|
||||||
using SubSonic.Repository;
|
using SubSonic.Repository;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -10,11 +11,14 @@ namespace NzbDrone.Core.Providers
|
||||||
class SeasonProvider : ISeasonProvider
|
class SeasonProvider : ISeasonProvider
|
||||||
{
|
{
|
||||||
private readonly IRepository _sonicRepo;
|
private readonly IRepository _sonicRepo;
|
||||||
|
private readonly ISeriesProvider _seriesProvider;
|
||||||
|
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public SeasonProvider(IRepository dataRepository)
|
public SeasonProvider(IRepository dataRepository, ISeriesProvider seriesProvider)
|
||||||
{
|
{
|
||||||
_sonicRepo = dataRepository;
|
_sonicRepo = dataRepository;
|
||||||
|
_seriesProvider = seriesProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Season GetSeason(int seasonId)
|
public Season GetSeason(int seasonId)
|
||||||
|
@ -22,6 +26,11 @@ namespace NzbDrone.Core.Providers
|
||||||
return _sonicRepo.Single<Season>(seasonId);
|
return _sonicRepo.Single<Season>(seasonId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Season GetSeason(int seriesId, int seasonNumber)
|
||||||
|
{
|
||||||
|
return _sonicRepo.Single<Season>(s => s.SeriesId == seriesId && s.SeasonNumber == seasonNumber);
|
||||||
|
}
|
||||||
|
|
||||||
public List<Season> GetSeasons(int seriesId)
|
public List<Season> GetSeasons(int seriesId)
|
||||||
{
|
{
|
||||||
return _sonicRepo.All<Season>().Where(s => s.SeriesId == seriesId).ToList();
|
return _sonicRepo.All<Season>().Where(s => s.SeriesId == seriesId).ToList();
|
||||||
|
@ -70,7 +79,7 @@ namespace NzbDrone.Core.Providers
|
||||||
if (season == null)
|
if (season == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return season.Monitored;
|
return !season.Monitored;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteSeason(int seasonId)
|
public void DeleteSeason(int seasonId)
|
||||||
|
|
Loading…
Reference in New Issue