From 69125add3e6c8c686c318629b65eecad8875494c Mon Sep 17 00:00:00 2001 From: Diego Heras Date: Fri, 11 Dec 2020 23:14:21 +0100 Subject: [PATCH] core: redo search cache from scratch. resolves #10382 (#10447) In simple words, when you make a request in Jackett, the results are saved in memory (cache). The next request will return results form the cache improving response time and making fewer requests to the sites. * We assume all indexers/sites are stateless, the same request return the same response. If you change the search term, categories or something in the query Jackett has to make a live request to the indexer. * There are some situations when we don't want to use the cache: ** When we are testing the indexers => if query.IsTest results are not cached ** When the user updates the configuration of one indexer => We call CleanIndexerCache to remove cached results before testing the configuration ** When there is some error/exception in the indexer => The results are not cached so we can retry in the next request * We want to limit the memory usage, so we try to remove elements from cache ASAP: ** Each indexer can have a maximum number of results in memory. If the limit is exceeded we remove old results ** Cached results expire after some time * Users can configure the cache or even disable it --- README.md | 2 +- src/Jackett.Common/Content/custom.css | 6 +- src/Jackett.Common/Content/custom.js | 15 ++ src/Jackett.Common/Content/custom_mobile.css | 6 +- src/Jackett.Common/Content/index.html | 22 +- src/Jackett.Common/Indexers/Abnormal.cs | 4 +- .../Indexers/Abstract/AvistazTracker.cs | 3 +- .../Indexers/Abstract/CouchPotatoTracker.cs | 5 +- .../Indexers/Abstract/GazelleTracker.cs | 7 +- src/Jackett.Common/Indexers/AlphaRatio.cs | 4 +- src/Jackett.Common/Indexers/AniDUB.cs | 4 +- src/Jackett.Common/Indexers/AniLibria.cs | 3 +- src/Jackett.Common/Indexers/Anidex.cs | 4 +- src/Jackett.Common/Indexers/AnimeBytes.cs | 4 +- src/Jackett.Common/Indexers/AnimeTorrents.cs | 4 +- src/Jackett.Common/Indexers/Animedia.cs | 4 +- src/Jackett.Common/Indexers/Anthelion.cs | 4 +- src/Jackett.Common/Indexers/AvistaZ.cs | 7 +- src/Jackett.Common/Indexers/AwesomeHD.cs | 4 +- src/Jackett.Common/Indexers/BB.cs | 4 +- src/Jackett.Common/Indexers/BJShare.cs | 4 +- src/Jackett.Common/Indexers/BakaBT.cs | 4 +- src/Jackett.Common/Indexers/BaseIndexer.cs | 32 ++- .../Indexers/BitCityReloaded.cs | 4 +- src/Jackett.Common/Indexers/BitHDTV.cs | 4 +- src/Jackett.Common/Indexers/BroadcasTheNet.cs | 4 +- src/Jackett.Common/Indexers/BrokenStones.cs | 4 +- src/Jackett.Common/Indexers/CGPeers.cs | 4 +- .../Indexers/CardigannIndexer.cs | 6 +- src/Jackett.Common/Indexers/Cinecalidad.cs | 4 +- src/Jackett.Common/Indexers/CinemaZ.cs | 7 +- src/Jackett.Common/Indexers/DICMusic.cs | 4 +- .../Indexers/DarmoweTorrenty.cs | 4 +- src/Jackett.Common/Indexers/DigitalCore.cs | 4 +- src/Jackett.Common/Indexers/DivxTotal.cs | 4 +- src/Jackett.Common/Indexers/EliteTracker.cs | 6 +- src/Jackett.Common/Indexers/EpubLibre.cs | 4 +- src/Jackett.Common/Indexers/ExoticaZ.cs | 7 +- .../Indexers/Feeds/AnimeTosho.cs | 4 +- .../Indexers/Feeds/BaseFeedIndexer.cs | 5 +- .../Indexers/Feeds/BaseNewznabIndexer.cs | 5 +- src/Jackett.Common/Indexers/FileList.cs | 4 +- src/Jackett.Common/Indexers/FunFile.cs | 4 +- src/Jackett.Common/Indexers/Fuzer.cs | 4 +- src/Jackett.Common/Indexers/GazelleGames.cs | 4 +- src/Jackett.Common/Indexers/GimmePeers.cs | 4 +- src/Jackett.Common/Indexers/HDBitsApi.cs | 4 +- src/Jackett.Common/Indexers/HDSpace.cs | 4 +- src/Jackett.Common/Indexers/HDTorrents.cs | 4 +- src/Jackett.Common/Indexers/Hebits.cs | 4 +- src/Jackett.Common/Indexers/IIndexer.cs | 8 +- src/Jackett.Common/Indexers/IPTorrents.cs | 4 +- src/Jackett.Common/Indexers/ImmortalSeed.cs | 4 +- .../Indexers/InternetArchive.cs | 4 +- src/Jackett.Common/Indexers/Libble.cs | 4 +- src/Jackett.Common/Indexers/LostFilm.cs | 4 +- src/Jackett.Common/Indexers/Magnetico.cs | 4 +- src/Jackett.Common/Indexers/MejorTorrent.cs | 4 +- .../Indexers/Meta/BaseMetaIndexer.cs | 12 +- .../Indexers/Meta/MetaIndexers.cs | 5 +- src/Jackett.Common/Indexers/Milkie.cs | 4 +- src/Jackett.Common/Indexers/MoreThanTV.cs | 4 +- src/Jackett.Common/Indexers/MyAnonamouse.cs | 4 +- src/Jackett.Common/Indexers/NCore.cs | 60 ++--- src/Jackett.Common/Indexers/Nebulance.cs | 4 +- src/Jackett.Common/Indexers/NewPCT.cs | 4 +- src/Jackett.Common/Indexers/NewRealWorld.cs | 4 +- src/Jackett.Common/Indexers/NorBits.cs | 4 +- src/Jackett.Common/Indexers/NotWhatCD.cs | 4 +- src/Jackett.Common/Indexers/Orpheus.cs | 4 +- src/Jackett.Common/Indexers/Partis.cs | 4 +- src/Jackett.Common/Indexers/PassThePopcorn.cs | 4 +- src/Jackett.Common/Indexers/PirateTheNet.cs | 4 +- src/Jackett.Common/Indexers/PixelHD.cs | 6 +- src/Jackett.Common/Indexers/PolishTracker.cs | 4 +- src/Jackett.Common/Indexers/PornoLab.cs | 4 +- src/Jackett.Common/Indexers/PreToMe.cs | 4 +- src/Jackett.Common/Indexers/PrivateHD.cs | 7 +- src/Jackett.Common/Indexers/PsyTorrents.cs | 4 +- src/Jackett.Common/Indexers/RarBG.cs | 4 +- src/Jackett.Common/Indexers/Redacted.cs | 4 +- src/Jackett.Common/Indexers/RevolutionTT.cs | 4 +- src/Jackett.Common/Indexers/RuTracker.cs | 4 +- src/Jackett.Common/Indexers/SceneHD.cs | 4 +- src/Jackett.Common/Indexers/SceneTime.cs | 4 +- src/Jackett.Common/Indexers/SecretCinema.cs | 4 +- src/Jackett.Common/Indexers/Shazbat.cs | 4 +- src/Jackett.Common/Indexers/ShizaProject.cs | 4 +- src/Jackett.Common/Indexers/ShowRSS.cs | 4 +- src/Jackett.Common/Indexers/SolidTorrents.cs | 4 +- src/Jackett.Common/Indexers/SpeedApp.cs | 4 +- src/Jackett.Common/Indexers/SpeedCD.cs | 4 +- src/Jackett.Common/Indexers/SuperBits.cs | 4 +- src/Jackett.Common/Indexers/TVStore.cs | 4 +- src/Jackett.Common/Indexers/TVVault.cs | 4 +- src/Jackett.Common/Indexers/ThePirateBay.cs | 11 +- src/Jackett.Common/Indexers/Toloka.cs | 4 +- src/Jackett.Common/Indexers/TorrenTech.cs | 4 +- src/Jackett.Common/Indexers/TorrentBytes.cs | 4 +- src/Jackett.Common/Indexers/TorrentDay.cs | 4 +- src/Jackett.Common/Indexers/TorrentHeaven.cs | 60 ++--- src/Jackett.Common/Indexers/TorrentLeech.cs | 4 +- src/Jackett.Common/Indexers/TorrentMafya.cs | 4 +- src/Jackett.Common/Indexers/TorrentNetwork.cs | 4 +- src/Jackett.Common/Indexers/TorrentSeeds.cs | 58 +++-- .../Indexers/TorrentSyndikat.cs | 4 +- src/Jackett.Common/Indexers/TorrentsCSV.cs | 4 +- src/Jackett.Common/Indexers/XSpeeds.cs | 4 +- src/Jackett.Common/Indexers/Xthor.cs | 4 +- src/Jackett.Common/Indexers/YTS.cs | 4 +- src/Jackett.Common/Indexers/ZonaQ.cs | 4 +- src/Jackett.Common/Models/CachedResult.cs | 17 -- .../Models/Config/ServerConfig.cs | 10 +- src/Jackett.Common/Models/DTO/ServerConfig.cs | 9 + src/Jackett.Common/Models/TrackerCache.cs | 4 +- .../Models/TrackerCacheQuery.cs | 15 ++ src/Jackett.Common/Services/CacheService.cs | 243 ++++++++++++++---- .../Services/IndexerManagerService.cs | 17 +- .../Services/Interfaces/ICacheService.cs | 5 +- .../Controllers/IndexerApiController.cs | 3 + .../Controllers/ResultsController.cs | 49 ++-- .../ServerConfigurationController.cs | 7 + src/Jackett.Server/Startup.cs | 2 + .../Common/Indexers/CardigannIndexerTests.cs | 6 +- .../Common/Models/ResultPageTests.cs | 3 +- .../TestHelpers/TestWebIndexer.cs | 3 +- 126 files changed, 742 insertions(+), 362 deletions(-) delete mode 100644 src/Jackett.Common/Models/CachedResult.cs create mode 100644 src/Jackett.Common/Models/TrackerCacheQuery.cs diff --git a/README.md b/README.md index 80d839c9ebef5..205afd660a9c0 100644 --- a/README.md +++ b/README.md @@ -676,7 +676,7 @@ Jackett is available as a beta package from [SynoCommunity](https://synocommunit ## Running Jackett behind a reverse proxy -When running jackett behind a reverse proxy make sure that the original hostname of the request is passed to Jackett. If HTTPS is used also set the X-Forwarded-Proto header to "https". Don't forget to adjust the "Base Path Override" Jackett option accordingly. +When running jackett behind a reverse proxy make sure that the original hostname of the request is passed to Jackett. If HTTPS is used also set the X-Forwarded-Proto header to "https". Don't forget to adjust the "Base path override" Jackett option accordingly. Example config for apache: ``` diff --git a/src/Jackett.Common/Content/custom.css b/src/Jackett.Common/Content/custom.css index 1d4895cde88f7..5692e2a99fc95 100644 --- a/src/Jackett.Common/Content/custom.css +++ b/src/Jackett.Common/Content/custom.css @@ -134,8 +134,8 @@ hr { } .input-header { - font-size: 18px; - width: 160px; + font-size: 16px; + width: 250px; display: inline-block; } @@ -165,7 +165,7 @@ hr { text-align: center; } -#jackett-allowext, #jackett-allowupdate, #jackett-logging, #jackett-prerelease { +#jackett-allowext, #jackett-allowupdate, #jackett-logging, #jackett-prerelease, #jackett-cache-enabled { width: 25px; } diff --git a/src/Jackett.Common/Content/custom.js b/src/Jackett.Common/Content/custom.js index f950241b84d44..f663ffed34857 100644 --- a/src/Jackett.Common/Content/custom.js +++ b/src/Jackett.Common/Content/custom.js @@ -98,6 +98,14 @@ function loadJackettSettings() { $("#jackett-allowupdate").attr('checked', data.updatedisabled); $("#jackett-prerelease").attr('checked', data.prerelease); $("#jackett-logging").attr('checked', data.logging); + + $("#jackett-cache-enabled").attr('checked', data.cache_enabled); + $("#jackett-cache-ttl").val(data.cache_ttl); + $("#jackett-cache-max-results-per-indexer").val(data.cache_max_results_per_indexer); + if (!data.cache_enabled) { + $("#jackett-show-releases").attr("disabled", true); + } + $("#jackett-omdbkey").val(data.omdbkey); $("#jackett-omdburl").val(data.omdburl); var password = data.password; @@ -1126,6 +1134,9 @@ function bindUIButtons() { var jackett_update = $("#jackett-allowupdate").is(':checked'); var jackett_prerelease = $("#jackett-prerelease").is(':checked'); var jackett_logging = $("#jackett-logging").is(':checked'); + var jackett_cache_enabled = $("#jackett-cache-enabled").is(':checked'); + var jackett_cache_ttl = $("#jackett-cache-ttl").val(); + var jackett_cache_max_results_per_indexer = $("#jackett-cache-max-results-per-indexer").val(); var jackett_omdb_key = $("#jackett-omdbkey").val(); var jackett_omdb_url = $("#jackett-omdburl").val(); @@ -1143,6 +1154,10 @@ function bindUIButtons() { blackholedir: $("#jackett-savedir").val(), logging: jackett_logging, basepathoverride: jackett_basepathoverride, + logging: jackett_logging, + cache_enabled: jackett_cache_enabled, + cache_ttl: jackett_cache_ttl, + cache_max_results_per_indexer: jackett_cache_max_results_per_indexer, omdbkey: jackett_omdb_key, omdburl: jackett_omdb_url, proxy_type: jackett_proxy_type, diff --git a/src/Jackett.Common/Content/custom_mobile.css b/src/Jackett.Common/Content/custom_mobile.css index b950fd617b38d..3c9fe822a3823 100644 --- a/src/Jackett.Common/Content/custom_mobile.css +++ b/src/Jackett.Common/Content/custom_mobile.css @@ -126,8 +126,8 @@ hr { } .input-header { - font-size: 18px; - width: 160px; + font-size: 16px; + width: 250px; display: inline-block; } @@ -157,7 +157,7 @@ hr { text-align: center; } -#jackett-allowext, #jackett-allowupdate, #jackett-logging, #jackett-prerelease { +#jackett-allowext, #jackett-allowupdate, #jackett-logging, #jackett-prerelease, #jackett-cache-enabled { width: 25px; } diff --git a/src/Jackett.Common/Content/index.html b/src/Jackett.Common/Content/index.html index 3730d2d96a747..cb1c89c1b76e3 100644 --- a/src/Jackett.Common/Content/index.html +++ b/src/Jackett.Common/Content/index.html @@ -33,8 +33,8 @@ - - + + @@ -127,7 +127,7 @@

Jackett Configuration

- Base Path Override: + Base path override:
@@ -135,7 +135,7 @@

Jackett Configuration

- Manual download blackhole directory: + Blackhole directory:
@@ -188,6 +188,18 @@

Jackett Configuration

Enhanced logging: +
+ Cache enabled (recommended): + +
+
+ Cache TTL (seconds): + +
+
+ Cache max results per indexer: + +
OMDB API key: @@ -680,6 +692,6 @@

Capabilities

