From ea069810a52a9c66d69164c9857f2d28f2baa580 Mon Sep 17 00:00:00 2001 From: KZ Date: Wed, 29 Jul 2015 00:10:04 +0100 Subject: [PATCH] Add indexer: Immortalseed. Add category mapping framework. --- src/Jackett.Test/Indexers/BakaBTTests.cs | 26 +-- src/Jackett/Content/index.html | 2 + src/Jackett/Content/logos/immortalseed.png | Bin 0 -> 9424 bytes src/Jackett/Controllers/APIController.cs | 6 +- src/Jackett/Indexers/AlphaRatio.cs | 4 +- src/Jackett/Indexers/AnimeBytes.cs | 8 +- src/Jackett/Indexers/BB.cs | 4 +- src/Jackett/Indexers/BakaBT.cs | 6 +- src/Jackett/Indexers/BaseIndexer.cs | 50 ++++++ src/Jackett/Indexers/BeyondHD.cs | 4 +- src/Jackett/Indexers/BitHdtv.cs | 7 +- src/Jackett/Indexers/BitMeTV.cs | 7 +- src/Jackett/Indexers/FrenchTorrentDb.cs | 4 +- src/Jackett/Indexers/Freshon.cs | 7 +- src/Jackett/Indexers/HDSpace.cs | 7 +- src/Jackett/Indexers/HDTorrents.cs | 5 +- src/Jackett/Indexers/IIndexer.cs | 4 +- src/Jackett/Indexers/IPTorrents.cs | 6 +- src/Jackett/Indexers/ImmortalSeed.cs | 156 ++++++++++++++++++ src/Jackett/Indexers/MoreThanTV.cs | 7 +- src/Jackett/Indexers/Pretome.cs | 7 +- src/Jackett/Indexers/PrivateHD.cs | 7 +- src/Jackett/Indexers/Rarbg.cs | 6 +- src/Jackett/Indexers/SceneAccess.cs | 4 +- src/Jackett/Indexers/SceneTime.cs | 4 +- src/Jackett/Indexers/ShowRSS.cs | 12 +- src/Jackett/Indexers/SpeedCD.cs | 4 +- src/Jackett/Indexers/Strike.cs | 4 +- src/Jackett/Indexers/T411.cs | 7 +- src/Jackett/Indexers/ThePirateBay.cs | 6 +- src/Jackett/Indexers/TorrentDay.cs | 4 +- src/Jackett/Indexers/TorrentLeech.cs | 7 +- src/Jackett/Indexers/TorrentShack.cs | 4 +- src/Jackett/Indexers/Torrentz.cs | 16 +- src/Jackett/Jackett.csproj | 3 + src/Jackett/JackettModule.cs | 6 + src/Jackett/Models/CategoryMapping.cs | 20 +++ src/Jackett/Models/ReleaseInfo.cs | 2 +- src/Jackett/Models/ResultPage.cs | 4 +- src/Jackett/Models/TorznabCatType.cs | 140 ++++++++++++++++ src/Jackett/Models/TorznabCategory.cs | 50 +----- src/Jackett/Models/TorznabQuery.cs | 7 +- src/Jackett/Models/TrackerCacheResult.cs | 1 + src/Jackett/Services/CacheService.cs | 9 +- src/Jackett/Services/IndexerManagerService.cs | 4 +- src/Jackett/Utils/TorznabCapsUtil.cs | 6 +- 46 files changed, 494 insertions(+), 170 deletions(-) create mode 100644 src/Jackett/Content/logos/immortalseed.png create mode 100644 src/Jackett/Indexers/ImmortalSeed.cs create mode 100644 src/Jackett/Models/CategoryMapping.cs create mode 100644 src/Jackett/Models/TorznabCatType.cs diff --git a/src/Jackett.Test/Indexers/BakaBTTests.cs b/src/Jackett.Test/Indexers/BakaBTTests.cs index 0b9b471eb..13c7c26b3 100644 --- a/src/Jackett.Test/Indexers/BakaBTTests.cs +++ b/src/Jackett.Test/Indexers/BakaBTTests.cs @@ -158,20 +158,20 @@ namespace JackettTest.Indexers indexer.LoadFromSavedConfiguration(JObject.Parse("{\"cookies\":\"bbtid=c\"}")); var results = await indexer.PerformQuery(new Jackett.Models.TorznabQuery() { SanitizedSearchTerm = "Series S1", Season = 1 }); - results.Length.Should().Be(44); - results[0].Title.Should().Be("Golden Time Season 1 (BD 720p) [FFF]"); - results[0].Guid.Should().Be("http://bakabt.me/torrent/180302/golden-time-bd-720p-fff"); - results[0].Comments.Should().Be("http://bakabt.me/torrent/180302/golden-time-bd-720p-fff"); - results[0].Size.Should().Be(10307921920); - results[0].Description.Should().Be("Golden Time Season 1 (BD 720p) [FFF]"); - results[0].Link.Should().Be("http://bakabt.me/torrent/180302/golden-time-bd-720p-fff"); - results[0].Peers.Should().Be(161); - results[0].Seeders.Should().Be(151); - results[0].MinimumRatio.Should().Be(1); + results.Count().Should().Be(44); + results.First().Title.Should().Be("Golden Time Season 1 (BD 720p) [FFF]"); + results.First().Guid.Should().Be("http://bakabt.me/torrent/180302/golden-time-bd-720p-fff"); + results.First().Comments.Should().Be("http://bakabt.me/torrent/180302/golden-time-bd-720p-fff"); + results.First().Size.Should().Be(10307921920); + results.First().Description.Should().Be("Golden Time Season 1 (BD 720p) [FFF]"); + results.First().Link.Should().Be("http://bakabt.me/torrent/180302/golden-time-bd-720p-fff"); + results.First().Peers.Should().Be(161); + results.First().Seeders.Should().Be(151); + results.First().MinimumRatio.Should().Be(1); - results[1].Title.Should().Be("Yowamushi Pedal Season 1 (BD 720p) [Commie]"); - results[4].Title.Should().Be("Dungeon ni Deai o Motomeru no wa Machigatte Iru Darouka: Familia Myth Season 1 (480p) [HorribleSubs]"); - results[5].Title.Should().Be("Is It Wrong to Try to Pick Up Girls in a Dungeon? Season 1 (480p) [HorribleSubs]"); + results.ElementAt(1).Title.Should().Be("Yowamushi Pedal Season 1 (BD 720p) [Commie]"); + results.ElementAt(4).Title.Should().Be("Dungeon ni Deai o Motomeru no wa Machigatte Iru Darouka: Familia Myth Season 1 (480p) [HorribleSubs]"); + results.ElementAt(5).Title.Should().Be("Is It Wrong to Try to Pick Up Girls in a Dungeon? Season 1 (480p) [HorribleSubs]"); } } } diff --git a/src/Jackett/Content/index.html b/src/Jackett/Content/index.html index a94688fd7..7a4cfd93b 100644 --- a/src/Jackett/Content/index.html +++ b/src/Jackett/Content/index.html @@ -38,6 +38,7 @@ First Seen Tracker Name + Category Seeds Leechers Download @@ -52,6 +53,7 @@ {{formatRelative FirstSeen}} {{Tracker}} {{Title}} + {{CategoryDesc}} {{Seeders}} {{Peers}} diff --git a/src/Jackett/Content/logos/immortalseed.png b/src/Jackett/Content/logos/immortalseed.png new file mode 100644 index 0000000000000000000000000000000000000000..7e8503e115d02cd22d7eebf24994e341075a2011 GIT binary patch literal 9424 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 Ww17DYI5v#{0000 PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); @@ -122,7 +122,7 @@ namespace Jackett.Indexers OnParseError(response.Content, ex); } - return releases.ToArray(); + return releases; } static DateTime UnixTimestampToDateTime(double unixTime) diff --git a/src/Jackett/Indexers/AnimeBytes.cs b/src/Jackett/Indexers/AnimeBytes.cs index 61b5223cc..8815e820f 100644 --- a/src/Jackett/Indexers/AnimeBytes.cs +++ b/src/Jackett/Indexers/AnimeBytes.cs @@ -33,7 +33,7 @@ namespace Jackett.Indexers description: "Powered by Tentacles", manager: i, client: client, - caps: new TorznabCapabilities(TorznabCategory.Anime), + caps: new TorznabCapabilities(TorznabCatType.Anime), logger: l) { } @@ -114,7 +114,7 @@ namespace Jackett.Indexers } } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { // The result list var releases = new List(); @@ -127,7 +127,7 @@ namespace Jackett.Indexers return releases.ToArray(); } - public async Task GetResults(string searchTerm) + public async Task> GetResults(string searchTerm) { // This tracker only deals with full seasons so chop off the episode/season number if we have it D: if (!string.IsNullOrWhiteSpace(searchTerm)) @@ -327,7 +327,7 @@ namespace Jackett.Indexers cache.Add(new CachedQueryResult(searchTerm, releases)); } - return releases.Select(s => (ReleaseInfo)s.Clone()).ToArray(); + return releases.Select(s => (ReleaseInfo)s.Clone()); } diff --git a/src/Jackett/Indexers/BB.cs b/src/Jackett/Indexers/BB.cs index edc9e3ca0..c652a4d6f 100644 --- a/src/Jackett/Indexers/BB.cs +++ b/src/Jackett/Indexers/BB.cs @@ -68,7 +68,7 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { List releases = new List(); @@ -113,7 +113,7 @@ namespace Jackett.Indexers { OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/BakaBT.cs b/src/Jackett/Indexers/BakaBT.cs index 46ccee3f9..8906664fa 100644 --- a/src/Jackett/Indexers/BakaBT.cs +++ b/src/Jackett/Indexers/BakaBT.cs @@ -25,7 +25,7 @@ namespace Jackett.Indexers : base(name: "BakaBT", description: "Anime Community", link: "http://bakabt.me/", - caps: new TorznabCapabilities(TorznabCategory.Anime), + caps: new TorznabCapabilities(TorznabCatType.Anime), manager: i, client: wc, logger: l) @@ -65,7 +65,7 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { // This tracker only deals with full seasons so chop off the episode/season number if we have it D: @@ -170,7 +170,7 @@ namespace Jackett.Indexers OnParseError(response.Content, ex); } - return releases.ToArray(); + return releases; } public override async Task Download(Uri link) diff --git a/src/Jackett/Indexers/BaseIndexer.cs b/src/Jackett/Indexers/BaseIndexer.cs index 105d96796..5c54451b9 100644 --- a/src/Jackett/Indexers/BaseIndexer.cs +++ b/src/Jackett/Indexers/BaseIndexer.cs @@ -29,6 +29,8 @@ namespace Jackett.Indexers protected IWebClient webclient; protected string cookieHeader = ""; + private List categoryMapping = new List(); + public BaseIndexer(string name, string link, string description, IIndexerManagerService manager, IWebClient client, Logger logger, TorznabCapabilities caps = null) { if (!link.EndsWith("/")) @@ -46,6 +48,19 @@ namespace Jackett.Indexers TorznabCaps = caps; } + protected int MapTrackerCatToNewznab(string input) + { + if (null != input) { + input = input.ToLowerInvariant(); + var mapping = categoryMapping.Where(m => m.TrackerCategory == input).FirstOrDefault(); + if(mapping!= null) + { + return mapping.NewzNabCategory; + } + } + return 0; + } + public static string GetIndexerID(Type type) { return StringUtil.StripNonAlphaNumeric(type.Name.ToLowerInvariant()); @@ -239,5 +254,40 @@ namespace Jackett.Indexers onError(); } } + + public virtual IEnumerable FilterResults(TorznabQuery query, IEnumerable results) + { + foreach(var result in results) + { + if(query.Categories.Length == 0 || query.Categories.Contains(result.Category) || result.Category == 0 || TorznabCatType.QueryContainsParentCategory(query.Categories, result.Category)) + { + yield return result; + } + } + } + + protected void AddCategoryMapping(string trackerCategory, int newznabCategory) + { + categoryMapping.Add(new CategoryMapping(trackerCategory, newznabCategory)); + } + + protected void AddCategoryMapping(int trackerCategory, TorznabCategory newznabCategory) + { + categoryMapping.Add(new CategoryMapping(trackerCategory.ToString(), newznabCategory.ID)); + if (!TorznabCaps.Categories.Contains(newznabCategory)) + TorznabCaps.Categories.Add(newznabCategory); + } + + protected void AddCategoryMapping(string trackerCategory, TorznabCategory newznabCategory) + { + categoryMapping.Add(new CategoryMapping(trackerCategory.ToString(), newznabCategory.ID)); + if (!TorznabCaps.Categories.Contains(newznabCategory)) + TorznabCaps.Categories.Add(newznabCategory); + } + + protected void AddCategoryMapping(int trackerCategory, int newznabCategory) + { + categoryMapping.Add(new CategoryMapping(trackerCategory.ToString(), newznabCategory)); + } } } diff --git a/src/Jackett/Indexers/BeyondHD.cs b/src/Jackett/Indexers/BeyondHD.cs index d4827561d..bf41d902e 100644 --- a/src/Jackett/Indexers/BeyondHD.cs +++ b/src/Jackett/Indexers/BeyondHD.cs @@ -56,7 +56,7 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { List releases = new List(); @@ -105,7 +105,7 @@ namespace Jackett.Indexers OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/BitHdtv.cs b/src/Jackett/Indexers/BitHdtv.cs index c64af764f..199754edf 100644 --- a/src/Jackett/Indexers/BitHdtv.cs +++ b/src/Jackett/Indexers/BitHdtv.cs @@ -61,10 +61,9 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { - List releases = new List(); - + var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString); var results = await RequestStringWithCookies(episodeSearchUrl); @@ -107,7 +106,7 @@ namespace Jackett.Indexers OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/BitMeTV.cs b/src/Jackett/Indexers/BitMeTV.cs index bb1b981ce..8de331ef3 100644 --- a/src/Jackett/Indexers/BitMeTV.cs +++ b/src/Jackett/Indexers/BitMeTV.cs @@ -74,10 +74,9 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { - List releases = new List(); - + var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format("{0}?search={1}&cat=0", SearchUrl, HttpUtility.UrlEncode(searchString)); var results = await RequestStringWithCookies(episodeSearchUrl); @@ -129,7 +128,7 @@ namespace Jackett.Indexers OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/FrenchTorrentDb.cs b/src/Jackett/Indexers/FrenchTorrentDb.cs index 698250440..e435cb0f5 100644 --- a/src/Jackett/Indexers/FrenchTorrentDb.cs +++ b/src/Jackett/Indexers/FrenchTorrentDb.cs @@ -55,7 +55,7 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { List releases = new List(); @@ -94,7 +94,7 @@ namespace Jackett.Indexers OnParseError(response.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/Freshon.cs b/src/Jackett/Indexers/Freshon.cs index 697eb9f8e..f936046f6 100644 --- a/src/Jackett/Indexers/Freshon.cs +++ b/src/Jackett/Indexers/Freshon.cs @@ -65,10 +65,9 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { - List releases = new List(); - + var releases = new List(); string episodeSearchUrl; if (string.IsNullOrEmpty(query.SanitizedSearchTerm)) @@ -125,7 +124,7 @@ namespace Jackett.Indexers OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/HDSpace.cs b/src/Jackett/Indexers/HDSpace.cs index e942726dc..82f7bfb0c 100644 --- a/src/Jackett/Indexers/HDSpace.cs +++ b/src/Jackett/Indexers/HDSpace.cs @@ -62,10 +62,9 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { - List releases = new List(); - + var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var response = await RequestStringWithCookies(episodeSearchUrl); @@ -117,7 +116,7 @@ namespace Jackett.Indexers { OnParseError(results, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/HDTorrents.cs b/src/Jackett/Indexers/HDTorrents.cs index 053c38998..2d25b7686 100644 --- a/src/Jackett/Indexers/HDTorrents.cs +++ b/src/Jackett/Indexers/HDTorrents.cs @@ -59,11 +59,10 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { var releases = new List(); var searchurls = new List(); - var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim())); var results = await RequestStringWithCookies(searchUrl); @@ -132,7 +131,7 @@ namespace Jackett.Indexers OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/IIndexer.cs b/src/Jackett/Indexers/IIndexer.cs index dc92bc3be..c768591eb 100644 --- a/src/Jackett/Indexers/IIndexer.cs +++ b/src/Jackett/Indexers/IIndexer.cs @@ -31,7 +31,9 @@ namespace Jackett.Indexers // Called on startup when initializing indexers from saved configuration void LoadFromSavedConfiguration(JToken jsonConfig); - Task PerformQuery(TorznabQuery query); + Task> PerformQuery(TorznabQuery query); + + IEnumerable FilterResults(TorznabQuery query, IEnumerable input); Task Download(Uri link); } diff --git a/src/Jackett/Indexers/IPTorrents.cs b/src/Jackett/Indexers/IPTorrents.cs index 6cc8dd13c..3ec755e94 100644 --- a/src/Jackett/Indexers/IPTorrents.cs +++ b/src/Jackett/Indexers/IPTorrents.cs @@ -30,7 +30,7 @@ namespace Jackett.Indexers client: wc, logger: l) { - TorznabCaps.Categories.Add(new TorznabCategory { ID = "5070", Name = "TV/Anime" }); + TorznabCaps.Categories.Add(TorznabCatType.Anime); } public Task GetConfigurationForSetup() @@ -67,7 +67,7 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); @@ -134,7 +134,7 @@ namespace Jackett.Indexers OnParseError(results, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/ImmortalSeed.cs b/src/Jackett/Indexers/ImmortalSeed.cs new file mode 100644 index 000000000..060b17820 --- /dev/null +++ b/src/Jackett/Indexers/ImmortalSeed.cs @@ -0,0 +1,156 @@ +using CsQuery; +using Jackett.Models; +using Jackett.Services; +using Jackett.Utils; +using Jackett.Utils.Clients; +using Newtonsoft.Json.Linq; +using NLog; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Web; + +namespace Jackett.Indexers +{ + public class ImmortalSeed : BaseIndexer, IIndexer + { + private string BrowsePage { get { return SiteLink + "browse.php"; } } + private string LoginUrl { get { return SiteLink + "takelogin.php"; } } + private string QueryString { get { return "?do=search&keywords={0}&search_type=t_name&category=0&include_dead_torrents=no"; } } + + public ImmortalSeed(IIndexerManagerService i, IWebClient wc, Logger l) + : base(name: "ImmortalSeed", + description: "ImmortalSeed", + link: "http://immortalseed.me/", + caps: TorznabCapsUtil.CreateDefaultTorznabTVCaps(), + manager: i, + client: wc, + logger: l) + { + AddCategoryMapping(32, TorznabCatType.Anime); + AddCategoryMapping(47, TorznabCatType.TVSD); + AddCategoryMapping(8, TorznabCatType.TVHD); + AddCategoryMapping(48, TorznabCatType.TVHD); + AddCategoryMapping(9, TorznabCatType.TVSD); + AddCategoryMapping(4, TorznabCatType.TVHD); + AddCategoryMapping(6, TorznabCatType.TVSD); + + AddCategoryMapping(22, TorznabCatType.Books); + AddCategoryMapping(41, TorznabCatType.Comic); + AddCategoryMapping(23, TorznabCatType.Apps); + + AddCategoryMapping(16, TorznabCatType.MoviesHD); + AddCategoryMapping(17, TorznabCatType.MoviesSD); + AddCategoryMapping(14, TorznabCatType.MoviesSD); + AddCategoryMapping(34, TorznabCatType.MoviesForeign); + AddCategoryMapping(18, TorznabCatType.MoviesForeign); + AddCategoryMapping(33, TorznabCatType.MoviesForeign); + + AddCategoryMapping(34, TorznabCatType.Audio); + AddCategoryMapping(37, TorznabCatType.AudioLossless); + AddCategoryMapping(35, TorznabCatType.AudioBooks); + AddCategoryMapping(36, TorznabCatType.AudioLossy); + + } + + public Task GetConfigurationForSetup() + { + return Task.FromResult(new ConfigurationDataBasicLogin()); + } + + public async Task ApplyConfiguration(JToken configJson) + { + var incomingConfig = new ConfigurationDataBasicLogin(); + incomingConfig.LoadValuesFromJson(configJson); + var pairs = new Dictionary { + { "username", incomingConfig.Username.Value }, + { "password", incomingConfig.Password.Value } + }; + var request = new Utils.Clients.WebRequest() + { + Url = LoginUrl, + Type = RequestType.POST, + Referer = SiteLink, + PostData = pairs + }; + var response = await webclient.GetString(request); + CQ splashDom = response.Content; + var link = splashDom[".trow2 a"].First(); + var resultPage = await RequestStringWithCookies(link.Attr("href"), response.Cookies); + CQ resultDom = resultPage.Content; + + ConfigureIfOK(response.Cookies, resultPage.Content.Contains("/logout.php"), () => + { + var tries = resultDom["#main tr:eq(1) td font"].First().Text(); + var errorMessage = "Incorrect username or password! " + tries + " tries remaining."; + throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)incomingConfig); + }); + } + + public async Task> PerformQuery(TorznabQuery query) + { + var releases = new List(); + var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); + var searchUrl = BrowsePage; + + if (!string.IsNullOrWhiteSpace(searchString)) + { + searchUrl += string.Format(QueryString, HttpUtility.UrlEncode(searchString)); + } + + var results = await RequestStringWithCookies(searchUrl); + + try + { + CQ dom = results.Content; + + var rows = dom["#sortabletable tr"]; + foreach (var row in rows.Skip(1)) + { + var release = new ReleaseInfo(); + var qRow = row.Cq(); + release.Title = qRow.Find(".tooltip-content div").First().Text(); + release.Description = qRow.Find(".tooltip-content div").Get(1).InnerText.Trim(); + + var qLink = row.Cq().Find("td:eq(2) a:eq(1)"); + release.Link = new Uri(qLink.Attr("href")); + release.Guid = release.Link; + release.Comments = new Uri(qRow.Find(".tooltip-target a").First().Attr("href")); + + // 07-22-2015 11:08 AM + var dateString = qRow.Find("td:eq(1) div").Last().Children().Remove().End().Text().Trim(); + release.PublishDate = DateTime.ParseExact(dateString, "MM-dd-yyyy hh:mm tt", CultureInfo.InvariantCulture); + + var sizeStr = qRow.Find("td:eq(4)").Text().Trim(); + release.Size = ReleaseInfo.GetBytes(sizeStr); + + release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:eq(6)").Text().Trim()); + release.Peers = ParseUtil.CoerceInt(qRow.Find("td:eq(7)").Text().Trim()) + release.Seeders; + + var catLink = row.Cq().Find("td:eq(0) a").First().Attr("href"); + var catSplit = catLink.IndexOf("category="); + if (catSplit > -1) + { + catLink = catLink.Substring(catSplit + 9); + } + + release.Category = MapTrackerCatToNewznab(catLink); + releases.Add(release); + } + } + catch (Exception ex) + { + OnParseError(results.Content, ex); + } + + return releases; + } + + + } +} diff --git a/src/Jackett/Indexers/MoreThanTV.cs b/src/Jackett/Indexers/MoreThanTV.cs index 23039992d..0622374b6 100644 --- a/src/Jackett/Indexers/MoreThanTV.cs +++ b/src/Jackett/Indexers/MoreThanTV.cs @@ -72,10 +72,9 @@ namespace Jackett.Indexers release.Link = new Uri(DownloadUrl + id); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { - List releases = new List(); - + var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString); WebClientStringResult response = null; @@ -136,7 +135,7 @@ namespace Jackett.Indexers OnParseError(response.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/Pretome.cs b/src/Jackett/Indexers/Pretome.cs index 671498464..ced0ee55f 100644 --- a/src/Jackett/Indexers/Pretome.cs +++ b/src/Jackett/Indexers/Pretome.cs @@ -69,10 +69,9 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { - List releases = new List(); - + var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); @@ -119,7 +118,7 @@ namespace Jackett.Indexers { OnParseError(response.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/PrivateHD.cs b/src/Jackett/Indexers/PrivateHD.cs index e895bba23..a8fb3caad 100644 --- a/src/Jackett/Indexers/PrivateHD.cs +++ b/src/Jackett/Indexers/PrivateHD.cs @@ -61,10 +61,9 @@ namespace Jackett.Indexers return Task.FromResult(new ConfigurationDataBasicLogin()); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { - List releases = new List(); - + var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); @@ -106,7 +105,7 @@ namespace Jackett.Indexers { OnParseError(response.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/Rarbg.cs b/src/Jackett/Indexers/Rarbg.cs index f60f31d1c..9ec9cf48f 100644 --- a/src/Jackett/Indexers/Rarbg.cs +++ b/src/Jackett/Indexers/Rarbg.cs @@ -71,12 +71,12 @@ namespace Jackett.Indexers return (string)obj["token"]; } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { return await PerformQuery(query, BaseUrl); } - async Task PerformQuery(TorznabQuery query, string baseUrl) + async Task> PerformQuery(TorznabQuery query, string baseUrl) { var releases = new List(); string token = await GetToken(baseUrl); @@ -109,7 +109,7 @@ namespace Jackett.Indexers { OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } public override Task Download(Uri link) diff --git a/src/Jackett/Indexers/SceneAccess.cs b/src/Jackett/Indexers/SceneAccess.cs index a3752c409..7b8062154 100644 --- a/src/Jackett/Indexers/SceneAccess.cs +++ b/src/Jackett/Indexers/SceneAccess.cs @@ -57,7 +57,7 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); @@ -104,7 +104,7 @@ namespace Jackett.Indexers OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/SceneTime.cs b/src/Jackett/Indexers/SceneTime.cs index fc3405b99..af3f16f2d 100644 --- a/src/Jackett/Indexers/SceneTime.cs +++ b/src/Jackett/Indexers/SceneTime.cs @@ -66,7 +66,7 @@ namespace Jackett.Indexers }; } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); @@ -111,7 +111,7 @@ namespace Jackett.Indexers { OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/ShowRSS.cs b/src/Jackett/Indexers/ShowRSS.cs index 84aad0787..8443fa6bd 100644 --- a/src/Jackett/Indexers/ShowRSS.cs +++ b/src/Jackett/Indexers/ShowRSS.cs @@ -45,7 +45,7 @@ namespace Jackett.Indexers var formattedUrl = config.GetFormattedHostUrl(); var releases = await PerformQuery(new TorznabQuery(), formattedUrl); - if (releases.Length == 0) + if (releases.Count() == 0) throw new Exception("Could not find releases from this URL"); BaseUrl = formattedUrl; @@ -62,7 +62,7 @@ namespace Jackett.Indexers IsConfigured = true; } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { return await PerformQuery(query, BaseUrl); } @@ -72,7 +72,7 @@ namespace Jackett.Indexers throw new NotImplementedException(); } - async Task PerformQuery(TorznabQuery query, string baseUrl) + async Task> PerformQuery(TorznabQuery query, string baseUrl) { var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); @@ -97,7 +97,9 @@ namespace Jackett.Indexers release.Title = serie_title; release.Comments = new Uri(node.SelectSingleNode("link").InnerText); - release.Category = node.SelectSingleNode("title").InnerText; + int category = 0; + int.TryParse(node.SelectSingleNode("title").InnerText, out category); + release.Category = category; var test = node.SelectSingleNode("enclosure"); release.Guid = new Uri(test.Attributes["url"].Value); release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture); @@ -116,7 +118,7 @@ namespace Jackett.Indexers OnParseError(result.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/SpeedCD.cs b/src/Jackett/Indexers/SpeedCD.cs index 47d8a76cc..9873f1206 100644 --- a/src/Jackett/Indexers/SpeedCD.cs +++ b/src/Jackett/Indexers/SpeedCD.cs @@ -60,7 +60,7 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { var releases = new List(); var formData = HttpUtility.ParseQueryString(SearchFormData); @@ -101,7 +101,7 @@ namespace Jackett.Indexers { OnParseError(response.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/Strike.cs b/src/Jackett/Indexers/Strike.cs index 1dea1605b..e3937744f 100644 --- a/src/Jackett/Indexers/Strike.cs +++ b/src/Jackett/Indexers/Strike.cs @@ -56,7 +56,7 @@ namespace Jackett.Indexers IsConfigured = !string.IsNullOrEmpty(baseUrl); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { List releases = new List(); @@ -105,7 +105,7 @@ namespace Jackett.Indexers OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } public override Task Download(Uri link) diff --git a/src/Jackett/Indexers/T411.cs b/src/Jackett/Indexers/T411.cs index 797ecdcd4..17b2a6d67 100644 --- a/src/Jackett/Indexers/T411.cs +++ b/src/Jackett/Indexers/T411.cs @@ -118,10 +118,9 @@ namespace Jackett.Indexers IsConfigured = true; } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { - List releases = new List(); - + var releases = new List(); var searchTerm = string.IsNullOrEmpty(query.SanitizedSearchTerm) ? "%20" : query.SanitizedSearchTerm; var searchString = searchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); @@ -166,7 +165,7 @@ namespace Jackett.Indexers { OnParseError(results, ex); } - return releases.ToArray(); + return releases; } public override async Task Download(Uri link) diff --git a/src/Jackett/Indexers/ThePirateBay.cs b/src/Jackett/Indexers/ThePirateBay.cs index 598022251..c854b7ec0 100644 --- a/src/Jackett/Indexers/ThePirateBay.cs +++ b/src/Jackett/Indexers/ThePirateBay.cs @@ -48,7 +48,7 @@ namespace Jackett.Indexers var formattedUrl = config.GetFormattedHostUrl(); var releases = await PerformQuery(new TorznabQuery(), formattedUrl); - if (releases.Length == 0) + if (releases.Count() == 0) throw new Exception("Could not find releases from this URL"); BaseUrl = formattedUrl; @@ -65,12 +65,12 @@ namespace Jackett.Indexers IsConfigured = true; } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { return await PerformQuery(query, BaseUrl); } - async Task PerformQuery(TorznabQuery query, string baseUrl) + async Task> PerformQuery(TorznabQuery query, string baseUrl) { var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); diff --git a/src/Jackett/Indexers/TorrentDay.cs b/src/Jackett/Indexers/TorrentDay.cs index 529c814a6..5f850cfbc 100644 --- a/src/Jackett/Indexers/TorrentDay.cs +++ b/src/Jackett/Indexers/TorrentDay.cs @@ -63,7 +63,7 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); @@ -103,7 +103,7 @@ namespace Jackett.Indexers { OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/TorrentLeech.cs b/src/Jackett/Indexers/TorrentLeech.cs index 131bc3e52..b0ecae6bb 100644 --- a/src/Jackett/Indexers/TorrentLeech.cs +++ b/src/Jackett/Indexers/TorrentLeech.cs @@ -59,10 +59,9 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { - List releases = new List(); - + var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var results = await RequestStringWithCookies(episodeSearchUrl); @@ -111,7 +110,7 @@ namespace Jackett.Indexers OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/TorrentShack.cs b/src/Jackett/Indexers/TorrentShack.cs index a01aa47fb..c8b04c45e 100644 --- a/src/Jackett/Indexers/TorrentShack.cs +++ b/src/Jackett/Indexers/TorrentShack.cs @@ -61,7 +61,7 @@ namespace Jackett.Indexers }); } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); @@ -99,7 +99,7 @@ namespace Jackett.Indexers { OnParseError(results.Content, ex); } - return releases.ToArray(); + return releases; } } } diff --git a/src/Jackett/Indexers/Torrentz.cs b/src/Jackett/Indexers/Torrentz.cs index da7b6f57d..365db306a 100644 --- a/src/Jackett/Indexers/Torrentz.cs +++ b/src/Jackett/Indexers/Torrentz.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using System.Web; using System.Windows.Forms; using System.Xml; +using System.Linq; namespace Jackett.Indexers { @@ -43,8 +44,8 @@ namespace Jackett.Indexers config.LoadValuesFromJson(configJson); var formattedUrl = config.GetFormattedHostUrl(); - var releases = await PerformQuery(new TorznabQuery(), formattedUrl); - if (releases.Length == 0) + IEnumerable releases = await PerformQuery(new TorznabQuery(), formattedUrl); + if (releases.Count() == 0) throw new Exception("Could not find releases from this URL"); BaseUrl = formattedUrl; @@ -52,10 +53,9 @@ namespace Jackett.Indexers configSaveData["base_url"] = BaseUrl; SaveConfig(configSaveData); IsConfigured = true; - } - async Task PerformQuery(TorznabQuery query, string baseUrl) + async Task> PerformQuery(TorznabQuery query, string baseUrl) { var releases = new List(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); @@ -82,7 +82,9 @@ namespace Jackett.Indexers release.Title = serie_title; release.Comments = new Uri(node.SelectSingleNode("link").InnerText); - release.Category = node.SelectSingleNode("category").InnerText; + int category = 0; + int.TryParse(node.SelectSingleNode("category").InnerText, out category); + release.Category = category; release.Guid = new Uri(node.SelectSingleNode("guid").InnerText); release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture); @@ -101,7 +103,7 @@ namespace Jackett.Indexers OnParseError(xml, ex); } - return releases.ToArray(); + return releases; } @@ -111,7 +113,7 @@ namespace Jackett.Indexers IsConfigured = true; } - public async Task PerformQuery(TorznabQuery query) + public async Task> PerformQuery(TorznabQuery query) { return await PerformQuery(query, BaseUrl); } diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index 15c99e613..c3aa3e18f 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -175,6 +175,7 @@ + @@ -192,6 +193,7 @@ + @@ -199,6 +201,7 @@ + diff --git a/src/Jackett/JackettModule.cs b/src/Jackett/JackettModule.cs index 0f1978581..96d4de638 100644 --- a/src/Jackett/JackettModule.cs +++ b/src/Jackett/JackettModule.cs @@ -9,6 +9,7 @@ using Jackett.Indexers; using Jackett.Utils; using Jackett.Utils.Clients; using AutoMapper; +using Jackett.Models; namespace Jackett { @@ -58,6 +59,11 @@ namespace Jackett Mapper.CreateMap(); Mapper.CreateMap(); + + Mapper.CreateMap().AfterMap((r, t) => + { + t.CategoryDesc = TorznabCatType.GetCatDesc(r.Category); + }); } } } diff --git a/src/Jackett/Models/CategoryMapping.cs b/src/Jackett/Models/CategoryMapping.cs new file mode 100644 index 000000000..6ab314c48 --- /dev/null +++ b/src/Jackett/Models/CategoryMapping.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Jackett.Models +{ + class CategoryMapping + { + public CategoryMapping(string trackerCat, int newzCat) + { + TrackerCategory = trackerCat.ToLowerInvariant(); + NewzNabCategory = newzCat; + } + + public string TrackerCategory { get; private set; } + public int NewzNabCategory { get; private set; } + } +} diff --git a/src/Jackett/Models/ReleaseInfo.cs b/src/Jackett/Models/ReleaseInfo.cs index a12dac0bf..2e24293b3 100644 --- a/src/Jackett/Models/ReleaseInfo.cs +++ b/src/Jackett/Models/ReleaseInfo.cs @@ -16,7 +16,7 @@ namespace Jackett.Models public Uri Link { get; set; } public Uri Comments { get; set; } public DateTime PublishDate { get; set; } - public string Category { get; set; } + public int Category { get; set; } public long? Size { get; set; } public string Description { get; set; } public long? RageID { get; set; } diff --git a/src/Jackett/Models/ResultPage.cs b/src/Jackett/Models/ResultPage.cs index fe238e225..7593ea0b6 100644 --- a/src/Jackett/Models/ResultPage.cs +++ b/src/Jackett/Models/ResultPage.cs @@ -63,8 +63,6 @@ namespace Jackett.Models new XElement("link", ChannelInfo.ImageLink.ToString()), new XElement("description", ChannelInfo.ImageDescription) ), - - from r in Releases select new XElement("item", new XElement("title", r.Title), @@ -74,7 +72,7 @@ namespace Jackett.Models r.Size == null ? null : new XElement("size", r.Size), new XElement("description", r.Description), new XElement("link", r.Link ?? r.MagnetUri), - r.Category == null ? null : new XElement("category", r.Category), + r.Category == 0 ? null : new XElement("category", r.Category), new XElement( "enclosure", new XAttribute("url", r.Link ?? r.MagnetUri), diff --git a/src/Jackett/Models/TorznabCatType.cs b/src/Jackett/Models/TorznabCatType.cs new file mode 100644 index 000000000..8270a2566 --- /dev/null +++ b/src/Jackett/Models/TorznabCatType.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Jackett.Models +{ + class TorznabCatType + { + private static Dictionary cats = new Dictionary(); + + static TorznabCatType() + { + cats.Add(5000, "TV"); + cats.Add(5030, "TV/SD"); + cats.Add(5040, "TV/HD"); + cats.Add(5070, "TV/Anime"); + cats.Add(8000, "Books"); + cats.Add(8020, "Books/Comics"); + cats.Add(4000, "PC"); + cats.Add(3030, "Audio/Audiobook"); + cats.Add(2040, "Movies/HD"); + cats.Add(2030, "Movies/SD"); + cats.Add(2010, "Movies/Foreign"); + cats.Add(3000, "Audio"); + cats.Add(3040, "Audio/Lossless"); + cats.Add(3010, "Audio/MP3"); + } + + public static bool QueryContainsParentCategory(int[] queryCats, int releaseCat) + { + if (cats.ContainsKey(releaseCat) && queryCats!=null) + { + var ncab = cats[releaseCat]; + var split = ncab.IndexOf("/"); + if (split > -1) + { + string parentCatName = ncab.Substring(0,split); + if (cats.ContainsValue(parentCatName)) + { + var parentCat = cats.Where(c => c.Value == parentCatName).First().Key; + return queryCats.Contains(parentCat); + } + } + } + + return false; + } + + public static string GetCatDesc(int newznabcat) + { + if (cats.ContainsKey(newznabcat)) + { + return cats[newznabcat]; + } + + return string.Empty; + } + + private static TorznabCategory GetCat(int id) + { + return new TorznabCategory() + { + ID = id, + Name = cats[id] + }; + } + + public static TorznabCategory Anime + { + get { return GetCat(5070); } + } + + public static TorznabCategory TV + { + get { return GetCat(5000); } + } + + public static TorznabCategory TVSD + { + get { return GetCat(5030); } + } + + public static TorznabCategory TVHD + { + get { return GetCat(5040); } + } + + public static TorznabCategory Books + { + get { return GetCat(8000); } + } + + public static TorznabCategory Comic + { + get { return GetCat(8020); } + } + + public static TorznabCategory Apps + { + get { return GetCat(4000); } + } + + public static TorznabCategory AudioBooks + { + get { return GetCat(3030); } + } + + public static TorznabCategory MoviesHD + { + get { return GetCat(2040); } + } + + public static TorznabCategory MoviesSD + { + get { return GetCat(2040); } + } + + public static TorznabCategory MoviesForeign + { + get { return GetCat(2040); } + } + + public static TorznabCategory Audio + { + get { return GetCat(3000); } + } + + public static TorznabCategory AudioLossless + { + get { return GetCat(3040); } + } + + public static TorznabCategory AudioLossy + { + get { return GetCat(3010); } + } + } +} diff --git a/src/Jackett/Models/TorznabCategory.cs b/src/Jackett/Models/TorznabCategory.cs index f1e059aa8..c65c3d784 100644 --- a/src/Jackett/Models/TorznabCategory.cs +++ b/src/Jackett/Models/TorznabCategory.cs @@ -8,7 +8,7 @@ namespace Jackett.Models { public class TorznabCategory { - public string ID { get; set; } + public int ID { get; set; } public string Name { get; set; } public List SubCategories { get; private set; } @@ -17,53 +17,5 @@ namespace Jackett.Models { SubCategories = new List(); } - - public static TorznabCategory Anime - { - get - { - return new TorznabCategory() - { - ID = "5070", - Name = "TV/Anime" - }; - } - } - - public static TorznabCategory TV - { - get - { - return new TorznabCategory() - { - ID = "5000", - Name = "TV" - }; - } - } - - public static TorznabCategory TVSD - { - get - { - return new TorznabCategory() - { - ID = "5030", - Name = "TV/SD" - }; - } - } - - public static TorznabCategory TVHD - { - get - { - return new TorznabCategory() - { - ID = "5040", - Name = "TV/HD" - }; - } - } } } diff --git a/src/Jackett/Models/TorznabQuery.cs b/src/Jackett/Models/TorznabQuery.cs index d27698517..449b3af96 100644 --- a/src/Jackett/Models/TorznabQuery.cs +++ b/src/Jackett/Models/TorznabQuery.cs @@ -12,7 +12,7 @@ namespace Jackett.Models public class TorznabQuery { public string QueryType { get; set; } - public string[] Categories { get; set; } + public int[] Categories { get; set; } public int Extended { get; set; } public string ApiKey { get; set; } public int Limit { get; set; } @@ -74,7 +74,10 @@ namespace Jackett.Models if (query["cat"] != null) { - q.Categories = query["cat"].Split(','); + q.Categories = query["cat"].Split(',').Select(s => int.Parse(s)).ToArray(); + }else + { + q.Categories = new int[0]; } if (query["extended"] != null) diff --git a/src/Jackett/Models/TrackerCacheResult.cs b/src/Jackett/Models/TrackerCacheResult.cs index 0ea9af650..13b1569e8 100644 --- a/src/Jackett/Models/TrackerCacheResult.cs +++ b/src/Jackett/Models/TrackerCacheResult.cs @@ -10,5 +10,6 @@ namespace Jackett.Models { public DateTime FirstSeen { get; set; } public string Tracker { get; set; } + public string CategoryDesc { get; set; } } } diff --git a/src/Jackett/Services/CacheService.cs b/src/Jackett/Services/CacheService.cs index 400649f38..1289a393d 100644 --- a/src/Jackett/Services/CacheService.cs +++ b/src/Jackett/Services/CacheService.cs @@ -10,7 +10,7 @@ namespace Jackett.Services { public interface ICacheService { - void CacheRssResults(string trackerId, ReleaseInfo[] releases); + void CacheRssResults(string trackerId, IEnumerable releases); List GetCachedResults(); } @@ -20,12 +20,7 @@ namespace Jackett.Services private readonly int MAX_RESULTS_PER_TRACKER = 100; private readonly TimeSpan AGE_LIMIT = new TimeSpan(2, 0, 0, 0); - static CacheService() - { - Mapper.CreateMap(); - } - - public void CacheRssResults(string trackerId, ReleaseInfo[] releases) + public void CacheRssResults(string trackerId, IEnumerable releases) { lock (cache) { diff --git a/src/Jackett/Services/IndexerManagerService.cs b/src/Jackett/Services/IndexerManagerService.cs index fe6ed4f06..28b855f43 100644 --- a/src/Jackett/Services/IndexerManagerService.cs +++ b/src/Jackett/Services/IndexerManagerService.cs @@ -77,8 +77,8 @@ namespace Jackett.Services var indexer = GetIndexer(name); var browseQuery = new TorznabQuery(); var results = await indexer.PerformQuery(browseQuery); - logger.Info(string.Format("Found {0} releases from {1}", results.Length, indexer.DisplayName)); - if (results.Length == 0) + logger.Info(string.Format("Found {0} releases from {1}", results.Count(), indexer.DisplayName)); + if (results.Count() == 0) throw new Exception("Found no results while trying to browse this tracker"); } diff --git a/src/Jackett/Utils/TorznabCapsUtil.cs b/src/Jackett/Utils/TorznabCapsUtil.cs index d9a25b23e..3dbe0db83 100644 --- a/src/Jackett/Utils/TorznabCapsUtil.cs +++ b/src/Jackett/Utils/TorznabCapsUtil.cs @@ -16,9 +16,9 @@ namespace Jackett.Utils caps.TVSearchAvailable = true; caps.SupportsTVRageSearch = false; caps.Categories.AddRange(new[] { - TorznabCategory.TV, - TorznabCategory.TVSD, - TorznabCategory.TVHD + TorznabCatType.TV, + TorznabCatType.TVSD, + TorznabCatType.TVHD }); return caps; }