New: Support for seed configuration in DownloadService

pull/1722/head
Bogdan 1 year ago
parent 1f1a345d25
commit d5daf6791c

@ -31,7 +31,7 @@ namespace NzbDrone.Core.Download.Clients.Aria2
_proxy = proxy; _proxy = proxy;
} }
protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink)
{ {
var gid = _proxy.AddUri(Settings, magnetLink); var gid = _proxy.AddUri(Settings, magnetLink);
@ -50,7 +50,7 @@ namespace NzbDrone.Core.Download.Clients.Aria2
return hash; return hash;
} }
protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent)
{ {
var gid = _proxy.AddTorrent(Settings, fileContent); var gid = _proxy.AddTorrent(Settings, fileContent);
@ -120,7 +120,7 @@ namespace NzbDrone.Core.Download.Clients.Aria2
return null; return null;
} }
protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink)
{ {
var gid = _proxy.AddUri(Settings, torrentLink); var gid = _proxy.AddUri(Settings, torrentLink);

@ -25,12 +25,12 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
{ {
} }
protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink)
{ {
throw new NotImplementedException("Blackhole does not support redirected indexers."); throw new NotImplementedException("Blackhole does not support redirected indexers.");
} }
protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink)
{ {
if (!Settings.SaveMagnetFiles) if (!Settings.SaveMagnetFiles)
{ {
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
return null; return null;
} }
protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent)
{ {
var title = release.Title; var title = release.Title;

@ -29,7 +29,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
_proxy = proxy; _proxy = proxy;
} }
protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink)
{ {
var actualHash = _proxy.AddTorrentFromMagnet(magnetLink, Settings); var actualHash = _proxy.AddTorrentFromMagnet(magnetLink, Settings);
@ -53,7 +53,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
return actualHash.ToUpper(); return actualHash.ToUpper();
} }
protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent)
{ {
var actualHash = _proxy.AddTorrentFromFile(filename, fileContent, Settings); var actualHash = _proxy.AddTorrentFromFile(filename, fileContent, Settings);
@ -211,7 +211,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge
return null; return null;
} }
protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

@ -53,7 +53,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
return _dsTaskProxy.GetTasks(Settings).Where(v => v.Type.ToLower() == DownloadStationTaskType.BT.ToString().ToLower()); return _dsTaskProxy.GetTasks(Settings).Where(v => v.Type.ToLower() == DownloadStationTaskType.BT.ToString().ToLower());
} }
protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink)
{ {
var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings); var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings);
@ -72,7 +72,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
throw new DownloadClientException("Failed to add magnet task to Download Station"); throw new DownloadClientException("Failed to add magnet task to Download Station");
} }
protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent)
{ {
var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings); var hashedSerialNumber = _serialNumberProvider.GetSerialNumber(Settings);
@ -315,7 +315,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
return null; return null;
} }
protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

@ -63,14 +63,14 @@ namespace NzbDrone.Core.Download.Clients.Flood
public override bool SupportsCategories => true; public override bool SupportsCategories => true;
public override ProviderMessage Message => new ProviderMessage("Prowlarr is unable to remove torrents that have finished seeding when using Flood", ProviderMessageType.Warning); public override ProviderMessage Message => new ProviderMessage("Prowlarr is unable to remove torrents that have finished seeding when using Flood", ProviderMessageType.Warning);
protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent)
{ {
_proxy.AddTorrentByFile(Convert.ToBase64String(fileContent), HandleTags(release, Settings, GetCategoryForRelease(release)), Settings); _proxy.AddTorrentByFile(Convert.ToBase64String(fileContent), HandleTags(release, Settings, GetCategoryForRelease(release)), Settings);
return hash; return hash;
} }
protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink)
{ {
_proxy.AddTorrentByUrl(magnetLink, HandleTags(release, Settings, GetCategoryForRelease(release)), Settings); _proxy.AddTorrentByUrl(magnetLink, HandleTags(release, Settings, GetCategoryForRelease(release)), Settings);
@ -93,7 +93,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
} }
} }
protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

