diff --git a/src/Jackett.Common/Definitions/danishbytes.yml b/src/Jackett.Common/Definitions/danishbytes.yml deleted file mode 100644 index e3810af05..000000000 --- a/src/Jackett.Common/Definitions/danishbytes.yml +++ /dev/null @@ -1,207 +0,0 @@ ---- -id: danishbytes -name: DANISH BYTES -description: "DANISH BYTES is a Private Danish Tracker" -language: en-us -type: private -encoding: UTF-8 -links: - - https://danishbytes.org/ - -caps: - categorymappings: - - {id: 1, cat: Movies, desc: "Movies"} - - {id: 2, cat: TV, desc: "TV"} - - {id: 3, cat: Audio, desc: "Music"} - - {id: 4, cat: PC/Games, desc: "Games"} - - {id: 5, cat: PC/0day, desc: "Appz"} - - {id: 8, cat: Books, desc: "Bookz"} - - modes: - search: [q] - tv-search: [q, season, ep, imdbid, tvdbid] - movie-search: [q, imdbid, tmdbid] - music-search: [q] - book-search: [q] - -settings: - - name: username - type: text - label: Username - - name: password - type: password - label: Password - - name: freeleech - type: checkbox - label: Search freeleech only - default: false - - name: sort - type: select - label: Sort requested from site - default: created_at - options: - created_at: created - seeders: seeders - size: size - name: title - - name: type - type: select - label: Order requested from site - default: desc - options: - desc: desc - asc: asc - -login: - path: login - method: form - form: form[action$="/login"] - inputs: - username: "{{ .Config.username }}" - password: "{{ .Config.password }}" - remember: on - selectorinputs: - _token: - selector: input[name="_token"] - attribute: value - error: - - selector: div#ERROR_COPY -# test: -# path: / -# selector: a[href$="/logout"] - -search: - paths: - - path: torrents/filter - inputs: - $raw: "{{ range .Categories }}categories[]={{.}}&{{end}}" - search: "{{ if .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}" # for dashboard imdbid search - description: "" - keywords: "" - uploader: "" - imdb: "{{ .Query.IMDBIDShort }}" - tvdb: "{{ .Query.TVDBID }}" - tmdb: "{{ .Query.TMDBID }}" - mal: "" - igdb: "" - start_year: "" - end_year: "" - sorting: "{{ .Config.sort }}" - direction: "{{ .Config.type }}" - qty: 100 - page: 0 - view: list - freeleech: "{{ if .Config.freeleech }}1{{ else }}{{ end }}" - - rows: - selector: table > tbody > tr - - fields: - category: - selector: i.torrent-icon - attribute: class - case: - i.fa-film: 1 - i.fa-tv-retro: 2 - i.fa-music: 3 - i.fa-gamepad: 4 - i.fa-compact-disc: 5 - i.fa-book-open: 8 - title: - selector: a.view-torrent - download: - selector: a[href*="/download/"] - attribute: href -# tracker has issue with some magnet downloads failing #10758 -# magnet: -# selector: a[href^="magnet"] -# attribute: href - details: - selector: a.view-torrent - attribute: href - poster: - selector: div.torrent-poster img - attribute: src - filters: - - name: replace - args: ["&w=52&h=80", "&w=180&h=270"] # for display on dashboard - - name: replace - args: ["https://images.weserv.nl/?url=https://via.placeholder.com/52x80&w=180&h=270", ""] - size: - selector: td:nth-last-child(4) - seeders: - selector: td:nth-last-child(3) - leechers: - selector: td:nth-last-child(2) - grabs: - selector: td:nth-last-child(1) - filters: - - name: regexp - args: (\d+) - imdb: - selector: a[href*="imdb.com/title/tt"] - attribute: href - tmdbid: - selector: a[href*="themoviedb.org/movie/"] - attribute: href - date: - selector: time - filters: - # translations for Turkish|Estonian|Danish|Italian|Polish|Norwegian|Portuguese|Czech|Russian|Romanian|Spanish|French|German|Bulgarian|Dutch|Chinese|Japanese|Swedish - - name: re_replace - args: ["(?i)(önce|tagasi|geleden|fa|temu|siden|há|atrás|nazpět|назад|acum|în urmă|hace|il y a|vor|преди|前|sedan)", " ago"] - - name: re_replace - args: ["(?i)(saniye|sekundit|sekunder|secondi|sekund|segundos|sekundami|секунд|secunde|secondes|Sekunden|секунди|seconden|秒前)", "seconds"] - - name: re_replace - args: ["(?i)(minutit|minutter|minuti|minuty|minutos|минуты|минут|Minuten|минути|minuten|minuter)", "minutes"] - - name: re_replace - args: ["(?i)(dakika|minut|minuto|minuta|minutt|минута|Minute|minuut|分钟|分)", " minute"] - - name: re_replace - args: ["(?i)(tundi|timer|ore|godziny|horas|hodiny|hoden|часа|часов|ore|heures|Stunden|timmar)", "hours"] - - name: re_replace - args: ["(?i)(saat|tund|time|ora|godzina|hora|hodina|час|oră|heure|Stunde|uur|小时|時間|timme)", " hour"] - - name: re_replace - args: ["(?i)(päeva|dage|giorni|dni|dias|dny|дня|дней|zile|días|jours|Tagen|дни|dagen|dagar)", "days"] - - name: re_replace - args: ["(?i)(gün|päev|dag|giorno|dzień|dia|den|день|zi|día|jour|Tag|ден|天|日)", " day"] - - name: re_replace - args: ["(?i)(nädalat|uger|settimane|tygodnie|uker|semanas|týdny|недели|недель|săptămâni|semaines|Wochen|седмици|weken|veckor)", "weeks"] - - name: re_replace - args: ["(?i)(hafta|nädal|uge|settimana|tydzień|uke|semana|týden|неделю|săptămână|semaine|Woche|седмица|周|週間|vecka)", " week"] - - name: re_replace - args: ["(?i) (ay)", "month"] - - name: re_replace - args: ["(?i)(kuud|måneder|mesi|miesiące|meses|měsíce|месяца|месяцев|luni|meses|mois|Monaten|месеца|maanden|månader)", "months"] - - name: re_replace - args: ["(?i)(kuu|måned|mese|miesiąc|mês|měsíc|месяц|lună|mes|Monat|месец|maand|个月|ヶ月|månad)", " month"] - - name: re_replace - args: ["(?i)(aastat|anni|lata|anos|roky|года|ani|años|ans|Jahren|години)", " years"] - - name: re_replace - args: ["(?i)(yil|aasta|år|anno|rok|ano|год|año|Jahr|година|jaar|年)", " year"] - - name: re_replace - args: ["(?i) (an)", "year"] - - name: re_replace - args: ["(?i)(För |und)", ""] # Misc removals - - name: timeago - downloadvolumefactor: - case: - i[class*="fa-id-badge text-orange"]: 0 # 24 Hour FreeLeech From PARA Store - i[class*="fa-trophy text-purple"]: 0 # Special FreeLeech For Certain User Groups - i[class*="fa-star text-bold"]: 0 # Freeleech From Token - i[class*="fa-coins text-bold"]: 0 # Freeleech From Token - i[class*="fa-globe text-blue"]: 0 # Global Freeleech - i[class*="fa-star text-gold"]: 0 # Freeleech - i[class*="fa-certificate text-pink"]: 0 # Featured Torrent - "*": 1 - uploadvolumefactor: - case: - i[class*="fa-gem text-green"]: 2 # Single Torrent Double Upload - i[class*="fa-globe text-green"]: 2 # Global Double Upload - i[class*="fa-certificate text-pink"]: 2 # Featured Torrent - "*": 1 - minimumratio: - text: 1.1 - minimumseedtime: - # 2 days (as seconds = 2 x 24 x 60 x 60) - text: 172800 -# UNIT3D 5.1.0 DBy-edition 0.75 diff --git a/src/Jackett.Common/Indexers/DanishBytes.cs b/src/Jackett.Common/Indexers/DanishBytes.cs new file mode 100644 index 000000000..dcfebaaca --- /dev/null +++ b/src/Jackett.Common/Indexers/DanishBytes.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Diagnostics.CodeAnalysis; +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 +{ + [ExcludeFromCodeCoverage] + public class DanishBytes : BaseWebIndexer + { + private string SearchURl => SiteLink + "api/torrents/v2/filter"; + + private new ConfigurationDataAPIKey configData => (ConfigurationDataAPIKey)base.configData; + + public DanishBytes(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps, + ICacheService cs) + : base(id: "danishbytes", + name: "DanishBytes", + description: "DanishBytes is a Private Danish Tracker", + link: "https://danishbytes.org/", + caps: new TorznabCapabilities + { + LimitsDefault = 25, + LimitsMax = 25, + TvSearchParams = new List + { + TvSearchParam.Q, TvSearchParam.ImdbId, TvSearchParam.TvdbId + }, + MovieSearchParams = new List + { + MovieSearchParam.Q, MovieSearchParam.ImdbId, MovieSearchParam.TmdbId + }, + MusicSearchParams = new List + { + MusicSearchParam.Q + }, + BookSearchParams = new List + { + BookSearchParam.Q + } + }, + configService: configService, + client: wc, + logger: l, + p: ps, + cacheService: cs, + configData: new ConfigurationDataAPIKey()) + + { + Encoding = Encoding.UTF8; + Language = "en-us"; + Type = "private"; + + AddCategoryMapping("1", TorznabCatType.Movies, "Movies"); + AddCategoryMapping("2", TorznabCatType.TV, "TV"); + AddCategoryMapping("3", TorznabCatType.Audio, "Music"); + AddCategoryMapping("4", TorznabCatType.PCGames, "Games"); + AddCategoryMapping("5", TorznabCatType.PC0day, "Appz"); + AddCategoryMapping("6", TorznabCatType.Books, "Bookz"); + } + + public override async Task ApplyConfiguration(JToken configJson) + { + LoadValuesFromJson(configJson); + + await PerformQuery(new TorznabQuery()); // throws exception if there is an error + + IsConfigured = true; + SaveConfig(); + return IndexerConfigurationStatus.Completed; + } + + protected override async Task> PerformQuery(TorznabQuery query) + { + var releases = new List(); + + var qc = new NameValueCollection + { + {"search", query.GetQueryString()}, + {"api_token", configData.Key.Value}, + }; + + if (query.IsImdbQuery) + qc.Add("imdb", query.ImdbID); + if (query.IsTvdbSearch) + qc.Add("tvdb", query.TvdbID.ToString()); + if (query.IsTmdbQuery) + qc.Add("tmdb", query.TmdbID.ToString()); + + var requestUrl = SearchURl; + var searchUrl = requestUrl + "?" + qc.GetQueryString(); + + foreach (var cat in MapTorznabCapsToTrackers(query)) + searchUrl += $"&categories[]={cat}"; + + var results = await RequestWithCookiesAsync(searchUrl); + if (results.Status != HttpStatusCode.OK) + throw new Exception($"Error code: {results.Status}"); + + try + { + var dbResponse = JsonConvert.DeserializeObject(results.ContentString); + foreach (var attr in dbResponse.torrents) + { + var release = new ReleaseInfo + { + Title = attr.name, + Details = new Uri($"{SiteLink}torrents/{attr.id}"), + Link = new Uri($"{SiteLink}torrent/download/{attr.id}.{dbResponse.rsskey}"), + PublishDate = attr.created_at, + Category = MapTrackerCatToNewznab(attr.category_id), + Size = attr.size, + Seeders = attr.seeders, + Peers = attr.leechers + attr.seeders, + Grabs = attr.times_completed, + DownloadVolumeFactor = attr.free ? 0 : 1, + UploadVolumeFactor = attr.doubleup ? 2 : 1 + }; + + releases.Add(release); + } + } + catch (Exception ex) + { + OnParseError(results.ContentString, ex); + } + + return releases; + } + + private class Torrent + { + public int id { get; set; } + public string name { get; set; } + public string info_hash { get; set; } + public long size { get; set; } + public int leechers { get; set; } + public int seeders { get; set; } + public int times_completed { get; set; } + public string category_id { get; set; } + public string tmdb { get; set; } + public string igdb { get; set; } + public string mal { get; set; } + public string tvdb { get; set; } + public string imdb { get; set; } + public int stream { get; set; } + public bool free { get; set; } + public bool on_fire { get; set; } + public bool doubleup { get; set; } + public bool highspeed { get; set; } + public bool featured { get; set; } + public bool webstream { get; set; } + public bool anon { get; set; } + public bool sticky { get; set; } + public bool sd { get; set; } + public DateTime created_at { get; set; } + public DateTime bumped_at { get; set; } + public int type_id { get; set; } + public int resolution_id { get; set; } + public string poster_image { get; set; } + public string video { get; set; } + public int thanks_count { get; set; } + public int comments_count { get; set; } + public string getSize { get; set; } + public string created_at_human { get; set; } + public bool bookmarked { get; set; } + public bool liked { get; set; } + public bool show_last_torrents { get; set; } + } + + private class PageLinks + { + public int to { get; set; } + public string qty { get; set; } + public int current_page { get; set; } + } + + private class DBResponse + { + public Torrent[] torrents { get; set; } + public int resultsCount { get; set; } + public PageLinks links { get; set; } + public string currentCount { get; set; } + public int torrentCountTotal { get; set; } + public string rsskey { get; set; } + } + + } +} diff --git a/src/Jackett.Updater/Program.cs b/src/Jackett.Updater/Program.cs index fe4275419..59336c004 100644 --- a/src/Jackett.Updater/Program.cs +++ b/src/Jackett.Updater/Program.cs @@ -292,6 +292,7 @@ namespace Jackett.Updater "Definitions/czteam.yml", "Definitions/cztorrent.yml", "Definitions/darmowetorenty.yml", // migrated to C# + "Definitions/danishbytes.yml", // migrated to C# "Definitions/demonsite.yml", "Definitions/desitorrents.yml", // migrated to C# "Definitions/digbt.yml",