mirror of
https://github.com/Sonarr/Sonarr.git
synced 2025-01-10 23:29:53 +02:00
removed most of existing rss code
This commit is contained in:
parent
11e2b63b60
commit
7e4c38ec3f
@ -86,7 +86,6 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="QualityProfileTest.cs" />
|
||||
<Compile Include="RepoTest.cs" />
|
||||
<Compile Include="RssProviderTest.cs" />
|
||||
<Compile Include="SabControllerTest.cs" />
|
||||
<Compile Include="SeriesProviderTest.cs" />
|
||||
<Compile Include="IndexerProviderTest.cs" />
|
||||
|
@ -65,7 +65,6 @@ public void tvdbid_is_preserved([RandomNumbers(Minimum = 100, Maximum = 999, Cou
|
||||
public void enteties_toString()
|
||||
{
|
||||
Console.WriteLine(new Episode().ToString());
|
||||
Console.WriteLine(new EpisodeModel().ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -1,35 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Policy;
|
||||
using System.Text;
|
||||
using Gallio.Framework;
|
||||
using MbUnit.Framework;
|
||||
using MbUnit.Framework.ContractVerifiers;
|
||||
using Moq;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using Rss;
|
||||
|
||||
namespace NzbDrone.Core.Test
|
||||
{
|
||||
[TestFixture]
|
||||
public class RssProviderTest
|
||||
{
|
||||
[Test]
|
||||
public void GetFeed()
|
||||
{
|
||||
//Setup
|
||||
var feedInfo = new FeedInfoModel("NzbMatrix", @"Files\Feed.nzbmatrix.com.xml");
|
||||
var target = new RssProvider();
|
||||
|
||||
//Act
|
||||
var enumerable = target.GetFeed(feedInfo);
|
||||
var result = new List<RssItem>();
|
||||
result.AddRange(enumerable);
|
||||
|
||||
//Assert
|
||||
Assert.GreaterThan(result.Count, 1); //Assert that the number of Items in the feed is greater than 1
|
||||
}
|
||||
}
|
||||
}
|
@ -67,14 +67,10 @@ public static void BindKernel()
|
||||
_kernel.Bind<IHistoryProvider>().To<HistoryProvider>();
|
||||
_kernel.Bind<IQualityProvider>().To<QualityProvider>();
|
||||
_kernel.Bind<IRootDirProvider>().To<RootDirProvider>();
|
||||
_kernel.Bind<IRssItemProcessingProvider>().To<RssItemProcessingProvider>();
|
||||
_kernel.Bind<IExtenalNotificationProvider>().To<ExternalNotificationProvider>();
|
||||
_kernel.Bind<IXbmcProvider>().To<XbmcProvider>();
|
||||
_kernel.Bind<IConfigProvider>().To<ConfigProvider>().InSingletonScope();
|
||||
_kernel.Bind<ISyncProvider>().To<SyncProvider>().InSingletonScope();
|
||||
_kernel.Bind<IRssProvider>().To<RssProvider>().InSingletonScope();
|
||||
_kernel.Bind<IBacklogProvider>().To<BacklogProvider>().InSingletonScope();
|
||||
_kernel.Bind<IRssSyncProvider>().To<RssSyncProvider>().InSingletonScope();
|
||||
_kernel.Bind<IIndexerProvider>().To<IndexerProvider>().InSingletonScope();
|
||||
_kernel.Bind<IRenameProvider>().To<RenameProvider>().InSingletonScope();
|
||||
_kernel.Bind<INotificationProvider>().To<NotificationProvider>().InSingletonScope();
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,53 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NzbDrone.Core.Model
|
||||
{
|
||||
public class FeedInfoModel
|
||||
{
|
||||
public FeedInfoModel(string name, string url)
|
||||
{
|
||||
Name = name ?? "UN-NAMED";
|
||||
Url = ParseUrl(url);
|
||||
}
|
||||
|
||||
public string Name { get; private set; }
|
||||
public string Url { get; private set; }
|
||||
|
||||
private static string ParseUrl(string url)
|
||||
{
|
||||
Uri uri;
|
||||
if (!Uri.TryCreate(url, UriKind.Absolute, out uri))
|
||||
{
|
||||
uri = new Uri(new Uri(CentralDispatch.ExecutablePath + Path.DirectorySeparatorChar), url);
|
||||
}
|
||||
return uri.IsFile ? uri.AbsolutePath.Replace("%20", " ") : uri.AbsoluteUri;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != typeof(FeedInfoModel)) return false;
|
||||
return Equals((FeedInfoModel) obj);
|
||||
}
|
||||
|
||||
public bool Equals(FeedInfoModel other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return Equals(other.Name, Name) && Equals(other.Url, Url);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return ((Name != null ? Name.GetHashCode() : 0)*397) ^ (Url != null ? Url.GetHashCode() : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -10,10 +10,7 @@ namespace NzbDrone.Core.Model
|
||||
public class NzbInfoModel
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string TitleFix { get; set; }
|
||||
public Uri Link { get; set; }
|
||||
public bool Proper { get; set; }
|
||||
public QualityTypes Quality { get; set; }
|
||||
|
||||
public bool IsPassworded()
|
||||
{
|
||||
|
@ -137,10 +137,6 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Libraries\NLog.Extended.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RSS.NET, Version=0.86.3627.40828, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Libraries\RSS.NET.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SubSonic.Core, Version=3.0.0.3, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>D:\OpenSource\sabscripts\SABSync\References\SubSonic.Core.dll</HintPath>
|
||||
</Reference>
|
||||
@ -172,13 +168,11 @@
|
||||
<Compile Include="Model\EpisodeRenameModel.cs" />
|
||||
<Compile Include="Model\EpisodeSortingType.cs" />
|
||||
<Compile Include="Model\EpisodeStatusType.cs" />
|
||||
<Compile Include="Model\FeedInfoModel.cs" />
|
||||
<Compile Include="Model\NzbInfoModel.cs" />
|
||||
<Compile Include="Model\SabnzbdPriorityType.cs" />
|
||||
<Compile Include="Model\SceneNameModel.cs" />
|
||||
<Compile Include="Model\SeasonParseResult.cs" />
|
||||
<Compile Include="Model\UpcomingEpisodesModel.cs" />
|
||||
<Compile Include="Providers\BacklogProvider.cs" />
|
||||
<Compile Include="Providers\FeedProviderBase.cs" />
|
||||
<Compile Include="Providers\ExternalNotificationProvider.cs" />
|
||||
<Compile Include="Providers\HistoryProvider.cs" />
|
||||
@ -191,9 +185,7 @@
|
||||
<Compile Include="Providers\IQualityProvider.cs" />
|
||||
<Compile Include="Providers\IRenameProvider.cs" />
|
||||
<Compile Include="Providers\IRootDirProvider.cs" />
|
||||
<Compile Include="Providers\IRssItemProcessingProvider.cs" />
|
||||
<Compile Include="Providers\IRssSyncProvider.cs" />
|
||||
<Compile Include="Providers\Core\IRssProvider.cs" />
|
||||
<Compile Include="Providers\ITimerProvider.cs" />
|
||||
<Compile Include="Providers\IUpcomingEpisodesProvider.cs" />
|
||||
<Compile Include="Providers\IXbmcProvider.cs" />
|
||||
@ -201,9 +193,6 @@
|
||||
<Compile Include="Providers\QualityProvider.cs" />
|
||||
<Compile Include="Providers\RenameProvider.cs" />
|
||||
<Compile Include="Providers\RootDirProvider.cs" />
|
||||
<Compile Include="Providers\RssItemProcessingProvider.cs" />
|
||||
<Compile Include="Providers\RssSyncProvider.cs" />
|
||||
<Compile Include="Providers\Core\RssProvider.cs" />
|
||||
<Compile Include="Providers\TimerProvider.cs" />
|
||||
<Compile Include="Providers\UpcomingEpisodesProvider.cs" />
|
||||
<Compile Include="Providers\XbmcProvider.cs" />
|
||||
@ -280,8 +269,6 @@
|
||||
<Content Include="Libraries\NLog.Extended.dll" />
|
||||
<Content Include="Libraries\NLog.Extended.xml" />
|
||||
<Content Include="Libraries\NLog.xml" />
|
||||
<Content Include="Libraries\RSS.NET.dll" />
|
||||
<Content Include="Libraries\RSS.NET.XML" />
|
||||
<Content Include="Libraries\SubSonic.Core.dll" />
|
||||
<Content Include="Libraries\SubSonic.Core.XML" />
|
||||
<Content Include="Libraries\System.Data.SQLite.dll" />
|
||||
|
@ -8,7 +8,6 @@
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Repository.Quality;
|
||||
using Rss;
|
||||
|
||||
namespace NzbDrone.Core
|
||||
{
|
||||
@ -38,7 +37,7 @@ internal static EpisodeParseResult ParseEpisodeInfo(string title)
|
||||
{
|
||||
Logger.Trace("Parsing string '{0}'", title);
|
||||
|
||||
foreach (var regex in ReportTitleRegex)
|
||||
foreach (var regex in ReportTitleRegex)
|
||||
{
|
||||
var match = regex.Matches(title);
|
||||
|
||||
@ -55,6 +54,7 @@ internal static EpisodeParseResult ParseEpisodeInfo(string title)
|
||||
|
||||
var parsedEpisode = new EpisodeParseResult
|
||||
{
|
||||
Proper = title.ToLower().Contains("proper"),
|
||||
SeriesTitle = seriesName,
|
||||
SeasonNumber = Convert.ToInt32(match[0].Groups["season"].Value),
|
||||
Year = year,
|
||||
@ -256,14 +256,6 @@ public static string NormalizePath(string path)
|
||||
return info.FullName.Trim('/', '\\', ' ');
|
||||
}
|
||||
|
||||
public static NzbInfoModel ParseNzbInfo(FeedInfoModel feed, RssItem item)
|
||||
{
|
||||
|
||||
return new NzbInfoModel
|
||||
{
|
||||
Title = item.Title,
|
||||
Link = item.Link
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,280 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Helpers;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Model.Notification;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using NzbDrone.Core.Repository;
|
||||
using Rss;
|
||||
|
||||
namespace NzbDrone.Core.Providers
|
||||
{
|
||||
public class BacklogProvider : IBacklogProvider
|
||||
{
|
||||
private readonly ISeriesProvider _seriesProvider;
|
||||
private readonly INotificationProvider _notificationProvider;
|
||||
private readonly IConfigProvider _configProvider;
|
||||
private readonly IIndexerProvider _indexerProvider;
|
||||
private readonly IRssProvider _rssProvider;
|
||||
private readonly IRssItemProcessingProvider _rssItemProcessor;
|
||||
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private List<Series> _seriesList;
|
||||
private Thread _backlogThread;
|
||||
private ProgressNotification _backlogSearchNotification;
|
||||
|
||||
public BacklogProvider(ISeriesProvider seriesProvider, INotificationProvider notificationProvider,
|
||||
IConfigProvider configProvider, IIndexerProvider indexerProvider,
|
||||
IRssProvider rssProvider, IRssItemProcessingProvider _rssItemProcessor)
|
||||
{
|
||||
_seriesProvider = seriesProvider;
|
||||
_notificationProvider = notificationProvider;
|
||||
_configProvider = configProvider;
|
||||
_indexerProvider = indexerProvider;
|
||||
_rssProvider = rssProvider;
|
||||
|
||||
_seriesList = new List<Series>();
|
||||
}
|
||||
|
||||
#region IBacklogProvider Members
|
||||
|
||||
public bool StartSearch()
|
||||
{
|
||||
Logger.Debug("Backlog Search Requested");
|
||||
if (_backlogThread == null || !_backlogThread.IsAlive)
|
||||
{
|
||||
Logger.Debug("Initializing Backlog Search");
|
||||
_backlogThread = new Thread(PerformSearch)
|
||||
{
|
||||
Name = "BacklogSearch",
|
||||
Priority = ThreadPriority.Lowest
|
||||
};
|
||||
|
||||
_seriesList.AddRange(_seriesProvider.GetAllSeries());
|
||||
_backlogThread.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warn("Backlog Search already in progress. Ignoring request.");
|
||||
|
||||
//return false if backlog search was already running
|
||||
return false;
|
||||
}
|
||||
|
||||
//return true if backlog search has started
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool StartSearch(int seriesId)
|
||||
{
|
||||
//Get the series
|
||||
//Start new Thread if one isn't already started
|
||||
|
||||
Logger.Debug("Backlog Search Requested");
|
||||
if (_backlogThread == null || !_backlogThread.IsAlive)
|
||||
{
|
||||
Logger.Debug("Initializing Backlog Search");
|
||||
_backlogThread = new Thread(PerformSearch)
|
||||
{
|
||||
Name = "BacklogSearch",
|
||||
Priority = ThreadPriority.Lowest
|
||||
};
|
||||
|
||||
var series = _seriesProvider.GetSeries(seriesId);
|
||||
|
||||
if (series == null)
|
||||
{
|
||||
Logger.Debug("Invalid Series - Not starting Backlog Search");
|
||||
return false;
|
||||
}
|
||||
|
||||
_seriesList.Add(series);
|
||||
_backlogThread.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warn("Backlog Search already in progress. Ignoring request.");
|
||||
|
||||
//return false if backlog search was already running
|
||||
return false;
|
||||
}
|
||||
|
||||
//return true if backlog search has started
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void PerformSearch()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (_backlogSearchNotification = new ProgressNotification("Series Scan"))
|
||||
{
|
||||
_notificationProvider.Register(_backlogSearchNotification);
|
||||
_backlogSearchNotification.CurrentStatus = "Starting Backlog Search";
|
||||
_backlogSearchNotification.ProgressMax = _seriesList.Count;
|
||||
|
||||
foreach (var series in _seriesList)
|
||||
{
|
||||
BackLogSeries(series);
|
||||
}
|
||||
|
||||
_backlogSearchNotification.CurrentStatus = "Backlog Search Completed";
|
||||
Logger.Info("Backlog Search has successfully completed.");
|
||||
Thread.Sleep(3000);
|
||||
_backlogSearchNotification.Status = ProgressNotificationStatus.Completed;
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WarnException(ex.Message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void BackLogSeries(Series series)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Do the searching here
|
||||
_backlogSearchNotification.CurrentStatus = String.Format("Backlog Searching For: {0}", series.Title);
|
||||
|
||||
var sceneNames = SceneNameHelper.FindById(series.SeriesId);
|
||||
|
||||
if (sceneNames.Count < 1)
|
||||
sceneNames.Add(series.Title);
|
||||
|
||||
foreach (var season in series.Seasons)
|
||||
{
|
||||
BackLogSeason(sceneNames, season);
|
||||
}
|
||||
//Done searching for each episode
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WarnException(ex.Message, ex);
|
||||
}
|
||||
|
||||
_backlogSearchNotification.ProgressValue++;
|
||||
}
|
||||
|
||||
private void BackLogSeason(List<string> sceneNames, Season season)
|
||||
{
|
||||
var episodesWithoutFiles = season.Episodes.Where(e => e.EpisodeFileId == 0);
|
||||
|
||||
if (season.Episodes.Count() == episodesWithoutFiles.Count())
|
||||
{
|
||||
//Whole season needs to be grabbed, look for the whole season first
|
||||
//Lookup scene name using seriesId
|
||||
|
||||
foreach (var sceneName in sceneNames)
|
||||
{
|
||||
var searchString = String.Format("{0} Season {1}", sceneName,
|
||||
season.SeasonNumber);
|
||||
|
||||
foreach (var i in _indexerProvider.EnabledIndexers())
|
||||
{
|
||||
//Get the users URL
|
||||
GetUsersUrl(i, searchString);
|
||||
|
||||
//If the url still contains '{' & '}' the user probably hasn't configured the indexer settings
|
||||
if (i.ApiUrl.Contains("{") && i.ApiUrl.Contains("}"))
|
||||
{
|
||||
Logger.Debug("Unable to Sync {0}. User Information has not been configured.", i.IndexerName);
|
||||
continue; //Skip this indexer
|
||||
}
|
||||
|
||||
var indexer = new FeedInfoModel(i.IndexerName, i.ApiUrl);
|
||||
|
||||
var feedItems = _rssProvider.GetFeed(indexer);
|
||||
|
||||
if (feedItems.Count() == 0)
|
||||
{
|
||||
Logger.Debug("Failed to download Backlog Search URL: {0}", indexer.Name);
|
||||
continue; //No need to process anything else
|
||||
}
|
||||
|
||||
foreach (RssItem item in feedItems)
|
||||
{
|
||||
NzbInfoModel nzb = Parser.ParseNzbInfo(indexer, item);
|
||||
QueueSeasonIfWanted(nzb, i);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GetUsersUrl(Indexer indexer, string searchString)
|
||||
{
|
||||
if (indexer.IndexerName == "NzbMatrix")
|
||||
{
|
||||
var nzbMatrixUsername = _configProvider.GetValue("NzbMatrixUsername", String.Empty, false);
|
||||
var nzbMatrixApiKey = _configProvider.GetValue("NzbMatrixApiKey", String.Empty, false);
|
||||
var retention = Convert.ToInt32(_configProvider.GetValue("Retention", String.Empty, false));
|
||||
|
||||
if (!String.IsNullOrEmpty(nzbMatrixUsername) && !String.IsNullOrEmpty(nzbMatrixApiKey))
|
||||
indexer.ApiUrl = indexer.ApiUrl.Replace("{USERNAME}", nzbMatrixUsername).Replace("{APIKEY}", nzbMatrixApiKey).Replace("{AGE}", retention.ToString()).Replace("{TERM}", searchString);
|
||||
|
||||
//Todo: Perform validation at the config level so a user is unable to enable a provider until user details are provided
|
||||
return;
|
||||
}
|
||||
|
||||
if (indexer.IndexerName == "NzbsOrg")
|
||||
{
|
||||
var nzbsOrgUId = _configProvider.GetValue("NzbsOrgUId", String.Empty, false);
|
||||
var nzbsOrgHash = _configProvider.GetValue("NzbsOrgHash", String.Empty, false);
|
||||
|
||||
if (!String.IsNullOrEmpty(nzbsOrgUId) && !String.IsNullOrEmpty(nzbsOrgHash))
|
||||
indexer.RssUrl = indexer.RssUrl.Replace("{UID}", nzbsOrgUId).Replace("{HASH}", nzbsOrgHash);
|
||||
|
||||
//Todo: Perform validation at the config level so a user is unable to enable a provider until user details are provided
|
||||
return;
|
||||
}
|
||||
|
||||
if (indexer.IndexerName == "NzbsOrg")
|
||||
{
|
||||
var nzbsrusUId = _configProvider.GetValue("NzbsrusUId", String.Empty, false);
|
||||
var nzbsrusHash = _configProvider.GetValue("NzbsrusHash", String.Empty, false);
|
||||
|
||||
if (!String.IsNullOrEmpty(nzbsrusUId) && !String.IsNullOrEmpty(nzbsrusHash))
|
||||
indexer.RssUrl = indexer.RssUrl.Replace("{UID}", nzbsrusUId).Replace("{HASH}", nzbsrusHash);
|
||||
|
||||
//Todo: Perform validation at the config level so a user is unable to enable a provider until user details are provided
|
||||
return;
|
||||
}
|
||||
|
||||
return; //Currently other providers do not require user information to be substituted, simply return
|
||||
}
|
||||
|
||||
private void QueueSeasonIfWanted(NzbInfoModel nzb, Indexer indexer)
|
||||
{
|
||||
//Do we want this item?
|
||||
try
|
||||
{
|
||||
if (nzb.IsPassworded())
|
||||
{
|
||||
Logger.Debug("Skipping Passworded Report {0}", nzb.Title);
|
||||
return;
|
||||
}
|
||||
|
||||
//Need to get REGEX that will handle "Show Name Season 1 quality"
|
||||
nzb.TitleFix = String.Empty;
|
||||
nzb.TitleFix = String.Format("{0} [{1}]", nzb.TitleFix, nzb.Quality); //Add Quality to the titleFix
|
||||
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.DebugException(ex.Message, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Model;
|
||||
using Rss;
|
||||
|
||||
namespace NzbDrone.Core.Providers.Core
|
||||
{
|
||||
public interface IRssProvider
|
||||
{
|
||||
IEnumerable<RssItem> GetFeed(FeedInfoModel feedInfo);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Model;
|
||||
using Rss;
|
||||
|
||||
namespace NzbDrone.Core.Providers.Core
|
||||
{
|
||||
public class RssProvider : IRssProvider
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
#region IRssProvider Members
|
||||
public IEnumerable<RssItem> GetFeed(FeedInfoModel feedInfo)
|
||||
{
|
||||
RssFeed feed = null;
|
||||
try
|
||||
{
|
||||
Logger.Info("INFO: Downloading feed {0} from {1}", feedInfo.Name, feedInfo.Url);
|
||||
feed = RssFeed.Read(feedInfo.Url);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.ErrorException(String.Format("ERROR: Could not download feed {0} from {1}", feedInfo.Name, feedInfo.Url), e);
|
||||
}
|
||||
if (feed == null || feed.Channels == null || feed.Channels.Count == 0)
|
||||
return Enumerable.Empty<RssItem>();
|
||||
return feed.Channels[0].Items.Cast<RssItem>();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Repository;
|
||||
|
||||
namespace NzbDrone.Core.Providers
|
||||
{
|
||||
public interface IRssItemProcessingProvider
|
||||
{
|
||||
//This interface will contain methods to process individual RSS Feed Items (Queue if wanted)
|
||||
|
||||
void DownloadIfWanted(NzbInfoModel nzb, Indexer indexer);
|
||||
string GetTitleFix(EpisodeParseResult episodes);
|
||||
}
|
||||
}
|
@ -1,337 +0,0 @@
|
||||
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.Providers.Core;
|
||||
using NzbDrone.Core.Repository;
|
||||
|
||||
namespace NzbDrone.Core.Providers
|
||||
{
|
||||
public class RssItemProcessingProvider : IRssItemProcessingProvider
|
||||
{
|
||||
private ISeriesProvider _seriesProvider;
|
||||
private ISeasonProvider _seasonProvider;
|
||||
private IEpisodeProvider _episodeProvider;
|
||||
private IHistoryProvider _historyProvider;
|
||||
private IDownloadProvider _sabProvider;
|
||||
private IConfigProvider _configProvider;
|
||||
private IHttpProvider _httpProvider;
|
||||
private IDiskProvider _diskProvider;
|
||||
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public RssItemProcessingProvider(ISeriesProvider seriesProvider, ISeasonProvider seasonProvider,
|
||||
IEpisodeProvider episodeProvider, IHistoryProvider historyProvider,
|
||||
IDownloadProvider sabProvider, IConfigProvider configProvider,
|
||||
IHttpProvider httpProvider, IDiskProvider diskProvider)
|
||||
{
|
||||
_seriesProvider = seriesProvider;
|
||||
_seasonProvider = seasonProvider;
|
||||
_episodeProvider = episodeProvider;
|
||||
_historyProvider = historyProvider;
|
||||
_sabProvider = sabProvider;
|
||||
_configProvider = configProvider;
|
||||
_httpProvider = httpProvider;
|
||||
_diskProvider = diskProvider;
|
||||
}
|
||||
|
||||
#region IRssItemProcessingProvider Members
|
||||
|
||||
public void DownloadIfWanted(NzbInfoModel nzb, Indexer indexer)
|
||||
{
|
||||
//Do we want this item?
|
||||
try
|
||||
{
|
||||
if (nzb.IsPassworded())
|
||||
{
|
||||
Logger.Debug("Skipping Passworded Report {0}", nzb.Title);
|
||||
return;
|
||||
}
|
||||
|
||||
var episodeParseResults = Parser.ParseEpisodeInfo(nzb.Title);
|
||||
|
||||
if (episodeParseResults.Episodes.Count() > 0)
|
||||
{
|
||||
ProcessStandardItem(nzb, indexer, episodeParseResults);
|
||||
return;
|
||||
}
|
||||
|
||||
//Handles Full Season NZBs
|
||||
var seasonParseResult = Parser.ParseSeasonInfo(nzb.Title);
|
||||
|
||||
if (seasonParseResult != null)
|
||||
{
|
||||
ProcessFullSeasonItem(nzb, indexer, seasonParseResult);
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.Debug("Unsupported Title: {0}", nzb.Title);
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Unsupported Title: {0}", nzb.Title);
|
||||
Logger.ErrorException("Error Parsing/Processing NZB: " + ex.Message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetTitleFix(EpisodeParseResult episodes)
|
||||
{
|
||||
int seasonNumber = 0;
|
||||
string episodeNumbers = String.Empty;
|
||||
string episodeTitles = String.Empty;
|
||||
|
||||
foreach (var episode in episodes.Episodes)
|
||||
{
|
||||
var episodeInDb = _episodeProvider.GetEpisode(episodes.SeriesId, episodes.SeasonNumber, episode);
|
||||
|
||||
if (episodeInDb == null)
|
||||
{
|
||||
//Todo: Handle this some other way?
|
||||
Logger.Debug("Episode Not found in Database, Fake it...");
|
||||
//return String.Format("{0} - {1:00}x{2}", series.Title, episode.SeasonNumber, episode.EpisodeNumber);
|
||||
episodeInDb = new Episode { EpisodeNumber = episode, Title = "TBA" };
|
||||
}
|
||||
|
||||
seasonNumber = episodes.SeasonNumber;
|
||||
episodeNumbers = String.Format("{0}x{1:00}", episodeNumbers, episodeInDb.EpisodeNumber);
|
||||
episodeTitles = String.Format("{0} + {1}", episodeTitles, episodeInDb.Title);
|
||||
}
|
||||
|
||||
episodeTitles = episodeTitles.Trim(' ', '+');
|
||||
|
||||
return String.Format("{0} - {1}{2} - {3}", episodes.SeriesTitle, seasonNumber, episodeNumbers, episodeTitles);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void ProcessStandardItem(NzbInfoModel nzb, Indexer indexer, EpisodeParseResult episodeParseResults)
|
||||
{
|
||||
//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(episodeParseResults.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(episodeParseResults.SeriesTitle);
|
||||
|
||||
if (sceneId != 0)
|
||||
series = _seriesProvider.GetSeries(sceneId);
|
||||
|
||||
if (series == null)
|
||||
{
|
||||
Logger.Debug("Show is not being watched: {0}", episodeParseResults.SeriesTitle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Debug("Show is being watched: {0}", series.Title);
|
||||
|
||||
nzb.Proper = Parser.ParseProper(nzb.Title);
|
||||
nzb.Quality = episodeParseResults.Quality;
|
||||
|
||||
//Loop through the list of the episodeParseResults to ensure that all the episodes are needed
|
||||
foreach (var episode in episodeParseResults.Episodes)
|
||||
{
|
||||
|
||||
if (!_episodeProvider.IsNeeded(episodeParseResults))
|
||||
return;
|
||||
|
||||
var titleFix = GetTitleFix(episodeParseResults);
|
||||
titleFix = String.Format("{0} [{1}]", titleFix, nzb.Quality); //Add Quality to the titleFix
|
||||
|
||||
//If it is a PROPER we want to put PROPER in the titleFix
|
||||
if (nzb.Proper)
|
||||
titleFix = String.Format("{0} [PROPER]", titleFix);
|
||||
|
||||
if (!Convert.ToBoolean(_configProvider.GetValue("UseBlackhole", true, true)))
|
||||
if (_sabProvider.IsInQueue(titleFix))
|
||||
return;
|
||||
}
|
||||
|
||||
nzb.TitleFix = GetTitleFix(episodeParseResults); //Get the TitleFix so we can use it later
|
||||
nzb.TitleFix = String.Format("{0} [{1}]", nzb.TitleFix, nzb.Quality); //Add Quality to the titleFix
|
||||
|
||||
//If it is a PROPER we want to put PROPER in the titleFix
|
||||
if (nzb.Proper)
|
||||
nzb.TitleFix = String.Format("{0} [PROPER]", nzb.TitleFix);
|
||||
|
||||
if (Convert.ToBoolean(_configProvider.GetValue("UseBlackHole", true, true)))
|
||||
{
|
||||
//if (DownloadNzb(nzb))
|
||||
//AddToHistory(episodeParseResults, nzb, indexer);
|
||||
}
|
||||
|
||||
//Send it to SABnzbd
|
||||
else
|
||||
{
|
||||
//Only need to do this check if it contains more than one episode (because we already checked individually before)
|
||||
if (episodeParseResults.Episodes.Count > 1)
|
||||
{
|
||||
if (_sabProvider.IsInQueue(nzb.TitleFix))
|
||||
return;
|
||||
}
|
||||
|
||||
if (indexer.IndexerName != "Newzbin")
|
||||
{
|
||||
//if (_sabProvider.AddByUrl(nzb.Link.ToString(), nzb.TitleFix))
|
||||
//AddToHistory(_episodeProvider.GetEpisode(episodeParseResults.), series, nzb, indexer);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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 = seasonParseResult.Quality;
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
//if (!_episodeProvider.IsNeeded(episode))
|
||||
{
|
||||
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
|
||||
}
|
||||
downloadWholeSeason = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadWholeSeason)
|
||||
{
|
||||
//Do the final check to ensure we should download this NZB
|
||||
|
||||
if (Convert.ToBoolean(_configProvider.GetValue("UseBlackHole", true, true)))
|
||||
{
|
||||
if (DownloadNzb(nzb))
|
||||
{
|
||||
AddToHistory(season.Episodes, nzb, indexer);
|
||||
}
|
||||
}
|
||||
|
||||
//Send it to SABnzbd
|
||||
else
|
||||
{
|
||||
if (_sabProvider.IsInQueue(nzb.TitleFix))
|
||||
return;
|
||||
|
||||
if (indexer.IndexerName != "Newzbin")
|
||||
{
|
||||
if (_sabProvider.AddByUrl(nzb.Link.ToString(), nzb.TitleFix))
|
||||
{
|
||||
AddToHistory(season.Episodes, nzb, indexer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Possibly grab the whole season if a certain % of the season is missing, rather than for 1 or 2 episodes
|
||||
}
|
||||
|
||||
private void AddToHistory(IEnumerable<Episode> episodes, NzbInfoModel nzb, Indexer indexer)
|
||||
{
|
||||
//Set episode status to grabbed
|
||||
//episode.Status = EpisodeStatusType.Grabbed;
|
||||
|
||||
//Add to History
|
||||
|
||||
foreach (var episode in episodes)
|
||||
{
|
||||
var history = new History();
|
||||
history.Date = DateTime.Now;
|
||||
history.EpisodeId = episode.EpisodeId;
|
||||
history.IndexerId = indexer.IndexerId;
|
||||
history.IsProper = nzb.Proper;
|
||||
history.Quality = nzb.Quality;
|
||||
history.NzbTitle = nzb.Title;
|
||||
|
||||
_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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,173 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Helpers;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Model.Notification;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Core.Repository.Quality;
|
||||
using Rss;
|
||||
|
||||
namespace NzbDrone.Core.Providers
|
||||
{
|
||||
public class RssSyncProvider : IRssSyncProvider
|
||||
{
|
||||
//Sync with RSS feeds to download files as needed
|
||||
|
||||
private Thread _rssSyncThread;
|
||||
private IIndexerProvider _indexerProvider;
|
||||
private IRssProvider _rss;
|
||||
private ISeriesProvider _series;
|
||||
private ISeasonProvider _season;
|
||||
private IEpisodeProvider _episode;
|
||||
private IHistoryProvider _history;
|
||||
private IDownloadProvider _sab;
|
||||
private IConfigProvider _configProvider;
|
||||
private IRssItemProcessingProvider _rssItemProcessor;
|
||||
private readonly INotificationProvider _notificationProvider;
|
||||
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private ProgressNotification _rssSyncNotification;
|
||||
|
||||
public RssSyncProvider(IIndexerProvider indexerProvider, IRssProvider rss,
|
||||
ISeriesProvider series, ISeasonProvider season,
|
||||
IEpisodeProvider episode, IHistoryProvider history,
|
||||
IDownloadProvider sab, INotificationProvider notificationProvider,
|
||||
IConfigProvider configProvider, IRssItemProcessingProvider rssItemProcessor)
|
||||
{
|
||||
_indexerProvider = indexerProvider;
|
||||
_rss = rss;
|
||||
_series = series;
|
||||
_season = season;
|
||||
_episode = episode;
|
||||
_history = history;
|
||||
_sab = sab;
|
||||
_notificationProvider = notificationProvider;
|
||||
_configProvider = configProvider;
|
||||
_rssItemProcessor = rssItemProcessor;
|
||||
}
|
||||
|
||||
#region IRssSyncProvider Members
|
||||
|
||||
public void Begin()
|
||||
{
|
||||
Logger.Debug("RSS Sync Starting");
|
||||
if (_rssSyncThread == null || !_rssSyncThread.IsAlive)
|
||||
{
|
||||
Logger.Debug("Initializing background sync of RSS Feeds.");
|
||||
_rssSyncThread = new Thread(SyncWithRss)
|
||||
{
|
||||
Name = "RssSync",
|
||||
Priority = ThreadPriority.Lowest
|
||||
};
|
||||
|
||||
_rssSyncThread.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warn("RSS Sync already in progress. Ignoring request.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void SyncWithRss()
|
||||
{
|
||||
//Get all enabled RSS providers
|
||||
//Download Feeds
|
||||
|
||||
var indexers = _indexerProvider.EnabledIndexers();
|
||||
|
||||
using (_rssSyncNotification = new ProgressNotification("RSS Sync"))
|
||||
{
|
||||
_notificationProvider.Register(_rssSyncNotification);
|
||||
_rssSyncNotification.CurrentStatus = "Starting Scan";
|
||||
_rssSyncNotification.ProgressMax = indexers.Count();
|
||||
|
||||
foreach (var i in indexers)
|
||||
{
|
||||
Logger.Info("Starting RSS Sync for: {0}", i.IndexerName);
|
||||
//Need to insert the users information in the the URL before trying to use it
|
||||
GetUsersUrl(i); //Get the new users specific url (with their information) to use for the Sync
|
||||
|
||||
//If the url still contains '{' & '}' the user probably hasn't configured the indexer settings
|
||||
if (i.RssUrl.Contains("{") && i.RssUrl.Contains("}"))
|
||||
{
|
||||
Logger.Debug("Unable to Sync {0}. User Information has not been configured.", i.IndexerName);
|
||||
continue; //Skip this indexer
|
||||
}
|
||||
|
||||
_rssSyncNotification.CurrentStatus = String.Format("Syncing with RSS Feed: {0}", i.IndexerName);
|
||||
|
||||
var indexer = new FeedInfoModel(i.IndexerName, i.RssUrl);
|
||||
|
||||
var feedItems = _rss.GetFeed(indexer);
|
||||
|
||||
if (feedItems.Count() == 0)
|
||||
{
|
||||
_rssSyncNotification.CurrentStatus = String.Format("Failed to download RSS Feed: {0}", //
|
||||
i.IndexerName);
|
||||
continue; //No need to process anything else
|
||||
}
|
||||
|
||||
foreach (RssItem item in feedItems)
|
||||
{
|
||||
NzbInfoModel nzb = Parser.ParseNzbInfo(indexer, item);
|
||||
_rssItemProcessor.DownloadIfWanted(nzb, i);
|
||||
}
|
||||
}
|
||||
_rssSyncNotification.CurrentStatus = "RSS Sync Completed";
|
||||
Logger.Info("RSS Sync has successfully completed.");
|
||||
Thread.Sleep(3000);
|
||||
_rssSyncNotification.Status = ProgressNotificationStatus.Completed;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetUsersUrl(Indexer indexer)
|
||||
{
|
||||
if (indexer.IndexerName == "NzbMatrix")
|
||||
{
|
||||
var nzbMatrixUsername = _configProvider.GetValue("NzbMatrixUsername", String.Empty, false);
|
||||
var nzbMatrixApiKey = _configProvider.GetValue("NzbMatrixApiKey", String.Empty, false);
|
||||
|
||||
if (!String.IsNullOrEmpty(nzbMatrixUsername) && !String.IsNullOrEmpty(nzbMatrixApiKey))
|
||||
indexer.RssUrl = indexer.RssUrl.Replace("{USERNAME}", nzbMatrixUsername).Replace("{APIKEY}", nzbMatrixApiKey);
|
||||
|
||||
//Todo: Perform validation at the config level so a user is unable to enable a provider until user details are provided
|
||||
return;
|
||||
}
|
||||
|
||||
if (indexer.IndexerName == "NzbsOrg")
|
||||
{
|
||||
var nzbsOrgUId = _configProvider.GetValue("NzbsOrgUId", String.Empty, false);
|
||||
var nzbsOrgHash = _configProvider.GetValue("NzbsOrgHash", String.Empty, false);
|
||||
|
||||
if (!String.IsNullOrEmpty(nzbsOrgUId) && !String.IsNullOrEmpty(nzbsOrgHash))
|
||||
indexer.RssUrl = indexer.RssUrl.Replace("{UID}", nzbsOrgUId).Replace("{HASH}", nzbsOrgHash);
|
||||
|
||||
//Todo: Perform validation at the config level so a user is unable to enable a provider until user details are provided
|
||||
return;
|
||||
}
|
||||
|
||||
if (indexer.IndexerName == "NzbsOrg")
|
||||
{
|
||||
var nzbsrusUId = _configProvider.GetValue("NzbsrusUId", String.Empty, false);
|
||||
var nzbsrusHash = _configProvider.GetValue("NzbsrusHash", String.Empty, false);
|
||||
|
||||
if (!String.IsNullOrEmpty(nzbsrusUId) && !String.IsNullOrEmpty(nzbsrusHash))
|
||||
indexer.RssUrl = indexer.RssUrl.Replace("{UID}", nzbsrusUId).Replace("{HASH}", nzbsrusHash);
|
||||
|
||||
//Todo: Perform validation at the config level so a user is unable to enable a provider until user details are provided
|
||||
return;
|
||||
}
|
||||
|
||||
return; //Currently other providers do not require user information to be substituted, simply return
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user