@ -36,7 +36,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload
return _proxy.GetTasks(Settings).Where(v => v.Type.ToLower() == FreeboxDownloadTaskType.Bt.ToString().ToLower()); return _proxy.GetTasks(Settings).Where(v => v.Type.ToLower() == FreeboxDownloadTaskType.Bt.ToString().ToLower());
} }
protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink)
{ {
return _proxy.AddTaskFromUrl(magnetLink, return _proxy.AddTaskFromUrl(magnetLink,
GetDownloadDirectory(release).EncodeBase64(), GetDownloadDirectory(release).EncodeBase64(),
@ -45,7 +45,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload
Settings); Settings);
} }
protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent)
{ {
return _proxy.AddTaskFromFile(filename, return _proxy.AddTaskFromFile(filename,
fileContent, fileContent,
@ -55,7 +55,7 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload
Settings); Settings);
} }
protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink)
{ {
return _proxy.AddTaskFromUrl(torrentLink, return _proxy.AddTaskFromUrl(torrentLink,
GetDownloadDirectory(release).EncodeBase64(), GetDownloadDirectory(release).EncodeBase64(),

@ -40,14 +40,14 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
failures.AddIfNotNull(TestGetTorrents()); failures.AddIfNotNull(TestGetTorrents());
} }
protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink)
{ {
_proxy.AddTorrentUri(Settings, magnetLink, GetCategoryForRelease(release) ?? Settings.Category); _proxy.AddTorrentUri(Settings, magnetLink, GetCategoryForRelease(release) ?? Settings.Category);
return hash.ToUpper(); return hash.ToUpper();
} }
protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent)
{ {
return _proxy.AddTorrentFile(Settings, fileContent, GetCategoryForRelease(release) ?? Settings.Category).ToUpper(); return _proxy.AddTorrentFile(Settings, fileContent, GetCategoryForRelease(release) ?? Settings.Category).ToUpper();
} }
@ -97,7 +97,7 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
return null; return null;
} }
protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

@ -41,7 +41,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
private IQBittorrentProxy Proxy => _proxySelector.GetProxy(Settings); private IQBittorrentProxy Proxy => _proxySelector.GetProxy(Settings);
private Version ProxyApiVersion => _proxySelector.GetApiVersion(Settings); private Version ProxyApiVersion => _proxySelector.GetApiVersion(Settings);
protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink)
{ {
if (!Proxy.GetConfig(Settings).DhtEnabled && !magnetLink.Contains("&tr=")) if (!Proxy.GetConfig(Settings).DhtEnabled && !magnetLink.Contains("&tr="))
{ {
@ -95,7 +95,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
return hash; return hash;
} }
protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent)
{ {
//var setShareLimits = release.SeedConfiguration != null && (release.SeedConfiguration.Ratio.HasValue || release.SeedConfiguration.SeedTime.HasValue); //var setShareLimits = release.SeedConfiguration != null && (release.SeedConfiguration.Ratio.HasValue || release.SeedConfiguration.SeedTime.HasValue);
//var addHasSetShareLimits = setShareLimits && ProxyApiVersion >= new Version(2, 8, 1); //var addHasSetShareLimits = setShareLimits && ProxyApiVersion >= new Version(2, 8, 1);
@ -450,7 +450,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
torrent.SeedingTime = torrentProperties.SeedingTime; torrent.SeedingTime = torrentProperties.SeedingTime;
} }
protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

@ -66,7 +66,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
return false; return false;
} }
protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink)
{ {
_proxy.AddTorrentFromUrl(magnetLink, GetDownloadDirectory(), Settings); _proxy.AddTorrentFromUrl(magnetLink, GetDownloadDirectory(), Settings);
@ -79,7 +79,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
return hash; return hash;
} }
protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent)
{ {
_proxy.AddTorrentFromData(fileContent, GetDownloadDirectory(), Settings); _proxy.AddTorrentFromData(fileContent, GetDownloadDirectory(), Settings);
@ -92,7 +92,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
return hash; return hash;
} }
protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

@ -34,7 +34,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
_rTorrentDirectoryValidator = rTorrentDirectoryValidator; _rTorrentDirectoryValidator = rTorrentDirectoryValidator;
} }
protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink)
{ {
var priority = (RTorrentPriority)Settings.Priority; var priority = (RTorrentPriority)Settings.Priority;
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
return hash; return hash;
} }
protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent)
{ {
var priority = (RTorrentPriority)Settings.Priority; var priority = (RTorrentPriority)Settings.Priority;
@ -157,7 +157,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
return false; return false;
} }
protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

