mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-17 15:02:34 +02:00
Fixes downloading a movie. However, now all downloaders except QBittorrent are non functional until they get fixed. See #14
This commit is contained in:
parent
2a3b0304cb
commit
0e02171938
@ -26,6 +26,7 @@ public class ReleaseModule : ReleaseModuleBase
|
|||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
private readonly ICached<RemoteEpisode> _remoteEpisodeCache;
|
private readonly ICached<RemoteEpisode> _remoteEpisodeCache;
|
||||||
|
private readonly ICached<RemoteMovie> _remoteMovieCache;
|
||||||
|
|
||||||
public ReleaseModule(IFetchAndParseRss rssFetcherAndParser,
|
public ReleaseModule(IFetchAndParseRss rssFetcherAndParser,
|
||||||
ISearchForNzb nzbSearchService,
|
ISearchForNzb nzbSearchService,
|
||||||
@ -49,6 +50,7 @@ public ReleaseModule(IFetchAndParseRss rssFetcherAndParser,
|
|||||||
PostValidator.RuleFor(s => s.Guid).NotEmpty();
|
PostValidator.RuleFor(s => s.Guid).NotEmpty();
|
||||||
|
|
||||||
_remoteEpisodeCache = cacheManager.GetCache<RemoteEpisode>(GetType(), "remoteEpisodes");
|
_remoteEpisodeCache = cacheManager.GetCache<RemoteEpisode>(GetType(), "remoteEpisodes");
|
||||||
|
_remoteMovieCache = cacheManager.GetCache<RemoteMovie>(GetType(), "remoteMovies");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response DownloadRelease(ReleaseResource release)
|
private Response DownloadRelease(ReleaseResource release)
|
||||||
@ -59,7 +61,26 @@ private Response DownloadRelease(ReleaseResource release)
|
|||||||
{
|
{
|
||||||
_logger.Debug("Couldn't find requested release in cache, cache timeout probably expired.");
|
_logger.Debug("Couldn't find requested release in cache, cache timeout probably expired.");
|
||||||
|
|
||||||
return new NotFoundResponse();
|
var remoteMovie = _remoteMovieCache.Find(release.Guid);
|
||||||
|
|
||||||
|
if (remoteMovie == null)
|
||||||
|
{
|
||||||
|
return new NotFoundResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_downloadService.DownloadReport(remoteMovie);
|
||||||
|
}
|
||||||
|
catch (ReleaseDownloadException ex)
|
||||||
|
{
|
||||||
|
_logger.Error(ex, ex.Message);
|
||||||
|
throw new NzbDroneClientException(HttpStatusCode.Conflict, "Getting release from indexer failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return release.AsResponse();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -139,7 +160,15 @@ private List<ReleaseResource> GetRss()
|
|||||||
|
|
||||||
protected override ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
|
protected override ReleaseResource MapDecision(DownloadDecision decision, int initialWeight)
|
||||||
{
|
{
|
||||||
_remoteEpisodeCache.Set(decision.RemoteEpisode.Release.Guid, decision.RemoteEpisode, TimeSpan.FromMinutes(30));
|
if (decision.IsForMovie)
|
||||||
|
{
|
||||||
|
_remoteMovieCache.Set(decision.RemoteMovie.Release.Guid, decision.RemoteMovie, TimeSpan.FromMinutes(30));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_remoteEpisodeCache.Set(decision.RemoteEpisode.Release.Guid, decision.RemoteEpisode, TimeSpan.FromMinutes(30));
|
||||||
|
}
|
||||||
|
|
||||||
return base.MapDecision(decision, initialWeight);
|
return base.MapDecision(decision, initialWeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,32 @@ public override string Download(RemoteEpisode remoteEpisode)
|
|||||||
return GetDownloadClientId(strmFile);
|
return GetDownloadClientId(strmFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string Download(RemoteMovie remoteEpisode)
|
||||||
|
{
|
||||||
|
var url = remoteEpisode.Release.DownloadUrl;
|
||||||
|
var title = remoteEpisode.Release.Title;
|
||||||
|
|
||||||
|
if (remoteEpisode.ParsedEpisodeInfo.FullSeason)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("Full season releases are not supported with Pneumatic.");
|
||||||
|
}
|
||||||
|
|
||||||
|
title = FileNameBuilder.CleanFileName(title);
|
||||||
|
|
||||||
|
//Save to the Pneumatic directory (The user will need to ensure its accessible by XBMC)
|
||||||
|
var nzbFile = Path.Combine(Settings.NzbFolder, title + ".nzb");
|
||||||
|
|
||||||
|
_logger.Debug("Downloading NZB from: {0} to: {1}", url, nzbFile);
|
||||||
|
_httpClient.DownloadFile(url, nzbFile);
|
||||||
|
|
||||||
|
_logger.Debug("NZB Download succeeded, saved to: {0}", nzbFile);
|
||||||
|
|
||||||
|
var strmFile = WriteStrmFile(title, nzbFile);
|
||||||
|
|
||||||
|
|
||||||
|
return GetDownloadClientId(strmFile);
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsConfigured => !string.IsNullOrWhiteSpace(Settings.NzbFolder);
|
public bool IsConfigured => !string.IsNullOrWhiteSpace(Settings.NzbFolder);
|
||||||
|
|
||||||
public override IEnumerable<DownloadClientItem> GetItems()
|
public override IEnumerable<DownloadClientItem> GetItems()
|
||||||
|
@ -40,7 +40,7 @@ protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string
|
|||||||
_proxy.SetTorrentLabel(hash.ToLower(), Settings.TvCategory, Settings);
|
_proxy.SetTorrentLabel(hash.ToLower(), Settings.TvCategory, Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
var isRecentEpisode = true;//remoteEpisode.IsRecentEpisode(); TODO: Update to use RemoteMovie!
|
var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||||
|
|
||||||
if (isRecentEpisode && Settings.RecentTvPriority == (int)QBittorrentPriority.First ||
|
if (isRecentEpisode && Settings.RecentTvPriority == (int)QBittorrentPriority.First ||
|
||||||
!isRecentEpisode && Settings.OlderTvPriority == (int)QBittorrentPriority.First)
|
!isRecentEpisode && Settings.OlderTvPriority == (int)QBittorrentPriority.First)
|
||||||
@ -71,6 +71,46 @@ protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string AddFromMagnetLink(RemoteMovie remoteEpisode, string hash, string magnetLink)
|
||||||
|
{
|
||||||
|
_proxy.AddTorrentFromUrl(magnetLink, Settings);
|
||||||
|
|
||||||
|
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
_proxy.SetTorrentLabel(hash.ToLower(), Settings.TvCategory, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||||
|
|
||||||
|
if (isRecentEpisode && Settings.RecentTvPriority == (int)QBittorrentPriority.First ||
|
||||||
|
!isRecentEpisode && Settings.OlderTvPriority == (int)QBittorrentPriority.First)
|
||||||
|
{
|
||||||
|
_proxy.MoveTorrentToTopInQueue(hash.ToLower(), Settings);
|
||||||
|
}*/ //TODO: Maybe reimplement for movies
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string AddFromTorrentFile(RemoteMovie remoteEpisode, string hash, string filename, Byte[] fileContent)
|
||||||
|
{
|
||||||
|
_proxy.AddTorrentFromFile(filename, fileContent, Settings);
|
||||||
|
|
||||||
|
if (Settings.TvCategory.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
_proxy.SetTorrentLabel(hash.ToLower(), Settings.TvCategory, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*var isRecentEpisode = remoteEpisode.IsRecentEpisode();
|
||||||
|
|
||||||
|
if (isRecentEpisode && Settings.RecentTvPriority == (int)QBittorrentPriority.First ||
|
||||||
|
!isRecentEpisode && Settings.OlderTvPriority == (int)QBittorrentPriority.First)
|
||||||
|
{
|
||||||
|
_proxy.MoveTorrentToTopInQueue(hash.ToLower(), Settings);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
public override string Name => "qBittorrent";
|
public override string Name => "qBittorrent";
|
||||||
|
|
||||||
public override IEnumerable<DownloadClientItem> GetItems()
|
public override IEnumerable<DownloadClientItem> GetItems()
|
||||||
|
@ -57,6 +57,7 @@ public abstract DownloadProtocol Protocol
|
|||||||
get;
|
get;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract string Download(RemoteEpisode remoteEpisode);
|
public abstract string Download(RemoteEpisode remoteEpisode);
|
||||||
public abstract IEnumerable<DownloadClientItem> GetItems();
|
public abstract IEnumerable<DownloadClientItem> GetItems();
|
||||||
public abstract void RemoveItem(string downloadId, bool deleteData);
|
public abstract void RemoveItem(string downloadId, bool deleteData);
|
||||||
@ -147,5 +148,7 @@ protected ValidationFailure TestFolder(string folder, string propertyName, bool
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract string Download(RemoteMovie remoteMovie);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ namespace NzbDrone.Core.Download
|
|||||||
public interface IDownloadService
|
public interface IDownloadService
|
||||||
{
|
{
|
||||||
void DownloadReport(RemoteEpisode remoteEpisode);
|
void DownloadReport(RemoteEpisode remoteEpisode);
|
||||||
|
void DownloadReport(RemoteMovie remoteMovie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -91,5 +92,62 @@ public void DownloadReport(RemoteEpisode remoteEpisode)
|
|||||||
_logger.ProgressInfo("Report sent to {0}. {1}", downloadClient.Definition.Name, downloadTitle);
|
_logger.ProgressInfo("Report sent to {0}. {1}", downloadClient.Definition.Name, downloadTitle);
|
||||||
_eventAggregator.PublishEvent(episodeGrabbedEvent);
|
_eventAggregator.PublishEvent(episodeGrabbedEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DownloadReport(RemoteMovie remoteMovie)
|
||||||
|
{
|
||||||
|
//Ensure.That(remoteEpisode.Series, () => remoteEpisode.Series).IsNotNull();
|
||||||
|
//Ensure.That(remoteEpisode.Episodes, () => remoteEpisode.Episodes).HasItems(); TODO update this shit
|
||||||
|
|
||||||
|
var downloadTitle = remoteMovie.Release.Title;
|
||||||
|
var downloadClient = _downloadClientProvider.GetDownloadClient(remoteMovie.Release.DownloadProtocol);
|
||||||
|
|
||||||
|
if (downloadClient == null)
|
||||||
|
{
|
||||||
|
_logger.Warn("{0} Download client isn't configured yet.", remoteMovie.Release.DownloadProtocol);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit grabs to 2 per second.
|
||||||
|
if (remoteMovie.Release.DownloadUrl.IsNotNullOrWhiteSpace() && !remoteMovie.Release.DownloadUrl.StartsWith("magnet:"))
|
||||||
|
{
|
||||||
|
var url = new HttpUri(remoteMovie.Release.DownloadUrl);
|
||||||
|
_rateLimitService.WaitAndPulse(url.Host, TimeSpan.FromSeconds(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
string downloadClientId = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
downloadClientId = downloadClient.Download(remoteMovie);
|
||||||
|
_indexerStatusService.RecordSuccess(remoteMovie.Release.IndexerId);
|
||||||
|
}
|
||||||
|
catch (NotImplementedException ex)
|
||||||
|
{
|
||||||
|
_logger.Error(ex, "The download client you are using is currently not configured to download movies. Please choose another one.");
|
||||||
|
}
|
||||||
|
catch (ReleaseDownloadException ex)
|
||||||
|
{
|
||||||
|
var http429 = ex.InnerException as TooManyRequestsException;
|
||||||
|
if (http429 != null)
|
||||||
|
{
|
||||||
|
_indexerStatusService.RecordFailure(remoteMovie.Release.IndexerId, http429.RetryAfter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_indexerStatusService.RecordFailure(remoteMovie.Release.IndexerId);
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
var episodeGrabbedEvent = new MovieGrabbedEvent(remoteMovie);
|
||||||
|
episodeGrabbedEvent.DownloadClient = downloadClient.GetType().Name;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(downloadClientId))
|
||||||
|
{
|
||||||
|
episodeGrabbedEvent.DownloadId = downloadClientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.ProgressInfo("Report sent to {0}. {1}", downloadClient.Definition.Name, downloadTitle);
|
||||||
|
_eventAggregator.PublishEvent(episodeGrabbedEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,6 +10,7 @@ public interface IDownloadClient : IProvider
|
|||||||
DownloadProtocol Protocol { get; }
|
DownloadProtocol Protocol { get; }
|
||||||
|
|
||||||
string Download(RemoteEpisode remoteEpisode);
|
string Download(RemoteEpisode remoteEpisode);
|
||||||
|
string Download(RemoteMovie remoteMovie);
|
||||||
IEnumerable<DownloadClientItem> GetItems();
|
IEnumerable<DownloadClientItem> GetItems();
|
||||||
void RemoveItem(string downloadId, bool deleteData);
|
void RemoveItem(string downloadId, bool deleteData);
|
||||||
DownloadClientStatus GetStatus();
|
DownloadClientStatus GetStatus();
|
||||||
|
17
src/NzbDrone.Core/Download/MovieGrabbedEvent.cs
Normal file
17
src/NzbDrone.Core/Download/MovieGrabbedEvent.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using NzbDrone.Common.Messaging;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Download
|
||||||
|
{
|
||||||
|
public class MovieGrabbedEvent : IEvent
|
||||||
|
{
|
||||||
|
public RemoteMovie Movie { get; private set; }
|
||||||
|
public string DownloadClient { get; set; }
|
||||||
|
public string DownloadId { get; set; }
|
||||||
|
|
||||||
|
public MovieGrabbedEvent(RemoteMovie movie)
|
||||||
|
{
|
||||||
|
Movie = movie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -40,35 +40,43 @@ protected TorrentClientBase(ITorrentFileInfoReader torrentFileInfoReader,
|
|||||||
|
|
||||||
protected abstract string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink);
|
protected abstract string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink);
|
||||||
protected abstract string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent);
|
protected abstract string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, byte[] fileContent);
|
||||||
|
protected virtual string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink)
|
||||||
public override string Download(RemoteEpisode remoteEpisode)
|
|
||||||
{
|
{
|
||||||
var torrentInfo = remoteEpisode.Release as TorrentInfo;
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
protected virtual string AddFromTorrentFile(RemoteMovie remoteMovie, string hash, string filename, byte[] fileContent)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Download(RemoteMovie remoteMovie)
|
||||||
|
{
|
||||||
|
var torrentInfo = remoteMovie.Release as TorrentInfo;
|
||||||
|
|
||||||
string magnetUrl = null;
|
string magnetUrl = null;
|
||||||
string torrentUrl = null;
|
string torrentUrl = null;
|
||||||
|
|
||||||
if (remoteEpisode.Release.DownloadUrl.IsNotNullOrWhiteSpace() && remoteEpisode.Release.DownloadUrl.StartsWith("magnet:"))
|
if (remoteMovie.Release.DownloadUrl.IsNotNullOrWhiteSpace() && remoteMovie.Release.DownloadUrl.StartsWith("magnet:"))
|
||||||
{
|
{
|
||||||
magnetUrl = remoteEpisode.Release.DownloadUrl;
|
magnetUrl = remoteMovie.Release.DownloadUrl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
torrentUrl = remoteEpisode.Release.DownloadUrl;
|
torrentUrl = remoteMovie.Release.DownloadUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (torrentInfo != null && !torrentInfo.MagnetUrl.IsNullOrWhiteSpace())
|
if (torrentInfo != null && !torrentInfo.MagnetUrl.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
magnetUrl = torrentInfo.MagnetUrl;
|
magnetUrl = torrentInfo.MagnetUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PreferTorrentFile)
|
if (PreferTorrentFile)
|
||||||
{
|
{
|
||||||
if (torrentUrl.IsNotNullOrWhiteSpace())
|
if (torrentUrl.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return DownloadFromWebUrl(remoteEpisode, torrentUrl);
|
return DownloadFromWebUrl(remoteMovie, torrentUrl);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -85,11 +93,11 @@ public override string Download(RemoteEpisode remoteEpisode)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return DownloadFromMagnetUrl(remoteEpisode, magnetUrl);
|
return DownloadFromMagnetUrl(remoteMovie, magnetUrl);
|
||||||
}
|
}
|
||||||
catch (NotSupportedException ex)
|
catch (NotSupportedException ex)
|
||||||
{
|
{
|
||||||
throw new ReleaseDownloadException(remoteEpisode.Release, "Magnet not supported by download client. ({0})", ex.Message);
|
throw new ReleaseDownloadException(remoteMovie.Release, "Magnet not supported by download client. ({0})", ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,13 +107,13 @@ public override string Download(RemoteEpisode remoteEpisode)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return DownloadFromMagnetUrl(remoteEpisode, magnetUrl);
|
return DownloadFromMagnetUrl(remoteMovie, magnetUrl);
|
||||||
}
|
}
|
||||||
catch (NotSupportedException ex)
|
catch (NotSupportedException ex)
|
||||||
{
|
{
|
||||||
if (torrentUrl.IsNullOrWhiteSpace())
|
if (torrentUrl.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
throw new ReleaseDownloadException(remoteEpisode.Release, "Magnet not supported by download client. ({0})", ex.Message);
|
throw new ReleaseDownloadException(remoteMovie.Release, "Magnet not supported by download client. ({0})", ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("Magnet not supported by download client, trying torrent. ({0})", ex.Message);
|
_logger.Debug("Magnet not supported by download client, trying torrent. ({0})", ex.Message);
|
||||||
@ -114,13 +122,193 @@ public override string Download(RemoteEpisode remoteEpisode)
|
|||||||
|
|
||||||
if (torrentUrl.IsNotNullOrWhiteSpace())
|
if (torrentUrl.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
return DownloadFromWebUrl(remoteEpisode, torrentUrl);
|
return DownloadFromWebUrl(remoteMovie, torrentUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string Download(RemoteEpisode remoteMovie)
|
||||||
|
{
|
||||||
|
var torrentInfo = remoteMovie.Release as TorrentInfo;
|
||||||
|
|
||||||
|
string magnetUrl = null;
|
||||||
|
string torrentUrl = null;
|
||||||
|
|
||||||
|
if (remoteMovie.Release.DownloadUrl.IsNotNullOrWhiteSpace() && remoteMovie.Release.DownloadUrl.StartsWith("magnet:"))
|
||||||
|
{
|
||||||
|
magnetUrl = remoteMovie.Release.DownloadUrl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
torrentUrl = remoteMovie.Release.DownloadUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (torrentInfo != null && !torrentInfo.MagnetUrl.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
magnetUrl = torrentInfo.MagnetUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PreferTorrentFile)
|
||||||
|
{
|
||||||
|
if (torrentUrl.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return DownloadFromWebUrl(remoteMovie, torrentUrl);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (!magnetUrl.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Debug("Torrent download failed, trying magnet. ({0})", ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (magnetUrl.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return DownloadFromMagnetUrl(remoteMovie, magnetUrl);
|
||||||
|
}
|
||||||
|
catch (NotSupportedException ex)
|
||||||
|
{
|
||||||
|
throw new ReleaseDownloadException(remoteMovie.Release, "Magnet not supported by download client. ({0})", ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (magnetUrl.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return DownloadFromMagnetUrl(remoteMovie, magnetUrl);
|
||||||
|
}
|
||||||
|
catch (NotSupportedException ex)
|
||||||
|
{
|
||||||
|
if (torrentUrl.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
throw new ReleaseDownloadException(remoteMovie.Release, "Magnet not supported by download client. ({0})", ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Debug("Magnet not supported by download client, trying torrent. ({0})", ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (torrentUrl.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
return DownloadFromWebUrl(remoteMovie, torrentUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string DownloadFromWebUrl(RemoteMovie remoteEpisode, string torrentUrl)
|
||||||
|
{
|
||||||
|
byte[] torrentFile = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var request = new HttpRequest(torrentUrl);
|
||||||
|
request.Headers.Accept = "application/x-bittorrent";
|
||||||
|
request.AllowAutoRedirect = false;
|
||||||
|
|
||||||
|
var response = _httpClient.Get(request);
|
||||||
|
|
||||||
|
if (response.StatusCode == HttpStatusCode.SeeOther || response.StatusCode == HttpStatusCode.Found)
|
||||||
|
{
|
||||||
|
var locationHeader = response.Headers.GetSingleValue("Location");
|
||||||
|
|
||||||
|
_logger.Trace("Torrent request is being redirected to: {0}", locationHeader);
|
||||||
|
|
||||||
|
if (locationHeader != null)
|
||||||
|
{
|
||||||
|
if (locationHeader.StartsWith("magnet:"))
|
||||||
|
{
|
||||||
|
return DownloadFromMagnetUrl(remoteEpisode, locationHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DownloadFromWebUrl(remoteEpisode, locationHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new WebException("Remote website tried to redirect without providing a location.");
|
||||||
|
}
|
||||||
|
|
||||||
|
torrentFile = response.ResponseData;
|
||||||
|
|
||||||
|
_logger.Debug("Downloading torrent for episode '{0}' finished ({1} bytes from {2})", remoteEpisode.Release.Title, torrentFile.Length, torrentUrl);
|
||||||
|
}
|
||||||
|
catch (HttpException ex)
|
||||||
|
{
|
||||||
|
if ((int)ex.Response.StatusCode == 429)
|
||||||
|
{
|
||||||
|
_logger.Error("API Grab Limit reached for {0}", torrentUrl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Error(ex, "Downloading torrent file for episode '{0}' failed ({1})", remoteEpisode.Release.Title, torrentUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ReleaseDownloadException(remoteEpisode.Release, "Downloading torrent failed", ex);
|
||||||
|
}
|
||||||
|
catch (WebException ex)
|
||||||
|
{
|
||||||
|
_logger.Error(ex, "Downloading torrent file for episode '{0}' failed ({1})", remoteEpisode.Release.Title, torrentUrl);
|
||||||
|
|
||||||
|
throw new ReleaseDownloadException(remoteEpisode.Release, "Downloading torrent failed", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
var filename = string.Format("{0}.torrent", FileNameBuilder.CleanFileName(remoteEpisode.Release.Title));
|
||||||
|
var hash = _torrentFileInfoReader.GetHashFromTorrentFile(torrentFile);
|
||||||
|
var actualHash = AddFromTorrentFile(remoteEpisode, hash, filename, torrentFile);
|
||||||
|
|
||||||
|
if (actualHash.IsNotNullOrWhiteSpace() && hash != actualHash)
|
||||||
|
{
|
||||||
|
_logger.Debug(
|
||||||
|
"{0} did not return the expected InfoHash for '{1}', Sonarr could potentially lose track of the download in progress.",
|
||||||
|
Definition.Implementation, remoteEpisode.Release.DownloadUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return actualHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string DownloadFromMagnetUrl(RemoteMovie remoteEpisode, string magnetUrl)
|
||||||
|
{
|
||||||
|
string hash = null;
|
||||||
|
string actualHash = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
hash = new MagnetLink(magnetUrl).InfoHash.ToHex();
|
||||||
|
}
|
||||||
|
catch (FormatException ex)
|
||||||
|
{
|
||||||
|
_logger.Error(ex, "Failed to parse magnetlink for episode '{0}': '{1}'", remoteEpisode.Release.Title, magnetUrl);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hash != null)
|
||||||
|
{
|
||||||
|
actualHash = AddFromMagnetLink(remoteEpisode, hash, magnetUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actualHash.IsNotNullOrWhiteSpace() && hash != actualHash)
|
||||||
|
{
|
||||||
|
_logger.Debug(
|
||||||
|
"{0} did not return the expected InfoHash for '{1}', Sonarr could potentially lose track of the download in progress.",
|
||||||
|
Definition.Implementation, remoteEpisode.Release.DownloadUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return actualHash;
|
||||||
|
}
|
||||||
|
|
||||||
private string DownloadFromWebUrl(RemoteEpisode remoteEpisode, string torrentUrl)
|
private string DownloadFromWebUrl(RemoteEpisode remoteEpisode, string torrentUrl)
|
||||||
{
|
{
|
||||||
byte[] torrentFile = null;
|
byte[] torrentFile = null;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
@ -31,6 +32,11 @@ protected UsenetClientBase(IHttpClient httpClient,
|
|||||||
|
|
||||||
protected abstract string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContent);
|
protected abstract string AddFromNzbFile(RemoteEpisode remoteEpisode, string filename, byte[] fileContent);
|
||||||
|
|
||||||
|
protected virtual string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContents)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public override string Download(RemoteEpisode remoteEpisode)
|
public override string Download(RemoteEpisode remoteEpisode)
|
||||||
{
|
{
|
||||||
var url = remoteEpisode.Release.DownloadUrl;
|
var url = remoteEpisode.Release.DownloadUrl;
|
||||||
@ -67,5 +73,42 @@ public override string Download(RemoteEpisode remoteEpisode)
|
|||||||
_logger.Info("Adding report [{0}] to the queue.", remoteEpisode.Release.Title);
|
_logger.Info("Adding report [{0}] to the queue.", remoteEpisode.Release.Title);
|
||||||
return AddFromNzbFile(remoteEpisode, filename, nzbData);
|
return AddFromNzbFile(remoteEpisode, filename, nzbData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string Download(RemoteMovie remoteEpisode)
|
||||||
|
{
|
||||||
|
var url = remoteEpisode.Release.DownloadUrl;
|
||||||
|
var filename = FileNameBuilder.CleanFileName(remoteEpisode.Release.Title) + ".nzb";
|
||||||
|
|
||||||
|
byte[] nzbData;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
nzbData = _httpClient.Get(new HttpRequest(url)).ResponseData;
|
||||||
|
|
||||||
|
_logger.Debug("Downloaded nzb for episode '{0}' finished ({1} bytes from {2})", remoteEpisode.Release.Title, nzbData.Length, url);
|
||||||
|
}
|
||||||
|
catch (HttpException ex)
|
||||||
|
{
|
||||||
|
if ((int)ex.Response.StatusCode == 429)
|
||||||
|
{
|
||||||
|
_logger.Error("API Grab Limit reached for {0}", url);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Error(ex, "Downloading nzb for episode '{0}' failed ({1})", remoteEpisode.Release.Title, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ReleaseDownloadException(remoteEpisode.Release, "Downloading nzb failed", ex);
|
||||||
|
}
|
||||||
|
catch (WebException ex)
|
||||||
|
{
|
||||||
|
_logger.Error(ex, "Downloading nzb for episode '{0}' failed ({1})", remoteEpisode.Release.Title, url);
|
||||||
|
|
||||||
|
throw new ReleaseDownloadException(remoteEpisode.Release, "Downloading nzb failed", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Info("Adding report [{0}] to the queue.", remoteEpisode.Release.Title);
|
||||||
|
return AddFromNzbFile(remoteEpisode, filename, nzbData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -457,6 +457,7 @@
|
|||||||
<Compile Include="Download\Clients\Vuze\Vuze.cs" />
|
<Compile Include="Download\Clients\Vuze\Vuze.cs" />
|
||||||
<Compile Include="Download\CompletedDownloadService.cs" />
|
<Compile Include="Download\CompletedDownloadService.cs" />
|
||||||
<Compile Include="Download\DownloadEventHub.cs" />
|
<Compile Include="Download\DownloadEventHub.cs" />
|
||||||
|
<Compile Include="Download\MovieGrabbedEvent.cs" />
|
||||||
<Compile Include="Download\TrackedDownloads\DownloadMonitoringService.cs" />
|
<Compile Include="Download\TrackedDownloads\DownloadMonitoringService.cs" />
|
||||||
<Compile Include="Download\TrackedDownloads\TrackedDownload.cs" />
|
<Compile Include="Download\TrackedDownloads\TrackedDownload.cs" />
|
||||||
<Compile Include="Download\TrackedDownloads\TrackedDownloadService.cs" />
|
<Compile Include="Download\TrackedDownloads\TrackedDownloadService.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user