1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2024-10-31 07:52:37 +01:00
Sonarr/NzbDrone.Core/Providers/RssSyncProvider.cs
markus101 a7780fab67 Issue with overwriting user settings for Indexers resolved.
Reworked RssSyncProvider to make it cleaner.

SeasonProvider was returning the reveresed boolean result

Indexer changed to not store empty strings as null when saving config (ApiUrl).
2011-02-15 23:58:39 -08:00

246 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using NLog;
using NzbDrone.Core.Model;
using NzbDrone.Core.Model.Notification;
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 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)
{
_indexerProvider = indexerProvider;
_rss = rss;
_series = series;
_season = season;
_episode = episode;
_history = history;
_sab = sab;
_notificationProvider = notificationProvider;
_configProvider = configProvider;
}
#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 = "SyncUnmappedFolders",
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);
foreach (RssItem item in _rss.GetFeed(indexer))
{
NzbInfoModel nzb = Parser.ParseNzbInfo(indexer, item);
QueueIfWanted(nzb);
}
}
_rssSyncNotification.CurrentStatus = "RSS Sync Completed";
Logger.Info("RSS Sync has successfully completed.");
Thread.Sleep(3000);
_rssSyncNotification.Status = ProgressNotificationStatus.Completed;
}
}
private void QueueIfWanted(NzbInfoModel nzb)
{
//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.Count() < 1)
{
Logger.Debug("Unsupported Title: {0}", nzb.Title);
return;
}
if (episodeParseResults.Count() > 0)
{
//Todo: How to determine if we want the show if the FeedTitle is drastically different from the TitleOnDisk (CSI is one that comes to mind)
var series = _series.FindSeries(episodeParseResults[0].SeriesTitle);
if (series == null)
{
Logger.Debug("Show is not being watched: {0}", episodeParseResults[0].SeriesTitle);
return;
}
Logger.Debug("Show is being watched: {0}", series.Title);
nzb.TitleFix = GetTitleFix(episodeParseResults, series.SeriesId); //Get the TitleFix so we can use it later
nzb.Proper = Parser.ParseProper(nzb.Title);
//Loop through the list of the episodeParseResults to ensure that all the episodes are needed)
foreach (var episode in episodeParseResults)
{
//IsEpisodeWanted?
var episodeModel = new EpisodeModel();
episodeModel.Proper = nzb.Proper;
episodeModel.SeriesId = series.SeriesId;
episodeModel.SeriesTitle = series.Title;
episodeModel.Quality = Parser.ParseQuality(nzb.Title);
episodeModel.SeasonNumber = episode.SeasonNumber;
episodeModel.EpisodeNumber = episode.EpisodeNumber;
if (!_episode.IsNeeded(episodeModel))
return;
var titleFix = GetTitleFix(new List<EpisodeParseResult> { episode }, episodeModel.SeriesId);
_sab.IsInQueue(titleFix);
}
}
}
catch (Exception ex)
{
Logger.ErrorException("Error Parsing NZB: " + ex.Message, ex);
}
}
private string GetTitleFix(List<EpisodeParseResult> episodes, int seriesId)
{
var series = _series.GetSeries(seriesId);
int seasonNumber = 0;
string episodeNumbers = String.Empty;
string episodeTitles = String.Empty;
foreach (var episode in episodes)
{
var episodeInDb = _episode.GetEpisode(seriesId, episode.SeasonNumber, episode.EpisodeNumber);
if (episodeInDb == null)
{
Logger.Debug("Episode Not found in Database");
return String.Format("{0} - {1}x{2:00}", series.Title, episode.SeasonNumber, episode.SeriesTitle);
}
seasonNumber = episodeInDb.SeasonNumber;
episodeNumbers = String.Format("{0}x{1:00}", episodeNumbers, episodeInDb.EpisodeNumber);
episodeTitles = String.Format("{0} + {1}", episodeTitles, episodeInDb.Title);
}
return String.Format("{0} - {1}{2} - {3}", series.Title, seasonNumber, episodeNumbers, episodeTitles);
}
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
}
}
}