@ -32,7 +32,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
_torrentCache = cacheManager.GetCache<UTorrentTorrentCache>(GetType(), "differentialTorrents"); _torrentCache = cacheManager.GetCache<UTorrentTorrentCache>(GetType(), "differentialTorrents");
} }
protected override string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink) protected override string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink)
{ {
_proxy.AddTorrentFromUrl(magnetLink, Settings); _proxy.AddTorrentFromUrl(magnetLink, Settings);
@ -53,7 +53,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
return hash; return hash;
} }
protected override string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent) protected override string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent)
{ {
_proxy.AddTorrentFromFile(filename, fileContent, Settings); _proxy.AddTorrentFromFile(filename, fileContent, Settings);
@ -148,7 +148,7 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
return null; return null;
} }
protected override string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink) protected override string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

@ -29,6 +29,7 @@ namespace NzbDrone.Core.Download
private readonly IIndexerStatusService _indexerStatusService; private readonly IIndexerStatusService _indexerStatusService;
private readonly IRateLimitService _rateLimitService; private readonly IRateLimitService _rateLimitService;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly ISeedConfigProvider _seedConfigProvider;
private readonly Logger _logger; private readonly Logger _logger;
public DownloadService(IProvideDownloadClient downloadClientProvider, public DownloadService(IProvideDownloadClient downloadClientProvider,
@ -37,6 +38,7 @@ namespace NzbDrone.Core.Download
IIndexerStatusService indexerStatusService, IIndexerStatusService indexerStatusService,
IRateLimitService rateLimitService, IRateLimitService rateLimitService,
IEventAggregator eventAggregator, IEventAggregator eventAggregator,
ISeedConfigProvider seedConfigProvider,
Logger logger) Logger logger)
{ {
_downloadClientProvider = downloadClientProvider; _downloadClientProvider = downloadClientProvider;
@ -45,6 +47,7 @@ namespace NzbDrone.Core.Download
_indexerStatusService = indexerStatusService; _indexerStatusService = indexerStatusService;
_rateLimitService = rateLimitService; _rateLimitService = rateLimitService;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_seedConfigProvider = seedConfigProvider;
_logger = logger; _logger = logger;
} }
@ -59,7 +62,8 @@ namespace NzbDrone.Core.Download
} }
// Get the seed configuration for this release. // Get the seed configuration for this release.
// remoteMovie.SeedConfiguration = _seedConfigProvider.GetSeedConfiguration(remoteMovie); ((TorrentInfo)release).SeedConfiguration = _seedConfigProvider.GetSeedConfiguration(release);
var indexer = _indexerFactory.GetInstance(_indexerFactory.Get(release.IndexerId)); var indexer = _indexerFactory.GetInstance(_indexerFactory.Get(release.IndexerId));
var grabEvent = new IndexerDownloadEvent(release, true, source, host, release.Title, release.DownloadUrl) var grabEvent = new IndexerDownloadEvent(release, true, source, host, release.Title, release.DownloadUrl)

