From 05379494976ff69582f6ffee6d31188746587521 Mon Sep 17 00:00:00 2001 From: dandag Date: Sun, 8 Sep 2019 00:41:22 +0200 Subject: [PATCH] add Corsaro.red (#5962) --- README.md | 1 + src/Jackett.Common/Indexers/Corsarored.cs | 254 ++++++++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 src/Jackett.Common/Indexers/Corsarored.cs diff --git a/README.md b/README.md index def2cbb73..93a4b8554 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/ * BTDB * BTKitty * ConCen + * Corsaro.red * cpasbien * cpasbienClone * Demonoid diff --git a/src/Jackett.Common/Indexers/Corsarored.cs b/src/Jackett.Common/Indexers/Corsarored.cs new file mode 100644 index 000000000..c80e67f33 --- /dev/null +++ b/src/Jackett.Common/Indexers/Corsarored.cs @@ -0,0 +1,254 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Jackett.Common.Models; +using Jackett.Common.Models.IndexerConfig; +using Jackett.Common.Services.Interfaces; +using Jackett.Common.Utils; +using Jackett.Common.Utils.Clients; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NLog; +using static Jackett.Common.Models.IndexerConfig.ConfigurationData; + +namespace Jackett.Common.Indexers +{ + public class Corsarored : BaseWebIndexer + { + private string APILatest { get { return SiteLink + "api/latests"; } } + private string APISearch { get { return SiteLink + "api/search"; } } + + private Dictionary APIHeaders = new Dictionary() + { + {"Content-Type", "application/json"}, + }; + + private readonly int MAX_SEARCH_PAGE_LIMIT = 8; // 1page 25 items, 200 + + private new ConfigurationData configData + { + get { return (ConfigurationData)base.configData; } + set { base.configData = value; } + } + + public Corsarored(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + : base(name: "Corsaro.red", + description: "Italian Torrents", + link: "https://corsaro.red/", + caps: new TorznabCapabilities(), + configService: configService, + client: wc, + logger: l, + p: ps, + configData: new ConfigurationData()) + { + Encoding = Encoding.UTF8; + Language = "it-it"; + Type = "public"; + + //wc.requestDelay = 2.5; + + // TNTVillage cats + AddCategoryMapping(1, TorznabCatType.TV, "TV"); + AddCategoryMapping(2, TorznabCatType.Audio, "Music"); + AddCategoryMapping(3, TorznabCatType.BooksEbook, "Books"); + AddCategoryMapping(4, TorznabCatType.Movies, "Movies"); + AddCategoryMapping(6, TorznabCatType.PC, "Software"); + AddCategoryMapping(7, TorznabCatType.TVAnime, "Anime"); + AddCategoryMapping(8, TorznabCatType.TVAnime, "Cartoons"); + AddCategoryMapping(9, TorznabCatType.PC, "Software"); + AddCategoryMapping(10, TorznabCatType.PC0day, "Software"); + AddCategoryMapping(11, TorznabCatType.PCGames, "Games"); + AddCategoryMapping(12, TorznabCatType.Console, "Games"); + AddCategoryMapping(13, TorznabCatType.Books, "Books"); + AddCategoryMapping(14, TorznabCatType.TVDocumentary, "Documentaries"); + AddCategoryMapping(21, TorznabCatType.AudioVideo, "Music Video"); + AddCategoryMapping(22, TorznabCatType.TVSport, "Sport"); + AddCategoryMapping(23, TorznabCatType.TV, "TV"); + AddCategoryMapping(24, TorznabCatType.TV, "TV"); + AddCategoryMapping(26, TorznabCatType.Console, "Games"); + AddCategoryMapping(27, TorznabCatType.Other, "Wallpaper"); + AddCategoryMapping(29, TorznabCatType.TV, "TV Series"); + AddCategoryMapping(30, TorznabCatType.BooksComics, "Comics"); + AddCategoryMapping(31, TorznabCatType.TV, "TV"); + AddCategoryMapping(32, TorznabCatType.Console, "Games"); + AddCategoryMapping(34, TorznabCatType.AudioAudiobook, "Audiobook"); + AddCategoryMapping(35, TorznabCatType.Audio, "Music"); + AddCategoryMapping(36, TorznabCatType.Books, "Books"); + } + + public override async Task ApplyConfiguration(JToken configJson) + { + base.LoadValuesFromJson(configJson); + var releases = await PerformQuery(new TorznabQuery()); + + await ConfigureIfOK(String.Empty, releases.Count() > 0, () => + { + throw new Exception("Could not find release from this URL."); + }); + + return IndexerConfigurationStatus.Completed; + } + + private dynamic checkResponse(WebClientStringResult result) + { + try + { + dynamic json = JsonConvert.DeserializeObject(result.Content); + + if (json is JObject) + if (json["ok"] != null && ((bool)json["ok"]) == false) + throw new Exception("Server error"); + + return json; + } + catch (Exception e) + { + logger.Error("checkResponse() Error: ", e.Message); + throw new ExceptionWithConfigData(result.Content, configData); + } + } + + private async Task SendAPIRequest(List> data) + { + var jsonData = JsonConvert.SerializeObject(data); + var result = await PostDataWithCookiesAndRetry(APISearch, data, null, SiteLink, APIHeaders, null, true); + return checkResponse(result); + } + + private async Task SendAPIRequestLatest() + { + var result = await RequestStringWithCookiesAndRetry(APILatest, null, SiteLink, APIHeaders); + return checkResponse(result); + } + + protected override async Task> PerformQuery(TorznabQuery query) + { + var releases = new List(); + + var searchString = query.GetQueryString(); + var queryCollection = new List>(); + int page = 0; + + if (!string.IsNullOrWhiteSpace(searchString)) + queryCollection.Add("term", searchString); + else + { + // no term execute latest search + var result = await SendAPIRequestLatest(); + + try + { + // this time is a jarray + JArray json = (JArray)result; + + foreach (var torrent in json) + { + // add release + releases.Add(makeRelease(torrent)); + } + } + catch (Exception ex) + { + OnParseError(result.ToString(), ex); + } + + return releases; + } + + var cats = MapTorznabCapsToTrackers(query); + if (cats.Count > 0) + queryCollection.Add("category", string.Join(",", cats)); + else + queryCollection.Add("category", "0"); // set ALL category + + // lazy horrible page initialization + queryCollection.Add("page", page.ToString()); + + do + { + // update page number + queryCollection.RemoveAt(queryCollection.Count - 1); // remove last elem: page number + queryCollection.Add("page", (++page).ToString()); + + var result = await SendAPIRequest(queryCollection); + try + { + // this time is a jobject + JObject json = (JObject)result; + + if (json["results"] == null) + throw new Exception("Error invalid JSON response"); + + // check number result + if (((JArray)json["results"]).Count() == 0) + break; + + foreach (var torrent in json["results"]) + { + // add release + releases.Add( makeRelease(torrent) ); + } + } + catch (Exception ex) + { + OnParseError(result.ToString(), ex); + } + + } while (page < MAX_SEARCH_PAGE_LIMIT); + + return releases; + } + + private ReleaseInfo makeRelease(JToken torrent) + { + var release = new ReleaseInfo(); + + release.Title = (String)torrent["title"]; + + //https://corsaro.red/details/E5BB62E2E58C654F4450325046723A3F013CD7A4 + release.Comments = new Uri(SiteLink + "details/" + (string)torrent["hash"]); + release.Guid = release.Comments; + //release.Link = release.Comments; + + release.PublishDate = DateTime.Now; + if (torrent["last_updated"] != null) + release.PublishDate = DateTime.Parse((string)torrent["last_updated"]); + + // TODO: don't know how to map this cats.. + int cat = (int)torrent["category"]; + release.Category = MapTrackerCatToNewznab(cat.ToString()); + + if (torrent["size"] != null) + release.Size = (long)torrent["size"]; + + release.Grabs = (long)torrent["completed"]; + + release.Description = (string)torrent["category"] + " " + (string)torrent["description"]; + + /* + RageID = copyFrom.RageID; + Imdb = copyFrom.Imdb; + TMDb = copyFrom.TMDb; + */ + + release.Seeders = (int)torrent["seeders"]; + release.Peers = release.Seeders + (int)torrent["leechers"]; + + release.InfoHash = (string)torrent["hash"]; + release.MagnetUri = new Uri((string)torrent["magnet"]); + + /* + MinimumRatio = copyFrom.MinimumRatio; + MinimumSeedTime = copyFrom.MinimumSeedTime; + DownloadVolumeFactor = copyFrom.DownloadVolumeFactor; + UploadVolumeFactor = copyFrom.UploadVolumeFactor; + */ + + return release; + } + } +}