- + diff --git a/src/Jackett.Common/Indexers/Abnormal.cs b/src/Jackett.Common/Indexers/Abnormal.cs index 0d9cd9944f7f1..13fdded6660ec 100644 --- a/src/Jackett.Common/Indexers/Abnormal.cs +++ b/src/Jackett.Common/Indexers/Abnormal.cs @@ -49,7 +49,8 @@ private ConfigurationDataAbnormal ConfigData set => configData = value; } - public Abnormal(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public Abnormal(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "abnormal", name: "Abnormal", description: "General French Private Tracker", @@ -68,6 +69,7 @@ public Abnormal(IIndexerConfigurationService configService, WebClient w, Logger client: w, logger: l, p: ps, + cacheService: cs, downloadBase: "https://abnormal.ws/torrents.php?action=download&id=", configData: new ConfigurationDataAbnormal()) { diff --git a/src/Jackett.Common/Indexers/Abstract/AvistazTracker.cs b/src/Jackett.Common/Indexers/Abstract/AvistazTracker.cs index 698a920ab5482..7062ca852b86d 100644 --- a/src/Jackett.Common/Indexers/Abstract/AvistazTracker.cs +++ b/src/Jackett.Common/Indexers/Abstract/AvistazTracker.cs @@ -106,7 +106,7 @@ var res when _hdResolutions.Contains(res) => TorznabCatType.TVHD.ID, protected AvistazTracker(string link, string id, string name, string description, IIndexerConfigurationService configService, WebClient client, Logger logger, - IProtectionService p, TorznabCapabilities caps) + IProtectionService p, ICacheService cs, TorznabCapabilities caps) : base(id: id, name: name, description: description, @@ -116,6 +116,7 @@ protected AvistazTracker(string link, string id, string name, string description client: client, logger: logger, p: p, + cacheService: cs, configData: new ConfigurationDataBasicLoginWithPID(@"You have to check 'Enable RSS Feed' in 'My Account', without this configuration the torrent download does not work.
You can find the PID in 'My profile'.")) { diff --git a/src/Jackett.Common/Indexers/Abstract/CouchPotatoTracker.cs b/src/Jackett.Common/Indexers/Abstract/CouchPotatoTracker.cs index aa97a6ec794a3..2582c4bf4c7b8 100644 --- a/src/Jackett.Common/Indexers/Abstract/CouchPotatoTracker.cs +++ b/src/Jackett.Common/Indexers/Abstract/CouchPotatoTracker.cs @@ -27,8 +27,8 @@ public abstract class CouchPotatoTracker : BaseWebIndexer protected CouchPotatoTracker(string link, string id, string name, string description, IIndexerConfigurationService configService, WebClient client, Logger logger, - IProtectionService p, TorznabCapabilities caps, ConfigurationData configData, - string endpoint) + IProtectionService p, ICacheService cs, TorznabCapabilities caps, + ConfigurationData configData, string endpoint) : base(id: id, name: name, description: description, @@ -38,6 +38,7 @@ protected CouchPotatoTracker(string link, string id, string name, string descrip client: client, logger: logger, p: p, + cacheService: cs, configData: configData) { this.endpoint = endpoint; diff --git a/src/Jackett.Common/Indexers/Abstract/GazelleTracker.cs b/src/Jackett.Common/Indexers/Abstract/GazelleTracker.cs index 00e36f672e277..4e38db1dcf0cb 100644 --- a/src/Jackett.Common/Indexers/Abstract/GazelleTracker.cs +++ b/src/Jackett.Common/Indexers/Abstract/GazelleTracker.cs @@ -37,9 +37,9 @@ public abstract class GazelleTracker : BaseWebIndexer protected GazelleTracker(string link, string id, string name, string description, IIndexerConfigurationService configService, WebClient client, Logger logger, - IProtectionService p, TorznabCapabilities caps, bool supportsFreeleechTokens, - bool imdbInTags = false, bool has2Fa = false, bool useApiKey = false, - string instructionMessageOptional = null) + IProtectionService p, ICacheService cs, TorznabCapabilities caps, + bool supportsFreeleechTokens, bool imdbInTags = false, bool has2Fa = false, + bool useApiKey = false, string instructionMessageOptional = null) : base(id: id, name: name, description: description, @@ -49,6 +49,7 @@ protected GazelleTracker(string link, string id, string name, string description client: client, logger: logger, p: p, + cacheService: cs, configData: new ConfigurationDataGazelleTracker( has2Fa, supportsFreeleechTokens, useApiKey, instructionMessageOptional)) { diff --git a/src/Jackett.Common/Indexers/AlphaRatio.cs b/src/Jackett.Common/Indexers/AlphaRatio.cs index f6056de14e2d8..05523e43b3dda 100644 --- a/src/Jackett.Common/Indexers/AlphaRatio.cs +++ b/src/Jackett.Common/Indexers/AlphaRatio.cs @@ -12,7 +12,8 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class AlphaRatio : GazelleTracker { - public AlphaRatio(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public AlphaRatio(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "alpharatio", name: "AlphaRatio", description: "AlphaRatio (AR) is a Private Torrent Tracker for 0DAY / GENERAL", @@ -32,6 +33,7 @@ public AlphaRatio(IIndexerConfigurationService configService, WebClient wc, Logg client: wc, logger: l, p: ps, + cs: cs, supportsFreeleechTokens: true, imdbInTags: true) { diff --git a/src/Jackett.Common/Indexers/AniDUB.cs b/src/Jackett.Common/Indexers/AniDUB.cs index 1d4084f2e02f7..7b35b7054fd64 100644 --- a/src/Jackett.Common/Indexers/AniDUB.cs +++ b/src/Jackett.Common/Indexers/AniDUB.cs @@ -27,7 +27,8 @@ internal class AniDUB : BaseWebIndexer private static readonly Regex SeasonInfoRegex = new Regex(@"(?:(?:TV-)|(?:ТВ-))(\d+)", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Lazy StripRussianTitleRegex = new Lazy(() => new Regex(@"^.*?\/\s*", RegexOptions.Compiled)); - public AniDUB(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public AniDUB(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "anidub", name: "AniDUB", description: "AniDUB Tracker is a semi-private russian tracker and release group for anime", @@ -51,6 +52,7 @@ public AniDUB(IIndexerConfigurationService configService, WebClient wc, Logger l client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataAniDub()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/AniLibria.cs b/src/Jackett.Common/Indexers/AniLibria.cs index d41e27f7915f5..8988abebc24d1 100644 --- a/src/Jackett.Common/Indexers/AniLibria.cs +++ b/src/Jackett.Common/Indexers/AniLibria.cs @@ -18,7 +18,7 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class AniLibria : BaseWebIndexer { - public AniLibria(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps) + public AniLibria(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps, ICacheService cs) : base(id: "AniLibria", name: "AniLibria", description: "AniLibria is a Public torrent tracker for anime, voiced on russian by AniLibria team", @@ -34,6 +34,7 @@ public AniLibria(IIndexerConfigurationService configService, Utils.Clients.WebCl client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataAniLibria()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/Anidex.cs b/src/Jackett.Common/Indexers/Anidex.cs index 960555f501eef..2f8d098d0ea3f 100644 --- a/src/Jackett.Common/Indexers/Anidex.cs +++ b/src/Jackett.Common/Indexers/Anidex.cs @@ -23,7 +23,8 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class Anidex : BaseWebIndexer { - public Anidex(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps) + public Anidex(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "anidex", name: "Anidex", description: "Anidex is a Public torrent tracker and indexer, primarily for English fansub groups of anime", @@ -39,6 +40,7 @@ public Anidex(IIndexerConfigurationService configService, Utils.Clients.WebClien client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/AnimeBytes.cs b/src/Jackett.Common/Indexers/AnimeBytes.cs index 2da2cde8d5a90..01d560b40d021 100644 --- a/src/Jackett.Common/Indexers/AnimeBytes.cs +++ b/src/Jackett.Common/Indexers/AnimeBytes.cs @@ -32,7 +32,8 @@ public class AnimeBytes : BaseCachingWebIndexer private ConfigurationDataAnimeBytes ConfigData => (ConfigurationDataAnimeBytes)configData; - public AnimeBytes(IIndexerConfigurationService configService, WebClient client, Logger l, IProtectionService ps) + public AnimeBytes(IIndexerConfigurationService configService, WebClient client, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "animebytes", name: "AnimeBytes", description: "Powered by Tentacles", @@ -59,6 +60,7 @@ public AnimeBytes(IIndexerConfigurationService configService, WebClient client, }, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataAnimeBytes("Note: Go to AnimeBytes site and open your account settings. Go to 'Account' tab, move cursor over black part near 'Passkey' and copy its value. Your username is case sensitive.")) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/AnimeTorrents.cs b/src/Jackett.Common/Indexers/AnimeTorrents.cs index e71377a2ca2b6..94002747984a2 100644 --- a/src/Jackett.Common/Indexers/AnimeTorrents.cs +++ b/src/Jackett.Common/Indexers/AnimeTorrents.cs @@ -32,7 +32,8 @@ public class AnimeTorrents : BaseWebIndexer set => base.configData = value; } - public AnimeTorrents(IIndexerConfigurationService configService, WebClient c, Logger l, IProtectionService ps) + public AnimeTorrents(IIndexerConfigurationService configService, WebClient c, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "animetorrents", name: "AnimeTorrents", description: "Definitive source for anime and manga", @@ -51,6 +52,7 @@ public AnimeTorrents(IIndexerConfigurationService configService, WebClient c, Lo client: c, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/Animedia.cs b/src/Jackett.Common/Indexers/Animedia.cs index d02e90bf0ce29..b6f10827f0a63 100644 --- a/src/Jackett.Common/Indexers/Animedia.cs +++ b/src/Jackett.Common/Indexers/Animedia.cs @@ -27,7 +27,8 @@ internal class Animedia : BaseWebIndexer private static readonly Regex SizeInfoQueryRegex = new Regex(@"Размер:(.*)\n", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex ReleaseDateInfoQueryRegex = new Regex(@"Добавлен:(.*)\n", RegexOptions.Compiled | RegexOptions.IgnoreCase); - public Animedia(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public Animedia(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "Animedia", name: "Animedia", description: "Animedia is a public russian tracker and release group for anime.", @@ -43,6 +44,7 @@ public Animedia(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/Anthelion.cs b/src/Jackett.Common/Indexers/Anthelion.cs index ea5eae8c5abc7..a264937b5e8ce 100644 --- a/src/Jackett.Common/Indexers/Anthelion.cs +++ b/src/Jackett.Common/Indexers/Anthelion.cs @@ -30,7 +30,8 @@ public class Anthelion : BaseWebIndexer "https://tehconnection.me/" }; - public Anthelion(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public Anthelion(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "anthelion", name: "Anthelion", // old name: TehConnection.me description: "A movies tracker", @@ -49,6 +50,7 @@ public Anthelion(IIndexerConfigurationService configService, WebClient wc, Logge client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/AvistaZ.cs b/src/Jackett.Common/Indexers/AvistaZ.cs index 7a755c232ec0d..73d53a2cc6b2f 100644 --- a/src/Jackett.Common/Indexers/AvistaZ.cs +++ b/src/Jackett.Common/Indexers/AvistaZ.cs @@ -11,7 +11,8 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class AvistaZ : AvistazTracker { - public AvistaZ(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public AvistaZ(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "avistaz", name: "AvistaZ", description: "Aka AsiaTorrents", @@ -30,7 +31,9 @@ public AvistaZ(IIndexerConfigurationService configService, WebClient wc, Logger configService: configService, client: wc, logger: l, - p: ps) + p: ps, + cs: cs + ) { AddCategoryMapping(1, TorznabCatType.Movies); AddCategoryMapping(1, TorznabCatType.MoviesUHD); diff --git a/src/Jackett.Common/Indexers/AwesomeHD.cs b/src/Jackett.Common/Indexers/AwesomeHD.cs index 5360f2b54c9da..3ab092c4433cc 100644 --- a/src/Jackett.Common/Indexers/AwesomeHD.cs +++ b/src/Jackett.Common/Indexers/AwesomeHD.cs @@ -24,7 +24,8 @@ public class AwesomeHD : BaseWebIndexer private readonly Regex _removeYearRegex = new Regex(@" [\(\[]?(19|20)\d{2}[\)\]]?$", RegexOptions.Compiled); private new ConfigurationDataPasskey configData => (ConfigurationDataPasskey)base.configData; - public AwesomeHD(IIndexerConfigurationService configService, Utils.Clients.WebClient c, Logger l, IProtectionService ps) + public AwesomeHD(IIndexerConfigurationService configService, Utils.Clients.WebClient c, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "awesomehd", name: "Awesome-HD", description: "An HD tracker", @@ -48,6 +49,7 @@ public AwesomeHD(IIndexerConfigurationService configService, Utils.Clients.WebCl client: c, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataPasskey("Note: You can find the Passkey in your profile, " + "next to Personal information.")) { diff --git a/src/Jackett.Common/Indexers/BB.cs b/src/Jackett.Common/Indexers/BB.cs index f0dd07182bc10..8d94890c7e6e2 100644 --- a/src/Jackett.Common/Indexers/BB.cs +++ b/src/Jackett.Common/Indexers/BB.cs @@ -33,7 +33,8 @@ public class BB : BaseWebIndexer set => base.configData = value; } - public BB(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public BB(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "bb", name: "bB", description: "bB is a Private Torrent Tracker for 0DAY / GENERAL", @@ -61,6 +62,7 @@ public BB(IIndexerConfigurationService configService, WebClient w, Logger l, IPr client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/BJShare.cs b/src/Jackett.Common/Indexers/BJShare.cs index a92ba68ba49bd..653300e646c98 100644 --- a/src/Jackett.Common/Indexers/BJShare.cs +++ b/src/Jackett.Common/Indexers/BJShare.cs @@ -60,7 +60,8 @@ public class BJShare : BaseWebIndexer {"greys anatomy", "grey's anatomy"} }; - public BJShare(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public BJShare(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "bjshare", name: "BJ-Share", description: "A brazilian tracker.", @@ -88,6 +89,7 @@ public BJShare(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLoginWithRSSAndDisplay()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/BakaBT.cs b/src/Jackett.Common/Indexers/BakaBT.cs index 546814dde81bd..18b75f445f474 100644 --- a/src/Jackett.Common/Indexers/BakaBT.cs +++ b/src/Jackett.Common/Indexers/BakaBT.cs @@ -35,7 +35,8 @@ public class BakaBT : BaseWebIndexer set => base.configData = value; } - public BakaBT(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps) + public BakaBT(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "bakabt", name: "BakaBT", description: "Anime Comunity", @@ -59,6 +60,7 @@ public BakaBT(IIndexerConfigurationService configService, Utils.Clients.WebClien client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBakaBT("To prevent 0-results-error, Enable the " + "Show-Adult-Content option in your BakaBT account Settings.")) { diff --git a/src/Jackett.Common/Indexers/BaseIndexer.cs b/src/Jackett.Common/Indexers/BaseIndexer.cs index 36c09f93f3950..edc5f06c8307b 100644 --- a/src/Jackett.Common/Indexers/BaseIndexer.cs +++ b/src/Jackett.Common/Indexers/BaseIndexer.cs @@ -36,6 +36,7 @@ public abstract class BaseIndexer : IIndexer protected Logger logger; protected IIndexerConfigurationService configurationService; protected IProtectionService protectionService; + protected ICacheService cacheService; protected ConfigurationData configData; @@ -62,11 +63,12 @@ public string LastError // standard constructor used by most indexers public BaseIndexer(string link, string id, string name, string description, IIndexerConfigurationService configService, Logger logger, ConfigurationData configData, - IProtectionService p) + IProtectionService p, ICacheService cs) { this.logger = logger; configurationService = configService; protectionService = p; + cacheService = cs; if (!link.EndsWith("/", StringComparison.Ordinal)) throw new Exception("Site link must end with a slash."); @@ -378,14 +380,19 @@ public void Unconfigure() public virtual async Task ResultsForQuery(TorznabQuery query, bool isMetaIndexer) { if (!CanHandleQuery(query) || !CanHandleCategories(query, isMetaIndexer)) - return new IndexerResult(this, new ReleaseInfo[0]); + return new IndexerResult(this, new ReleaseInfo[0], false); + + var cachedReleases = cacheService.Search(this, query); + if (cachedReleases != null) + return new IndexerResult(this, cachedReleases, true); try { var results = await PerformQuery(query); results = FilterResults(query, results); results = FixResults(query, results); - return new IndexerResult(this, results); + cacheService.CacheResults(this, query, results.ToList()); + return new IndexerResult(this, results, false); } catch (Exception ex) { @@ -400,9 +407,9 @@ public abstract class BaseWebIndexer : BaseIndexer, IWebIndexer { protected BaseWebIndexer(string link, string id, string name, string description, IIndexerConfigurationService configService, WebClient client, Logger logger, - ConfigurationData configData, IProtectionService p, TorznabCapabilities caps, - string downloadBase = null) - : base(link, id, name, description, configService, logger, configData, p) + ConfigurationData configData, IProtectionService p, ICacheService cacheService, + TorznabCapabilities caps, string downloadBase = null) + : base(link, id, name, description, configService, logger, configData, p, cacheService) { webclient = client; downloadUrlBase = downloadBase; @@ -410,8 +417,9 @@ protected BaseWebIndexer(string link, string id, string name, string description } // minimal constructor used by e.g. cardigann generic indexer - protected BaseWebIndexer(IIndexerConfigurationService configService, WebClient client, Logger logger, IProtectionService p) - : base("/", "", "", "", configService, logger, null, p) => webclient = client; + protected BaseWebIndexer(IIndexerConfigurationService configService, WebClient client, Logger logger, + IProtectionService p, ICacheService cacheService) + : base("/", "", "", "", configService, logger, null, p, cacheService) => webclient = client; public virtual async Task Download(Uri link) { @@ -658,7 +666,6 @@ public override async Task ResultsForQuery(TorznabQuery query, bo { var result = await base.ResultsForQuery(query, isMetaIndexer); result.Releases = CleanLinks(result.Releases); - return result; } @@ -696,9 +703,9 @@ public abstract class BaseCachingWebIndexer : BaseWebIndexer { protected BaseCachingWebIndexer(string link,string id, string name, string description, IIndexerConfigurationService configService, WebClient client, Logger logger, - ConfigurationData configData, IProtectionService p, TorznabCapabilities caps = null, - string downloadBase = null) - : base(link, id, name, description, configService, client, logger, configData, p, caps, downloadBase) + ConfigurationData configData, IProtectionService p, ICacheService cacheService, + TorznabCapabilities caps = null, string downloadBase = null) + : base(link, id, name, description, configService, client, logger, configData, p, cacheService, caps, downloadBase) { } @@ -710,6 +717,7 @@ protected void CleanCache() } } + // TODO: remove this implementation and use gloal cache protected static List cache = new List(); protected static readonly TimeSpan cacheTime = new TimeSpan(0, 9, 0); } diff --git a/src/Jackett.Common/Indexers/BitCityReloaded.cs b/src/Jackett.Common/Indexers/BitCityReloaded.cs index 1faa48a84044b..5adc73f24d405 100644 --- a/src/Jackett.Common/Indexers/BitCityReloaded.cs +++ b/src/Jackett.Common/Indexers/BitCityReloaded.cs @@ -30,7 +30,8 @@ public class BitCityReloaded : BaseWebIndexer set => base.configData = value; } - public BitCityReloaded(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public BitCityReloaded(IIndexerConfigurationService configService, WebClient wc, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "bitcityreloaded", name: "Bit-City Reloaded", description: "A German general tracker.", @@ -58,6 +59,7 @@ public BitCityReloaded(IIndexerConfigurationService configService, WebClient wc, client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLoginWithRSSAndDisplay("Only the results from the first search result page are shown, adjust your profile settings to show a reasonable amount (it looks like there's no maximum).")) { Encoding = Encoding.GetEncoding("iso-8859-1"); diff --git a/src/Jackett.Common/Indexers/BitHDTV.cs b/src/Jackett.Common/Indexers/BitHDTV.cs index e45319b85ef05..74831bbd88e79 100644 --- a/src/Jackett.Common/Indexers/BitHDTV.cs +++ b/src/Jackett.Common/Indexers/BitHDTV.cs @@ -25,7 +25,8 @@ public class BitHDTV : BaseWebIndexer private new ConfigurationDataCookie configData => (ConfigurationDataCookie)base.configData; - public BitHDTV(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public BitHDTV(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "bithdtv", name: "BIT-HDTV", description: "BIT-HDTV - Home of High Definition", @@ -45,6 +46,7 @@ public BitHDTV(IIndexerConfigurationService configService, WebClient w, Logger l client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataCookie("For best results, change the 'Torrents per page' setting to 100 in your profile.")) { Encoding = Encoding.GetEncoding("iso-8859-1"); diff --git a/src/Jackett.Common/Indexers/BroadcasTheNet.cs b/src/Jackett.Common/Indexers/BroadcasTheNet.cs index 4113abfba12fc..b5402487089fb 100644 --- a/src/Jackett.Common/Indexers/BroadcasTheNet.cs +++ b/src/Jackett.Common/Indexers/BroadcasTheNet.cs @@ -28,7 +28,8 @@ public class BroadcasTheNet : BaseWebIndexer set => base.configData = value; } - public BroadcasTheNet(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public BroadcasTheNet(IIndexerConfigurationService configService, WebClient wc, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "broadcasthenet", name: "BroadcasTheNet", description: "BroadcasTheNet (BTN) is an invite-only torrent tracker focused on TV shows", @@ -46,6 +47,7 @@ public BroadcasTheNet(IIndexerConfigurationService configService, WebClient wc, client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataAPIKey()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/BrokenStones.cs b/src/Jackett.Common/Indexers/BrokenStones.cs index 0fe9cb608ebba..53fa82571599d 100644 --- a/src/Jackett.Common/Indexers/BrokenStones.cs +++ b/src/Jackett.Common/Indexers/BrokenStones.cs @@ -10,7 +10,8 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class BrokenStones : GazelleTracker { - public BrokenStones(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public BrokenStones(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "brokenstones", name: "BrokenStones", description: "Broken Stones is a Private site for MacOS and iOS APPS / GAMES", @@ -20,6 +21,7 @@ public BrokenStones(IIndexerConfigurationService configService, WebClient wc, Lo client: wc, logger: l, p: ps, + cs: cs, supportsFreeleechTokens: true) { Language = "en-us"; diff --git a/src/Jackett.Common/Indexers/CGPeers.cs b/src/Jackett.Common/Indexers/CGPeers.cs index f007136c71a5a..08e4bcfbff501 100644 --- a/src/Jackett.Common/Indexers/CGPeers.cs +++ b/src/Jackett.Common/Indexers/CGPeers.cs @@ -14,7 +14,8 @@ public class CGPeers : GazelleTracker "https://www.cgpeers.com/" }; - public CGPeers(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public CGPeers(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "cgpeers", name: "CGPeers", description: "CGPeers is a Private Torrent Tracker for GRAPHICS SOFTWARE / TUTORIALS / ETC", @@ -24,6 +25,7 @@ public CGPeers(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cs: cs, supportsFreeleechTokens: true) { Language = "en-us"; diff --git a/src/Jackett.Common/Indexers/CardigannIndexer.cs b/src/Jackett.Common/Indexers/CardigannIndexer.cs index c037ba3dc5dec..b0312dcf2e9ba 100644 --- a/src/Jackett.Common/Indexers/CardigannIndexer.cs +++ b/src/Jackett.Common/Indexers/CardigannIndexer.cs @@ -58,11 +58,13 @@ public class CardigannIndexer : BaseWebIndexer @$"\b({string.Join("|", _SupportedLogicFunctions.Select(Regex.Escape))})(?:\s+(\(?\.[^\)\s]+\)?|""[^""]+"")){{2,}}"); public CardigannIndexer(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, - IProtectionService ps, IndexerDefinition Definition) + IProtectionService ps, ICacheService cs, IndexerDefinition Definition) : base(configService: configService, client: wc, logger: l, - p: ps) + p: ps, + cacheService: cs + ) { this.Definition = Definition; Id = Definition.Id; diff --git a/src/Jackett.Common/Indexers/Cinecalidad.cs b/src/Jackett.Common/Indexers/Cinecalidad.cs index a91ba208a995e..cbf0a6c3ea267 100644 --- a/src/Jackett.Common/Indexers/Cinecalidad.cs +++ b/src/Jackett.Common/Indexers/Cinecalidad.cs @@ -31,7 +31,8 @@ public class Cinecalidad : BaseWebIndexer "https://www.cinecalidad.eu/" }; - public Cinecalidad(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public Cinecalidad(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "cinecalidad", name: "Cinecalidad", description: "Películas Full HD en Castellano y Latino Dual.", @@ -43,6 +44,7 @@ public Cinecalidad(IIndexerConfigurationService configService, WebClient wc, Log client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/CinemaZ.cs b/src/Jackett.Common/Indexers/CinemaZ.cs index e6c7adf9ebef2..cbb4c1b27a3a2 100644 --- a/src/Jackett.Common/Indexers/CinemaZ.cs +++ b/src/Jackett.Common/Indexers/CinemaZ.cs @@ -11,7 +11,8 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class CinemaZ : AvistazTracker { - public CinemaZ(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public CinemaZ(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "cinemaz", name: "CinemaZ", description: "Part of the Avistaz network.", @@ -30,7 +31,9 @@ public CinemaZ(IIndexerConfigurationService configService, WebClient wc, Logger configService: configService, client: wc, logger: l, - p: ps) + p: ps, + cs: cs + ) { AddCategoryMapping(1, TorznabCatType.Movies); AddCategoryMapping(1, TorznabCatType.MoviesUHD); diff --git a/src/Jackett.Common/Indexers/DICMusic.cs b/src/Jackett.Common/Indexers/DICMusic.cs index fdda2a640bd87..e7017fcb4ec71 100644 --- a/src/Jackett.Common/Indexers/DICMusic.cs +++ b/src/Jackett.Common/Indexers/DICMusic.cs @@ -13,7 +13,8 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class DICMusic : GazelleTracker { - public DICMusic(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public DICMusic(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "dicmusic", name: "DICMusic", description: "DICMusic is a CHINESE Private Torrent Tracker for MUSIC", @@ -29,6 +30,7 @@ public DICMusic(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cs: cs, supportsFreeleechTokens: true, has2Fa: true) { diff --git a/src/Jackett.Common/Indexers/DarmoweTorrenty.cs b/src/Jackett.Common/Indexers/DarmoweTorrenty.cs index cac0eb2a25ce0..7728534da47be 100644 --- a/src/Jackett.Common/Indexers/DarmoweTorrenty.cs +++ b/src/Jackett.Common/Indexers/DarmoweTorrenty.cs @@ -35,7 +35,8 @@ public class DarmoweTorenty : BaseWebIndexer set => base.configData = value; } - public DarmoweTorenty(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public DarmoweTorenty(IIndexerConfigurationService configService, WebClient wc, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "darmowetorenty", name: "Darmowe torenty", description: "Darmowe torenty is a POLISH Semi-Private Torrent Tracker for MOVIES / TV / GENERAL", @@ -63,6 +64,7 @@ public DarmoweTorenty(IIndexerConfigurationService configService, WebClient wc, client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLoginWithRSSAndDisplay()) { Encoding = Encoding.GetEncoding("iso-8859-2"); diff --git a/src/Jackett.Common/Indexers/DigitalCore.cs b/src/Jackett.Common/Indexers/DigitalCore.cs index b6f37adc398de..6adb50ed14e42 100644 --- a/src/Jackett.Common/Indexers/DigitalCore.cs +++ b/src/Jackett.Common/Indexers/DigitalCore.cs @@ -29,7 +29,8 @@ public class DigitalCore : BaseWebIndexer set => base.configData = value; } - public DigitalCore(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public DigitalCore(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "digitalcore", name: "DigitalCore", description: "DigitalCore is a Private Torrent Tracker for MOVIES / TV / GENERAL", @@ -57,6 +58,7 @@ public DigitalCore(IIndexerConfigurationService configService, WebClient w, Logg client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataCookie()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/DivxTotal.cs b/src/Jackett.Common/Indexers/DivxTotal.cs index db9b1221c5ad6..7f5e09cd1e5df 100644 --- a/src/Jackett.Common/Indexers/DivxTotal.cs +++ b/src/Jackett.Common/Indexers/DivxTotal.cs @@ -49,7 +49,8 @@ private static class DivxTotalFizeSizes "https://www.divxtotal.la/" }; - public DivxTotal(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public DivxTotal(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "divxtotal", name: "DivxTotal", description: "DivxTotal is a SPANISH site for Movies, TV series and Software", @@ -68,6 +69,7 @@ public DivxTotal(IIndexerConfigurationService configService, WebClient w, Logger client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/EliteTracker.cs b/src/Jackett.Common/Indexers/EliteTracker.cs index 4d0db0756bdb2..9b55d171a57ef 100644 --- a/src/Jackett.Common/Indexers/EliteTracker.cs +++ b/src/Jackett.Common/Indexers/EliteTracker.cs @@ -24,7 +24,8 @@ internal class EliteTracker : BaseWebIndexer private string BrowseUrl => SiteLink + "browse.php"; private new ConfigurationDataEliteTracker configData => (ConfigurationDataEliteTracker)base.configData; - public EliteTracker(IIndexerConfigurationService configService, WebClient webClient, Logger logger, IProtectionService protectionService) + public EliteTracker(IIndexerConfigurationService configService, WebClient webClient, Logger logger, + IProtectionService ps, ICacheService cs) : base(id: "elitetracker", name: "Elite-Tracker", description: "French Torrent Tracker", @@ -50,7 +51,8 @@ public EliteTracker(IIndexerConfigurationService configService, WebClient webCli }, configService: configService, logger: logger, - p: protectionService, + p: ps, + cacheService: cs, client: webClient, configData: new ConfigurationDataEliteTracker() ) diff --git a/src/Jackett.Common/Indexers/EpubLibre.cs b/src/Jackett.Common/Indexers/EpubLibre.cs index 3a2487db13cfc..dc7039eb8bdd4 100644 --- a/src/Jackett.Common/Indexers/EpubLibre.cs +++ b/src/Jackett.Common/Indexers/EpubLibre.cs @@ -53,7 +53,8 @@ public class EpubLibre : BaseWebIndexer "https://epublibre.unblockit.app/" }; - public EpubLibre(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public EpubLibre(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "epublibre", name: "EpubLibre", description: "Más libros, Más libres", @@ -69,6 +70,7 @@ public EpubLibre(IIndexerConfigurationService configService, WebClient wc, Logge client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/ExoticaZ.cs b/src/Jackett.Common/Indexers/ExoticaZ.cs index 284addfea9faf..db8c77069ad06 100644 --- a/src/Jackett.Common/Indexers/ExoticaZ.cs +++ b/src/Jackett.Common/Indexers/ExoticaZ.cs @@ -19,7 +19,8 @@ public class ExoticaZ : AvistazTracker "https://torrents.yourexotic.com/" }; - public ExoticaZ(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public ExoticaZ(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "exoticaz", name: "ExoticaZ", description: "ExoticaZ (YourExotic) is a Private Torrent Tracker for 3X", @@ -34,7 +35,9 @@ public ExoticaZ(IIndexerConfigurationService configService, WebClient wc, Logger configService: configService, client: wc, logger: l, - p: ps) + p: ps, + cs: cs + ) { AddCategoryMapping(1, TorznabCatType.XXXx264); AddCategoryMapping(2, TorznabCatType.XXXPack); diff --git a/src/Jackett.Common/Indexers/Feeds/AnimeTosho.cs b/src/Jackett.Common/Indexers/Feeds/AnimeTosho.cs index 50425cfa9bd32..c6b98e293c2f9 100644 --- a/src/Jackett.Common/Indexers/Feeds/AnimeTosho.cs +++ b/src/Jackett.Common/Indexers/Feeds/AnimeTosho.cs @@ -16,7 +16,8 @@ namespace Jackett.Common.Indexers.Feeds [ExcludeFromCodeCoverage] public class AnimeTosho : BaseNewznabIndexer { - public AnimeTosho(IIndexerConfigurationService configService, WebClient client, Logger logger, IProtectionService ps) + public AnimeTosho(IIndexerConfigurationService configService, WebClient client, Logger logger, + IProtectionService ps, ICacheService cs) : base(id: "animetosho", name: "Anime Tosho", description: "AnimeTosho (AT) is an automated service that provides torrent files, magnet links and DDL for all anime releases", @@ -32,6 +33,7 @@ public AnimeTosho(IIndexerConfigurationService configService, WebClient client, client: client, logger: logger, p: ps, + cs: cs, configData: new ConfigurationData()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/Feeds/BaseFeedIndexer.cs b/src/Jackett.Common/Indexers/Feeds/BaseFeedIndexer.cs index a4a8e9b1b9b06..a8fc3147d2cab 100644 --- a/src/Jackett.Common/Indexers/Feeds/BaseFeedIndexer.cs +++ b/src/Jackett.Common/Indexers/Feeds/BaseFeedIndexer.cs @@ -18,8 +18,8 @@ public abstract class BaseFeedIndexer : BaseWebIndexer protected BaseFeedIndexer(string link, string id, string name, string description, IIndexerConfigurationService configService, WebClient client, Logger logger, - ConfigurationData configData, IProtectionService p, TorznabCapabilities caps = null, - string downloadBase = null) + ConfigurationData configData, IProtectionService p, ICacheService cs, + TorznabCapabilities caps = null, string downloadBase = null) : base(id: id, name: name, description: description, @@ -29,6 +29,7 @@ protected BaseFeedIndexer(string link, string id, string name, string descriptio client: client, logger: logger, p: p, + cacheService: cs, configData: configData, downloadBase: downloadBase) { diff --git a/src/Jackett.Common/Indexers/Feeds/BaseNewznabIndexer.cs b/src/Jackett.Common/Indexers/Feeds/BaseNewznabIndexer.cs index e2ac031f87d7a..c0a8060b480c6 100644 --- a/src/Jackett.Common/Indexers/Feeds/BaseNewznabIndexer.cs +++ b/src/Jackett.Common/Indexers/Feeds/BaseNewznabIndexer.cs @@ -17,8 +17,8 @@ public abstract class BaseNewznabIndexer : BaseFeedIndexer { protected BaseNewznabIndexer(string link, string id, string name, string description, IIndexerConfigurationService configService, WebClient client, Logger logger, - ConfigurationData configData, IProtectionService p, TorznabCapabilities caps = null, - string downloadBase = null) + ConfigurationData configData, IProtectionService p, ICacheService cs, + TorznabCapabilities caps = null, string downloadBase = null) : base(id: id, name: name, description: description, @@ -28,6 +28,7 @@ protected BaseNewznabIndexer(string link, string id, string name, string descrip client: client, logger: logger, p: p, + cs: cs, configData: configData, downloadBase: downloadBase) { diff --git a/src/Jackett.Common/Indexers/FileList.cs b/src/Jackett.Common/Indexers/FileList.cs index 724d2367190bd..437eb2fb9637b 100644 --- a/src/Jackett.Common/Indexers/FileList.cs +++ b/src/Jackett.Common/Indexers/FileList.cs @@ -30,7 +30,8 @@ public class FileList : BaseWebIndexer private new ConfigurationDataFileList configData => (ConfigurationDataFileList)base.configData; - public FileList(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public FileList(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "filelist", name: "FileList", description: "The best Romanian site.", @@ -58,6 +59,7 @@ public FileList(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataFileList()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/FunFile.cs b/src/Jackett.Common/Indexers/FunFile.cs index 4d225b2fd27fd..699a85a8d0599 100644 --- a/src/Jackett.Common/Indexers/FunFile.cs +++ b/src/Jackett.Common/Indexers/FunFile.cs @@ -23,7 +23,8 @@ public class FunFile : BaseWebIndexer private new ConfigurationDataBasicLogin configData => (ConfigurationDataBasicLogin)base.configData; - public FunFile(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public FunFile(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "funfile", name: "FunFile", description: "A general tracker", @@ -51,6 +52,7 @@ public FunFile(IIndexerConfigurationService configService, WebClient w, Logger l client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin("For best results, change the 'Torrents per page' setting to 100 in your profile.")) { Encoding = Encoding.GetEncoding("iso-8859-1"); diff --git a/src/Jackett.Common/Indexers/Fuzer.cs b/src/Jackett.Common/Indexers/Fuzer.cs index bcebeb4ded4f6..721751b3cce15 100644 --- a/src/Jackett.Common/Indexers/Fuzer.cs +++ b/src/Jackett.Common/Indexers/Fuzer.cs @@ -30,7 +30,8 @@ public class Fuzer : BaseWebIndexer private new ConfigurationDataCookie configData => (ConfigurationDataCookie)base.configData; - public Fuzer(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public Fuzer(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "fuzer", name: "Fuzer", description: "Fuzer is a private torrent website with israeli torrents.", @@ -58,6 +59,7 @@ public Fuzer(IIndexerConfigurationService configService, WebClient w, Logger l, client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataCookie()) { Encoding = Encoding.GetEncoding("windows-1255"); diff --git a/src/Jackett.Common/Indexers/GazelleGames.cs b/src/Jackett.Common/Indexers/GazelleGames.cs index db2b97185a973..a4193c7d033d1 100644 --- a/src/Jackett.Common/Indexers/GazelleGames.cs +++ b/src/Jackett.Common/Indexers/GazelleGames.cs @@ -30,7 +30,8 @@ public class GazelleGames : BaseWebIndexer set => base.configData = value; } - public GazelleGames(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public GazelleGames(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "gazellegames", name: "GazelleGames", description: "A gaming tracker.", @@ -40,6 +41,7 @@ public GazelleGames(IIndexerConfigurationService configService, WebClient wc, Lo client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataCookie()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/GimmePeers.cs b/src/Jackett.Common/Indexers/GimmePeers.cs index 3397dfe6997f1..96fb6f73707f4 100644 --- a/src/Jackett.Common/Indexers/GimmePeers.cs +++ b/src/Jackett.Common/Indexers/GimmePeers.cs @@ -29,7 +29,8 @@ public class GimmePeers : BaseWebIndexer set => base.configData = value; } - public GimmePeers(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public GimmePeers(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "gimmepeers", name: "GimmePeers", description: "Formerly ILT", @@ -57,6 +58,7 @@ public GimmePeers(IIndexerConfigurationService configService, WebClient wc, Logg client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin()) { Encoding = Encoding.GetEncoding("iso-8859-1"); diff --git a/src/Jackett.Common/Indexers/HDBitsApi.cs b/src/Jackett.Common/Indexers/HDBitsApi.cs index b9c8c7212df76..8902e91c16def 100644 --- a/src/Jackett.Common/Indexers/HDBitsApi.cs +++ b/src/Jackett.Common/Indexers/HDBitsApi.cs @@ -25,7 +25,8 @@ public class HDBitsApi : BaseWebIndexer set => base.configData = value; } - public HDBitsApi(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public HDBitsApi(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "hdbitsapi", name: "HDBits (API)", description: "The HighDefinition Bittorrent Community", @@ -45,6 +46,7 @@ public HDBitsApi(IIndexerConfigurationService configService, WebClient wc, Logge client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataHDBitsApi()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/HDSpace.cs b/src/Jackett.Common/Indexers/HDSpace.cs index 8c828a16fa2b5..2a01f0003ac7e 100644 --- a/src/Jackett.Common/Indexers/HDSpace.cs +++ b/src/Jackett.Common/Indexers/HDSpace.cs @@ -25,7 +25,8 @@ public class HDSpace : BaseWebIndexer private new ConfigurationDataBasicLogin configData => (ConfigurationDataBasicLogin)base.configData; - public HDSpace(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public HDSpace(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "hdspace", name: "HD-Space", description: "Sharing The Universe", @@ -49,6 +50,7 @@ public HDSpace(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/HDTorrents.cs b/src/Jackett.Common/Indexers/HDTorrents.cs index 2ea6c16f27a31..d730fbb84cbd4 100644 --- a/src/Jackett.Common/Indexers/HDTorrents.cs +++ b/src/Jackett.Common/Indexers/HDTorrents.cs @@ -44,7 +44,8 @@ public class HDTorrents : BaseWebIndexer private new ConfigurationDataBasicLogin configData => (ConfigurationDataBasicLogin)base.configData; - public HDTorrents(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public HDTorrents(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "hdtorrents", name: "HD-Torrents", description: "HD-Torrents is a private torrent website with HD torrents and strict rules on their content.", @@ -68,6 +69,7 @@ public HDTorrents(IIndexerConfigurationService configService, WebClient w, Logge client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin( "For best results, change the Torrents per page: setting to 100 on your account profile.")) { diff --git a/src/Jackett.Common/Indexers/Hebits.cs b/src/Jackett.Common/Indexers/Hebits.cs index 5910f44d14365..1b4b4e795219f 100644 --- a/src/Jackett.Common/Indexers/Hebits.cs +++ b/src/Jackett.Common/Indexers/Hebits.cs @@ -29,7 +29,8 @@ public class Hebits : BaseWebIndexer set => base.configData = value; } - public Hebits(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps) + public Hebits(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "hebits", name: "Hebits", description: "The Israeli Tracker", @@ -57,6 +58,7 @@ public Hebits(IIndexerConfigurationService configService, Utils.Clients.WebClien client: wc, logger: l, p: ps, + cacheService: cs, downloadBase: "https://hebits.net/", configData: new ConfigurationDataBasicLogin()) { diff --git a/src/Jackett.Common/Indexers/IIndexer.cs b/src/Jackett.Common/Indexers/IIndexer.cs index 088dd8cb26467..484839171149b 100644 --- a/src/Jackett.Common/Indexers/IIndexer.cs +++ b/src/Jackett.Common/Indexers/IIndexer.cs @@ -12,11 +12,13 @@ public class IndexerResult { public IIndexer Indexer { get; set; } public IEnumerable Releases { get; set; } + public bool IsFromCache; - public IndexerResult(IIndexer Indexer, IEnumerable Releases) + public IndexerResult(IIndexer indexer, IEnumerable releases, bool isFromCache) { - this.Indexer = Indexer; - this.Releases = Releases; + Indexer = indexer; + Releases = releases; + IsFromCache = isFromCache; } } diff --git a/src/Jackett.Common/Indexers/IPTorrents.cs b/src/Jackett.Common/Indexers/IPTorrents.cs index 0522bdd0c1d06..40ead53c042d1 100644 --- a/src/Jackett.Common/Indexers/IPTorrents.cs +++ b/src/Jackett.Common/Indexers/IPTorrents.cs @@ -49,7 +49,8 @@ public class IPTorrents : BaseWebIndexer private new ConfigurationDataCookie configData => (ConfigurationDataCookie)base.configData; - public IPTorrents(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public IPTorrents(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "iptorrents", name: "IPTorrents", description: "Always a step ahead.", @@ -77,6 +78,7 @@ public IPTorrents(IIndexerConfigurationService configService, WebClient wc, Logg client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataCookie("For best results, change the 'Torrents per page' option to 100 and check the 'Torrents - Show files count' option in the website Settings.")) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/ImmortalSeed.cs b/src/Jackett.Common/Indexers/ImmortalSeed.cs index d0b99695790e1..5f6e3f757f64c 100644 --- a/src/Jackett.Common/Indexers/ImmortalSeed.cs +++ b/src/Jackett.Common/Indexers/ImmortalSeed.cs @@ -33,7 +33,8 @@ public class ImmortalSeed : BaseWebIndexer set => base.configData = value; } - public ImmortalSeed(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps) + public ImmortalSeed(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "immortalseed", name: "ImmortalSeed", description: "ImmortalSeed (iS) is a Private Torrent Tracker for MOVIES / TV / GENERAL", @@ -61,6 +62,7 @@ public ImmortalSeed(IIndexerConfigurationService configService, Utils.Clients.We client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/InternetArchive.cs b/src/Jackett.Common/Indexers/InternetArchive.cs index 4cad1e96da907..23c29ecd88c14 100644 --- a/src/Jackett.Common/Indexers/InternetArchive.cs +++ b/src/Jackett.Common/Indexers/InternetArchive.cs @@ -32,7 +32,8 @@ public class InternetArchive : BaseWebIndexer private ConfigurationData ConfigData => configData; - public InternetArchive(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public InternetArchive(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "internetarchive", name: "Internet Archive", description: "Internet Archive is a non-profit digital library offering free universal access to books, movies & music, as well as 406 billion archived web pages", @@ -60,6 +61,7 @@ public InternetArchive(IIndexerConfigurationService configService, WebClient wc, client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/Libble.cs b/src/Jackett.Common/Indexers/Libble.cs index 4757ade91532f..d686aa80acc14 100644 --- a/src/Jackett.Common/Indexers/Libble.cs +++ b/src/Jackett.Common/Indexers/Libble.cs @@ -55,7 +55,8 @@ class VolumeFactorTag set => base.configData = value; } - public Libble(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public Libble(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "libble", name: "Libble", description: "Libble is a Private Torrent Tracker for MUSIC", @@ -71,6 +72,7 @@ public Libble(IIndexerConfigurationService configService, WebClient wc, Logger l client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/LostFilm.cs b/src/Jackett.Common/Indexers/LostFilm.cs index fd57868b3aa18..be428e56470d7 100644 --- a/src/Jackett.Common/Indexers/LostFilm.cs +++ b/src/Jackett.Common/Indexers/LostFilm.cs @@ -93,7 +93,8 @@ internal string GetEpisodeString() set => base.configData = value; } - public LostFilm(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public LostFilm(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "lostfilm", name: "LostFilm.tv", description: "Unique portal about foreign series", @@ -112,6 +113,7 @@ public LostFilm(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataCaptchaLogin()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/Magnetico.cs b/src/Jackett.Common/Indexers/Magnetico.cs index e7cb1438be2c5..af881386f2938 100644 --- a/src/Jackett.Common/Indexers/Magnetico.cs +++ b/src/Jackett.Common/Indexers/Magnetico.cs @@ -23,7 +23,8 @@ public class Magnetico : BaseWebIndexer private new ConfigurationDataBasicLogin configData => (ConfigurationDataBasicLogin)base.configData; - public Magnetico(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public Magnetico(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "magnetico", name: "Magnetico (Local DHT)", description: "Magnetico is a self-hosted BitTorrent DHT search engine", @@ -51,6 +52,7 @@ public Magnetico(IIndexerConfigurationService configService, WebClient wc, Logge client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin("Configure the URL, username and password from your local magneticow.
" + "Default credentials are: username=username, password=password.
" + "If you have many torrents, it is recommended to use PostgreSQL database to make queries faster. With SQLite, timeouts may occur.")) diff --git a/src/Jackett.Common/Indexers/MejorTorrent.cs b/src/Jackett.Common/Indexers/MejorTorrent.cs index 8d91c41a9ed64..e433de24f4a02 100644 --- a/src/Jackett.Common/Indexers/MejorTorrent.cs +++ b/src/Jackett.Common/Indexers/MejorTorrent.cs @@ -43,7 +43,8 @@ private static class MejorTorrentCatType "http://www.mejortorrentt.org/" }; - public MejorTorrent(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public MejorTorrent(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "mejortorrent", name: "MejorTorrent", description: "MejorTorrent - Hay veces que un torrent viene mejor! :)", @@ -67,6 +68,7 @@ public MejorTorrent(IIndexerConfigurationService configService, WebClient w, Log client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/Meta/BaseMetaIndexer.cs b/src/Jackett.Common/Indexers/Meta/BaseMetaIndexer.cs index 4eb8982ac23ee..87690dbacae29 100644 --- a/src/Jackett.Common/Indexers/Meta/BaseMetaIndexer.cs +++ b/src/Jackett.Common/Indexers/Meta/BaseMetaIndexer.cs @@ -17,8 +17,8 @@ public abstract class BaseMetaIndexer : BaseWebIndexer protected BaseMetaIndexer(string name, string id, string description, IFallbackStrategyProvider fallbackStrategyProvider, IResultFilterProvider resultFilterProvider,IIndexerConfigurationService configService, - WebClient client, Logger logger, ConfigurationData configData, IProtectionService p, - Func filter) + WebClient client, Logger logger, ConfigurationData configData, IProtectionService ps, + ICacheService cs, Func filter) : base(id: id, name: name, description: description, @@ -27,7 +27,8 @@ protected BaseMetaIndexer(string name, string id, string description, configService: configService, client: client, logger: logger, - p: p, + p: ps, + cacheService: cs, configData: configData) { filterFunc = filter; @@ -49,13 +50,14 @@ public override bool CanHandleQuery(TorznabQuery query) public override async Task ResultsForQuery(TorznabQuery query, bool isMetaIndexer) { if (!CanHandleQuery(query) || !CanHandleCategories(query, true)) - return new IndexerResult(this, new ReleaseInfo[0]); + return new IndexerResult(this, new ReleaseInfo[0], false); try { var results = await PerformQuery(query); // the results are already filtered and fixed by each indexer - return new IndexerResult(this, results); + // some results may come from cache, but we can't inform without refactor the code + return new IndexerResult(this, results, false); } catch (Exception ex) { diff --git a/src/Jackett.Common/Indexers/Meta/MetaIndexers.cs b/src/Jackett.Common/Indexers/Meta/MetaIndexers.cs index 76bb2093aa01c..bd8459b125e3c 100644 --- a/src/Jackett.Common/Indexers/Meta/MetaIndexers.cs +++ b/src/Jackett.Common/Indexers/Meta/MetaIndexers.cs @@ -10,14 +10,15 @@ public class AggregateIndexer : BaseMetaIndexer { public AggregateIndexer(IFallbackStrategyProvider fallbackStrategyProvider, IResultFilterProvider resultFilterProvider, IIndexerConfigurationService configService, - WebClient client, Logger logger, IProtectionService ps) + WebClient client, Logger logger, IProtectionService ps, ICacheService cs) : base(id: "all", name: "AggregateSearch", description: "This feed includes all configured trackers", configService: configService, client: client, logger: logger, - p: ps, + ps: ps, + cs: cs, configData: new ConfigurationData(), fallbackStrategyProvider: fallbackStrategyProvider, resultFilterProvider: resultFilterProvider, diff --git a/src/Jackett.Common/Indexers/Milkie.cs b/src/Jackett.Common/Indexers/Milkie.cs index aba7f5748112d..10bc6a3a8b1aa 100644 --- a/src/Jackett.Common/Indexers/Milkie.cs +++ b/src/Jackett.Common/Indexers/Milkie.cs @@ -23,7 +23,8 @@ public class Milkie : BaseWebIndexer private new ConfigurationDataAPIKey configData => (ConfigurationDataAPIKey)base.configData; - public Milkie(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public Milkie(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "milkie", name: "Milkie", description: "Milkie.cc (ME) is private torrent tracker for 0day / general", @@ -51,6 +52,7 @@ public Milkie(IIndexerConfigurationService configService, WebClient wc, Logger l client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataAPIKey()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/MoreThanTV.cs b/src/Jackett.Common/Indexers/MoreThanTV.cs index 5a1038413743f..b5efa5b07b116 100644 --- a/src/Jackett.Common/Indexers/MoreThanTV.cs +++ b/src/Jackett.Common/Indexers/MoreThanTV.cs @@ -33,7 +33,8 @@ public class MoreThanTV : BaseWebIndexer private ConfigurationDataBasicLogin ConfigData => (ConfigurationDataBasicLogin)configData; - public MoreThanTV(IIndexerConfigurationService configService, WebClient c, Logger l, IProtectionService ps) + public MoreThanTV(IIndexerConfigurationService configService, WebClient c, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "morethantv", name: "MoreThanTV", description: "Private torrent tracker for TV / MOVIES, and the internal tracker for the release group DRACULA.", @@ -53,6 +54,7 @@ public MoreThanTV(IIndexerConfigurationService configService, WebClient c, Logge client: c, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/MyAnonamouse.cs b/src/Jackett.Common/Indexers/MyAnonamouse.cs index 7d714538ab6e2..4b2ec1e573ff2 100644 --- a/src/Jackett.Common/Indexers/MyAnonamouse.cs +++ b/src/Jackett.Common/Indexers/MyAnonamouse.cs @@ -24,7 +24,8 @@ public class MyAnonamouse : BaseWebIndexer private new ConfigurationDataMyAnonamouse configData => (ConfigurationDataMyAnonamouse)base.configData; - public MyAnonamouse(IIndexerConfigurationService configService, WebClient c, Logger l, IProtectionService ps) + public MyAnonamouse(IIndexerConfigurationService configService, WebClient c, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "myanonamouse", name: "MyAnonamouse", description: "Friendliness, Warmth and Sharing", @@ -40,6 +41,7 @@ public MyAnonamouse(IIndexerConfigurationService configService, WebClient c, Log client: c, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataMyAnonamouse()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/NCore.cs b/src/Jackett.Common/Indexers/NCore.cs index 0577dd7f3537c..83fde10136c10 100644 --- a/src/Jackett.Common/Indexers/NCore.cs +++ b/src/Jackett.Common/Indexers/NCore.cs @@ -41,35 +41,37 @@ public class NCore : BaseWebIndexer "ebook" }; - public NCore(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) : - base(id: "ncore", - name: "nCore", - description: "A Hungarian private torrent site.", - link: "https://ncore.cc/", - caps: new TorznabCapabilities - { - TvSearchParams = new List - { - TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep, TvSearchParam.ImdbId - }, - MovieSearchParams = new List - { - MovieSearchParam.Q, MovieSearchParam.ImdbId - }, - MusicSearchParams = new List - { - MusicSearchParam.Q - }, - BookSearchParams = new List - { - BookSearchParam.Q - } - }, - configService: configService, - client: wc, - logger: l, - p: ps, - configData: new ConfigurationDataNCore()) + public NCore(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) + : base(id: "ncore", + name: "nCore", + description: "A Hungarian private torrent site.", + link: "https://ncore.cc/", + caps: new TorznabCapabilities + { + TvSearchParams = new List + { + TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep, TvSearchParam.ImdbId + }, + MovieSearchParams = new List + { + MovieSearchParam.Q, MovieSearchParam.ImdbId + }, + MusicSearchParams = new List + { + MusicSearchParam.Q + }, + BookSearchParams = new List + { + BookSearchParam.Q + } + }, + configService: configService, + client: wc, + logger: l, + p: ps, + cacheService: cs, + configData: new ConfigurationDataNCore()) { Encoding = Encoding.UTF8; Language = "hu-hu"; diff --git a/src/Jackett.Common/Indexers/Nebulance.cs b/src/Jackett.Common/Indexers/Nebulance.cs index c1ea30976bdc7..1aa13de014cb2 100644 --- a/src/Jackett.Common/Indexers/Nebulance.cs +++ b/src/Jackett.Common/Indexers/Nebulance.cs @@ -24,7 +24,8 @@ public class Nebulance : BaseWebIndexer private new ConfigurationDataBasicLoginWith2FA configData => (ConfigurationDataBasicLoginWith2FA)base.configData; - public Nebulance(IIndexerConfigurationService configService, Utils.Clients.WebClient c, Logger l, IProtectionService ps) + public Nebulance(IIndexerConfigurationService configService, Utils.Clients.WebClient c, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "nebulance", name: "Nebulance", description: "At Nebulance we will change the way you think about TV", @@ -40,6 +41,7 @@ public Nebulance(IIndexerConfigurationService configService, Utils.Clients.WebCl client: c, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLoginWith2FA(@"If 2FA is disabled, let the field empty. We recommend to disable 2FA because re-login will require manual actions.
For best results, change the 'Torrents per page' setting to 100 in your profile on the NBL webpage.")) diff --git a/src/Jackett.Common/Indexers/NewPCT.cs b/src/Jackett.Common/Indexers/NewPCT.cs index 72b3322ef6910..e14e50aebc2eb 100644 --- a/src/Jackett.Common/Indexers/NewPCT.cs +++ b/src/Jackett.Common/Indexers/NewPCT.cs @@ -116,7 +116,8 @@ private class DownloadMatcher "https://pctnew.org/" }; - public NewPCT(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public NewPCT(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "newpct", name: "NewPCT", description: "NewPCT - Descargar peliculas, series y estrenos torrent gratis", @@ -135,6 +136,7 @@ public NewPCT(IIndexerConfigurationService configService, WebClient wc, Logger l client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.GetEncoding("windows-1252"); diff --git a/src/Jackett.Common/Indexers/NewRealWorld.cs b/src/Jackett.Common/Indexers/NewRealWorld.cs index 3ab9496ac7465..722c851bfbe7f 100644 --- a/src/Jackett.Common/Indexers/NewRealWorld.cs +++ b/src/Jackett.Common/Indexers/NewRealWorld.cs @@ -29,7 +29,8 @@ public class NewRealWorld : BaseWebIndexer set => base.configData = value; } - public NewRealWorld(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public NewRealWorld(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "newrealworld", name: "New Real World", description: "A German general tracker.", @@ -57,6 +58,7 @@ public NewRealWorld(IIndexerConfigurationService configService, WebClient wc, Lo client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLoginWithRSSAndDisplay()) { Encoding = Encoding.GetEncoding("iso-8859-1"); diff --git a/src/Jackett.Common/Indexers/NorBits.cs b/src/Jackett.Common/Indexers/NorBits.cs index 472aeaed9b1a5..0be6d98342181 100644 --- a/src/Jackett.Common/Indexers/NorBits.cs +++ b/src/Jackett.Common/Indexers/NorBits.cs @@ -41,7 +41,8 @@ public class NorBits : BaseCachingWebIndexer private ConfigurationDataNorbits ConfigData => (ConfigurationDataNorbits)configData; - public NorBits(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public NorBits(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "norbits", name: "NorBits", description: "NorBits is a Norwegian Private site for MOVIES / TV / GENERAL", @@ -69,6 +70,7 @@ public NorBits(IIndexerConfigurationService configService, WebClient w, Logger l client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataNorbits()) { Encoding = Encoding.GetEncoding("iso-8859-1"); diff --git a/src/Jackett.Common/Indexers/NotWhatCD.cs b/src/Jackett.Common/Indexers/NotWhatCD.cs index 68283349980ed..6add2bcc53fc2 100644 --- a/src/Jackett.Common/Indexers/NotWhatCD.cs +++ b/src/Jackett.Common/Indexers/NotWhatCD.cs @@ -11,7 +11,8 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class NotWhatCD : GazelleTracker { - public NotWhatCD(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public NotWhatCD(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "notwhatcd", name: "notwhat.cd", description: "A music tracker", @@ -39,6 +40,7 @@ public NotWhatCD(IIndexerConfigurationService configService, WebClient wc, Logge client: wc, logger: l, p: ps, + cs: cs, supportsFreeleechTokens: true) { Language = "en-us"; diff --git a/src/Jackett.Common/Indexers/Orpheus.cs b/src/Jackett.Common/Indexers/Orpheus.cs index d738090a8b9ae..52affe4f078a4 100644 --- a/src/Jackett.Common/Indexers/Orpheus.cs +++ b/src/Jackett.Common/Indexers/Orpheus.cs @@ -11,7 +11,8 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class Orpheus : GazelleTracker { - public Orpheus(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public Orpheus(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "orpheus", name: "Orpheus", description: "A music tracker", @@ -39,6 +40,7 @@ public Orpheus(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cs: cs, supportsFreeleechTokens: true, has2Fa: true) { diff --git a/src/Jackett.Common/Indexers/Partis.cs b/src/Jackett.Common/Indexers/Partis.cs index fd2d2c95fdecd..36269a7b2adf4 100644 --- a/src/Jackett.Common/Indexers/Partis.cs +++ b/src/Jackett.Common/Indexers/Partis.cs @@ -28,7 +28,8 @@ public class Partis : BaseWebIndexer set => base.configData = value; } - public Partis(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public Partis(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "partis", name: "Partis", description: "Partis is a SLOVENIAN Private Torrent Tracker", @@ -56,6 +57,7 @@ public Partis(IIndexerConfigurationService configService, WebClient wc, Logger l client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/PassThePopcorn.cs b/src/Jackett.Common/Indexers/PassThePopcorn.cs index d15256e8bcc14..0513de1442f92 100644 --- a/src/Jackett.Common/Indexers/PassThePopcorn.cs +++ b/src/Jackett.Common/Indexers/PassThePopcorn.cs @@ -30,7 +30,8 @@ public class PassThePopcorn : BaseWebIndexer set => base.configData = value; } - public PassThePopcorn(IIndexerConfigurationService configService, Utils.Clients.WebClient c, Logger l, IProtectionService ps) + public PassThePopcorn(IIndexerConfigurationService configService, Utils.Clients.WebClient c, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "passthepopcorn", name: "PassThePopcorn", description: "PassThePopcorn is a Private site for MOVIES / TV", @@ -50,6 +51,7 @@ public PassThePopcorn(IIndexerConfigurationService configService, Utils.Clients. client: c, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataAPILoginWithUserAndPasskeyAndFilter(@"Enter filter options below to restrict search results. Separate options with a space if using more than one option.
Filter options available:
GoldenPopcorn
Scene
Checked
Free")) diff --git a/src/Jackett.Common/Indexers/PirateTheNet.cs b/src/Jackett.Common/Indexers/PirateTheNet.cs index f6d45bc35ec3f..515ed6c8da259 100644 --- a/src/Jackett.Common/Indexers/PirateTheNet.cs +++ b/src/Jackett.Common/Indexers/PirateTheNet.cs @@ -31,7 +31,8 @@ public class PirateTheNet : BaseWebIndexer set => base.configData = value; } - public PirateTheNet(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public PirateTheNet(IIndexerConfigurationService configService, WebClient w, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "piratethenet", name: "PirateTheNet", description: "A movie tracker", @@ -47,6 +48,7 @@ public PirateTheNet(IIndexerConfigurationService configService, WebClient w, Log client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLoginWithRSSAndDisplay("Only the results from the first search result page are shown, adjust your profile settings to show the maximum.")) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/PixelHD.cs b/src/Jackett.Common/Indexers/PixelHD.cs index fe19367f23f5f..04f105e9a8cf9 100644 --- a/src/Jackett.Common/Indexers/PixelHD.cs +++ b/src/Jackett.Common/Indexers/PixelHD.cs @@ -32,7 +32,8 @@ public class PixelHD : BaseWebIndexer private string input_username = null; private string input_password = null; - public PixelHD(IIndexerConfigurationService configService, WebClient webClient, Logger logger, IProtectionService protectionService) + public PixelHD(IIndexerConfigurationService configService, WebClient webClient, Logger logger, + IProtectionService ps, ICacheService cs) : base(id: "pixelhd", name: "PiXELHD", description: "PixelHD (PxHD) is a Private Torrent Tracker for HD .MP4 MOVIES / TV", @@ -46,7 +47,8 @@ public PixelHD(IIndexerConfigurationService configService, WebClient webClient, }, configService: configService, logger: logger, - p: protectionService, + p: ps, + cacheService: cs, client: webClient, configData: new ConfigurationDataCaptchaLogin() ) diff --git a/src/Jackett.Common/Indexers/PolishTracker.cs b/src/Jackett.Common/Indexers/PolishTracker.cs index 49d2430792e65..d03ca9e92d96d 100644 --- a/src/Jackett.Common/Indexers/PolishTracker.cs +++ b/src/Jackett.Common/Indexers/PolishTracker.cs @@ -27,7 +27,8 @@ public class PolishTracker : BaseWebIndexer private new ConfigurationDataCookie configData => (ConfigurationDataCookie)base.configData; - public PolishTracker(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public PolishTracker(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "polishtracker", name: "PolishTracker", description: "Polish Tracker is a POLISH Private site for 0DAY / MOVIES / GENERAL", @@ -55,6 +56,7 @@ public PolishTracker(IIndexerConfigurationService configService, WebClient wc, L client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataCookie()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/PornoLab.cs b/src/Jackett.Common/Indexers/PornoLab.cs index ea3f26c787784..e8131b15a3ce1 100644 --- a/src/Jackett.Common/Indexers/PornoLab.cs +++ b/src/Jackett.Common/Indexers/PornoLab.cs @@ -33,7 +33,8 @@ public class PornoLab : BaseWebIndexer set => base.configData = value; } - public PornoLab(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public PornoLab(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "pornolab", name: "PornoLab", description: "PornoLab is a Semi-Private Russian site for Adult content", @@ -43,6 +44,7 @@ public PornoLab(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataPornolab()) { Encoding = Encoding.GetEncoding("windows-1251"); diff --git a/src/Jackett.Common/Indexers/PreToMe.cs b/src/Jackett.Common/Indexers/PreToMe.cs index f6586f062e00d..e2f23927a7857 100644 --- a/src/Jackett.Common/Indexers/PreToMe.cs +++ b/src/Jackett.Common/Indexers/PreToMe.cs @@ -23,7 +23,8 @@ public class PreToMe : BaseWebIndexer private string SearchUrl => SiteLink + "browse.php"; private new ConfigurationDataPinNumber configData => (ConfigurationDataPinNumber)base.configData; - public PreToMe(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public PreToMe(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "pretome", name: "PreToMe", description: "BitTorrent site for High Quality, High Definition (HD) movies and TV Shows", @@ -51,6 +52,7 @@ public PreToMe(IIndexerConfigurationService configService, WebClient wc, Logger configService: configService, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataPinNumber("For best results, change the 'Torrents per page' setting to 100 in 'Profile => Torrent browse settings'.")) { Encoding = Encoding.GetEncoding("iso-8859-1"); diff --git a/src/Jackett.Common/Indexers/PrivateHD.cs b/src/Jackett.Common/Indexers/PrivateHD.cs index e3b8e642b3e39..298c525b92aef 100644 --- a/src/Jackett.Common/Indexers/PrivateHD.cs +++ b/src/Jackett.Common/Indexers/PrivateHD.cs @@ -11,7 +11,8 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class PrivateHD : AvistazTracker { - public PrivateHD(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public PrivateHD(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "privatehd", name: "PrivateHD", description: "BitTorrent site for High Quality, High Definition (HD) movies and TV Shows", @@ -34,7 +35,9 @@ public PrivateHD(IIndexerConfigurationService configService, WebClient wc, Logge configService: configService, client: wc, logger: l, - p: ps) + p: ps, + cs: cs + ) { AddCategoryMapping(1, TorznabCatType.Movies); AddCategoryMapping(1, TorznabCatType.MoviesUHD); diff --git a/src/Jackett.Common/Indexers/PsyTorrents.cs b/src/Jackett.Common/Indexers/PsyTorrents.cs index bb743ab658d81..f43e4c0a428a7 100644 --- a/src/Jackett.Common/Indexers/PsyTorrents.cs +++ b/src/Jackett.Common/Indexers/PsyTorrents.cs @@ -12,7 +12,8 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class PsyTorrents : GazelleTracker { - public PsyTorrents(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public PsyTorrents(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "psytorrents", name: "Psytorrents", description: "Psytorrents (PSY) is a Private Torrent Tracker for ELECTRONIC MUSIC", @@ -32,6 +33,7 @@ public PsyTorrents(IIndexerConfigurationService configService, WebClient wc, Log client: wc, logger: l, p: ps, + cs: cs, supportsFreeleechTokens: true) { Language = "en-us"; diff --git a/src/Jackett.Common/Indexers/RarBG.cs b/src/Jackett.Common/Indexers/RarBG.cs index d5084ef49ad37..332249d2191b4 100644 --- a/src/Jackett.Common/Indexers/RarBG.cs +++ b/src/Jackett.Common/Indexers/RarBG.cs @@ -30,7 +30,8 @@ public class RarBG : BaseWebIndexer private new ConfigurationData configData => base.configData; - public RarBG(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps) + public RarBG(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "rarbg", name: "RARBG", description: "RARBG is a Public torrent site for MOVIES / TV / GENERAL", @@ -58,6 +59,7 @@ public RarBG(IIndexerConfigurationService configService, Utils.Clients.WebClient client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.GetEncoding("windows-1252"); diff --git a/src/Jackett.Common/Indexers/Redacted.cs b/src/Jackett.Common/Indexers/Redacted.cs index 68eaae5faf26f..c3f5f7f36e4bc 100644 --- a/src/Jackett.Common/Indexers/Redacted.cs +++ b/src/Jackett.Common/Indexers/Redacted.cs @@ -15,7 +15,8 @@ public class Redacted : GazelleTracker { protected override string DownloadUrl => SiteLink + "torrents.php?action=download&usetoken=" + (useTokens ? "1" : "0") + "&id="; - public Redacted(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public Redacted(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "redacted", name: "Redacted", description: "A music tracker", @@ -43,6 +44,7 @@ public Redacted(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cs: cs, supportsFreeleechTokens: true, has2Fa: true, useApiKey: false diff --git a/src/Jackett.Common/Indexers/RevolutionTT.cs b/src/Jackett.Common/Indexers/RevolutionTT.cs index 1a4417b8d2618..ad62ed4feec42 100644 --- a/src/Jackett.Common/Indexers/RevolutionTT.cs +++ b/src/Jackett.Common/Indexers/RevolutionTT.cs @@ -25,7 +25,8 @@ public class RevolutionTT : BaseWebIndexer private new ConfigurationDataBasicLogin configData => (ConfigurationDataBasicLogin)base.configData; - public RevolutionTT(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps) + public RevolutionTT(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "revolutiontt", name: "RevolutionTT", description: "The Revolution has begun", @@ -53,6 +54,7 @@ public RevolutionTT(IIndexerConfigurationService configService, Utils.Clients.We client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin("For best results, change the 'Torrents per page' setting to 100 in your Profile.")) { Encoding = Encoding.GetEncoding("iso-8859-1"); diff --git a/src/Jackett.Common/Indexers/RuTracker.cs b/src/Jackett.Common/Indexers/RuTracker.cs index 2070b53140cad..9ed906fcd9aed 100644 --- a/src/Jackett.Common/Indexers/RuTracker.cs +++ b/src/Jackett.Common/Indexers/RuTracker.cs @@ -34,7 +34,8 @@ public class RuTracker : BaseWebIndexer "https://rutracker.net/" }; - public RuTracker(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public RuTracker(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "rutracker", name: "RuTracker", description: "RuTracker is a Semi-Private Russian torrent site with a thriving file-sharing community", @@ -62,6 +63,7 @@ public RuTracker(IIndexerConfigurationService configService, WebClient wc, Logge client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataRutracker()) { Encoding = Encoding.GetEncoding("windows-1251"); diff --git a/src/Jackett.Common/Indexers/SceneHD.cs b/src/Jackett.Common/Indexers/SceneHD.cs index 3359c5109f6ab..644dca44f6936 100644 --- a/src/Jackett.Common/Indexers/SceneHD.cs +++ b/src/Jackett.Common/Indexers/SceneHD.cs @@ -25,7 +25,8 @@ public class SceneHD : BaseWebIndexer private new ConfigurationDataPasskey configData => (ConfigurationDataPasskey)base.configData; - public SceneHD(IIndexerConfigurationService configService, WebClient c, Logger l, IProtectionService ps) + public SceneHD(IIndexerConfigurationService configService, WebClient c, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "scenehd", name: "SceneHD", description: "SceneHD is Private site for HD TV / MOVIES", @@ -49,6 +50,7 @@ public SceneHD(IIndexerConfigurationService configService, WebClient c, Logger l client: c, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataPasskey("You can find the Passkey if you generate a RSS " + "feed link. It's the last parameter in the URL.")) { diff --git a/src/Jackett.Common/Indexers/SceneTime.cs b/src/Jackett.Common/Indexers/SceneTime.cs index b9f5f118274d6..46a6aebad1e49 100644 --- a/src/Jackett.Common/Indexers/SceneTime.cs +++ b/src/Jackett.Common/Indexers/SceneTime.cs @@ -25,7 +25,8 @@ public class SceneTime : BaseWebIndexer private new ConfigurationDataSceneTime configData => (ConfigurationDataSceneTime)base.configData; - public SceneTime(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public SceneTime(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "scenetime", name: "SceneTime", description: "Always on time", @@ -53,6 +54,7 @@ public SceneTime(IIndexerConfigurationService configService, WebClient w, Logger client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataSceneTime()) { Encoding = Encoding.GetEncoding("iso-8859-1"); diff --git a/src/Jackett.Common/Indexers/SecretCinema.cs b/src/Jackett.Common/Indexers/SecretCinema.cs index bfa12840070dd..e8f7377eb0d77 100644 --- a/src/Jackett.Common/Indexers/SecretCinema.cs +++ b/src/Jackett.Common/Indexers/SecretCinema.cs @@ -14,7 +14,8 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class SecretCinema : GazelleTracker { - public SecretCinema(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public SecretCinema(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "secretcinema", name: "Secret Cinema", description: "A tracker for rare movies.", @@ -34,6 +35,7 @@ public SecretCinema(IIndexerConfigurationService configService, WebClient wc, Lo client: wc, logger: l, p: ps, + cs: cs, supportsFreeleechTokens: false) // ratioless tracker { Language = "en-us"; diff --git a/src/Jackett.Common/Indexers/Shazbat.cs b/src/Jackett.Common/Indexers/Shazbat.cs index c5f1ea3cf413c..8f16d3181e9ba 100644 --- a/src/Jackett.Common/Indexers/Shazbat.cs +++ b/src/Jackett.Common/Indexers/Shazbat.cs @@ -31,7 +31,8 @@ public class Shazbat : BaseWebIndexer set => base.configData = value; } - public Shazbat(IIndexerConfigurationService configService, WebClient c, Logger l, IProtectionService ps) + public Shazbat(IIndexerConfigurationService configService, WebClient c, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "shazbat", name: "Shazbat", description: "Modern indexer", @@ -47,6 +48,7 @@ public Shazbat(IIndexerConfigurationService configService, WebClient c, Logger l client: c, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLoginWithRSS()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/ShizaProject.cs b/src/Jackett.Common/Indexers/ShizaProject.cs index 6982b53b442ca..d394a4adc0f87 100644 --- a/src/Jackett.Common/Indexers/ShizaProject.cs +++ b/src/Jackett.Common/Indexers/ShizaProject.cs @@ -19,7 +19,8 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] internal class ShizaProject : BaseWebIndexer { - public ShizaProject(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public ShizaProject(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "ShizaProject", name: "ShizaProject", description: "ShizaProject Tracker is a semi-private russian tracker and release group for anime", @@ -35,6 +36,7 @@ public ShizaProject(IIndexerConfigurationService configService, WebClient wc, Lo client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLoginWithEmail()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/ShowRSS.cs b/src/Jackett.Common/Indexers/ShowRSS.cs index 1decb79e5e751..bc22be13e636b 100644 --- a/src/Jackett.Common/Indexers/ShowRSS.cs +++ b/src/Jackett.Common/Indexers/ShowRSS.cs @@ -26,7 +26,8 @@ public class ShowRSS : BaseWebIndexer private new ConfigurationData configData => base.configData; - public ShowRSS(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public ShowRSS(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "showrss", name: "ShowRSS", description: "showRSS is a service that allows you to keep track of your favorite TV shows", @@ -42,6 +43,7 @@ public ShowRSS(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/SolidTorrents.cs b/src/Jackett.Common/Indexers/SolidTorrents.cs index 8c85a03162cc7..4bc38b12d0356 100644 --- a/src/Jackett.Common/Indexers/SolidTorrents.cs +++ b/src/Jackett.Common/Indexers/SolidTorrents.cs @@ -35,7 +35,8 @@ private ConfigurationData ConfigData set => configData = value; } - public SolidTorrents(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public SolidTorrents(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "solidtorrents", name: "Solid Torrents", description: "Solid Torrents is a Public torrent meta-search engine", @@ -63,6 +64,7 @@ public SolidTorrents(IIndexerConfigurationService configService, WebClient wc, L client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/SpeedApp.cs b/src/Jackett.Common/Indexers/SpeedApp.cs index 00d42d38eb165..3b846c1aef95f 100644 --- a/src/Jackett.Common/Indexers/SpeedApp.cs +++ b/src/Jackett.Common/Indexers/SpeedApp.cs @@ -44,7 +44,8 @@ public class SpeedApp : BaseWebIndexer "https://www.myxz.org/" }; - public SpeedApp(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public SpeedApp(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base( id: "speedapp", name: "SpeedApp", @@ -73,6 +74,7 @@ public SpeedApp(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLoginWithEmail()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/SpeedCD.cs b/src/Jackett.Common/Indexers/SpeedCD.cs index 569cef905d5e8..84c26963c2ee7 100644 --- a/src/Jackett.Common/Indexers/SpeedCD.cs +++ b/src/Jackett.Common/Indexers/SpeedCD.cs @@ -32,7 +32,8 @@ public class SpeedCD : BaseWebIndexer private new ConfigurationDataBasicLogin configData => (ConfigurationDataBasicLogin)base.configData; - public SpeedCD(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public SpeedCD(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "speedcd", name: "Speed.cd", description: "Your home now!", @@ -60,6 +61,7 @@ public SpeedCD(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin( @"Speed.Cd have increased their security. If you are having problems please check the security tab in your Speed.Cd profile. Eg. Geo Locking, your seedbox may be in a different country to the one where you login via your diff --git a/src/Jackett.Common/Indexers/SuperBits.cs b/src/Jackett.Common/Indexers/SuperBits.cs index 73e26c0c9c268..8217c5eb6724f 100644 --- a/src/Jackett.Common/Indexers/SuperBits.cs +++ b/src/Jackett.Common/Indexers/SuperBits.cs @@ -29,7 +29,8 @@ public class SuperBits : BaseWebIndexer set => base.configData = value; } - public SuperBits(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public SuperBits(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "superbits", name: "Superbits", description: "Superbits is a SWEDISH Private Torrent Tracker for MOVIES / TV / GENERAL", @@ -57,6 +58,7 @@ public SuperBits(IIndexerConfigurationService configService, WebClient w, Logger client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataCookie()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/TVStore.cs b/src/Jackett.Common/Indexers/TVStore.cs index 0958524940a36..eec8df26b94fc 100644 --- a/src/Jackett.Common/Indexers/TVStore.cs +++ b/src/Jackett.Common/Indexers/TVStore.cs @@ -31,7 +31,8 @@ private readonly Dictionary private readonly Regex _seriesInfoSearchRegex = new Regex( @"S(?\d{1,3})(?:E(?\d{1,3}))?$", RegexOptions.IgnoreCase); - public TVStore(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) : + public TVStore(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "tvstore", name: "TV Store", description: "TV Store is a HUNGARIAN Private Torrent Tracker for TV", @@ -51,6 +52,7 @@ public TVStore(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataTVstore()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/TVVault.cs b/src/Jackett.Common/Indexers/TVVault.cs index 360bf5ea6466b..ff24ae0c97081 100644 --- a/src/Jackett.Common/Indexers/TVVault.cs +++ b/src/Jackett.Common/Indexers/TVVault.cs @@ -27,7 +27,8 @@ public class TVVault : BaseWebIndexer private new ConfigurationDataBasicLogin configData => (ConfigurationDataBasicLogin)base.configData; - public TVVault(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public TVVault(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "tvvault", name: "TV-Vault", description: "A TV tracker for old shows", @@ -47,6 +48,7 @@ public TVVault(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/ThePirateBay.cs b/src/Jackett.Common/Indexers/ThePirateBay.cs index a6133f290a701..396fc908f37ef 100644 --- a/src/Jackett.Common/Indexers/ThePirateBay.cs +++ b/src/Jackett.Common/Indexers/ThePirateBay.cs @@ -55,12 +55,8 @@ public class ThePirateBay : BaseWebIndexer private static readonly Uri _ApiBaseUri = new Uri("https://apibay.org/"); - public ThePirateBay( - IIndexerConfigurationService configService, - WebClient client, - Logger logger, - IProtectionService p - ) : base( + public ThePirateBay(IIndexerConfigurationService configService, WebClient client, Logger logger, + IProtectionService ps, ICacheService cs) : base( id: "thepiratebay", name: "The Pirate Bay", description: "Pirate Bay (TPB) is the galaxy’s most resilient Public BitTorrent site", @@ -87,7 +83,8 @@ IProtectionService p configService: configService, client: client, logger: logger, - p: p, + p: ps, + cacheService: cs, configData: new ConfigurationData() ) { diff --git a/src/Jackett.Common/Indexers/Toloka.cs b/src/Jackett.Common/Indexers/Toloka.cs index 4e8a2a86e0cff..4477a16c4f9dc 100644 --- a/src/Jackett.Common/Indexers/Toloka.cs +++ b/src/Jackett.Common/Indexers/Toloka.cs @@ -31,7 +31,8 @@ public class Toloka : BaseWebIndexer set => base.configData = value; } - public Toloka(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public Toloka(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "toloka", name: "Toloka.to", description: "Toloka is a Semi-Private Ukrainian torrent site with a thriving file-sharing community", @@ -59,6 +60,7 @@ public Toloka(IIndexerConfigurationService configService, WebClient wc, Logger l client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataToloka()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/TorrenTech.cs b/src/Jackett.Common/Indexers/TorrenTech.cs index 5cb42cb127c90..25f579bd31a79 100644 --- a/src/Jackett.Common/Indexers/TorrenTech.cs +++ b/src/Jackett.Common/Indexers/TorrenTech.cs @@ -31,7 +31,8 @@ public class TorrenTech : BaseWebIndexer set => base.configData = value; } - public TorrenTech(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps) + public TorrenTech(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "torrentech", name: "Torrentech", description: "Torrentech (TTH) is a Private Torrent Tracker for ELECTRONIC MUSIC", @@ -47,6 +48,7 @@ public TorrenTech(IIndexerConfigurationService configService, Utils.Clients.WebC client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLoginWithRSSAndDisplay()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/TorrentBytes.cs b/src/Jackett.Common/Indexers/TorrentBytes.cs index 7e67c01374036..e5430fb9ecf4f 100644 --- a/src/Jackett.Common/Indexers/TorrentBytes.cs +++ b/src/Jackett.Common/Indexers/TorrentBytes.cs @@ -24,7 +24,8 @@ public class TorrentBytes : BaseWebIndexer private new ConfigurationDataBasicLogin configData => (ConfigurationDataBasicLogin)base.configData; - public TorrentBytes(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public TorrentBytes(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "torrentbytes", name: "TorrentBytes", description: "A decade of TorrentBytes", @@ -48,6 +49,7 @@ public TorrentBytes(IIndexerConfigurationService configService, WebClient wc, Lo client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin("For best results, change the 'Torrents per page' setting to 100 in your profile on the TorrentBytes webpage.")) { Encoding = Encoding.GetEncoding("iso-8859-1"); diff --git a/src/Jackett.Common/Indexers/TorrentDay.cs b/src/Jackett.Common/Indexers/TorrentDay.cs index 28773932e891f..bf4ecd5628159 100644 --- a/src/Jackett.Common/Indexers/TorrentDay.cs +++ b/src/Jackett.Common/Indexers/TorrentDay.cs @@ -46,7 +46,8 @@ public class TorrentDay : BaseWebIndexer private new ConfigurationDataCookie configData => (ConfigurationDataCookie)base.configData; - public TorrentDay(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public TorrentDay(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "torrentday", name: "TorrentDay", description: "TorrentDay (TD) is a Private site for TV / MOVIES / GENERAL", @@ -74,6 +75,7 @@ public TorrentDay(IIndexerConfigurationService configService, WebClient wc, Logg client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataCookie( "Make sure you get the cookies from the same torrent day domain as configured above.")) { diff --git a/src/Jackett.Common/Indexers/TorrentHeaven.cs b/src/Jackett.Common/Indexers/TorrentHeaven.cs index e50c64bd76429..4c48cb3828ee4 100644 --- a/src/Jackett.Common/Indexers/TorrentHeaven.cs +++ b/src/Jackett.Common/Indexers/TorrentHeaven.cs @@ -20,35 +20,37 @@ namespace Jackett.Common.Indexers [ExcludeFromCodeCoverage] public class TorrentHeaven : BaseWebIndexer { - public TorrentHeaven(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) : - base(id: "torrentheaven", - name: "TorrentHeaven", - description: "A German general tracker.", - link: "https://newheaven.nl/", - caps: new TorznabCapabilities - { - TvSearchParams = new List - { - TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep - }, - MovieSearchParams = new List - { - MovieSearchParam.Q - }, - MusicSearchParams = new List - { - MusicSearchParam.Q - }, - BookSearchParams = new List - { - BookSearchParam.Q - } - }, - configService: configService, - client: wc, - logger: l, - p: ps, - configData: new ConfigurationDataCaptchaLogin()) + public TorrentHeaven(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) + : base(id: "torrentheaven", + name: "TorrentHeaven", + description: "A German general tracker.", + link: "https://newheaven.nl/", + caps: new TorznabCapabilities + { + TvSearchParams = new List + { + TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep + }, + MovieSearchParams = new List + { + MovieSearchParam.Q + }, + MusicSearchParams = new List + { + MusicSearchParam.Q + }, + BookSearchParams = new List + { + BookSearchParam.Q + } + }, + configService: configService, + client: wc, + logger: l, + p: ps, + cacheService: cs, + configData: new ConfigurationDataCaptchaLogin()) { Encoding = Encoding.GetEncoding("iso-8859-1"); Language = "de-de"; diff --git a/src/Jackett.Common/Indexers/TorrentLeech.cs b/src/Jackett.Common/Indexers/TorrentLeech.cs index 68f076065deba..736120511ac26 100644 --- a/src/Jackett.Common/Indexers/TorrentLeech.cs +++ b/src/Jackett.Common/Indexers/TorrentLeech.cs @@ -30,7 +30,8 @@ public class TorrentLeech : BaseWebIndexer "https://v4.torrentleech.org/" }; - public TorrentLeech(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps) + public TorrentLeech(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "torrentleech", name: "TorrentLeech", description: "This is what happens when you seed", @@ -58,6 +59,7 @@ public TorrentLeech(IIndexerConfigurationService configService, Utils.Clients.We client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin( "For best results, change the 'Default Number of Torrents per Page' setting to 100 in your Profile.")) { diff --git a/src/Jackett.Common/Indexers/TorrentMafya.cs b/src/Jackett.Common/Indexers/TorrentMafya.cs index ac0d3211a14a3..d7297ca05354d 100644 --- a/src/Jackett.Common/Indexers/TorrentMafya.cs +++ b/src/Jackett.Common/Indexers/TorrentMafya.cs @@ -30,7 +30,8 @@ private class TorrentMafyaArchiveResponse public IEnumerable aaData { get; set; } } - public TorrentMafya(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public TorrentMafya(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "torrentmafya", name: "TorrentMafya", description: "TorrentMafya is a Turkish general torrent tracker ", @@ -49,6 +50,7 @@ public TorrentMafya(IIndexerConfigurationService configService, WebClient wc, Lo client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/TorrentNetwork.cs b/src/Jackett.Common/Indexers/TorrentNetwork.cs index 457d13eb03a49..d18930a9d2347 100644 --- a/src/Jackett.Common/Indexers/TorrentNetwork.cs +++ b/src/Jackett.Common/Indexers/TorrentNetwork.cs @@ -33,7 +33,8 @@ public class TorrentNetwork : BaseWebIndexer set => base.configData = value; } - public TorrentNetwork(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public TorrentNetwork(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "torrentnetwork", name: "Torrent Network", description: "Torrent Network (TN) is a GERMAN Private site for TV / MOVIES / GENERAL", @@ -61,6 +62,7 @@ public TorrentNetwork(IIndexerConfigurationService configService, WebClient wc, client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLoginWithRSSAndDisplay()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/TorrentSeeds.cs b/src/Jackett.Common/Indexers/TorrentSeeds.cs index dec3915634ba7..e54854a1258d3 100644 --- a/src/Jackett.Common/Indexers/TorrentSeeds.cs +++ b/src/Jackett.Common/Indexers/TorrentSeeds.cs @@ -27,35 +27,37 @@ public class TorrentSeeds : BaseWebIndexer private new ConfigurationDataBasicLoginWithRSSAndDisplay configData => (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; - public TorrentSeeds(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps) : - base(id: "torrentseeds", - name: "TorrentSeeds", - description: "TorrentSeeds is a Private site for MOVIES / TV / GENERAL", - link: "https://torrentseeds.org/", - caps: new TorznabCapabilities - { - TvSearchParams = new List - { - TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep - }, - MovieSearchParams = new List - { + public TorrentSeeds(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, + IProtectionService ps, ICacheService cs) + : base(id: "torrentseeds", + name: "TorrentSeeds", + description: "TorrentSeeds is a Private site for MOVIES / TV / GENERAL", + link: "https://torrentseeds.org/", + caps: new TorznabCapabilities + { + TvSearchParams = new List + { + TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep + }, + MovieSearchParams = new List + { MovieSearchParam.Q - }, - MusicSearchParams = new List - { - MusicSearchParam.Q - }, - BookSearchParams = new List - { - BookSearchParam.Q - } - }, - configService: configService, - client: wc, - logger: l, - p: ps, - configData: new ConfigurationDataBasicLoginWithRSSAndDisplay("For best results, change the Torrents per page: setting to 100 on your account profile.")) + }, + MusicSearchParams = new List + { + MusicSearchParam.Q + }, + BookSearchParams = new List + { + BookSearchParam.Q + } + }, + configService: configService, + client: wc, + logger: l, + p: ps, + cacheService: cs, + configData: new ConfigurationDataBasicLoginWithRSSAndDisplay("For best results, change the Torrents per page: setting to 100 on your account profile.")) { Encoding = Encoding.UTF8; Language = "en-us"; diff --git a/src/Jackett.Common/Indexers/TorrentSyndikat.cs b/src/Jackett.Common/Indexers/TorrentSyndikat.cs index db71bca022fa2..f9fca1d594757 100644 --- a/src/Jackett.Common/Indexers/TorrentSyndikat.cs +++ b/src/Jackett.Common/Indexers/TorrentSyndikat.cs @@ -28,7 +28,8 @@ private ConfigurationDataAPIKey ConfigData set => configData = value; } - public TorrentSyndikat(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps) + public TorrentSyndikat(IIndexerConfigurationService configService, WebClient w, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "torrentsyndikat", name: "Torrent-Syndikat", description: "A German general tracker", @@ -56,6 +57,7 @@ public TorrentSyndikat(IIndexerConfigurationService configService, WebClient w, client: w, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataAPIKey()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/TorrentsCSV.cs b/src/Jackett.Common/Indexers/TorrentsCSV.cs index 61a5f2d59b32c..afcf7f9fc4f6a 100644 --- a/src/Jackett.Common/Indexers/TorrentsCSV.cs +++ b/src/Jackett.Common/Indexers/TorrentsCSV.cs @@ -22,7 +22,8 @@ public class TorrentsCSV : BaseWebIndexer private new ConfigurationData configData => base.configData; - public TorrentsCSV(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public TorrentsCSV(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "torrentscsv", name: "Torrents.csv", description: "Torrents.csv is a self-hostable, open source torrent search engine and database", @@ -42,6 +43,7 @@ public TorrentsCSV(IIndexerConfigurationService configService, WebClient wc, Log client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/XSpeeds.cs b/src/Jackett.Common/Indexers/XSpeeds.cs index 1e624b3f00972..3ec1b5a75bcad 100644 --- a/src/Jackett.Common/Indexers/XSpeeds.cs +++ b/src/Jackett.Common/Indexers/XSpeeds.cs @@ -29,7 +29,8 @@ public class XSpeeds : BaseWebIndexer private new ConfigurationDataBasicLoginWithRSSAndDisplay configData => (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; - public XSpeeds(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public XSpeeds(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "xspeeds", name: "XSpeeds", description: "XSpeeds (XS) is a Private Torrent Tracker for MOVIES / TV / GENERAL", @@ -53,6 +54,7 @@ public XSpeeds(IIndexerConfigurationService configService, WebClient wc, Logger client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLoginWithRSSAndDisplay()) { Encoding = Encoding.UTF8; diff --git a/src/Jackett.Common/Indexers/Xthor.cs b/src/Jackett.Common/Indexers/Xthor.cs index 75b50a70adb78..1ab3ad45f7fcb 100644 --- a/src/Jackett.Common/Indexers/Xthor.cs +++ b/src/Jackett.Common/Indexers/Xthor.cs @@ -40,7 +40,8 @@ public class Xthor : BaseCachingWebIndexer public Dictionary EmulatedBrowserHeaders { get; } = new Dictionary(); private ConfigurationDataXthor ConfigData => (ConfigurationDataXthor)configData; - public Xthor(IIndexerConfigurationService configService, Utils.Clients.WebClient w, Logger l, IProtectionService ps) + public Xthor(IIndexerConfigurationService configService, Utils.Clients.WebClient w, Logger l, + IProtectionService ps, ICacheService cs) : base(id: "xthor", name: "Xthor", description: "General French Private Tracker", @@ -68,6 +69,7 @@ public Xthor(IIndexerConfigurationService configService, Utils.Clients.WebClient client: w, logger: l, p: ps, + cacheService: cs, downloadBase: "https://xthor.tk/download.php?torrent=", configData: new ConfigurationDataXthor()) { diff --git a/src/Jackett.Common/Indexers/YTS.cs b/src/Jackett.Common/Indexers/YTS.cs index 3435d8419f942..212d46544e890 100644 --- a/src/Jackett.Common/Indexers/YTS.cs +++ b/src/Jackett.Common/Indexers/YTS.cs @@ -33,7 +33,8 @@ public class YTS : BaseWebIndexer set => base.configData = value; } - public YTS(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public YTS(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "yts", name: "YTS", description: "YTS is a Public torrent site specialising in HD movies of small size", @@ -46,6 +47,7 @@ public YTS(IIndexerConfigurationService configService, WebClient wc, Logger l, I client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationData()) { Encoding = Encoding.GetEncoding("windows-1252"); diff --git a/src/Jackett.Common/Indexers/ZonaQ.cs b/src/Jackett.Common/Indexers/ZonaQ.cs index fa465442a115e..50c203d2ea1db 100644 --- a/src/Jackett.Common/Indexers/ZonaQ.cs +++ b/src/Jackett.Common/Indexers/ZonaQ.cs @@ -32,7 +32,8 @@ public class ZonaQ : BaseWebIndexer private new ConfigurationDataBasicLogin configData => (ConfigurationDataBasicLogin)base.configData; - public ZonaQ(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + public ZonaQ(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) : base(id: "zonaq", name: "ZonaQ", description: "ZonaQ is a SPANISH Private Torrent Tracker for MOVIES / TV", @@ -52,6 +53,7 @@ public ZonaQ(IIndexerConfigurationService configService, WebClient wc, Logger l, client: wc, logger: l, p: ps, + cacheService: cs, configData: new ConfigurationDataBasicLogin("For best results, change the 'Torrents por página' option to 100 in 'Mi Panel' page.")) { diff --git a/src/Jackett.Common/Models/CachedResult.cs b/src/Jackett.Common/Models/CachedResult.cs deleted file mode 100644 index e105b4a35124a..0000000000000 --- a/src/Jackett.Common/Models/CachedResult.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Jackett.Common.Models -{ - public class CachedResult - { - public ReleaseInfo Result - { - set; get; - } - - public DateTime Created - { - set; get; - } - } -} diff --git a/src/Jackett.Common/Models/Config/ServerConfig.cs b/src/Jackett.Common/Models/Config/ServerConfig.cs index 6faccdbdcaa4f..11c3bebd7bbaa 100644 --- a/src/Jackett.Common/Models/Config/ServerConfig.cs +++ b/src/Jackett.Common/Models/Config/ServerConfig.cs @@ -13,8 +13,13 @@ public class ServerConfig : IObservable public ServerConfig(RuntimeSettings runtimeSettings) { observers = new List>(); + // Default values Port = 9117; - AllowExternal = System.Environment.OSVersion.Platform == PlatformID.Unix; + AllowExternal = Environment.OSVersion.Platform == PlatformID.Unix; + CacheEnabled = true; + // Sonarr 15min, Radarr 60min, LazyLibrarian 20min, Readarr 15min, Lidarr = 15min + CacheTtl = 2100; // 35 minutes is a reasonable value for all of them and to avoid race conditions + CacheMaxResultsPerIndexer = 1000; RuntimeSettings = runtimeSettings; } @@ -34,6 +39,9 @@ internal void OnDeserializedMethod(StreamingContext context) public bool UpdateDisabled { get; set; } public bool UpdatePrerelease { get; set; } public string BasePathOverride { get; set; } + public bool CacheEnabled { get; set; } + public long CacheTtl { get; set; } + public long CacheMaxResultsPerIndexer { get; set; } public string OmdbApiKey { get; set; } public string OmdbApiUrl { get; set; } diff --git a/src/Jackett.Common/Models/DTO/ServerConfig.cs b/src/Jackett.Common/Models/DTO/ServerConfig.cs index 2141d71278921..2e935a25908e0 100644 --- a/src/Jackett.Common/Models/DTO/ServerConfig.cs +++ b/src/Jackett.Common/Models/DTO/ServerConfig.cs @@ -28,6 +28,12 @@ public class ServerConfig [DataMember] public string basepathoverride { get; set; } [DataMember] + public bool cache_enabled { get; set; } + [DataMember] + public long cache_ttl { get; set; } + [DataMember] + public long cache_max_results_per_indexer { get; set; } + [DataMember] public string omdbkey { get; set; } [DataMember] public string omdburl { get; set; } @@ -61,6 +67,9 @@ public ServerConfig(IEnumerable notices, Models.Config.ServerConfig conf password = string.IsNullOrEmpty(config.AdminPassword) ? string.Empty : config.AdminPassword.Substring(0, 10); logging = config.RuntimeSettings.TracingEnabled; basepathoverride = config.BasePathOverride; + cache_enabled = config.CacheEnabled; + cache_ttl = config.CacheTtl; + cache_max_results_per_indexer = config.CacheMaxResultsPerIndexer; omdbkey = config.OmdbApiKey; omdburl = config.OmdbApiUrl; app_version = version; diff --git a/src/Jackett.Common/Models/TrackerCache.cs b/src/Jackett.Common/Models/TrackerCache.cs index 03fcc90b11e08..ab3ef47abdd51 100644 --- a/src/Jackett.Common/Models/TrackerCache.cs +++ b/src/Jackett.Common/Models/TrackerCache.cs @@ -1,3 +1,4 @@ + using System.Collections.Generic; namespace Jackett.Common.Models @@ -6,7 +7,6 @@ internal class TrackerCache { public string TrackerId { set; get; } public string TrackerName { set; get; } - - public List Results = new List(); + public Dictionary Queries = new Dictionary(); } } diff --git a/src/Jackett.Common/Models/TrackerCacheQuery.cs b/src/Jackett.Common/Models/TrackerCacheQuery.cs new file mode 100644 index 0000000000000..921c11c6f0d51 --- /dev/null +++ b/src/Jackett.Common/Models/TrackerCacheQuery.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +namespace Jackett.Common.Models +{ + internal class TrackerCacheQuery + { + public DateTime Created + { + set; get; + } + + public List Results = new List(); + } +} diff --git a/src/Jackett.Common/Services/CacheService.cs b/src/Jackett.Common/Services/CacheService.cs index eb753a9a8ff70..c05f46dad6187 100644 --- a/src/Jackett.Common/Services/CacheService.cs +++ b/src/Jackett.Common/Services/CacheService.cs @@ -1,104 +1,235 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; +using System.Text; using AutoMapper; using Jackett.Common.Indexers; using Jackett.Common.Models; +using Jackett.Common.Models.Config; using Jackett.Common.Services.Interfaces; +using Jint.Parser; +using NLog; namespace Jackett.Common.Services { - + /// + /// This service is in charge of Jackett cache. In simple words, when you make a request in Jackett, the results are + /// saved in memory (cache). The next request will return results form the cache improving response time and making + /// fewer requests to the sites. + /// * We assume all indexers/sites are stateless, the same request return the same response. If you change the + /// search term, categories or something in the query Jackett has to make a live request to the indexer. + /// * There are some situations when we don't want to use the cache: + /// * When we are testing the indexers => if query.IsTest results are not cached + /// * When the user updates the configuration of one indexer => We call CleanIndexerCache to remove cached results + /// before testing the configuration + /// * When there is some error/exception in the indexer => The results are not cached so we can retry in the + /// next request + /// * We want to limit the memory usage, so we try to remove elements from cache ASAP: + /// * Each indexer can have a maximum number of results in memory. If the limit is exceeded we remove old results + /// * Cached results expire after some time + /// * Users can configure the cache or even disable it + /// public class CacheService : ICacheService { - private readonly List cache = new List(); - private readonly int MAX_RESULTS_PER_TRACKER = 1000; - private readonly TimeSpan AGE_LIMIT = new TimeSpan(0, 1, 0, 0); + private readonly Logger _logger; + private readonly ServerConfig _serverConfig; + private readonly SHA256Managed _sha256 = new SHA256Managed(); + private readonly Dictionary _cache = new Dictionary(); + + public CacheService(Logger logger, ServerConfig serverConfig) + { + _logger = logger; + _serverConfig = serverConfig; + } - public void CacheRssResults(IIndexer indexer, IEnumerable releases) + public void CacheResults(IIndexer indexer, TorznabQuery query, List releases) { - lock (cache) + // do not cache test queries! + if (query.IsTest) + return; + + lock (_cache) { - var trackerCache = cache.FirstOrDefault(c => c.TrackerId == indexer.Id); - if (trackerCache == null) + if (!IsCacheEnabled()) + return; + + if (!_cache.ContainsKey(indexer.Id)) { - trackerCache = new TrackerCache + _cache.Add(indexer.Id, new TrackerCache { TrackerId = indexer.Id, TrackerName = indexer.DisplayName - }; - cache.Add(trackerCache); + }); } - foreach (var release in releases.OrderByDescending(i => i.PublishDate)) + var trackerCacheQuery = new TrackerCacheQuery { - var existingItem = trackerCache.Results.FirstOrDefault(i => i.Result.Guid == release.Guid); - if (existingItem == null) - { - existingItem = new CachedResult - { - Created = DateTime.Now - }; - trackerCache.Results.Add(existingItem); - } + Created = DateTime.Now, + Results = releases + }; - existingItem.Result = release; - } + var trackerCache = _cache[indexer.Id]; + var queryHash = GetQueryHash(query); + if (trackerCache.Queries.ContainsKey(queryHash)) + trackerCache.Queries[queryHash] = trackerCacheQuery; // should not happen, just in case + else + trackerCache.Queries.Add(queryHash, trackerCacheQuery); - // Prune cache - foreach (var tracker in cache) - { - tracker.Results = tracker.Results.Where(x => x.Created > DateTime.Now.Subtract(AGE_LIMIT)).OrderByDescending(i => i.Created).Take(MAX_RESULTS_PER_TRACKER).ToList(); - } + _logger.Debug($"CACHE CacheResults / Indexer: {trackerCache.TrackerId} / Added: {releases.Count} releases"); + + PruneCacheByMaxResultsPerIndexer(); // remove old results if we exceed the maximum limit } } - public int GetNewItemCount(IIndexer indexer, IEnumerable releases) + public List Search(IIndexer indexer, TorznabQuery query) { - lock (cache) + lock (_cache) { - var newItemCount = 0; - var trackerCache = cache.FirstOrDefault(c => c.TrackerId == indexer.Id); - if (trackerCache != null) + if (!IsCacheEnabled()) + return null; + + PruneCacheByTtl(); // remove expired results + + if (!_cache.ContainsKey(indexer.Id)) + return null; + + var trackerCache = _cache[indexer.Id]; + var queryHash = GetQueryHash(query); + if (!trackerCache.Queries.ContainsKey(queryHash)) + return null; + + var releases = trackerCache.Queries[queryHash].Results; + _logger.Debug($"CACHE Search / Indexer: {trackerCache.TrackerId} / Found: {releases.Count} releases"); + + return releases; + } + } + + public List GetCachedResults() + { + lock (_cache) + { + if (!IsCacheEnabled()) + return new List(); + + PruneCacheByTtl(); // remove expired results + + var results = new List(); + foreach (var trackerCache in _cache.Values) { - foreach (var release in releases) + var trackerResults = new List(); + foreach (var query in trackerCache.Queries.Values.OrderByDescending(q => q.Created)) // newest first { - if (trackerCache.Results.Count(i => i.Result.Guid == release.Guid) == 0) + foreach (var release in query.Results) { - newItemCount++; + var item = Mapper.Map(release); + item.FirstSeen = query.Created; + item.Tracker = trackerCache.TrackerName; + item.TrackerId = trackerCache.TrackerId; + item.Peers -= item.Seeders; // Use peers as leechers + trackerResults.Add(item); } } + trackerResults = trackerResults.GroupBy(r => r.Guid).Select(y => y.First()).Take(300).ToList(); + results.AddRange(trackerResults); } - else - { - newItemCount++; - } + var result = results.OrderByDescending(i => i.PublishDate).Take(3000).ToList(); + + _logger.Debug($"CACHE GetCachedResults / Results: {result.Count} (cache may contain more results)"); + PrintCacheStatus(); - return newItemCount; + return result; } } - public List GetCachedResults() + public void CleanIndexerCache(IIndexer indexer) { - lock (cache) + lock (_cache) { - var results = new List(); + if (!IsCacheEnabled()) + return; + + if (_cache.ContainsKey(indexer.Id)) + _cache.Remove(indexer.Id); + + _logger.Debug($"CACHE CleanIndexerCache / Indexer: {indexer.Id}"); + + PruneCacheByTtl(); // remove expired results + } + } + + private bool IsCacheEnabled() + { + if (!_serverConfig.CacheEnabled) + { + // remove cached results just in case user disabled cache recently + _cache.Clear(); + _logger.Debug("CACHE IsCacheEnabled => false"); + } + return _serverConfig.CacheEnabled; + } + + private void PruneCacheByTtl() + { + var prunedCounter = 0; + var expirationDate = DateTime.Now.AddSeconds(-_serverConfig.CacheTtl); + foreach (var trackerCache in _cache.Values) + { + // Remove expired queries + var queriesToRemove = trackerCache.Queries + .Where(q => q.Value.Created < expirationDate) + .Select(q => q.Key).ToList(); + foreach (var queryHash in queriesToRemove) + trackerCache.Queries.Remove(queryHash); + prunedCounter += queriesToRemove.Count; + } + if (_logger.IsDebugEnabled) + { + _logger.Debug($"CACHE PruneCacheByTtl / Pruned queries: {prunedCounter}"); + PrintCacheStatus(); + } + } - foreach (var tracker in cache) + private void PruneCacheByMaxResultsPerIndexer() + { + var prunedCounter = 0; + foreach (var trackerCache in _cache.Values) + { + // Remove queries exceeding max results per indexer + var resultsPerQuery = trackerCache.Queries + .OrderByDescending(q => q.Value.Created) // newest first + .Select(q => new Tuple(q.Key, q.Value.Results.Count)).ToList(); + while (true) { - foreach (var release in tracker.Results.OrderByDescending(i => i.Result.PublishDate).Take(300)) - { - var item = Mapper.Map(release.Result); - item.FirstSeen = release.Created; - item.Tracker = tracker.TrackerName; - item.TrackerId = tracker.TrackerId; - item.Peers = item.Peers - item.Seeders; // Use peers as leechers - results.Add(item); - } + var total = resultsPerQuery.Select(q => q.Item2).Sum(); + if (total <= _serverConfig.CacheMaxResultsPerIndexer) + break; + trackerCache.Queries.Remove(resultsPerQuery.Pop().Item1); // remove the older + prunedCounter++; } - - return results.Take(3000).OrderByDescending(i => i.PublishDate).ToList(); } + if (_logger.IsDebugEnabled) + { + _logger.Debug($"CACHE PruneCacheByMaxResultsPerIndexer / Pruned queries: {prunedCounter}"); + PrintCacheStatus(); + } + } + + private string GetQueryHash(TorznabQuery query) + { + var json = Newtonsoft.Json.JsonConvert.SerializeObject(query); + _logger.Debug($"CACHE Request query: {json}"); + // Changes in the query to improve cache hits + // Both request must return the same results, if not we are breaking Jackett search + json = json.Replace("\"SearchTerm\":null", "\"SearchTerm\":\"\""); + // Compute the hash + return BitConverter.ToString(_sha256.ComputeHash(Encoding.ASCII.GetBytes(json))); + } + + private void PrintCacheStatus() + { + _logger.Debug($"CACHE Status / Total cached results: {_cache.Values.SelectMany(tc => tc.Queries).Select(q => q.Value.Results.Count).Sum()}"); } } } diff --git a/src/Jackett.Common/Services/IndexerManagerService.cs b/src/Jackett.Common/Services/IndexerManagerService.cs index 57aa0d34c24c1..fec9150f6ce83 100644 --- a/src/Jackett.Common/Services/IndexerManagerService.cs +++ b/src/Jackett.Common/Services/IndexerManagerService.cs @@ -114,14 +114,14 @@ private void InitIndexers() var indexerTypes = allNonMetaInstantiatableIndexerTypes.Where(p => p.Name != "CardigannIndexer"); var nativeIndexers = indexerTypes.Select(type => { - var constructorArgumentTypes = new [] { typeof(IIndexerConfigurationService), typeof(WebClient), typeof(Logger), typeof(IProtectionService) }; + var constructorArgumentTypes = new [] { typeof(IIndexerConfigurationService), typeof(WebClient), typeof(Logger), typeof(IProtectionService), typeof(ICacheService) }; var constructor = type.GetConstructor(constructorArgumentTypes); if (constructor != null) { // create own webClient instance for each indexer (separate cookies stores, etc.) var indexerWebClientInstance = (WebClient)Activator.CreateInstance(webClient.GetType(), processService, logger, globalConfigService, serverConfig); - var arguments = new object[] { configService, indexerWebClientInstance, logger, protectionService }; + var arguments = new object[] { configService, indexerWebClientInstance, logger, protectionService, cacheService }; var indexer = (IIndexer)constructor.Invoke(arguments); return indexer; } @@ -176,7 +176,7 @@ private void InitCardigannIndexers(IEnumerable path) // create own webClient instance for each indexer (seperate cookies stores, etc.) var indexerWebClientInstance = (WebClient)Activator.CreateInstance(webClient.GetType(), processService, logger, globalConfigService, serverConfig); - IIndexer indexer = new CardigannIndexer(configService, indexerWebClientInstance, logger, protectionService, definition); + IIndexer indexer = new CardigannIndexer(configService, indexerWebClientInstance, logger, protectionService, cacheService, definition); configService.Load(indexer); return indexer; } @@ -229,7 +229,7 @@ public void InitAggregateIndexer() } logger.Info("Adding aggregate indexer ('all' indexer) ..."); - aggregateIndexer = new AggregateIndexer(fallbackStrategyProvider, resultFilterProvider, configService, webClient, logger, protectionService) + aggregateIndexer = new AggregateIndexer(fallbackStrategyProvider, resultFilterProvider, configService, webClient, logger, protectionService, cacheService) { Indexers = indexers.Values }; @@ -291,17 +291,18 @@ public IWebIndexer GetWebIndexer(string name) public async Task TestIndexer(string name) { var indexer = GetIndexer(name); - var browseQuery = new TorznabQuery + var query = new TorznabQuery { QueryType = "search", SearchTerm = "", IsTest = true }; - var result = await indexer.ResultsForQuery(browseQuery); - logger.Info($"Found {result.Releases.Count()} releases from {indexer.DisplayName}"); + var result = await indexer.ResultsForQuery(query); + + logger.Info($"Test search in {indexer.DisplayName} => Found {result.Releases.Count()} releases"); + if (!result.Releases.Any()) throw new Exception("Found no results while trying to browse this tracker"); - cacheService.CacheRssResults(indexer, result.Releases); } public void DeleteIndexer(string name) diff --git a/src/Jackett.Common/Services/Interfaces/ICacheService.cs b/src/Jackett.Common/Services/Interfaces/ICacheService.cs index 5e10485882e96..cd76b12a8f555 100644 --- a/src/Jackett.Common/Services/Interfaces/ICacheService.cs +++ b/src/Jackett.Common/Services/Interfaces/ICacheService.cs @@ -6,8 +6,9 @@ namespace Jackett.Common.Services.Interfaces { public interface ICacheService { - void CacheRssResults(IIndexer indexer, IEnumerable releases); + List Search(IIndexer indexer, TorznabQuery query); + void CacheResults(IIndexer indexer, TorznabQuery query, List releases); List GetCachedResults(); - int GetNewItemCount(IIndexer indexer, IEnumerable releases); + void CleanIndexerCache(IIndexer indexer); } } diff --git a/src/Jackett.Server/Controllers/IndexerApiController.cs b/src/Jackett.Server/Controllers/IndexerApiController.cs index b55ea3d17df46..2aee70154f468 100644 --- a/src/Jackett.Server/Controllers/IndexerApiController.cs +++ b/src/Jackett.Server/Controllers/IndexerApiController.cs @@ -85,6 +85,9 @@ public async Task Config() [TypeFilter(typeof(RequiresIndexer))] public async Task UpdateConfig([FromBody]Common.Models.DTO.ConfigItem[] config) { + // invalidate cache for this indexer + cacheService.CleanIndexerCache(CurrentIndexer); + try { // HACK diff --git a/src/Jackett.Server/Controllers/ResultsController.cs b/src/Jackett.Server/Controllers/ResultsController.cs index 3073094ecad24..271b27cc93d0d 100644 --- a/src/Jackett.Server/Controllers/ResultsController.cs +++ b/src/Jackett.Server/Controllers/ResultsController.cs @@ -271,7 +271,6 @@ public async Task Results([FromQuery] ApiSearch requestt) { var searchResults = t.Result.Releases; var indexer = t.Result.Indexer; - cacheService.CacheRssResults(indexer, searchResults); return searchResults.Select(result => { @@ -279,14 +278,20 @@ public async Task Results([FromQuery] ApiSearch requestt) item.Tracker = indexer.DisplayName; item.TrackerId = indexer.Id; item.Peers = item.Peers - item.Seeders; // Use peers as leechers - return item; }); }).OrderByDescending(d => d.PublishDate).ToList(); ConfigureCacheResults(manualResult.Results); - logger.Info(string.Format("Manual search for \"{0}\" on {1} with {2} results.", CurrentQuery.SanitizedSearchTerm, string.Join(", ", manualResult.Indexers.Select(i => i.ID)), manualResult.Results.Count())); + // Log info + var indexersName = string.Join(", ", manualResult.Indexers.Select(i => i.ID)); + var cacheStr = tasks.Where(t => t.Status == TaskStatus.RanToCompletion).Any(t => t.Result.IsFromCache) ? " (from cache)" : ""; + if (string.IsNullOrWhiteSpace(CurrentQuery.SanitizedSearchTerm)) + logger.Info($"Manual search in {indexersName} => Found {manualResult.Results.Count()} releases{cacheStr}"); + else + logger.Info($"Manual search in {indexersName} for {CurrentQuery.GetQueryString()} => Found {manualResult.Results.Count()} releases{cacheStr}"); + return Json(manualResult); } @@ -386,33 +391,12 @@ from i in indexers { var result = await CurrentIndexer.ResultsForQuery(CurrentQuery); - // Some trackers do not support multiple category filtering so filter the releases that match manually. - int? newItemCount = null; - - // Cache non query results - if (string.IsNullOrEmpty(CurrentQuery.SanitizedSearchTerm)) - { - newItemCount = cacheService.GetNewItemCount(CurrentIndexer, result.Releases); - cacheService.CacheRssResults(CurrentIndexer, result.Releases); - } - // Log info - var logBuilder = new StringBuilder(); - if (newItemCount != null) - { - logBuilder.AppendFormat("Found {0} ({1} new) releases from {2}", result.Releases.Count(), newItemCount, CurrentIndexer.DisplayName); - } + var cacheStr = result.IsFromCache ? " (from cache)" : ""; + if (string.IsNullOrWhiteSpace(CurrentQuery.SanitizedSearchTerm)) + logger.Info($"Torznab search in {CurrentIndexer.DisplayName} => Found {result.Releases.Count()} releases{cacheStr}"); else - { - logBuilder.AppendFormat("Found {0} releases from {1}", result.Releases.Count(), CurrentIndexer.DisplayName); - } - - if (!string.IsNullOrWhiteSpace(CurrentQuery.SanitizedSearchTerm)) - { - logBuilder.AppendFormat(" for: {0}", CurrentQuery.GetQueryString()); - } - - logger.Info(logBuilder.ToString()); + logger.Info($"Torznab search in {CurrentIndexer.DisplayName} for {CurrentQuery.GetQueryString()} => Found {result.Releases.Count()} releases{cacheStr}"); var serverUrl = serverService.GetServerUrl(Request); var resultPage = new ResultPage(new ChannelInfo @@ -501,15 +485,12 @@ public async Task Potato([FromQuery]TorrentPotatoRequest { var result = await CurrentIndexer.ResultsForQuery(CurrentQuery); - // Cache non query results - if (string.IsNullOrEmpty(CurrentQuery.SanitizedSearchTerm)) - cacheService.CacheRssResults(CurrentIndexer, result.Releases); - // Log info + var cacheStr = result.IsFromCache ? " (from cache)" : ""; if (string.IsNullOrWhiteSpace(CurrentQuery.SanitizedSearchTerm)) - logger.Info($"Found {result.Releases.Count()} torrentpotato releases from {CurrentIndexer.DisplayName}"); + logger.Info($"Potato search in {CurrentIndexer.DisplayName} => Found {result.Releases.Count()} releases{cacheStr}"); else - logger.Info($"Found {result.Releases.Count()} torrentpotato releases from {CurrentIndexer.DisplayName} for: {CurrentQuery.GetQueryString()}"); + logger.Info($"Potato search in {CurrentIndexer.DisplayName} for {CurrentQuery.GetQueryString()} => Found {result.Releases.Count()} releases{cacheStr}"); var serverUrl = serverService.GetServerUrl(Request); var potatoReleases = result.Releases.Where(r => r.Link != null || r.MagnetUri != null).Select(r => diff --git a/src/Jackett.Server/Controllers/ServerConfigurationController.cs b/src/Jackett.Server/Controllers/ServerConfigurationController.cs index b7f27d2a82112..30edc2f794b90 100644 --- a/src/Jackett.Server/Controllers/ServerConfigurationController.cs +++ b/src/Jackett.Server/Controllers/ServerConfigurationController.cs @@ -88,6 +88,9 @@ public IActionResult UpdateConfig([FromBody]Common.Models.DTO.ServerConfig confi throw new Exception("The Base Path Override must start with a /"); } + var cacheEnabled = config.cache_enabled; + var cacheTtl = config.cache_ttl; + var cacheMaxResultsPerIndexer = config.cache_max_results_per_indexer; var omdbApiKey = config.omdbkey; var omdbApiUrl = config.omdburl; @@ -99,6 +102,10 @@ public IActionResult UpdateConfig([FromBody]Common.Models.DTO.ServerConfig confi serverConfig.UpdateDisabled = updateDisabled; serverConfig.UpdatePrerelease = preRelease; serverConfig.BasePathOverride = basePathOverride; + serverConfig.CacheEnabled = cacheEnabled; + serverConfig.CacheTtl = cacheTtl; + serverConfig.CacheMaxResultsPerIndexer = cacheMaxResultsPerIndexer; + serverConfig.RuntimeSettings.BasePath = serverService.BasePath(); configService.SaveConfig(serverConfig); diff --git a/src/Jackett.Server/Startup.cs b/src/Jackett.Server/Startup.cs index 297fb7e20550f..29f093a98925b 100644 --- a/src/Jackett.Server/Startup.cs +++ b/src/Jackett.Server/Startup.cs @@ -6,6 +6,7 @@ using Autofac.Extensions.DependencyInjection; using Jackett.Common.Models.Config; using Jackett.Common.Plumbing; +using Jackett.Common.Services; using Jackett.Common.Services.Interfaces; using Jackett.Server.Middleware; using Jackett.Server.Services; @@ -87,6 +88,7 @@ public IServiceProvider ConfigureServices(IServiceCollection services) builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); diff --git a/src/Jackett.Test/Common/Indexers/CardigannIndexerTests.cs b/src/Jackett.Test/Common/Indexers/CardigannIndexerTests.cs index 2a2e208686316..4b161e8d20682 100644 --- a/src/Jackett.Test/Common/Indexers/CardigannIndexerTests.cs +++ b/src/Jackett.Test/Common/Indexers/CardigannIndexerTests.cs @@ -25,7 +25,7 @@ public void TestCardigannTorznabCategories() }, Search = new searchBlock() }; - var indexer = new CardigannIndexer(null, null, null, null, definition); + var indexer = new CardigannIndexer(null, null, null, null, null, definition); Assert.True(indexer.TorznabCaps.SearchAvailable); Assert.IsEmpty(indexer.TorznabCaps.TvSearchParams); @@ -90,7 +90,7 @@ public void TestCardigannTorznabCategories() }, Search = new searchBlock() }; - indexer = new CardigannIndexer(null, null, null, null, definition); + indexer = new CardigannIndexer(null, null, null, null, null, definition); // test categories var expected = new List @@ -125,7 +125,7 @@ public void TestCardigannTorznabCategories() }, Search = new searchBlock() }; - indexer = new CardigannIndexer(null, null, null, null, definition); + indexer = new CardigannIndexer(null, null, null, null, null, definition); Assert.True(indexer.TorznabCaps.SearchAvailable); Assert.AreEqual( diff --git a/src/Jackett.Test/Common/Models/ResultPageTests.cs b/src/Jackett.Test/Common/Models/ResultPageTests.cs index 729bbf6a0d3e3..4b0014d6a8777 100644 --- a/src/Jackett.Test/Common/Models/ResultPageTests.cs +++ b/src/Jackett.Test/Common/Models/ResultPageTests.cs @@ -20,7 +20,8 @@ public TestIndexer() configService: null, logger: null, configData: null, - p: null) + p: null, + cs: null) { } diff --git a/src/Jackett.Test/TestHelpers/TestWebIndexer.cs b/src/Jackett.Test/TestHelpers/TestWebIndexer.cs index 1a24f3197e178..6463d4c421a4d 100644 --- a/src/Jackett.Test/TestHelpers/TestWebIndexer.cs +++ b/src/Jackett.Test/TestHelpers/TestWebIndexer.cs @@ -21,7 +21,8 @@ public TestWebIndexer(): configService: null, logger: null, configData: new ConfigurationData(), - p: null) + p: null, + cacheService: null) { Encoding = Encoding.UTF8; Language = "en-us";