Feature/remove autofac from indexer manager (#1549)

* Line endings...

* Remove Autofac and all its shenanigans from IndexerManager

I'm starting my warpath against Autofac. For the next couple PRs I want
to focus on refactoring things rather than creating new things. This
includes introducing LINQ extensions wherever possible as well as
removing Autofac/Automapper dependencies in classes (or any other
dependency, there's a great chance that most of the classes that use
Jackett.Services wouldn't need so many of them). All this is order to
boost performance and eventually reach testability. Can't stop, won't
stop.

* Remove unnecessary extension

* Modify test project

* As per @kaso17, iterating through iterator types rather than allocating them manually

* Cleaning up a little

* Adjusting interface in tests
This commit is contained in:
chibidev 2017-07-14 07:39:52 +02:00 committed by kaso17
parent f96dca5653
commit 7c2b801ee9
35 changed files with 231 additions and 225 deletions

View File

@ -33,7 +33,7 @@ namespace JackettTest
throw new NotImplementedException(); throw new NotImplementedException();
} }
public void InitIndexers() public void InitIndexers(IEnumerable<string> path)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -48,16 +48,6 @@ namespace JackettTest
throw new NotImplementedException(); throw new NotImplementedException();
} }
public void InitCardigannIndexers(string path)
{
throw new NotImplementedException();
}
public void SortIndexers()
{
throw new NotImplementedException();
}
public void InitAggregateIndexer() public void InitAggregateIndexer()
{ {
throw new NotImplementedException(); throw new NotImplementedException();

View File

@ -33,7 +33,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public BB(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public BB(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "bB", : base(name: "bB",
description: "bB", description: "bB",
link: "https://baconbits.org/", link: "https://baconbits.org/",

View File

@ -26,7 +26,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public BeyondHD(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public BeyondHD(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "BeyondHD", : base(name: "BeyondHD",
description: "Without BeyondHD, your HDTV is just a TV", description: "Without BeyondHD, your HDTV is just a TV",
link: "https://beyond-hd.me/", link: "https://beyond-hd.me/",

View File

@ -32,7 +32,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public BitHdtv(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public BitHdtv(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "BIT-HDTV", : base(name: "BIT-HDTV",
description: "Home of high definition invites", description: "Home of high definition invites",
link: "https://www.bit-hdtv.com/", link: "https://www.bit-hdtv.com/",

View File

@ -33,7 +33,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public BitMeTV(IIndexerConfigurationService configService, Logger l, IWebClient c, IProtectionService ps) public BitMeTV(IIndexerConfigurationService configService, IWebClient c, Logger l, IProtectionService ps)
: base(name: "BitMeTV", : base(name: "BitMeTV",
description: "TV Episode specialty tracker", description: "TV Episode specialty tracker",
link: "http://www.bitmetv.org/", link: "http://www.bitmetv.org/",

View File

@ -29,7 +29,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public DanishBits(IIndexerConfigurationService configService, Logger l, IWebClient c, IProtectionService ps) public DanishBits(IIndexerConfigurationService configService, IWebClient c, Logger l, IProtectionService ps)
: base(name: "DanishBits", : base(name: "DanishBits",
description: "A danish closed torrent tracker", description: "A danish closed torrent tracker",
link: "https://danishbits.org/", link: "https://danishbits.org/",
@ -160,7 +160,7 @@ namespace Jackett.Indexers
var releasesPerPage = 100; var releasesPerPage = 100;
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var page = (query.Offset/releasesPerPage) + 1; var page = (query.Offset / releasesPerPage) + 1;
string episodeSearchUrl; string episodeSearchUrl;
if (string.IsNullOrEmpty(query.GetQueryString())) if (string.IsNullOrEmpty(query.GetQueryString()))
@ -212,13 +212,13 @@ namespace Jackett.Indexers
var catUrl = catAnchor.GetAttribute("href"); var catUrl = catAnchor.GetAttribute("href");
var catStr = Regex.Match(catUrl, "filter_(?<catNo>[0-9]+)=on").Groups["catNo"].Value; var catStr = Regex.Match(catUrl, "filter_(?<catNo>[0-9]+)=on").Groups["catNo"].Value;
var catNo = int.Parse(catStr); var catNo = int.Parse(catStr);
var moviesCatsDanish = new[] { 2,3,10,28,29,31 }; var moviesCatsDanish = new[] { 2, 3, 10, 28, 29, 31 };
var moviesCatsIntl = new[] { 8,9,11,22,24 }; var moviesCatsIntl = new[] { 8, 9, 11, 22, 24 };
var moviesCats = configData.OnlyDanishCategories.Value var moviesCats = configData.OnlyDanishCategories.Value
? moviesCatsDanish ? moviesCatsDanish
: moviesCatsDanish.Concat(moviesCatsIntl); : moviesCatsDanish.Concat(moviesCatsIntl);
var seriesCatsDanish = new[] { 1,4,30 }; var seriesCatsDanish = new[] { 1, 4, 30 };
var seriesCatsIntl = new[] { 20,21 }; var seriesCatsIntl = new[] { 20, 21 };
var seriesCats = configData.OnlyDanishCategories.Value var seriesCats = configData.OnlyDanishCategories.Value
? seriesCatsDanish ? seriesCatsDanish
: seriesCatsDanish.Concat(seriesCatsIntl); : seriesCatsDanish.Concat(seriesCatsIntl);
@ -248,7 +248,7 @@ namespace Jackett.Indexers
var addedElement = qRow.Find("span.time").FirstElement(); var addedElement = qRow.Find("span.time").FirstElement();
var addedStr = addedElement.GetAttribute("title"); var addedStr = addedElement.GetAttribute("title");
release.PublishDate = TimeZoneInfo.ConvertTimeToUtc(DateTime.ParseExact(addedStr, "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture), denmarkTz).ToLocalTime(); release.PublishDate = TimeZoneInfo.ConvertTimeToUtc(DateTime.ParseExact(addedStr, "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture), denmarkTz).ToLocalTime();
var columns = qRow.Children(); var columns = qRow.Children();
var seedersElement = columns.Reverse().Skip(1).First(); var seedersElement = columns.Reverse().Skip(1).First();
release.Seeders = int.Parse(seedersElement.InnerText); release.Seeders = int.Parse(seedersElement.InnerText);

View File

@ -27,7 +27,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public Demonoid(IIndexerConfigurationService configService, Logger l, IWebClient wc, IProtectionService ps) public Demonoid(IIndexerConfigurationService configService, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "Demonoid", : base(name: "Demonoid",
description: "Demonoid", description: "Demonoid",
link: "https://www.demonoid.pw/", link: "https://www.demonoid.pw/",

View File

@ -29,7 +29,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public DigitalHive(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public DigitalHive(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "DigitalHive", : base(name: "DigitalHive",
description: "DigitalHive is one of the oldest general trackers", description: "DigitalHive is one of the oldest general trackers",
link: "https://www.digitalhive.org/", link: "https://www.digitalhive.org/",

View File

@ -25,7 +25,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public FunFile(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public FunFile(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "FunFile", : base(name: "FunFile",
description: "A general tracker", description: "A general tracker",
link: "https://www.funfile.org/", link: "https://www.funfile.org/",

View File

@ -32,7 +32,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public Fuzer(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public Fuzer(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "Fuzer", : base(name: "Fuzer",
description: "Fuzer is a private torrent website with israeli torrents.", description: "Fuzer is a private torrent website with israeli torrents.",
link: "https://fuzer.me/", link: "https://fuzer.me/",

View File

@ -34,7 +34,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public GFTracker(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public GFTracker(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "GFTracker", : base(name: "GFTracker",
description: "Home of user happiness", description: "Home of user happiness",
link: "https://www.thegft.org/", link: "https://www.thegft.org/",

View File

@ -28,7 +28,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public HD4Free(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public HD4Free(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "HD4Free", : base(name: "HD4Free",
description: "A HD trackers", description: "A HD trackers",
link: "https://hd4free.xyz/", link: "https://hd4free.xyz/",

View File

@ -32,7 +32,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public HDTorrents(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public HDTorrents(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "HD-Torrents", : base(name: "HD-Torrents",
description: "HD-Torrents is a private torrent website with HD torrents and strict rules on their content.", description: "HD-Torrents is a private torrent website with HD torrents and strict rules on their content.",
link: "https://hdts.ru/",// Of the accessible domains the .ru seems the most reliable. https://hdts.ru | https://hd-torrents.org | https://hd-torrents.net | https://hd-torrents.me link: "https://hdts.ru/",// Of the accessible domains the .ru seems the most reliable. https://hdts.ru | https://hd-torrents.org | https://hd-torrents.net | https://hd-torrents.me

View File

@ -1,4 +1,4 @@
using Jackett.Models; using Jackett.Models;
using Jackett.Services; using Jackett.Services;
using Jackett.Utils; using Jackett.Utils;
using Jackett.Utils.Clients; using Jackett.Utils.Clients;
@ -26,7 +26,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public Hardbay(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public Hardbay(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "Hardbay", : base(name: "Hardbay",
description: null, description: null,
link: "https://hardbay.club/", link: "https://hardbay.club/",

View File

@ -28,7 +28,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public Hebits(IIndexerConfigurationService configService, Logger l, IWebClient wc, IProtectionService ps) public Hebits(IIndexerConfigurationService configService, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "Hebits", : base(name: "Hebits",
description: "The Israeli Tracker", description: "The Israeli Tracker",
link: "https://hebits.net/", link: "https://hebits.net/",

View File

@ -23,28 +23,28 @@ using System.Text.RegularExpressions;
namespace Jackett.Indexers namespace Jackett.Indexers
{ {
public class Hounddawgs : BaseWebIndexer public class Hounddawgs : BaseWebIndexer
{ {
private string LoginUrl { get { return SiteLink + "login.php"; } } private string LoginUrl { get { return SiteLink + "login.php"; } }
private string SearchUrl { get { return SiteLink + "torrents.php"; } } private string SearchUrl { get { return SiteLink + "torrents.php"; } }
new NxtGnConfigurationData configData new NxtGnConfigurationData configData
{ {
get { return (NxtGnConfigurationData)base.configData; } get { return (NxtGnConfigurationData)base.configData; }
set { base.configData = value; } set { base.configData = value; }
} }
public Hounddawgs(IIndexerConfigurationService configService, Logger l, IWebClient c, IProtectionService ps) public Hounddawgs(IIndexerConfigurationService configService, IWebClient c, Logger l, IProtectionService ps)
: base(name: "Hounddawgs", : base(name: "Hounddawgs",
description: "A danish closed torrent tracker", description: "A danish closed torrent tracker",
link: "https://hounddawgs.org/", link: "https://hounddawgs.org/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(), caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
configService: configService, configService: configService,
client: c, client: c,
logger: l, logger: l,
p: ps, p: ps,
configData: new NxtGnConfigurationData()) configData: new NxtGnConfigurationData())
{ {
Encoding = Encoding.GetEncoding("UTF-8"); Encoding = Encoding.GetEncoding("UTF-8");
Language = "da-dk"; Language = "da-dk";
Type = "private"; Type = "private";
@ -84,32 +84,32 @@ namespace Jackett.Indexers
AddCategoryMapping(67, TorznabCatType.XXX, "XXX"); AddCategoryMapping(67, TorznabCatType.XXX, "XXX");
} }
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson) public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{ {
LoadValuesFromJson(configJson); LoadValuesFromJson(configJson);
var pairs = new Dictionary<string, string> { var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value }, { "username", configData.Username.Value },
{ "password", configData.Password.Value }, { "password", configData.Password.Value },
{ "keeplogged", "1" }, { "keeplogged", "1" },
{ "login", "Login" } { "login", "Login" }
}; };
// Get inital cookies // Get inital cookies
var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, "https://hounddawgs.org/"); var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, "https://hounddawgs.org/");
await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("Velkommen til"), () => await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("Velkommen til"), () =>
{ {
CQ dom = response.Content; CQ dom = response.Content;
var messageEl = dom["inputs"]; var messageEl = dom["inputs"];
var errorMessage = messageEl.Text().Trim(); var errorMessage = messageEl.Text().Trim();
throw new ExceptionWithConfigData(errorMessage, configData); throw new ExceptionWithConfigData(errorMessage, configData);
}); });
return IndexerConfigurationStatus.RequiresTesting; return IndexerConfigurationStatus.RequiresTesting;
} }
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.GetQueryString(); var searchString = query.GetQueryString();
var searchUrl = SearchUrl; var searchUrl = SearchUrl;
var queryCollection = new NameValueCollection(); var queryCollection = new NameValueCollection();
@ -129,34 +129,34 @@ namespace Jackett.Indexers
searchUrl += "?" + queryCollection.GetQueryString(); searchUrl += "?" + queryCollection.GetQueryString();
var results = await RequestStringWithCookiesAndRetry(searchUrl); var results = await RequestStringWithCookiesAndRetry(searchUrl);
if (results.Content.Contains("Din søgning gav intet resultat.")) if (results.Content.Contains("Din søgning gav intet resultat."))
{ {
return releases; return releases;
} }
try try
{ {
CQ dom = results.Content; CQ dom = results.Content;
var rows = dom["#torrent_table > tbody > tr"].ToArray(); var rows = dom["#torrent_table > tbody > tr"].ToArray();
foreach (var row in rows.Skip(1)) foreach (var row in rows.Skip(1))
{ {
var qRow = row.Cq(); var qRow = row.Cq();
var release = new ReleaseInfo(); var release = new ReleaseInfo();
release.MinimumRatio = 1; release.MinimumRatio = 1;
release.MinimumSeedTime = 172800; release.MinimumSeedTime = 172800;
var qCat = row.ChildElements.ElementAt(0).ChildElements.ElementAt(0).Cq(); var qCat = row.ChildElements.ElementAt(0).ChildElements.ElementAt(0).Cq();
var catUrl = qCat.Attr("href"); var catUrl = qCat.Attr("href");
var cat = catUrl.Substring(catUrl.LastIndexOf('[') + 1).Trim(']'); var cat = catUrl.Substring(catUrl.LastIndexOf('[') + 1).Trim(']');
release.Category = MapTrackerCatToNewznab(cat); release.Category = MapTrackerCatToNewznab(cat);
var qAdded = row.ChildElements.ElementAt(4).ChildElements.ElementAt(0).Cq(); var qAdded = row.ChildElements.ElementAt(4).ChildElements.ElementAt(0).Cq();
var addedStr = qAdded.Attr("title"); var addedStr = qAdded.Attr("title");
release.PublishDate = DateTime.ParseExact(addedStr, "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture); release.PublishDate = DateTime.ParseExact(addedStr, "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture);
var overlayScript = qRow.Find("script:contains(\"var overlay\")").Text(); var overlayScript = qRow.Find("script:contains(\"var overlay\")").Text();
var overlayHtmlEscaped = overlayScript.Substring(overlayScript.IndexOf('=')+1).Trim().Trim('"'); var overlayHtmlEscaped = overlayScript.Substring(overlayScript.IndexOf('=') + 1).Trim().Trim('"');
var overlayHtml = Regex.Unescape(overlayHtmlEscaped); var overlayHtml = Regex.Unescape(overlayHtmlEscaped);
CQ qOverlay = overlayHtml; CQ qOverlay = overlayHtml;
var title = qOverlay.Find("td.overlay > strong"); var title = qOverlay.Find("td.overlay > strong");
@ -177,46 +177,46 @@ namespace Jackett.Indexers
var qLink = row.Cq().Find("a[href^=\"torrents.php?id=\"][onmouseover]"); var qLink = row.Cq().Find("a[href^=\"torrents.php?id=\"][onmouseover]");
release.Comments = new Uri(SiteLink + qLink.Attr("href")); release.Comments = new Uri(SiteLink + qLink.Attr("href"));
release.Guid = release.Comments; release.Guid = release.Comments;
var qDownload = row.ChildElements.ElementAt(1).ChildElements.ElementAt(1).ChildElements.ElementAt(0).Cq(); var qDownload = row.ChildElements.ElementAt(1).ChildElements.ElementAt(1).ChildElements.ElementAt(0).Cq();
release.Link = new Uri(SiteLink + qDownload.Attr("href")); release.Link = new Uri(SiteLink + qDownload.Attr("href"));
var sizeStr = row.ChildElements.ElementAt(5).Cq().Text(); var sizeStr = row.ChildElements.ElementAt(5).Cq().Text();
release.Size = ReleaseInfo.GetBytes(sizeStr); release.Size = ReleaseInfo.GetBytes(sizeStr);
release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(6).Cq().Text()); release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(6).Cq().Text());
release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text()) + release.Seeders; release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text()) + release.Seeders;
var files = row.Cq().Find("td:nth-child(4)").Text(); var files = row.Cq().Find("td:nth-child(4)").Text();
release.Files = ParseUtil.CoerceInt(files); release.Files = ParseUtil.CoerceInt(files);
if (row.Cq().Find("img[src=\"/static//common/browse/freeleech.png\"]").Any()) if (row.Cq().Find("img[src=\"/static//common/browse/freeleech.png\"]").Any())
release.DownloadVolumeFactor = 0; release.DownloadVolumeFactor = 0;
else else
release.DownloadVolumeFactor = 1; release.DownloadVolumeFactor = 1;
release.UploadVolumeFactor = 1; release.UploadVolumeFactor = 1;
releases.Add(release); releases.Add(release);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
OnParseError(results.Content, ex); OnParseError(results.Content, ex);
} }
return releases; return releases;
} }
public class NxtGnConfigurationData : ConfigurationData public class NxtGnConfigurationData : ConfigurationData
{ {
public NxtGnConfigurationData() public NxtGnConfigurationData()
{ {
Username = new StringItem { Name = "Username" }; Username = new StringItem { Name = "Username" };
Password = new StringItem { Name = "Password" }; Password = new StringItem { Name = "Password" };
} }
public StringItem Username { get; private set; } public StringItem Username { get; private set; }
public StringItem Password { get; private set; } public StringItem Password { get; private set; }
} }
} }
} }

View File

@ -29,7 +29,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public HouseOfTorrents(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public HouseOfTorrents(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "House-of-Torrents", : base(name: "House-of-Torrents",
description: "A general tracker", description: "A general tracker",
link: "https://houseoftorrents.club/", link: "https://houseoftorrents.club/",

View File

@ -22,14 +22,14 @@ namespace Jackett.Indexers
private string indexUrl { get { return "https://passthepopcorn.me/ajax.php?action=login"; } } private string indexUrl { get { return "https://passthepopcorn.me/ajax.php?action=login"; } }
private string SearchUrl { get { return "https://passthepopcorn.me/torrents.php"; } } private string SearchUrl { get { return "https://passthepopcorn.me/torrents.php"; } }
private string DetailURL { get { return "https://passthepopcorn.me/torrents.php?torrentid="; } } private string DetailURL { get { return "https://passthepopcorn.me/torrents.php?torrentid="; } }
private string AuthKey { get; set; } private string AuthKey { get; set; }
new ConfigurationDataBasicLoginWithFilterAndPasskey configData new ConfigurationDataBasicLoginWithFilterAndPasskey configData
{ {
get { return (ConfigurationDataBasicLoginWithFilterAndPasskey)base.configData; } get { return (ConfigurationDataBasicLoginWithFilterAndPasskey)base.configData; }
set { base.configData = value; } set { base.configData = value; }
} }
public PassThePopcorn(IIndexerConfigurationService configService, Logger l, IWebClient c, IProtectionService ps) public PassThePopcorn(IIndexerConfigurationService configService, IWebClient c, Logger l, IProtectionService ps)
: base(name: "PassThePopcorn", : base(name: "PassThePopcorn",
description: "PassThePopcorn", description: "PassThePopcorn",
link: "https://passthepopcorn.me/", link: "https://passthepopcorn.me/",
@ -91,7 +91,7 @@ namespace Jackett.Indexers
// Landing page wil have "Result":"Error" if log in fails // Landing page wil have "Result":"Error" if log in fails
string errorMessage = (string)js_response["Message"]; string errorMessage = (string)js_response["Message"];
throw new ExceptionWithConfigData(errorMessage, configData); throw new ExceptionWithConfigData(errorMessage, configData);
}); });
} }
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
@ -108,7 +108,7 @@ namespace Jackett.Indexers
{ {
movieListSearchUrl = string.Format("{0}?json=noredirect&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.ImdbID)); movieListSearchUrl = string.Format("{0}?json=noredirect&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.ImdbID));
} }
else if(!string.IsNullOrEmpty(query.GetQueryString())) else if (!string.IsNullOrEmpty(query.GetQueryString()))
{ {
movieListSearchUrl = string.Format("{0}?json=noredirect&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString())); movieListSearchUrl = string.Format("{0}?json=noredirect&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
} }
@ -132,7 +132,7 @@ namespace Jackett.Indexers
if (!string.IsNullOrEmpty(coverStr)) if (!string.IsNullOrEmpty(coverStr))
coverUri = new Uri(coverStr); coverUri = new Uri(coverStr);
long? movie_imdbid = null; long? movie_imdbid = null;
if(!string.IsNullOrEmpty(movie_imdbid_str)) if (!string.IsNullOrEmpty(movie_imdbid_str))
movie_imdbid = long.Parse(movie_imdbid_str); movie_imdbid = long.Parse(movie_imdbid_str);
string movie_groupid = (string)movie["GroupId"]; string movie_groupid = (string)movie["GroupId"];
foreach (var torrent in movie["Torrents"]) foreach (var torrent in movie["Torrents"])
@ -149,9 +149,9 @@ namespace Jackett.Indexers
release.Grabs = long.Parse((string)torrent["Snatched"]); release.Grabs = long.Parse((string)torrent["Snatched"]);
release.Seeders = int.Parse((string)torrent["Seeders"]); release.Seeders = int.Parse((string)torrent["Seeders"]);
release.Peers = release.Seeders + int.Parse((string)torrent["Leechers"]); release.Peers = release.Seeders + int.Parse((string)torrent["Leechers"]);
release.PublishDate = DateTime.ParseExact((string)torrent["UploadTime"], "yyyy-MM-dd HH:mm:ss", release.PublishDate = DateTime.ParseExact((string)torrent["UploadTime"], "yyyy-MM-dd HH:mm:ss",
CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime(); CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();
release.Link = new Uri(string.Format("{0}?action=download&id={1}&authkey={2}&torrent_pass={3}", release.Link = new Uri(string.Format("{0}?action=download&id={1}&authkey={2}&torrent_pass={3}",
SearchUrl, HttpUtility.UrlEncode((string)torrent["Id"]), HttpUtility.UrlEncode(AuthKey), HttpUtility.UrlEncode(configData.Passkey.Value))); SearchUrl, HttpUtility.UrlEncode((string)torrent["Id"]), HttpUtility.UrlEncode(AuthKey), HttpUtility.UrlEncode(configData.Passkey.Value)));
release.MinimumRatio = 1; release.MinimumRatio = 1;
release.MinimumSeedTime = 345600; release.MinimumSeedTime = 345600;

View File

@ -30,7 +30,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public PirateTheNet(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public PirateTheNet(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "PirateTheNet", : base(name: "PirateTheNet",
description: "A movie tracker", description: "A movie tracker",
link: "http://piratethenet.org/", link: "http://piratethenet.org/",

View File

@ -36,7 +36,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public RevolutionTT(IIndexerConfigurationService configService, Logger l, IWebClient wc, IProtectionService ps) public RevolutionTT(IIndexerConfigurationService configService, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "RevolutionTT", : base(name: "RevolutionTT",
description: "The Revolution has begun", description: "The Revolution has begun",
link: "https://revolutiontt.me/", link: "https://revolutiontt.me/",

View File

@ -28,7 +28,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public SceneTime(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public SceneTime(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "SceneTime", : base(name: "SceneTime",
description: "Always on time", description: "Always on time",
link: "https://www.scenetime.com/", link: "https://www.scenetime.com/",

View File

@ -25,7 +25,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public ShowRSS(IIndexerConfigurationService configService, Logger l, IWebClient wc, IProtectionService ps) public ShowRSS(IIndexerConfigurationService configService, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "ShowRSS", : base(name: "ShowRSS",
description: "showRSS is a service that allows you to keep track of your favorite TV shows", description: "showRSS is a service that allows you to keep track of your favorite TV shows",
link: "http://showrss.info/", link: "http://showrss.info/",

View File

@ -27,7 +27,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public SpeedCD(IIndexerConfigurationService configService, Logger l, IWebClient wc, IProtectionService ps) public SpeedCD(IIndexerConfigurationService configService, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "Speed.cd", : base(name: "Speed.cd",
description: "Your home now!", description: "Your home now!",
link: "https://speed.cd/", link: "https://speed.cd/",

View File

@ -26,7 +26,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public Superbits(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public Superbits(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "Superbits", : base(name: "Superbits",
description: null, description: null,
link: "https://superbits.org/", link: "https://superbits.org/",

View File

@ -32,7 +32,7 @@ namespace Jackett.Indexers
private Dictionary<int, List<int>> _mediaCategoryMapping = new Dictionary<int, List<int>>(); private Dictionary<int, List<int>> _mediaCategoryMapping = new Dictionary<int, List<int>>();
public T411(IIndexerConfigurationService configService, Logger l, IWebClient wc, IProtectionService ps) public T411(IIndexerConfigurationService configService, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "T411", : base(name: "T411",
description: "French Torrent Tracker", description: "French Torrent Tracker",
link: "https://t411.al/", link: "https://t411.al/",

View File

@ -21,14 +21,14 @@ namespace Jackett.Indexers
private string LoginUrl { get { return SiteLink + "login.php"; } } private string LoginUrl { get { return SiteLink + "login.php"; } }
private string indexUrl { get { return SiteLink + "index.php"; } } private string indexUrl { get { return SiteLink + "index.php"; } }
private string SearchUrl { get { return SiteLink + "torrents.php"; } } private string SearchUrl { get { return SiteLink + "torrents.php"; } }
new ConfigurationDataBasicLoginWithFilter configData new ConfigurationDataBasicLoginWithFilter configData
{ {
get { return (ConfigurationDataBasicLoginWithFilter)base.configData; } get { return (ConfigurationDataBasicLoginWithFilter)base.configData; }
set { base.configData = value; } set { base.configData = value; }
} }
public TehConnection(IIndexerConfigurationService configService, Logger l, IWebClient c, IProtectionService ps) public TehConnection(IIndexerConfigurationService configService, IWebClient c, Logger l, IProtectionService ps)
: base(name: "TehConnection", : base(name: "TehConnection",
description: "Working towards providing a well-seeded archive of all available digital forms of cinema and film in their highest possible quality", description: "Working towards providing a well-seeded archive of all available digital forms of cinema and film in their highest possible quality",
link: "https://tehconnection.eu/", link: "https://tehconnection.eu/",
@ -111,7 +111,7 @@ namespace Jackett.Indexers
{ {
movieListSearchUrl = string.Format("{0}?action=basic&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.ImdbID)); movieListSearchUrl = string.Format("{0}?action=basic&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.ImdbID));
} }
else if(!string.IsNullOrEmpty(query.GetQueryString())) else if (!string.IsNullOrEmpty(query.GetQueryString()))
{ {
movieListSearchUrl = string.Format("{0}?action=basic&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString())); movieListSearchUrl = string.Format("{0}?action=basic&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
} }
@ -155,7 +155,7 @@ namespace Jackett.Indexers
{ {
var release = new ReleaseInfo(); var release = new ReleaseInfo();
var qRow = row.Cq(); var qRow = row.Cq();
string title = qRow.Find("[id^=desc_] > h2 > strong").First().Text().Trim(); string title = qRow.Find("[id^=desc_] > h2 > strong").First().Text().Trim();
Uri link = new Uri(SiteLink.TrimEnd('/') + qRow.Find("a[title='Download']").First().Attr("href").Trim()); Uri link = new Uri(SiteLink.TrimEnd('/') + qRow.Find("a[title='Download']").First().Attr("href").Trim());
Uri guid = new Uri(SiteLink.TrimEnd('/') + qRow.Find("a[title='Permalink']").First().Attr("href").Trim()); Uri guid = new Uri(SiteLink.TrimEnd('/') + qRow.Find("a[title='Permalink']").First().Attr("href").Trim());
@ -170,7 +170,7 @@ namespace Jackett.Indexers
Uri CoverUrl = new Uri(dom.Find("div[id='poster'] > a > img").First().Attr("src").Trim()); Uri CoverUrl = new Uri(dom.Find("div[id='poster'] > a > img").First().Attr("src").Trim());
release.BannerUrl = CoverUrl; release.BannerUrl = CoverUrl;
} }
bool freeleech = qRow.Find("span[class='freeleech']").Length == 1 ? true : false; bool freeleech = qRow.Find("span[class='freeleech']").Length == 1 ? true : false;
bool qualityEncode = qRow.Find("img[class='approved']").Length == 1 ? true : false; bool qualityEncode = qRow.Find("img[class='approved']").Length == 1 ? true : false;
string grabs = qRow.Find("img[title='Snatches']").First().Parent().Text().Trim(); string grabs = qRow.Find("img[title='Snatches']").First().Parent().Text().Trim();
@ -181,11 +181,11 @@ namespace Jackett.Indexers
{ sizeStr = secondSizeStr.Replace("(", "").Replace(")", "").Trim(); } { sizeStr = secondSizeStr.Replace("(", "").Replace(")", "").Trim(); }
} }
if(string.IsNullOrWhiteSpace(title)) if (string.IsNullOrWhiteSpace(title))
{ {
title = dom.Find("div.title_text").Text() + " - " + qRow.Find("div.details_title > a").Text(); title = dom.Find("div.title_text").Text() + " - " + qRow.Find("div.details_title > a").Text();
} }
release.Title = title; release.Title = title;
release.Guid = guid; release.Guid = guid;
@ -199,11 +199,12 @@ namespace Jackett.Indexers
release.MinimumSeedTime = 345600; release.MinimumSeedTime = 345600;
release.Category = new List<int> { 2000 }; release.Category = new List<int> { 2000 };
release.Comments = movieReleasesLink; release.Comments = movieReleasesLink;
if (imdb_id > 0) { if (imdb_id > 0)
{
release.Imdb = imdb_id; release.Imdb = imdb_id;
} }
var files = qRow.Find("div[id^=\"filelist\"] tr").Count()-1; var files = qRow.Find("div[id^=\"filelist\"] tr").Count() - 1;
release.Files = files; release.Files = files;
release.Grabs = ParseUtil.CoerceLong(grabs); release.Grabs = ParseUtil.CoerceLong(grabs);

View File

@ -44,7 +44,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public TorrentDay(IIndexerConfigurationService configService, Logger l, IWebClient wc, IProtectionService ps) public TorrentDay(IIndexerConfigurationService configService, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "TorrentDay", : base(name: "TorrentDay",
description: "TorrentDay", description: "TorrentDay",
link: "https://torrentday.it/", link: "https://torrentday.it/",

View File

@ -29,7 +29,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public TorrentLeech(IIndexerConfigurationService configService, Logger l, IWebClient wc, IProtectionService ps) public TorrentLeech(IIndexerConfigurationService configService, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "TorrentLeech", : base(name: "TorrentLeech",
description: "This is what happens when you seed", description: "This is what happens when you seed",
link: "https://www.torrentleech.org/", link: "https://www.torrentleech.org/",

View File

@ -30,7 +30,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public TorrentSyndikat(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public TorrentSyndikat(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "Torrent-Syndikat", : base(name: "Torrent-Syndikat",
description: "A German general tracker", description: "A German general tracker",
link: "https://torrent-syndikat.org/", link: "https://torrent-syndikat.org/",

View File

@ -27,7 +27,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public TransmitheNet(IIndexerConfigurationService configService, Logger l, IWebClient c, IProtectionService ps) public TransmitheNet(IIndexerConfigurationService configService, IWebClient c, Logger l, IProtectionService ps)
: base(name: "Nebulance", : base(name: "Nebulance",
description: " At Nebulance we will change the way you think about TV", description: " At Nebulance we will change the way you think about TV",
link: "https://nebulance.io/", link: "https://nebulance.io/",

View File

@ -27,7 +27,7 @@ namespace Jackett.Indexers
set { base.configData = value; } set { base.configData = value; }
} }
public x264(IIndexerConfigurationService configService, Logger l, IWebClient w, IProtectionService ps) public x264(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
: base(name: "x264", : base(name: "x264",
description: "A movie/TV tracker", description: "A movie/TV tracker",
link: "https://x264.me/", link: "https://x264.me/",

View File

@ -115,17 +115,6 @@ namespace Jackett
break; break;
} }
// Register indexers
var allTypes = thisAssembly.GetTypes();
var allIndexerTypes = allTypes.Where(p => typeof(IIndexer).IsAssignableFrom(p));
var allInstantiatableIndexerTypes = allIndexerTypes.Where(p => !p.IsInterface && !p.IsAbstract);
var allNonMetaInstantiatableIndexerTypes = allInstantiatableIndexerTypes.Where(p => !typeof(BaseMetaIndexer).IsAssignableFrom(p));
var indexerTypes = allNonMetaInstantiatableIndexerTypes.Where(p => p.Name != "CardigannIndexer");
foreach (var indexer in indexerTypes)
{
builder.RegisterType(indexer).Named<IIndexer>(BaseIndexer.GetIndexerID(indexer));
}
Mapper.CreateMap<WebClientByteResult, WebClientStringResult>().ForMember(x => x.Content, opt => opt.Ignore()).AfterMap((be, str) => Mapper.CreateMap<WebClientByteResult, WebClientStringResult>().ForMember(x => x.Content, opt => opt.Ignore()).AfterMap((be, str) =>
{ {
str.Content = Encoding.UTF8.GetString(be.Content); str.Content = Encoding.UTF8.GetString(be.Content);

View File

@ -1,5 +1,4 @@
using Autofac; using Jackett.Indexers;
using Jackett.Indexers;
using Jackett.Models; using Jackett.Models;
using Jackett.Utils; using Jackett.Utils;
using Jackett.Utils.Clients; using Jackett.Utils.Clients;
@ -24,71 +23,112 @@ namespace Jackett.Services
IWebIndexer GetWebIndexer(string name); IWebIndexer GetWebIndexer(string name);
IEnumerable<IIndexer> GetAllIndexers(); IEnumerable<IIndexer> GetAllIndexers();
void InitIndexers(); void InitIndexers(IEnumerable<string> path);
void InitCardigannIndexers(string path);
void InitAggregateIndexer(); void InitAggregateIndexer();
void SortIndexers();
} }
public class IndexerManagerService : IIndexerManagerService public class IndexerManagerService : IIndexerManagerService
{ {
private IContainer container;
private Logger logger;
private Dictionary<string, IIndexer> indexers = new Dictionary<string, IIndexer>();
private ICacheService cacheService; private ICacheService cacheService;
private IIndexerConfigurationService configService; private IIndexerConfigurationService configService;
private IProtectionService protectionService;
private IWebClient webClient;
private Logger logger;
private Dictionary<string, IIndexer> indexers = new Dictionary<string, IIndexer>();
private AggregateIndexer aggregateIndexer; private AggregateIndexer aggregateIndexer;
public IndexerManagerService(IContainer c, IIndexerConfigurationService config, Logger l, ICacheService cache) public IndexerManagerService(IIndexerConfigurationService config, IProtectionService protectionService, IWebClient webClient, Logger l, ICacheService cache)
{ {
container = c;
configService = config; configService = config;
this.protectionService = protectionService;
this.webClient = webClient;
logger = l; logger = l;
cacheService = cache; cacheService = cache;
} }
public void InitIndexers() public void InitIndexers(IEnumerable<string> path)
{ {
logger.Info("Using HTTP Client: " + container.Resolve<IWebClient>().GetType().Name); InitIndexers();
InitCardigannIndexers(path);
InitAggregateIndexer();
}
foreach (var idx in container.Resolve<IEnumerable<IIndexer>>().OrderBy(_ => _.DisplayName)) private void InitIndexers()
{
logger.Info("Using HTTP Client: " + webClient.GetType().Name);
var allTypes = GetType().Assembly.GetTypes();
var allIndexerTypes = allTypes.Where(p => typeof(IIndexer).IsAssignableFrom(p));
var allInstantiatableIndexerTypes = allIndexerTypes.Where(p => !p.IsInterface && !p.IsAbstract);
var allNonMetaInstantiatableIndexerTypes = allInstantiatableIndexerTypes.Where(p => !typeof(BaseMetaIndexer).IsAssignableFrom(p));
var indexerTypes = allNonMetaInstantiatableIndexerTypes.Where(p => p.Name != "CardigannIndexer");
var ixs = indexerTypes.Select(type =>
{ {
var constructorArgumentTypes = new Type[] { typeof(IIndexerConfigurationService), typeof(IWebClient), typeof(Logger), typeof(IProtectionService) };
var constructor = type.GetConstructor(constructorArgumentTypes);
if (constructor != null)
{
var arguments = new object[] { configService, webClient, logger, protectionService };
var indexer = (IIndexer)constructor.Invoke(arguments);
return indexer;
}
else
{
logger.Error("Cannot instantiate " + type.Name);
}
return null;
});
foreach (var idx in ixs)
{
if (idx == null)
continue;
indexers.Add(idx.ID, idx); indexers.Add(idx.ID, idx);
configService.Load(idx); configService.Load(idx);
} }
} }
public void InitCardigannIndexers(string path) private void InitCardigannIndexers(IEnumerable<string> path)
{ {
logger.Info("Loading Cardigann definitions from: " + path); logger.Info("Loading Cardigann definitions from: " + string.Join(", ", path));
try var deserializer = new DeserializerBuilder()
{
if (!Directory.Exists(path))
return;
DirectoryInfo d = new DirectoryInfo(path);
foreach (var file in d.GetFiles("*.yml"))
{
logger.Info("Loading Cardigann definition " + file.FullName);
string DefinitionString = File.ReadAllText(file.FullName);
var deserializer = new DeserializerBuilder()
.WithNamingConvention(new CamelCaseNamingConvention()) .WithNamingConvention(new CamelCaseNamingConvention())
.IgnoreUnmatchedProperties() .IgnoreUnmatchedProperties()
.Build(); .Build();
try
{
var directoryInfos = path.Select(p => new DirectoryInfo(p));
var existingDirectories = directoryInfos.Where(d => d.Exists);
var files = existingDirectories.SelectMany(d => d.GetFiles("*.yml"));
var definitions = files.Select(file =>
{
logger.Info("Loading Cardigann definition " + file.FullName);
string DefinitionString = File.ReadAllText(file.FullName);
var definition = deserializer.Deserialize<IndexerDefinition>(DefinitionString); var definition = deserializer.Deserialize<IndexerDefinition>(DefinitionString);
CardigannIndexer idx = new CardigannIndexer(configService, container.Resolve<IWebClient>(), logger, container.Resolve<IProtectionService>(), definition); return definition;
if (indexers.ContainsKey(idx.ID)) });
var cardigannIndexers = definitions.Select(definition =>
{
IIndexer indexer = new CardigannIndexer(configService, webClient, logger, protectionService, definition);
configService.Load(indexer);
return indexer;
}).ToList(); // Explicit conversion to list to avoid repeated resource loading
foreach (var indexer in cardigannIndexers)
{
if (indexers.ContainsKey(indexer.ID))
{ {
logger.Debug(string.Format("Ignoring definition ID={0}, file={1}: Indexer already exists", idx.ID, file.FullName)); logger.Debug(string.Format("Ignoring definition ID={0}: Indexer already exists", indexer.ID));
} continue;
else
{
indexers.Add(idx.ID, idx);
configService.Load(idx);
} }
indexers.Add(indexer.ID, indexer);
} }
} }
catch (Exception ex) catch (Exception ex)
@ -99,12 +139,12 @@ namespace Jackett.Services
public void InitAggregateIndexer() public void InitAggregateIndexer()
{ {
var omdbApiKey = container.Resolve<IServerService>().Config.OmdbApiKey; var omdbApiKey = Engine.Server.Config.OmdbApiKey;
IFallbackStrategyProvider fallbackStrategyProvider = null; IFallbackStrategyProvider fallbackStrategyProvider = null;
IResultFilterProvider resultFilterProvider = null; IResultFilterProvider resultFilterProvider = null;
if (omdbApiKey != null) if (omdbApiKey != null)
{ {
var imdbResolver = new OmdbResolver(container.Resolve<IWebClient>(), omdbApiKey.ToNonNull()); var imdbResolver = new OmdbResolver(webClient, omdbApiKey.ToNonNull());
fallbackStrategyProvider = new ImdbFallbackStrategyProvider(imdbResolver); fallbackStrategyProvider = new ImdbFallbackStrategyProvider(imdbResolver);
resultFilterProvider = new ImdbTitleResultFilterProvider(imdbResolver); resultFilterProvider = new ImdbTitleResultFilterProvider(imdbResolver);
} }
@ -115,7 +155,7 @@ namespace Jackett.Services
} }
logger.Info("Adding aggregate indexer"); logger.Info("Adding aggregate indexer");
aggregateIndexer = new AggregateIndexer(fallbackStrategyProvider, resultFilterProvider, configService, container.Resolve<IWebClient>(), logger, container.Resolve<IProtectionService>()); aggregateIndexer = new AggregateIndexer(fallbackStrategyProvider, resultFilterProvider, configService, webClient, logger, protectionService);
aggregateIndexer.Indexers = indexers.Values; aggregateIndexer.Indexers = indexers.Values;
} }
@ -147,7 +187,7 @@ namespace Jackett.Services
public IEnumerable<IIndexer> GetAllIndexers() public IEnumerable<IIndexer> GetAllIndexers()
{ {
return indexers.Values; return indexers.Values.OrderBy(_ => _.DisplayName);
} }
public async Task TestIndexer(string name) public async Task TestIndexer(string name)
@ -168,15 +208,5 @@ namespace Jackett.Services
configService.Delete(indexer); configService.Delete(indexer);
indexer.Unconfigure(); indexer.Unconfigure();
} }
public void SortIndexers()
{
// Apparently Dictionary are ordered but can't be sorted again
// This will recreate the indexers Dictionary to workaround this limitation
Dictionary<string, IIndexer> newIndexers = new Dictionary<string, IIndexer>();
foreach (var indexer in indexers.OrderBy(_ => _.Value.DisplayName))
newIndexers.Add(indexer.Key, indexer.Value);
indexers = newIndexers;
}
} }
} }

View File

@ -12,6 +12,8 @@ namespace Jackett.Services
{ {
public interface IProtectionService public interface IProtectionService
{ {
byte[] InstanceKey { get; set; }
string Protect(string plainText); string Protect(string plainText);
string UnProtect(string plainText); string UnProtect(string plainText);
} }
@ -22,12 +24,10 @@ namespace Jackett.Services
private const string JACKETT_KEY = "JACKETT_KEY"; private const string JACKETT_KEY = "JACKETT_KEY";
const string APPLICATION_KEY = "Dvz66r3n8vhTGip2/quiw5ISyM37f7L2iOdupzdKmzkvXGhAgQiWK+6F+4qpxjPVNks1qO7LdWuVqRlzgLzeW8mChC6JnBMUS1Fin4N2nS9lh4XPuCZ1che75xO92Nk2vyXUo9KSFG1hvEszAuLfG2Mcg1r0sVyVXd2gQDU/TbY="; const string APPLICATION_KEY = "Dvz66r3n8vhTGip2/quiw5ISyM37f7L2iOdupzdKmzkvXGhAgQiWK+6F+4qpxjPVNks1qO7LdWuVqRlzgLzeW8mChC6JnBMUS1Fin4N2nS9lh4XPuCZ1che75xO92Nk2vyXUo9KSFG1hvEszAuLfG2Mcg1r0sVyVXd2gQDU/TbY=";
IServerService serverService; public byte[] InstanceKey { get; set; }
public ProtectionService(IServerService s) public ProtectionService()
{ {
serverService = s;
if (System.Environment.OSVersion.Platform == PlatformID.Unix) if (System.Environment.OSVersion.Platform == PlatformID.Unix)
{ {
// We should not be running as root and will only have access to the local store. // We should not be running as root and will only have access to the local store.
@ -70,7 +70,7 @@ namespace Jackett.Services
var plainBytes = Encoding.UTF8.GetBytes(plainText); var plainBytes = Encoding.UTF8.GetBytes(plainText);
var appKey = Convert.FromBase64String(APPLICATION_KEY); var appKey = Convert.FromBase64String(APPLICATION_KEY);
var instanceKey = Encoding.UTF8.GetBytes(serverService.Config.InstanceId); var instanceKey = InstanceKey;
var entropy = new byte[appKey.Length + instanceKey.Length]; var entropy = new byte[appKey.Length + instanceKey.Length];
Buffer.BlockCopy(instanceKey, 0, entropy, 0, instanceKey.Length); Buffer.BlockCopy(instanceKey, 0, entropy, 0, instanceKey.Length);
Buffer.BlockCopy(appKey, 0, entropy, instanceKey.Length, appKey.Length); Buffer.BlockCopy(appKey, 0, entropy, instanceKey.Length, appKey.Length);
@ -108,7 +108,7 @@ namespace Jackett.Services
return string.Empty; return string.Empty;
var protectedBytes = Convert.FromBase64String(plainText); var protectedBytes = Convert.FromBase64String(plainText);
var instanceKey = Encoding.UTF8.GetBytes(serverService.Config.InstanceId); var instanceKey = InstanceKey;
using (MemoryStream ms = new MemoryStream()) using (MemoryStream ms = new MemoryStream())
{ {
@ -155,12 +155,12 @@ namespace Jackett.Services
{ {
var type = obj.GetType(); var type = obj.GetType();
foreach(var property in type.GetProperties(BindingFlags.SetProperty |BindingFlags.GetProperty | BindingFlags.Public)) foreach (var property in type.GetProperties(BindingFlags.SetProperty | BindingFlags.GetProperty | BindingFlags.Public))
{ {
if(property.GetCustomAttributes(typeof(JackettProtectedAttribute), false).Count() > 0) if (property.GetCustomAttributes(typeof(JackettProtectedAttribute), false).Count() > 0)
{ {
var value = property.GetValue(obj); var value = property.GetValue(obj);
if(value is string) if (value is string)
{ {
var protectedString = Protect(value as string); var protectedString = Protect(value as string);
property.SetValue(obj, protectedString); property.SetValue(obj, protectedString);

View File

@ -57,7 +57,7 @@ namespace Jackett.Services
private IUpdateService updater; private IUpdateService updater;
private List<string> _notices = new List<string>(); private List<string> _notices = new List<string>();
public ServerService(IIndexerManagerService i, IProcessService p, ISerializeService s, IConfigurationService c, Logger l, IWebClient w, IUpdateService u) public ServerService(IIndexerManagerService i, IProcessService p, ISerializeService s, IConfigurationService c, Logger l, IWebClient w, IUpdateService u, IProtectionService protectionService)
{ {
indexerService = i; indexerService = i;
processService = p; processService = p;
@ -68,6 +68,8 @@ namespace Jackett.Services
updater = u; updater = u;
LoadConfig(); LoadConfig();
// "TEMPORARY" HACK
protectionService.InstanceKey = Encoding.UTF8.GetBytes(Config.InstanceId);
} }
public ServerConfig Config public ServerConfig Config
@ -283,13 +285,7 @@ namespace Jackett.Services
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
// Load indexers // Load indexers
indexerService.InitIndexers(); indexerService.InitIndexers(configService.GetCardigannDefinitionsFolders());
foreach (string dir in configService.GetCardigannDefinitionsFolders())
{
indexerService.InitCardigannIndexers(dir);
}
indexerService.InitAggregateIndexer();
indexerService.SortIndexers();
client.Init(); client.Init();
updater.CleanupTempDir(); updater.CleanupTempDir();
} }