diff --git a/src/Jackett.Updater/Program.cs b/src/Jackett.Updater/Program.cs index e04273392..17ee4a6a7 100644 --- a/src/Jackett.Updater/Program.cs +++ b/src/Jackett.Updater/Program.cs @@ -192,6 +192,7 @@ namespace Jackett.Updater "Definitions/qctorrent.yml", "Definitions/dragonworld.yml", "Definitions/hdclub.yml", + "Definitions/polishtracker.yml", }; foreach (var oldFIle in oldFiles) diff --git a/src/Jackett/Definitions/polishtracker.yml b/src/Jackett/Definitions/polishtracker.yml deleted file mode 100644 index 4769e65a8..000000000 --- a/src/Jackett/Definitions/polishtracker.yml +++ /dev/null @@ -1,118 +0,0 @@ ---- - site: polishtracker - name: PolishTracker - language: pl-pl - type: private - encoding: UTF-8 - links: - - https://polishtracker.net/ - certificates: - - 95EAB2795D8E35A14A9B35619C2568F974AE4D95 # expired - - caps: - categorymappings: - - {id: 32, cat: PC/0day, desc: "0day"} - - {id: 21, cat: TV/Anime, desc: "Anime"} - - {id: 1, cat: PC/ISO, desc: "Apps"} - - {id: 17, cat: Console, desc: "Consoles"} - - {id: 33, cat: Movies/DVD, desc: "DVDR Custom"} - - {id: 3, cat: Books, desc: "E-Books"} - - {id: 28, cat: Movies/BluRay, desc: "Movies BDiSC"} - - {id: 20, cat: Movies/DVD, desc: "Movies DVD"} - - {id: 26, cat: Movies/HD, desc: "Movies HD"} - - {id: 19, cat: Movies/SD, desc: "Movies SD"} - - {id: 6, cat: Audio, desc: "Music"} - - {id: 24, cat: Audio/Other, desc: "Music DVD"} - - {id: 8, cat: Audio/Video, desc: "Music Video"} - - {id: 4, cat: PC/Games, desc: "PC Games"} - - {id: 29, cat: TV/SD, desc: "TV DVDRip"} - - {id: 31, cat: TV/HD, desc: "TV HD"} - - {id: 7, cat: TV/SD, desc: "TV SD"} - - {id: 9, cat: XXX, desc: "XXX"} - - - modes: - search: [q] - tv-search: [q, season, ep] - movie-search: [q] - - login: - path: login.php - method: form - cookies: ["language=1", "eid=123", "dabg=yes", "dasc=yes", "dafx=yes", "dabo=yes", "dapi=yes"] - captcha: - type: image - image: img[src^="/login.php?rand="] - input: kodzik - inputs: - username: "{{ .Config.username }}" - password: "{{ .Config.password }}" - error: - - selector: td.embedded:has(h2:contains("FAILED")) - test: - path: browse.php - selector: a[href^="logout.php?"] - - search: - path: browse.php - inputs: - search: "{{ .Query.Keywords }}" - rows: - selector: div#bro1 > table.shad1 > tbody > tr[class^="rowfx"] - error: - - selector: table.textfx2 td:contains("In order to use PolishTracker we require users to familiarize with FAQ, Rules and any News from Home Page.") - fields: - download: - selector: a[href^="/download.php/"] - attribute: href - title: - selector: a[href^="/details.php?id="] - title: - selector: a[href^="/details.php?id="][onmouseover] - optional: true - attribute: title - filters: - - name: strdump - - name: regexp - args: "(.*?)" - details: - selector: a[href^="/details.php?id="] - attribute: href - category: - selector: a[href^="browse.php?cat="] - attribute: href - filters: - - name: querystring - args: cat - imdb: - selector: a[href^="http://www.imdb.com/title/tt"] - optional: true - attribute: href - date: - selector: td:nth-child(4) - filters: - - name: append - args: " +00:00" - - name: dateparse - args: "2006-01-0215:04:05 -07:00" - seeders: - selector: td:nth-child(7) - leechers: - selector: td:nth-child(8) - grabs: - selector: td:nth-child(6) > b - size: - selector: td:nth-child(5) - remove: font - downloadvolumefactor: - case: - img[alt^="Freebie torrent."]: "0" - img[alt*="-50% download"]: "0.5" - "*": "1" - uploadvolumefactor: - case: - img[alt*="+50% upload"]: "1.5" - "*": "1" - description: - selector: td:nth-child(2) - remove: a \ No newline at end of file diff --git a/src/Jackett/Indexers/BaseIndexer.cs b/src/Jackett/Indexers/BaseIndexer.cs index af6aebddc..65a9f6bf5 100644 --- a/src/Jackett/Indexers/BaseIndexer.cs +++ b/src/Jackett/Indexers/BaseIndexer.cs @@ -24,7 +24,7 @@ namespace Jackett.Indexers } public string SiteLink { get; protected set; } - public string[] LegacySiteLinks { get; protected set; } + public virtual string[] LegacySiteLinks { get; protected set; } public string DefaultSiteLink { get; protected set; } public virtual string[] AlternativeSiteLinks { get; protected set; } = new string[] { }; public string DisplayDescription { get; protected set; } diff --git a/src/Jackett/Indexers/PolishTracker.cs b/src/Jackett/Indexers/PolishTracker.cs new file mode 100644 index 000000000..86d1fca42 --- /dev/null +++ b/src/Jackett/Indexers/PolishTracker.cs @@ -0,0 +1,201 @@ +using Jackett.Utils.Clients; +using NLog; +using Jackett.Services; +using Jackett.Utils; +using Jackett.Models; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using System.Collections.Generic; +using System; +using Jackett.Models.IndexerConfig; +using System.Collections.Specialized; +using System.Text; +using Newtonsoft.Json; +using static Jackett.Models.IndexerConfig.ConfigurationData; +using System.Globalization; + +namespace Jackett.Indexers +{ + public class PolishTracker : BaseWebIndexer + { + string LoginUrl { get { return SiteLink + "login"; } } + string TorrentApiUrl { get { return SiteLink + "apitorrents"; } } + string CDNUrl { get { return "https://cdn.pte.nu/"; } } + + public override string[] LegacySiteLinks { get; protected set; } = new string[] { + "https://polishtracker.net/", + }; + + new ConfigurationDataBasicLoginWithRSSAndDisplay configData + { + get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; } + set { base.configData = value; } + } + + public PolishTracker(IIndexerConfigurationService configService, IWebClient wc, Logger l, IProtectionService ps) + : base(name: "PolishTracker", + description: null, + link: "https://pte.nu/", + caps: new TorznabCapabilities(), + configService: configService, + client: wc, + logger: l, + p: ps, + configData: new ConfigurationDataBasicLoginWithRSSAndDisplay()) + { + Encoding = Encoding.GetEncoding("UTF-8"); + Language = "pl-pl"; + Type = "private"; + + AddCategoryMapping(1, TorznabCatType.PC0day, "0-Day"); + AddCategoryMapping(3, TorznabCatType.PC0day, "Apps"); + AddCategoryMapping(4, TorznabCatType.Console, "Consoles"); + AddCategoryMapping(5, TorznabCatType.Books, "E-book"); + AddCategoryMapping(6, TorznabCatType.MoviesHD, "Movies HD"); + AddCategoryMapping(7, TorznabCatType.MoviesSD, "Movies SD"); + AddCategoryMapping(8, TorznabCatType.Audio, "Music"); + AddCategoryMapping(9, TorznabCatType.AudioVideo, "MusicVideo"); + AddCategoryMapping(10, TorznabCatType.PCGames, "PcGames"); + AddCategoryMapping(11, TorznabCatType.TVHD, "TV HD"); + AddCategoryMapping(12, TorznabCatType.TVSD, "TV SD"); + AddCategoryMapping(13, TorznabCatType.XXX, "XXX"); + } + + public override async Task ApplyConfiguration(JToken configJson) + { + LoadValuesFromJson(configJson); + + var pairs = new Dictionary + { + { "email", configData.Username.Value }, + { "pass", configData.Password.Value } + }; + var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, SiteLink); + + await ConfigureIfOK(result.Cookies, result.Cookies != null && result.Cookies.Contains("id="), () => + { + var errorMessage = result.Content; + throw new ExceptionWithConfigData(errorMessage, configData); + }); + return IndexerConfigurationStatus.RequiresTesting; + } + + protected override async Task> PerformQuery(TorznabQuery query) + { + var releases = new List(); + + var searchUrl = TorrentApiUrl; + var searchString = query.GetQueryString(); + var queryCollection = new NameValueCollection(); + queryCollection.Add("tpage", "1"); + foreach (var cat in MapTorznabCapsToTrackers(query)) + { + queryCollection.Add("cat[]", cat); + } + + if (!string.IsNullOrWhiteSpace(searchString)) + queryCollection.Add("search", searchString); + + var cats = MapTorznabCapsToTrackers(query); + if (cats.Count > 0) + queryCollection.Add("cats", string.Join(",", cats)); + + searchUrl += "?" + queryCollection.GetQueryString(); + + var result = await RequestStringWithCookiesAndRetry(searchUrl, null, TorrentApiUrl); + if (result.IsRedirect) + { + // re-login + await ApplyConfiguration(null); + result = await RequestStringWithCookiesAndRetry(searchUrl, null, TorrentApiUrl); + } + + if (!result.Content.StartsWith("{")) // not JSON => error + throw new ExceptionWithConfigData(result.Content, configData); + dynamic json = JsonConvert.DeserializeObject(result.Content); + try + { + dynamic torrents = json["torrents"]; // latest torrents + + if (json["hits"] != null) // is search result + torrents = json.SelectTokens("$.hits[?(@._type == 'torrent')]._source"); + /* + { + "id":426868, + "name":"Realease-nameE", + "size":"2885494332", + "category":11, + "added":"2017-09-11T11:36:26.936Z", + "comments":0, + "leechers":0, + "seeders":1, + "completed":0, + "poster":true, + "imdb_id":"3743822", + "cdu_id":null, + "steam_id":null, + "subs":null, + "language":"en" + }, + */ + + + foreach (var torrent in torrents) + { + var release = new ReleaseInfo(); + var descriptions = new List(); + release.MinimumRatio = 1; + release.MinimumSeedTime = 0; + + release.Category = MapTrackerCatToNewznab(torrent.category.ToString()); + release.Title = torrent.name.ToString(); + var torrentID = (long)torrent.id; + release.Comments = new Uri(SiteLink + "torrents/" + torrentID); + release.Guid = release.Comments; + release.Link = new Uri(SiteLink + "download/" + torrentID); + var date = (DateTime)torrent.added; + release.PublishDate = date; + release.Size = ParseUtil.CoerceLong(torrent.size.ToString()); + release.Seeders = (int)torrent.seeders; + release.Peers = release.Seeders + (int)torrent.leechers; + var imdbid = torrent.imdb_id.ToString(); + if (!string.IsNullOrEmpty(imdbid)) + release.Imdb = ParseUtil.CoerceLong(imdbid); + + if ((bool)torrent.poster == true) + { + if (release.Imdb != null) + release.BannerUrl = new Uri(CDNUrl + "images/torrents/poster/imd/l/" + imdbid + ".jpg"); + else if (torrent["cdu_id"] != null) + release.BannerUrl = new Uri(CDNUrl + "images/torrents/poster/cdu/b/" + torrent["cdu_id"] + "_front.jpg"); + else if (torrent["steam_id"] != null) + release.BannerUrl = new Uri(CDNUrl + "images/torrents/poster/ste/l/" + torrent["steam_id"] + ".jpg"); + } + + release.UploadVolumeFactor = 1; + release.DownloadVolumeFactor = 1; + + release.Grabs = (long)torrent.completed; + + var language = (string)torrent.language; + if (!string.IsNullOrEmpty(language)) + descriptions.Add("Language: " + language); + else if ((bool?)torrent.polish == true) + descriptions.Add("Language: pl"); + + if (descriptions.Count > 0) + release.Description = string.Join("
\n", descriptions); + + releases.Add(release); + } + } + catch (Exception ex) + { + OnParseError(result.ToString(), ex); + } + + return releases; + } + } +} + diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index 51f9ad0b6..c32e0d7bb 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -183,6 +183,7 @@ + @@ -442,7 +443,436 @@ PreserveNewest - + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + PreserveNewest