diff --git a/frontend/src/Indexer/Stats/Stats.js b/frontend/src/Indexer/Stats/Stats.js index 127732f2b..f88acb50c 100644 --- a/frontend/src/Indexer/Stats/Stats.js +++ b/frontend/src/Indexer/Stats/Stats.js @@ -30,6 +30,21 @@ function getTotalRequestsData(indexerStats) { return data; } +function getNumberGrabsData(indexerStats) { + const data = indexerStats.map((indexer) => { + return { + label: indexer.indexerName, + value: indexer.numberOfGrabs + }; + }); + + data.sort((a, b) => { + return b.value - a.value; + }); + + return data; +} + function Stats(props) { const { items, @@ -70,6 +85,12 @@ function Stats(props) { title='Total Indexer Queries' /> +
+ +
} diff --git a/src/NzbDrone.Core/History/HistoryService.cs b/src/NzbDrone.Core/History/HistoryService.cs index b78e19ff3..532436b0b 100644 --- a/src/NzbDrone.Core/History/HistoryService.cs +++ b/src/NzbDrone.Core/History/HistoryService.cs @@ -111,6 +111,7 @@ namespace NzbDrone.Core.History }; history.Data.Add("Successful", message.Successful.ToString()); + history.Data.Add("Source", message.Source ?? string.Empty); _historyRepository.Insert(history); } diff --git a/src/NzbDrone.Core/IndexerStats/IndexerStatistics.cs b/src/NzbDrone.Core/IndexerStats/IndexerStatistics.cs index 3443507b1..f8376adb1 100644 --- a/src/NzbDrone.Core/IndexerStats/IndexerStatistics.cs +++ b/src/NzbDrone.Core/IndexerStats/IndexerStatistics.cs @@ -8,5 +8,6 @@ namespace NzbDrone.Core.IndexerStats public string IndexerName { get; set; } public int AverageResponseTime { get; set; } public int NumberOfQueries { get; set; } + public int NumberOfGrabs { get; set; } } } diff --git a/src/NzbDrone.Core/IndexerStats/IndexerStatisticsRepository.cs b/src/NzbDrone.Core/IndexerStats/IndexerStatisticsRepository.cs index 613857e84..1508a39f1 100644 --- a/src/NzbDrone.Core/IndexerStats/IndexerStatisticsRepository.cs +++ b/src/NzbDrone.Core/IndexerStats/IndexerStatisticsRepository.cs @@ -48,7 +48,8 @@ namespace NzbDrone.Core.IndexerStats private SqlBuilder Builder() => new SqlBuilder() .Select(@"Indexers.Id AS IndexerId, Indexers.Name AS IndexerName, - COUNT(History.Id) AS NumberOfQueries, + SUM(CASE WHEN EventType == 2 then 1 else 0 end) AS NumberOfQueries, + SUM(CASE WHEN EventType == 1 then 1 else 0 end) AS NumberOfGrabs, AVG(json_extract(History.Data,'$.elapsedTime')) AS AverageResponseTime") .Join((t, r) => t.IndexerId == r.Id) .GroupBy(x => x.Id); diff --git a/src/NzbDrone.Core/Indexers/DownloadService.cs b/src/NzbDrone.Core/Indexers/DownloadService.cs index 0f5ac3d75..d10f477cc 100644 --- a/src/NzbDrone.Core/Indexers/DownloadService.cs +++ b/src/NzbDrone.Core/Indexers/DownloadService.cs @@ -13,7 +13,7 @@ namespace NzbDrone.Core.Indexers { public interface IDownloadService { - byte[] DownloadReport(string link, int indexerId); + byte[] DownloadReport(string link, int indexerId, string source); } public class DownloadService : IDownloadService @@ -37,7 +37,7 @@ namespace NzbDrone.Core.Indexers _logger = logger; } - public byte[] DownloadReport(string link, int indexerId) + public byte[] DownloadReport(string link, int indexerId, string source) { var url = new HttpUri(link); @@ -48,7 +48,7 @@ namespace NzbDrone.Core.Indexers } var indexer = _indexerFactory.GetInstance(_indexerFactory.Get(indexerId)); - bool success; + var success = false; var downloadedBytes = Array.Empty(); try @@ -60,7 +60,7 @@ namespace NzbDrone.Core.Indexers catch (ReleaseUnavailableException) { _logger.Trace("Release {0} no longer available on indexer.", link); - _eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, false)); + _eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, success, source)); throw; } catch (ReleaseDownloadException ex) @@ -75,11 +75,11 @@ namespace NzbDrone.Core.Indexers _indexerStatusService.RecordFailure(indexerId); } - _eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, false)); + _eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, success, source)); throw; } - _eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, success)); + _eventAggregator.PublishEvent(new IndexerDownloadEvent(indexerId, success, source)); return downloadedBytes; } } diff --git a/src/NzbDrone.Core/Indexers/Events/IndexerDownloadEvent.cs b/src/NzbDrone.Core/Indexers/Events/IndexerDownloadEvent.cs index cb060b158..8527b8f7c 100644 --- a/src/NzbDrone.Core/Indexers/Events/IndexerDownloadEvent.cs +++ b/src/NzbDrone.Core/Indexers/Events/IndexerDownloadEvent.cs @@ -11,11 +11,13 @@ namespace NzbDrone.Core.Indexers.Events { public int IndexerId { get; set; } public bool Successful { get; set; } + public string Source { get; set; } - public IndexerDownloadEvent(int indexerId, bool successful) + public IndexerDownloadEvent(int indexerId, bool successful, string source) { IndexerId = indexerId; Successful = successful; + Source = source; } } } diff --git a/src/Prowlarr.Api.V1/Indexers/IndexerModule.cs b/src/Prowlarr.Api.V1/Indexers/IndexerModule.cs index c2e2d8d05..5921d2ee2 100644 --- a/src/Prowlarr.Api.V1/Indexers/IndexerModule.cs +++ b/src/Prowlarr.Api.V1/Indexers/IndexerModule.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Net; using System.Text; using Nancy; using Nancy.ModelBinding; @@ -115,8 +116,10 @@ namespace Prowlarr.Api.V1.Indexers var indexerInstance = _indexerFactory.GetInstance(indexer); + var source = UserAgentParser.ParseSource(Request.Headers.UserAgent); + var downloadBytes = Array.Empty(); - downloadBytes = _downloadService.DownloadReport(_downloadMappingService.ConvertToNormalLink(link), id); + downloadBytes = _downloadService.DownloadReport(_downloadMappingService.ConvertToNormalLink(link), id, source); // handle magnet URLs if (downloadBytes.Length >= 7 diff --git a/src/Prowlarr.Api.V1/Indexers/IndexerStatsResource.cs b/src/Prowlarr.Api.V1/Indexers/IndexerStatsResource.cs index a46c5571b..867f176b8 100644 --- a/src/Prowlarr.Api.V1/Indexers/IndexerStatsResource.cs +++ b/src/Prowlarr.Api.V1/Indexers/IndexerStatsResource.cs @@ -11,6 +11,7 @@ namespace Prowlarr.Api.V1.Indexers public string IndexerName { get; set; } public int NumberOfQueries { get; set; } public int AverageResponseTime { get; set; } + public int NumberOfGrabs { get; set; } } public static class IndexerStatsResourceMapper @@ -27,7 +28,8 @@ namespace Prowlarr.Api.V1.Indexers IndexerId = model.IndexerId, IndexerName = model.IndexerName, NumberOfQueries = model.NumberOfQueries, - AverageResponseTime = model.AverageResponseTime + AverageResponseTime = model.AverageResponseTime, + NumberOfGrabs = model.NumberOfGrabs }; }