@ -40,21 +40,109 @@ namespace NzbDrone.Core.Download
protected abstract string AddFromMagnetLink ( RemoteEpisode remoteEpisode , string hash , string magnetLink ) ;
protected abstract string AddFromTorrentFile ( RemoteEpisode remoteEpisode , string hash , string filename , byte [ ] fileContent ) ;
protected virtual string AddFromMagnetLink ( RemoteMovie remoteMovie , string hash , string magnetLink )
{
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 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 ) ;
}
}
public override string Download ( RemoteEpisode remoteEpisode )
if ( torrentUrl . IsNotNullOrWhiteSpace ( ) )
{
return DownloadFromWebUrl ( remoteMovie , torrentUrl ) ;
}
}
return null ;
}
public override string Download ( RemoteEpisode remoteMovie )
{
var torrentInfo = remoteEpisode . Release as TorrentInfo ;
var torrentInfo = remote Movi e. Release as TorrentInfo ;
string magnetUrl = null ;
string torrentUrl = null ;
if ( remoteEpisode . Release . DownloadUrl . IsNotNullOrWhiteSpace ( ) & & remoteEpisode . Release . DownloadUrl . StartsWith ( "magnet:" ) )
if ( remote Movi e. Release . DownloadUrl . IsNotNullOrWhiteSpace ( ) & & remote Movi e. Release . DownloadUrl . StartsWith ( "magnet:" ) )
{
magnetUrl = remoteEpisode . Release . DownloadUrl ;
magnetUrl = remote Movi e. Release . DownloadUrl ;
}
else
{
torrentUrl = remoteEpisode . Release . DownloadUrl ;
torrentUrl = remote Movi e. Release . DownloadUrl ;
}
if ( torrentInfo ! = null & & ! torrentInfo . MagnetUrl . IsNullOrWhiteSpace ( ) )
@ -68,7 +156,7 @@ namespace NzbDrone.Core.Download
{
try
{
return DownloadFromWebUrl ( remote Episod e, torrentUrl ) ;
return DownloadFromWebUrl ( remote Movi e, torrentUrl ) ;
}
catch ( Exception ex )
{
@ -85,11 +173,11 @@ namespace NzbDrone.Core.Download
{
try
{
return DownloadFromMagnetUrl ( remote Episod e, magnetUrl ) ;
return DownloadFromMagnetUrl ( remote Movi e, magnetUrl ) ;
}
catch ( NotSupportedException ex )
{
throw new ReleaseDownloadException ( remote Episod e. Release , "Magnet not supported by download client. ({0})" , ex . Message ) ;
throw new ReleaseDownloadException ( remote Movi e. Release , "Magnet not supported by download client. ({0})" , ex . Message ) ;
}
}
}
@ -99,13 +187,13 @@ namespace NzbDrone.Core.Download
{
try
{
return DownloadFromMagnetUrl ( remote Episod e, magnetUrl ) ;
return DownloadFromMagnetUrl ( remote Movi e, magnetUrl ) ;
}
catch ( NotSupportedException ex )
{
if ( torrentUrl . IsNullOrWhiteSpace ( ) )
{
throw new ReleaseDownloadException ( remote Episod e. Release , "Magnet not supported by download client. ({0})" , ex . Message ) ;
throw new ReleaseDownloadException ( remote Movi e. Release , "Magnet not supported by download client. ({0})" , ex . Message ) ;
}
_logger . Debug ( "Magnet not supported by download client, trying torrent. ({0})" , ex . Message ) ;
@ -114,13 +202,113 @@ namespace NzbDrone.Core.Download
if ( torrentUrl . IsNotNullOrWhiteSpace ( ) )
{
return DownloadFromWebUrl ( remote Episod e, torrentUrl ) ;
return DownloadFromWebUrl ( remote Movi e, 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 )
{
byte [ ] torrentFile = null ;