diff --git a/src/Jackett.Common/Definitions/icetorrent.yml b/src/Jackett.Common/Definitions/icetorrent.yml deleted file mode 100644 index aa2f08dc7..000000000 --- a/src/Jackett.Common/Definitions/icetorrent.yml +++ /dev/null @@ -1,186 +0,0 @@ ---- -id: icetorrent -name: ICE Torrent -description: "ICE Torrent is a ratioless ROMANIAN Private Torrent Tracker for 0DAY / GENERAL" -language: ro-ro -type: private -encoding: UTF-8 -links: - - https://icetorrent.org/ -legacylinks: - - https://www.icetorrent.org/ - -caps: - categorymappings: - - {id: 38, cat: Movies, desc: "Movie Packs"} - - {id: 10, cat: Movies/SD, desc: "Movies: SD"} - - {id: 35, cat: Movies/SD, desc: "Movies: SD Ro"} - - {id: 8, cat: Movies/HD, desc: "Movies: HD"} - - {id: 29, cat: Movies/HD, desc: "Movies: HD Ro"} - - {id: 7, cat: Movies/DVD, desc: "Movies: DVD"} - - {id: 2, cat: Movies/DVD, desc: "Movies: DVD Ro"} - - {id: 17, cat: Movies/BluRay, desc: "Movies: BluRay"} - - {id: 24, cat: Movies/BluRay, desc: "Movies: BluRay Ro"} - - {id: 59, cat: Movies, desc: "Movies: Ro"} - - {id: 57, cat: Movies/UHD, desc: "Movies: 4K (2160p) Ro"} - - {id: 61, cat: Movies/UHD, desc: "Movies: 4K (2160p)"} - - {id: 41, cat: TV, desc: "TV Packs"} - - {id: 66, cat: TV, desc: "TV Packs Ro"} - - {id: 45, cat: TV, desc: "TV Episodes"} - - {id: 46, cat: TV, desc: "TV Episodes Ro"} - - {id: 43, cat: TV/HD, desc: "TV Episodes HD"} - - {id: 44, cat: TV/HD, desc: "TV Episodes HD Ro"} - - {id: 60, cat: TV, desc: "TV Ro"} - - {id: 11, cat: PC/Games, desc: "Games: PC-ISO"} - - {id: 52, cat: Console, desc: "Games: Console"} - - {id: 1, cat: PC/0day, desc: "Applications"} - - {id: 14, cat: PC, desc: "Applications: Linux"} - - {id: 37, cat: PC/Mac, desc: "Applications: Mac"} - - {id: 19, cat: PC/Phone-Other, desc: "Applications: Mobile"} - - {id: 62, cat: TV, desc: "TV Cartoons"} - - {id: 3, cat: TV/Anime, desc: "TV Anime / Hentai"} - - {id: 6, cat: Books/Ebook, desc: "E-books"} - - {id: 5, cat: Audio, desc: "Music"} - - {id: 64, cat: Audio/Video, desc: "Music Video"} - - {id: 18, cat: Other, desc: "Images"} - - {id: 22, cat: TV/Sport, desc: "TV Sports"} - - {id: 58, cat: TV/Sport, desc: "TV Sports Ro"} - - {id: 9, cat: TV/Documentary, desc: "TV Documentary"} - - {id: 63, cat: TV/Documentary, desc: "TV Documentary Ro"} - - {id: 65, cat: Other, desc: "Tutorial"} - - {id: 67, cat: Other, desc: "Miscellaneous"} - - {id: 15, cat: XXX, desc: "XXX Movies"} - - {id: 47, cat: XXX, desc: "XXX DVD"} - - {id: 48, cat: XXX, desc: "XXX HD"} - - {id: 49, cat: XXX, desc: "XXX Images"} - - {id: 50, cat: XXX, desc: "XXX Packs"} - - {id: 51, cat: XXX, desc: "XXX SD"} - - modes: - search: [q, imdbid] - tv-search: [q, season, ep, imdbid] - movie-search: [q, imdbid] - music-search: [q] - -settings: - - name: username - type: text - label: Username - - name: password - type: password - label: Password - - name: sort - type: select - label: Sort requested from site - default: "refreshAt" - options: - "refreshAt": "created" - "seeders": "seeders" - "size": "size" - - name: type - type: select - label: Order requested from site - default: "desc" - options: - "desc": "desc" - "asc": "asc" - - name: browseadult - type: checkbox - label: Use the Adult search engine - default: false - - name: info_browseadult - type: info - label: "About the Adult search engine" - default: "The Adult search engine only returns Adult category results.
And Vice Versa." - - name: info_Search - type: info - label: "About Search results" - default: "This indexer supports only the English language. Choosing non-English languages will cause incorrect dates to be returned.
For best results edit your profile and set your Torrents per page to 100. The Default is 50." - -login: - path: login - method: form - form: form - inputs: - username: "{{ .Config.username }}" - password: "{{ .Config.password }}" - _remember_me: on - selectorinputs: - _csrf_token: - selector: input[name="_csrf_token"] - attribute: value - error: - - selector: span:contains("Error") - - selector: div.alert:contains("failed") - test: - path: / - selector: a[href*="/logout?_csrf_token="] - -ratio: - text: -1 - -search: - paths: - # https://icetorrent.org/browse?search=&submit=&sort=torrent.size&direction=desc&page=1 - - path: "{{ if .Config.browseadult }}adult{{else}}browse{{end}}" - inputs: - $raw: "{{ range .Categories }}categories[]={{.}}&{{end}}" - search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}" - sort: "torrent.{{ .Config.sort }}" - direction: "{{ .Config.type }}" - - rows: - selector: div.kt-portlet--mobile > div.kt-portlet__body--fit > div.mr-0 - - fields: - category: - selector: a[href^="/browse?categories"] - attribute: href - filters: - - name: regexp - args: (\d+)$ - title: - selector: a[href^="/browse/"] - details: - selector: a[href^="/browse/"] - attribute: href - download: - selector: a[href^="/torrents/"] - attribute: href - imdb: - optional: true - selector: a[href*="imdb.com/title/tt"] - attribute: href - date: - selector: div[data-toggle="kt-tooltip"] - attribute: title - filters: - - name: dateparse - args: "Jan 2, 2006, 3:04:05 PM" - size: - selector: div[data-toggle="kt-tooltip"] + div + div - grabs: - selector: div[data-toggle="kt-tooltip"] + div - filters: - - name: regexp - args: (\d+) - seeders: - selector: div[data-toggle="kt-tooltip"] + div + div + div > div div:nth-child(1) - filters: - - name: regexp - args: (\d+) - leechers: - selector: div[data-toggle="kt-tooltip"] + div + div + div > div div:nth-child(2) - filters: - - name: regexp - args: (\d+) - downloadvolumefactor: - case: - "span.kt-badge--success:contains(\"free\")": 0 - "span.kt-badge--dark:contains(\"half\")": 0.5 - "*": 1 - uploadvolumefactor: - case: - "span.kt-badge--info:contains(\"double\")": 2 - "*": 1 -# engine n/a diff --git a/src/Jackett.Common/Definitions/scenefz.yml b/src/Jackett.Common/Definitions/scenefz.yml deleted file mode 100644 index 363aa8c4b..000000000 --- a/src/Jackett.Common/Definitions/scenefz.yml +++ /dev/null @@ -1,165 +0,0 @@ ---- -id: scenefz -name: SceneFZ -description: "SceneFZ is a ratioless ROMANIAN Private Torrent Tracker for MOVIES / TV / GENERAL" -language: ro-ro -type: private -encoding: UTF-8 -links: - - https://scenefz.me/ -legacylinks: - - https://www.scenefz.me/ - - https://www.u-torrents.ro/ - -caps: - categorymappings: - - {id: 62, cat: TV, desc: "Cartoons"} - - {id: 3, cat: TV/Anime, desc: "Anime/Hentai"} - - {id: 1, cat: PC/0day, desc: "Appz"} - - {id: 9, cat: TV/Documentary, desc: "Documentary"} - - {id: 63, cat: TV/Documentary, desc: "Documentary-RO"} - - {id: 6, cat: Books, desc: "eBooks"} - - {id: 52, cat: Console, desc: "Games-Console"} - - {id: 11, cat: PC/Games, desc: "Games-PC"} - - {id: 18, cat: Other, desc: "Images"} - - {id: 65, cat: Other, desc: "Tutorial"} - - {id: 14, cat: PC, desc: "Linux"} - - {id: 37, cat: PC/Mac, desc: "Mac"} - - {id: 19, cat: PC/Phone-Other, desc: "Mobile"} - - {id: 17, cat: Movies/BluRay, desc: "Movies-BluRay"} - - {id: 24, cat: Movies/BluRay, desc: "Movies-BluRayRO"} - - {id: 7, cat: Movies/DVD, desc: "Movies-DVD"} - - {id: 2, cat: Movies/DVD, desc: "Movies-DVD-RO"} - - {id: 8, cat: Movies/HD, desc: "Movies-HD"} - - {id: 29, cat: Movies/HD, desc: "Movies-HD-RO"} - - {id: 59, cat: Movies/Foreign, desc: "Movies-RO"} - - {id: 57, cat: Movies/UHD, desc: "Movies-UHD-RO"} - - {id: 61, cat: Movies/UHD, desc: "Movies-UHD"} - - {id: 38, cat: Movies, desc: "Movies-Packs"} - - {id: 10, cat: Movies/SD, desc: "Movies-SD"} - - {id: 35, cat: Movies/SD, desc: "Movies-SD-RO"} - - {id: 5, cat: Audio, desc: "Music"} - - {id: 64, cat: Audio/Video, desc: "Music Videos"} - - {id: 22, cat: TV/Sport, desc: "Sport"} - - {id: 58, cat: TV/Sport, desc: "Sports-RO"} - - {id: 43, cat: TV/HD, desc: "TV-HD"} - - {id: 44, cat: TV/HD, desc: "TV-HD-RO"} - - {id: 41, cat: TV, desc: "TV-Packs"} - - {id: 45, cat: TV/SD, desc: "TV-SD"} - - {id: 46, cat: TV/SD, desc: "TV-SD-RO"} - - {id: 60, cat: TV/FOREIGN, desc: "TV-RO"} - - {id: 66, cat: TV/FOREIGN, desc: "TV-Packs-RO"} - - {id: 15, cat: XXX, desc: "XXX"} - - {id: 47, cat: XXX, desc: "XXX-DVD"} - - {id: 48, cat: XXX, desc: "XXX-HD"} - - {id: 49, cat: XXX/Imageset, desc: "XXX-IMGSet"} - - {id: 50, cat: XXX, desc: "XXX-Packs"} - - {id: 51, cat: XXX, desc: "XXX-SD"} - - modes: - search: [q, imdbid] - tv-search: [q, season, ep, imdbid] - movie-search: [q, imdbid] - music-search: [q] - -settings: - - name: username - type: text - label: Username - - name: password - type: password - label: Password - - name: sort - type: select - label: Sort requested from site - default: "torrent.refreshAt" - options: - "torrent.refreshAt": "created" - "torrent.seeders": "seeders" - "torrent.size": "size" - - name: type - type: select - label: Order requested from site - default: "desc" - options: - "desc": "desc" - "asc": "asc" - -login: - path: login - method: form - form: form:has(input[name="_remember_me"]) - inputs: - username: "{{ .Config.username }}" - password: "{{ .Config.password }}" - _remember_me: on - error: - - selector: td.embedded:has(center > h2:contains(failed)) - - selector: span:contains("Error") - test: - path: browse - -search: - paths: - - path: browse - inputs: - $raw: "{{ range .Categories }}categories[]={{.}}&{{end}}" - search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}" - sort: "{{ .Config.sort }}" - direction: "{{ .Config.type }}" - - rows: - selector: div.kt-portlet--mobile > div.kt-portlet__body--fit > div.mr-0 - - fields: - category: - selector: a[href^="/browse?categories"] - attribute: href - filters: - - name: regexp - args: (\d+)$ - title: - selector: a[href^="/browse/"] - details: - selector: a[href^="/browse/"] - attribute: href - download: - selector: a[href^="/torrents/"] - attribute: href - imdb: - optional: true - selector: a[href*="imdb.com/title/tt"] - attribute: href - date: - selector: div[data-toggle="kt-tooltip"] - attribute: title - filters: - - name: dateparse - args: "Jan 2, 2006, 03:04:05 PM" - size: - selector: div[data-toggle="kt-tooltip"] + div + div - grabs: - selector: div[data-toggle="kt-tooltip"] + div - filters: - - name: regexp - args: (\d+) - seeders: - selector: div[data-toggle="kt-tooltip"] + div + div + div > div div:nth-child(1) - filters: - - name: regexp - args: (\d+) - leechers: - selector: div[data-toggle="kt-tooltip"] + div + div + div > div div:nth-child(2) - filters: - - name: regexp - args: (\d+) - downloadvolumefactor: - case: - "span.kt-badge--success:contains(\"free\")": 0 - "span.kt-badge--dark:contains(\"half\")": 0.5 - "*": 1 - uploadvolumefactor: - case: - "span.kt-badge--info:contains(\"double\")": 2 - "*": 1 -# engine n/a diff --git a/src/Jackett.Common/Definitions/xtremezone.yml b/src/Jackett.Common/Definitions/xtremezone.yml deleted file mode 100644 index 2d1d3b6e0..000000000 --- a/src/Jackett.Common/Definitions/xtremezone.yml +++ /dev/null @@ -1,169 +0,0 @@ ---- -id: xtremezone -name: Xtreme Zone -description: "XtreMeZone (MYXZ) is a ROMANIAN Private Torrent Tracker for MOVIES / TV / GENERAL" -language: ro-ro -type: private -encoding: UTF-8 -links: - - https://myxz.eu/ -legacylinks: - - https://www.myxz.eu/ - - https://www.myxz.org/ - -caps: - categorymappings: - - {id: 62, cat: TV, desc: "Cartoons"} - - {id: 3, cat: TV/Anime, desc: "Anime/Hentai"} - - {id: 1, cat: PC/0day, desc: "Appz"} - - {id: 9, cat: TV/Documentary, desc: "Documentary"} - - {id: 63, cat: TV/Documentary, desc: "Documentary-RO"} - - {id: 6, cat: Books, desc: "eBooks"} - - {id: 52, cat: Console, desc: "Games-Console"} - - {id: 11, cat: PC/Games, desc: "Games-PC"} - - {id: 18, cat: Other, desc: "Images"} - - {id: 65, cat: Other, desc: "Tutorial"} - - {id: 14, cat: PC, desc: "Linux"} - - {id: 37, cat: PC/Mac, desc: "Mac"} - - {id: 19, cat: PC/Phone-Other, desc: "Mobile"} - - {id: 17, cat: Movies/BluRay, desc: "Movies-BluRay"} - - {id: 24, cat: Movies/BluRay, desc: "Movies-BluRayRO"} - - {id: 7, cat: Movies/DVD, desc: "Movies-DVD"} - - {id: 2, cat: Movies/DVD, desc: "Movies-DVD-RO"} - - {id: 8, cat: Movies/HD, desc: "Movies-HD"} - - {id: 29, cat: Movies/HD, desc: "Movies-HD-RO"} - - {id: 59, cat: Movies/Foreign, desc: "Movies-RO"} - - {id: 57, cat: Movies/UHD, desc: "Movies-UHD-RO"} - - {id: 61, cat: Movies/UHD, desc: "Movies-UHD"} - - {id: 38, cat: Movies, desc: "Movies-Packs"} - - {id: 10, cat: Movies/SD, desc: "Movies-SD"} - - {id: 35, cat: Movies/SD, desc: "Movies-SD-RO"} - - {id: 5, cat: Audio, desc: "Music"} - - {id: 64, cat: Audio/Video, desc: "Music Videos"} - - {id: 22, cat: TV/Sport, desc: "Sport"} - - {id: 58, cat: TV/Sport, desc: "Sports-RO"} - - {id: 43, cat: TV/HD, desc: "TV-HD"} - - {id: 44, cat: TV/HD, desc: "TV-HD-RO"} - - {id: 41, cat: TV, desc: "TV-Packs"} - - {id: 45, cat: TV/SD, desc: "TV-SD"} - - {id: 46, cat: TV/SD, desc: "TV-SD-RO"} - - {id: 60, cat: TV/FOREIGN, desc: "TV-RO"} - - {id: 66, cat: TV/FOREIGN, desc: "TV-Packs-RO"} - - {id: 15, cat: XXX, desc: "XXX"} - - {id: 47, cat: XXX, desc: "XXX-DVD"} - - {id: 48, cat: XXX, desc: "XXX-HD"} - - {id: 49, cat: XXX/Imageset, desc: "XXX-IMGSet"} - - {id: 50, cat: XXX, desc: "XXX-Packs"} - - {id: 51, cat: XXX, desc: "XXX-SD"} - - modes: - search: [q, imdbid] - tv-search: [q, season, ep, imdbid] - movie-search: [q, imdbid] - music-search: [q] - -settings: - - name: username - type: text - label: Username - - name: password - type: password - label: Password - - name: sort - type: select - label: Sort requested from site - default: "torrent.refreshAt" - options: - "torrent.refreshAt": "created" - "torrent.seeders": "seeders" - "torrent.size": "size" - - name: type - type: select - label: Order requested from site - default: "desc" - options: - "desc": "desc" - "asc": "asc" - -login: - path: login - method: form - form: form:has(input[name="_remember_me"]) - inputs: - username: "{{ .Config.username }}" - password: "{{ .Config.password }}" - _remember_me: on - error: - - selector: td.embedded:has(center > h2:contains(failed)) - - selector: span:contains("Error") - test: - path: browse - -ratio: - path: browse - selector: font:contains("Ratio:")+font - -search: - paths: - - path: browse - inputs: - $raw: "{{ range .Categories }}categories[]={{.}}&{{end}}" - search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}" - sort: "{{ .Config.sort }}" - direction: "{{ .Config.type }}" - - rows: - selector: div.kt-portlet--mobile > div.kt-portlet__body--fit > div.mr-0 - - fields: - category: - selector: a[href^="/browse?categories"] - attribute: href - filters: - - name: regexp - args: (\d+)$ - title: - selector: a[href^="/browse/"] - details: - selector: a[href^="/browse/"] - attribute: href - download: - selector: a[href^="/torrents/"] - attribute: href - imdb: - optional: true - selector: a[href*="imdb.com/title/tt"] - attribute: href - date: - selector: div[data-toggle="kt-tooltip"] - attribute: title - filters: - - name: dateparse - args: "Jan 2, 2006, 03:04:05 PM" - size: - selector: div[data-toggle="kt-tooltip"] + div + div - grabs: - selector: div[data-toggle="kt-tooltip"] + div - filters: - - name: regexp - args: (\d+) - seeders: - selector: div[data-toggle="kt-tooltip"] + div + div + div > div div:nth-child(1) - filters: - - name: regexp - args: (\d+) - leechers: - selector: div[data-toggle="kt-tooltip"] + div + div + div > div div:nth-child(2) - filters: - - name: regexp - args: (\d+) - downloadvolumefactor: - case: - "span.kt-badge--success:contains(\"free\")": 0 - "span.kt-badge--dark:contains(\"half\")": 0.5 - "*": 1 - uploadvolumefactor: - case: - "span.kt-badge--info:contains(\"double\")": 2 - "*": 1 -# engine n/a diff --git a/src/Jackett.Common/Indexers/Abstract/XtremeZoneTracker.cs b/src/Jackett.Common/Indexers/Abstract/XtremeZoneTracker.cs new file mode 100644 index 000000000..11b6635b8 --- /dev/null +++ b/src/Jackett.Common/Indexers/Abstract/XtremeZoneTracker.cs @@ -0,0 +1,186 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq; +using System.Net; +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 Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NLog; +using WebClient = Jackett.Common.Utils.Clients.WebClient; + +namespace Jackett.Common.Indexers.Abstract +{ + [ExcludeFromCodeCoverage] + public abstract class XtremeZoneTracker : BaseWebIndexer + { + private readonly Dictionary ApiHeaders = new Dictionary + { + {"Accept", "application/json"}, + {"Content-Type", "application/json"} + }; + private string LoginUrl => SiteLink + "api/login"; + private string SearchUrl => SiteLink + "api/torrent"; + private string _token; + + private new ConfigurationDataBasicLogin configData => (ConfigurationDataBasicLogin)base.configData; + + protected XtremeZoneTracker(string link, string id, string name, string description, + IIndexerConfigurationService configService, WebClient client, Logger logger, + IProtectionService p, TorznabCapabilities caps) + : base(id: id, + name: name, + description: description, + link: link, + caps: caps, + configService: configService, + client: client, + logger: logger, + p: p, + configData: new ConfigurationDataBasicLogin()) + { + Encoding = Encoding.UTF8; + Language = "ro-ro"; + Type = "private"; + + // requestDelay for API Limit (1 request per 2 seconds) + webclient.requestDelay = 2.1; + } + + public override async Task ApplyConfiguration(JToken configJson) + { + LoadValuesFromJson(configJson); + + await RenewalTokenAsync(); + + var releases = await PerformQuery(new TorznabQuery()); + await ConfigureIfOK(string.Empty, releases.Any(), + () => throw new Exception("Could not find releases.")); + + return IndexerConfigurationStatus.Completed; + } + + private async Task RenewalTokenAsync() + { + var body = new Dictionary + { + { "username", configData.Username.Value.Trim() }, + { "password", configData.Password.Value.Trim() } + }; + var jsonData = JsonConvert.SerializeObject(body); + var result = await PostDataWithCookies(LoginUrl, null, headers: ApiHeaders, rawbody: jsonData); + var json = JObject.Parse(result.Content); + _token = json.Value("token"); + if (_token == null) + throw new Exception(json.Value("message")); + } + + protected override async Task> PerformQuery(TorznabQuery query) + { + var releases = new List(); + + //var categoryMapping = MapTorznabCapsToTrackers(query).Distinct().ToList(); + var qc = new List> // NameValueCollection don't support cat[]=19&cat[]=6 + { + {"itemsPerPage", "100"}, + {"sort", "torrent.createdAt"}, + {"direction", "desc"} + }; + + foreach (var cat in MapTorznabCapsToTrackers(query)) + qc.Add("categories[]", cat); + + if (query.IsImdbQuery) + qc.Add("imdbId", query.ImdbID); + else + qc.Add("search", query.GetQueryString()); + + if (string.IsNullOrWhiteSpace(_token)) // fist time login + await RenewalTokenAsync(); + + var searchUrl = SearchUrl + "?" + qc.GetQueryString(); + var response = await RequestStringWithCookies(searchUrl, headers: GetSearchHeaders()); + if (response.Status == HttpStatusCode.Unauthorized) + { + await RenewalTokenAsync(); // re-login + response = await RequestStringWithCookies(searchUrl, headers: GetSearchHeaders()); + } + else if (response.Status != HttpStatusCode.OK) + throw new Exception($"Unknown error in search: {response.Content}"); + + try + { + var rows = JArray.Parse(response.Content); + foreach (var row in rows) + { + var id = row.Value("id"); + var comments = new Uri($"{SiteLink}browse/{id}"); + var link = new Uri($"{SiteLink}api/torrent/{id}/download"); + var publishDate = DateTime.Parse(row.Value("created_at"), CultureInfo.InvariantCulture); + var cat = row.Value("category").Value("id"); + + // "description" field in API has too much HTML code + var description = row.Value("short_description"); + + var jBanner = row.Value("poster"); + var banner = string.IsNullOrEmpty(jBanner) ? null : new Uri(jBanner); + + var dlVolumeFactor = row.Value("is_half_download") ? 0.5: 1.0; + dlVolumeFactor = row.Value("is_freeleech") ? 0.0 : dlVolumeFactor; + var ulVolumeFactor = row.Value("is_double_upload") ? 2.0: 1.0; + + var release = new ReleaseInfo + { + Title = row.Value("name"), + Link = link, + Comments = comments, + Guid = comments, + Category = MapTrackerCatToNewznab(cat), + PublishDate = publishDate, + Description = description, + BannerUrl = banner, + Size = row.Value("size"), + Grabs = row.Value("times_completed"), + Seeders = row.Value("seeders"), + Peers = row.Value("leechers") + row.Value("seeders"), + DownloadVolumeFactor = dlVolumeFactor, + UploadVolumeFactor = ulVolumeFactor, + MinimumRatio = 1, + MinimumSeedTime = 172800 // 48 hours + }; + + releases.Add(release); + } + } + catch (Exception ex) + { + OnParseError(response.Content, ex); + } + return releases; + } + + public override async Task Download(Uri link) + { + var response = await RequestBytesWithCookies(link.ToString(), headers: GetSearchHeaders()); + if (response.Status == HttpStatusCode.Unauthorized) + { + await RenewalTokenAsync(); + response = await RequestBytesWithCookies(link.ToString(), headers: GetSearchHeaders()); + } + else if (response.Status != HttpStatusCode.OK) + throw new Exception($"Unknown error in download: {response.Content}"); + return response.Content; + } + + private Dictionary GetSearchHeaders() => new Dictionary + { + {"Authorization", $"Bearer {_token}"} + }; + } +} diff --git a/src/Jackett.Common/Indexers/IceTorrent.cs b/src/Jackett.Common/Indexers/IceTorrent.cs new file mode 100644 index 000000000..339466384 --- /dev/null +++ b/src/Jackett.Common/Indexers/IceTorrent.cs @@ -0,0 +1,78 @@ +using System.Diagnostics.CodeAnalysis; +using Jackett.Common.Indexers.Abstract; +using Jackett.Common.Models; +using Jackett.Common.Services.Interfaces; +using Jackett.Common.Utils.Clients; +using NLog; + +namespace Jackett.Common.Indexers +{ + [ExcludeFromCodeCoverage] + public class IceTorrent : XtremeZoneTracker + { + public override string[] LegacySiteLinks { get; protected set; } = { + "https://www.icetorrent.org/" + }; + + public IceTorrent(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + : base( + id: "icetorrent", + name: "ICE Torrent", + description: "ICE Torrent is a ratioless ROMANIAN Private Torrent Tracker for 0DAY / GENERAL", + link: "https://icetorrent.org/", + caps: new TorznabCapabilities + { + SupportsImdbMovieSearch = true + // SupportsImdbTVSearch = true (supported by the site but disabled due to #8107) + }, + configService: configService, + client: wc, + logger: l, + p: ps) + { + AddCategoryMapping(38, TorznabCatType.Movies, "Movie Packs"); + AddCategoryMapping(10, TorznabCatType.MoviesSD, "Movies: SD"); + AddCategoryMapping(35, TorznabCatType.MoviesSD, "Movies: SD Ro"); + AddCategoryMapping(8, TorznabCatType.MoviesHD, "Movies: HD"); + AddCategoryMapping(29, TorznabCatType.MoviesHD, "Movies: HD Ro"); + AddCategoryMapping(7, TorznabCatType.MoviesDVD, "Movies: DVD"); + AddCategoryMapping(2, TorznabCatType.MoviesDVD, "Movies: DVD Ro"); + AddCategoryMapping(17, TorznabCatType.MoviesBluRay, "Movies: BluRay"); + AddCategoryMapping(24, TorznabCatType.MoviesBluRay, "Movies: BluRay Ro"); + AddCategoryMapping(59, TorznabCatType.Movies, "Movies: Ro"); + AddCategoryMapping(57, TorznabCatType.MoviesUHD, "Movies: 4K (2160p) Ro"); + AddCategoryMapping(61, TorznabCatType.MoviesUHD, "Movies: 4K (2160p)"); + AddCategoryMapping(41, TorznabCatType.TV, "TV Packs"); + AddCategoryMapping(66, TorznabCatType.TV, "TV Packs Ro"); + AddCategoryMapping(45, TorznabCatType.TV, "TV Episodes"); + AddCategoryMapping(46, TorznabCatType.TV, "TV Episodes Ro"); + AddCategoryMapping(43, TorznabCatType.TVHD, "TV Episodes HD"); + AddCategoryMapping(44, TorznabCatType.TVHD, "TV Episodes HD Ro"); + AddCategoryMapping(60, TorznabCatType.TV, "TV Ro"); + AddCategoryMapping(11, TorznabCatType.PCGames, "Games: PC-ISO"); + AddCategoryMapping(52, TorznabCatType.Console, "Games: Console"); + AddCategoryMapping(1, TorznabCatType.PC0day, "Applications"); + AddCategoryMapping(14, TorznabCatType.PC, "Applications: Linux"); + AddCategoryMapping(37, TorznabCatType.PCMac, "Applications: Mac"); + AddCategoryMapping(19, TorznabCatType.PCPhoneOther, "Applications: Mobile"); + AddCategoryMapping(62, TorznabCatType.TV, "TV Cartoons"); + AddCategoryMapping(3, TorznabCatType.TVAnime, "TV Anime / Hentai"); + AddCategoryMapping(6, TorznabCatType.BooksEbook, "E-books"); + AddCategoryMapping(5, TorznabCatType.Audio, "Music"); + AddCategoryMapping(64, TorznabCatType.AudioVideo, "Music Video"); + AddCategoryMapping(18, TorznabCatType.Other, "Images"); + AddCategoryMapping(22, TorznabCatType.TVSport, "TV Sports"); + AddCategoryMapping(58, TorznabCatType.TVSport, "TV Sports Ro"); + AddCategoryMapping(9, TorznabCatType.TVDocumentary, "TV Documentary"); + AddCategoryMapping(63, TorznabCatType.TVDocumentary, "TV Documentary Ro"); + AddCategoryMapping(65, TorznabCatType.Other, "Tutorial"); + AddCategoryMapping(67, TorznabCatType.Other, "Miscellaneous"); + AddCategoryMapping(15, TorznabCatType.XXX, "XXX Movies"); + AddCategoryMapping(47, TorznabCatType.XXX, "XXX DVD"); + AddCategoryMapping(48, TorznabCatType.XXX, "XXX HD"); + AddCategoryMapping(49, TorznabCatType.XXX, "XXX Images"); + AddCategoryMapping(50, TorznabCatType.XXX, "XXX Packs"); + AddCategoryMapping(51, TorznabCatType.XXX, "XXX SD"); + } + } +} diff --git a/src/Jackett.Common/Indexers/SceneFZ.cs b/src/Jackett.Common/Indexers/SceneFZ.cs new file mode 100644 index 000000000..2ed337c21 --- /dev/null +++ b/src/Jackett.Common/Indexers/SceneFZ.cs @@ -0,0 +1,78 @@ +using System.Diagnostics.CodeAnalysis; +using Jackett.Common.Indexers.Abstract; +using Jackett.Common.Models; +using Jackett.Common.Services.Interfaces; +using Jackett.Common.Utils.Clients; +using NLog; + +namespace Jackett.Common.Indexers +{ + [ExcludeFromCodeCoverage] + public class SceneFZ : XtremeZoneTracker + { + public override string[] LegacySiteLinks { get; protected set; } = { + "https://www.scenefz.me/", + "https://www.u-torrents.ro/" + }; + + public SceneFZ(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + : base( + id: "scenefz", + name: "SceneFZ", + description: "SceneFZ is a ratioless ROMANIAN Private Torrent Tracker for MOVIES / TV / GENERAL", + link: "https://scenefz.me/", + caps: new TorznabCapabilities + { + SupportsImdbMovieSearch = true + // SupportsImdbTVSearch = true (supported by the site but disabled due to #8107) + }, + configService: configService, + client: wc, + logger: l, + p: ps) + { + AddCategoryMapping(62, TorznabCatType.TV, "Cartoons"); + AddCategoryMapping(3, TorznabCatType.TVAnime, "Anime/Hentai"); + AddCategoryMapping(1, TorznabCatType.PC0day, "Appz"); + AddCategoryMapping(9, TorznabCatType.TVDocumentary, "Documentary"); + AddCategoryMapping(63, TorznabCatType.TVDocumentary, "Documentary-RO"); + AddCategoryMapping(6, TorznabCatType.Books, "eBooks"); + AddCategoryMapping(52, TorznabCatType.Console, "Games-Console"); + AddCategoryMapping(11, TorznabCatType.PCGames, "Games-PC"); + AddCategoryMapping(18, TorznabCatType.Other, "Images"); + AddCategoryMapping(65, TorznabCatType.Other, "Tutorial"); + AddCategoryMapping(14, TorznabCatType.PC, "Linux"); + AddCategoryMapping(37, TorznabCatType.PCMac, "Mac"); + AddCategoryMapping(19, TorznabCatType.PCPhoneOther, "Mobile"); + AddCategoryMapping(17, TorznabCatType.MoviesBluRay, "Movies-BluRay"); + AddCategoryMapping(24, TorznabCatType.MoviesBluRay, "Movies-BluRayRO"); + AddCategoryMapping(7, TorznabCatType.MoviesDVD, "Movies-DVD"); + AddCategoryMapping(2, TorznabCatType.MoviesDVD, "Movies-DVD-RO"); + AddCategoryMapping(8, TorznabCatType.MoviesHD, "Movies-HD"); + AddCategoryMapping(29, TorznabCatType.MoviesHD, "Movies-HD-RO"); + AddCategoryMapping(59, TorznabCatType.MoviesForeign, "Movies-RO"); + AddCategoryMapping(57, TorznabCatType.MoviesUHD, "Movies-UHD-RO"); + AddCategoryMapping(61, TorznabCatType.MoviesUHD, "Movies-UHD"); + AddCategoryMapping(38, TorznabCatType.Movies, "Movies-Packs"); + AddCategoryMapping(10, TorznabCatType.MoviesSD, "Movies-SD"); + AddCategoryMapping(35, TorznabCatType.MoviesSD, "Movies-SD-RO"); + AddCategoryMapping(5, TorznabCatType.Audio, "Music"); + AddCategoryMapping(64, TorznabCatType.AudioVideo, "Music Videos"); + AddCategoryMapping(22, TorznabCatType.TVSport, "Sport"); + AddCategoryMapping(58, TorznabCatType.TVSport, "Sports-RO"); + AddCategoryMapping(43, TorznabCatType.TVHD, "TV-HD"); + AddCategoryMapping(44, TorznabCatType.TVHD, "TV-HD-RO"); + AddCategoryMapping(41, TorznabCatType.TV, "TV-Packs"); + AddCategoryMapping(45, TorznabCatType.TVSD, "TV-SD"); + AddCategoryMapping(46, TorznabCatType.TVSD, "TV-SD-RO"); + AddCategoryMapping(60, TorznabCatType.TVFOREIGN, "TV-RO"); + AddCategoryMapping(66, TorznabCatType.TVFOREIGN, "TV-Packs-RO"); + AddCategoryMapping(15, TorznabCatType.XXX, "XXX"); + AddCategoryMapping(47, TorznabCatType.XXX, "XXX-DVD"); + AddCategoryMapping(48, TorznabCatType.XXX, "XXX-HD"); + AddCategoryMapping(49, TorznabCatType.XXXImageset, "XXX-IMGSet"); + AddCategoryMapping(50, TorznabCatType.XXX, "XXX-Packs"); + AddCategoryMapping(51, TorznabCatType.XXX, "XXX-SD"); + } + } +} diff --git a/src/Jackett.Common/Indexers/XtremeZone.cs b/src/Jackett.Common/Indexers/XtremeZone.cs new file mode 100644 index 000000000..fc1370f03 --- /dev/null +++ b/src/Jackett.Common/Indexers/XtremeZone.cs @@ -0,0 +1,78 @@ +using System.Diagnostics.CodeAnalysis; +using Jackett.Common.Indexers.Abstract; +using Jackett.Common.Models; +using Jackett.Common.Services.Interfaces; +using Jackett.Common.Utils.Clients; +using NLog; + +namespace Jackett.Common.Indexers +{ + [ExcludeFromCodeCoverage] + public class XtremeZone : XtremeZoneTracker + { + public override string[] LegacySiteLinks { get; protected set; } = { + "https://www.myxz.eu/", + "https://www.myxz.org/" + }; + + public XtremeZone(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps) + : base( + id: "xtremezone", + name: "Xtreme Zone", + description: "Xtreme Zone (MYXZ) is a ROMANIAN Private Torrent Tracker for MOVIES / TV / GENERAL", + link: "https://myxz.eu/", + caps: new TorznabCapabilities + { + SupportsImdbMovieSearch = true + // SupportsImdbTVSearch = true (supported by the site but disabled due to #8107) + }, + configService: configService, + client: wc, + logger: l, + p: ps) + { + AddCategoryMapping(62, TorznabCatType.TV, "Cartoons"); + AddCategoryMapping(3, TorznabCatType.TVAnime, "Anime/Hentai"); + AddCategoryMapping(1, TorznabCatType.PC0day, "Appz"); + AddCategoryMapping(9, TorznabCatType.TVDocumentary, "Documentary"); + AddCategoryMapping(63, TorznabCatType.TVDocumentary, "Documentary-RO"); + AddCategoryMapping(6, TorznabCatType.Books, "eBooks"); + AddCategoryMapping(52, TorznabCatType.Console, "Games-Console"); + AddCategoryMapping(11, TorznabCatType.PCGames, "Games-PC"); + AddCategoryMapping(18, TorznabCatType.Other, "Images"); + AddCategoryMapping(65, TorznabCatType.Other, "Tutorial"); + AddCategoryMapping(14, TorznabCatType.PC, "Linux"); + AddCategoryMapping(37, TorznabCatType.PCMac, "Mac"); + AddCategoryMapping(19, TorznabCatType.PCPhoneOther, "Mobile"); + AddCategoryMapping(17, TorznabCatType.MoviesBluRay, "Movies-BluRay"); + AddCategoryMapping(24, TorznabCatType.MoviesBluRay, "Movies-BluRayRO"); + AddCategoryMapping(7, TorznabCatType.MoviesDVD, "Movies-DVD"); + AddCategoryMapping(2, TorznabCatType.MoviesDVD, "Movies-DVD-RO"); + AddCategoryMapping(8, TorznabCatType.MoviesHD, "Movies-HD"); + AddCategoryMapping(29, TorznabCatType.MoviesHD, "Movies-HD-RO"); + AddCategoryMapping(59, TorznabCatType.MoviesForeign, "Movies-RO"); + AddCategoryMapping(57, TorznabCatType.MoviesUHD, "Movies-UHD-RO"); + AddCategoryMapping(61, TorznabCatType.MoviesUHD, "Movies-UHD"); + AddCategoryMapping(38, TorznabCatType.Movies, "Movies-Packs"); + AddCategoryMapping(10, TorznabCatType.MoviesSD, "Movies-SD"); + AddCategoryMapping(35, TorznabCatType.MoviesSD, "Movies-SD-RO"); + AddCategoryMapping(5, TorznabCatType.Audio, "Music"); + AddCategoryMapping(64, TorznabCatType.AudioVideo, "Music Videos"); + AddCategoryMapping(22, TorznabCatType.TVSport, "Sport"); + AddCategoryMapping(58, TorznabCatType.TVSport, "Sports-RO"); + AddCategoryMapping(43, TorznabCatType.TVHD, "TV-HD"); + AddCategoryMapping(44, TorznabCatType.TVHD, "TV-HD-RO"); + AddCategoryMapping(41, TorznabCatType.TV, "TV-Packs"); + AddCategoryMapping(45, TorznabCatType.TVSD, "TV-SD"); + AddCategoryMapping(46, TorznabCatType.TVSD, "TV-SD-RO"); + AddCategoryMapping(60, TorznabCatType.TVFOREIGN, "TV-RO"); + AddCategoryMapping(66, TorznabCatType.TVFOREIGN, "TV-Packs-RO"); + AddCategoryMapping(15, TorznabCatType.XXX, "XXX"); + AddCategoryMapping(47, TorznabCatType.XXX, "XXX-DVD"); + AddCategoryMapping(48, TorznabCatType.XXX, "XXX-HD"); + AddCategoryMapping(49, TorznabCatType.XXXImageset, "XXX-IMGSet"); + AddCategoryMapping(50, TorznabCatType.XXX, "XXX-Packs"); + AddCategoryMapping(51, TorznabCatType.XXX, "XXX-SD"); + } + } +} diff --git a/src/Jackett.Updater/Program.cs b/src/Jackett.Updater/Program.cs index 8db9575a4..a9269c63d 100644 --- a/src/Jackett.Updater/Program.cs +++ b/src/Jackett.Updater/Program.cs @@ -322,6 +322,7 @@ namespace Jackett.Updater "Definitions/hon3yhd-net.yml", "Definitions/horriblesubs.yml", "Definitions/hyperay.yml", + "Definitions/icetorrent.yml", // migrated to C# XtremeZone base tracker "Definitions/idopeclone.yml", "Definitions/iloveclassics.yml", "Definitions/infinityt.yml", @@ -352,6 +353,7 @@ namespace Jackett.Updater "Definitions/rns.yml", // site merged with audiobooktorrents "Definitions/rockethd.yml", "Definitions/rockhardlossless.yml", + "Definitions/scenefz.yml", // migrated to C# XtremeZone base tracker "Definitions/scenehd.yml", // migrated to C# (use JSON API) "Definitions/scenereactor.yml", "Definitions/scenexpress.yml", @@ -393,6 +395,7 @@ namespace Jackett.Updater "Definitions/worldofp2p.yml", "Definitions/worldwidetorrents.yml", "Definitions/xktorrent.yml", + "Definitions/xtremezone.yml", // migrated to C# XtremeZone base tracker "Definitions/yourexotic.yml", // renamed to exoticaz.yml "Microsoft.Owin.dll", "Microsoft.Owin.FileSystems.dll",