@ -36,9 +36,9 @@ namespace NzbDrone.Core.Download
public virtual bool PreferTorrentFile => false; public virtual bool PreferTorrentFile => false;
protected abstract string AddFromMagnetLink(ReleaseInfo release, string hash, string magnetLink); protected abstract string AddFromMagnetLink(TorrentInfo release, string hash, string magnetLink);
protected abstract string AddFromTorrentFile(ReleaseInfo release, string hash, string filename, byte[] fileContent); protected abstract string AddFromTorrentFile(TorrentInfo release, string hash, string filename, byte[] fileContent);
protected abstract string AddFromTorrentLink(ReleaseInfo release, string hash, string torrentLink); protected abstract string AddFromTorrentLink(TorrentInfo release, string hash, string torrentLink);
public override async Task<string> Download(ReleaseInfo release, bool redirect, IIndexer indexer) public override async Task<string> Download(ReleaseInfo release, bool redirect, IIndexer indexer)
{ {
@ -142,7 +142,7 @@ namespace NzbDrone.Core.Download
var filename = string.Format("{0}.torrent", StringUtil.CleanFileName(release.Title)); var filename = string.Format("{0}.torrent", StringUtil.CleanFileName(release.Title));
var hash = _torrentFileInfoReader.GetHashFromTorrentFile(torrentFile); var hash = _torrentFileInfoReader.GetHashFromTorrentFile(torrentFile);
var actualHash = AddFromTorrentFile(release, hash, filename, torrentFile); var actualHash = AddFromTorrentFile((TorrentInfo)release, hash, filename, torrentFile);
if (actualHash.IsNotNullOrWhiteSpace() && hash != actualHash) if (actualHash.IsNotNullOrWhiteSpace() && hash != actualHash)
{ {
@ -173,7 +173,7 @@ namespace NzbDrone.Core.Download
if (hash != null) if (hash != null)
{ {
actualHash = AddFromMagnetLink(release, hash, magnetUrl); actualHash = AddFromMagnetLink((TorrentInfo)release, hash, magnetUrl);
} }
if (actualHash.IsNotNullOrWhiteSpace() && hash != actualHash) if (actualHash.IsNotNullOrWhiteSpace() && hash != actualHash)

@ -0,0 +1,91 @@
using System;
using NzbDrone.Common.Cache;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Download.Clients;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.ThingiProvider.Events;
namespace NzbDrone.Core.Indexers
{
public interface ISeedConfigProvider
{
TorrentSeedConfiguration GetSeedConfiguration(ReleaseInfo release);
TorrentSeedConfiguration GetSeedConfiguration(int indexerId);
}
public class SeedConfigProvider : ISeedConfigProvider, IHandle<ProviderUpdatedEvent<IIndexer>>
{
private readonly IIndexerFactory _indexerFactory;
private readonly ICached<IndexerTorrentBaseSettings> _cache;
public SeedConfigProvider(IIndexerFactory indexerFactory, ICacheManager cacheManager)
{
_indexerFactory = indexerFactory;
_cache = cacheManager.GetRollingCache<IndexerTorrentBaseSettings>(GetType(), "criteriaByIndexer", TimeSpan.FromHours(1));
}
public TorrentSeedConfiguration GetSeedConfiguration(ReleaseInfo release)
{
if (release.DownloadProtocol != DownloadProtocol.Torrent)
{
return null;
}
if (release.IndexerId == 0)
{
return null;
}
return GetSeedConfiguration(release.IndexerId);
}
public TorrentSeedConfiguration GetSeedConfiguration(int indexerId)
{
if (indexerId == 0)
{
return null;
}
var seedCriteria = _cache.Get(indexerId.ToString(), () => FetchSeedCriteria(indexerId));
if (seedCriteria == null)
{
return null;
}
var seedConfig = new TorrentSeedConfiguration
{
Ratio = seedCriteria.SeedRatio
};
var seedTime = seedCriteria.SeedTime;
if (seedTime.HasValue)
{
seedConfig.SeedTime = TimeSpan.FromMinutes(seedTime.Value);
}
return seedConfig;
}
private IndexerTorrentBaseSettings FetchSeedCriteria(int indexerId)
{
try
{
var indexer = _indexerFactory.Get(indexerId);
var torrentIndexerSettings = indexer.Settings as ITorrentIndexerSettings;
return torrentIndexerSettings?.TorrentBaseSettings;
}
catch (ModelNotFoundException)
{
return null;
}
}
public void Handle(ProviderUpdatedEvent<IIndexer> message)
{
_cache.Clear();
}
}
}

@ -1,4 +1,5 @@
using System.Text; using System.Text;
using NzbDrone.Core.Download.Clients;
namespace NzbDrone.Core.Parser.Model namespace NzbDrone.Core.Parser.Model
{ {
@ -13,6 +14,8 @@ namespace NzbDrone.Core.Parser.Model
public double? DownloadVolumeFactor { get; set; } public double? DownloadVolumeFactor { get; set; }
public double? UploadVolumeFactor { get; set; } public double? UploadVolumeFactor { get; set; }
public TorrentSeedConfiguration SeedConfiguration { get; set; }
public static int? GetSeeders(ReleaseInfo release) public static int? GetSeeders(ReleaseInfo release)
{ {
var torrentInfo = release as TorrentInfo; var torrentInfo = release as TorrentInfo;

Loading…
Cancel
Save