diff --git a/src/Jackett.Common/Definitions/superbits.yml b/src/Jackett.Common/Definitions/superbits.yml
new file mode 100644
index 000000000..1b665e475
--- /dev/null
+++ b/src/Jackett.Common/Definitions/superbits.yml
@@ -0,0 +1,267 @@
+---
+id: superbits
+name: Superbits
+description: "Superbits is a SWEDISH Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: sv-SW
+type: private
+encoding: UTF-8
+links:
+ - https://superbits.org/
+
+caps:
+ categorymappings:
+ - {id: 1, cat: Movies/DVD, desc: DVD-R Swesub}
+ - {id: 2, cat: TV, desc: DVD-R TV}
+ - {id: 3, cat: Books/EBook, desc: eBok}
+ - {id: 4, cat: Movies/HD, desc: Film 1080}
+ - {id: 5, cat: Movies/3D, desc: Film 3D}
+ - {id: 6, cat: Movies/HD, desc: Film 720}
+ - {id: 7, cat: Movies/BluRay, desc: Film Bluray}
+ - {id: 24, cat: Movies/UHD, desc: Film 4K}
+ - {id: 8, cat: TV, desc: Svensk TV}
+ - {id: 9, cat: Audio/Audiobook, desc: Ljudböcker}
+ - {id: 10, cat: Audio/Video, desc: Musikvideos}
+ - {id: 11, cat: Books/Mags, desc: E-tidningar}
+ - {id: 12, cat: Audio, desc: MP3}
+ - {id: 13, cat: Other, desc: Omslag}
+ - {id: 14, cat: Other, desc: Övrigt}
+ - {id: 15, cat: PC/Games, desc: PC-Spel}
+ - {id: 16, cat: PC/0day, desc: Program}
+ - {id: 17, cat: Console/PS4, desc: Playstation}
+ - {id: 18, cat: TV, desc: TV}
+ - {id: 19, cat: Console/Other, desc: Nintendo}
+ - {id: 20, cat: Console/XBox, desc: Xbox}
+ - {id: 21, cat: Movies/SD, desc: Xvid}
+ - {id: 25, cat: Movies/Foreign, desc: Subpacks}
+ - {id: 22, cat: XXX, desc: XXX}
+ - {id: 23, cat: Audio/Lossless, desc: FLAC}
+ - {id: 26, cat: TV, desc: TV DK}
+ - {id: 27, cat: TV, desc: TV NO}
+ - {id: 28, cat: TV, desc: TV FI}
+
+ modes:
+ search: [q]
+ tv-search: [q, season, ep, imdbid]
+ movie-search: [q, imdbid]
+ music-search: [q]
+ book-search: [q]
+
+settings:
+ - name: cookie
+ type: text
+ label: Cookie
+ - name: info
+ type: info
+ label: How to get the Cookie
+ default: "
- Login to this tracker with your browser
- Open the DevTools panel by pressing F12
- Select the Network tab
- Click on the Doc button (Chrome Browser) or HTML button (FireFox)
- Refresh the page by pressing F5
- Click on the first row entry
- Select the Headers tab on the Right panel
- Find 'cookie:' in the Request Headers section
- Select and Copy the whole cookie string (everything after 'cookie: ') and Paste here.
"
+ - name: freeleech
+ type: checkbox
+ label: Search freeleech only
+ default: false
+ - name: sort
+ type: select
+ label: Sort requested from site
+ default: d
+ options:
+ d: created
+ up: seeders
+ s: size
+ n: title
+ - name: type
+ type: select
+ label: Order requested from site
+ default: desc
+ options:
+ desc: desc
+ asc: asc
+
+login:
+ method: cookie
+ inputs:
+ cookie: "{{ .Config.cookie }}"
+
+search:
+ paths:
+ - path: api/v1/torrents
+ response:
+ type: json
+ noResultsMessage: ""
+
+ inputs:
+ $raw: "{{ range .Categories }}categories[]={{.}}&{{end}}"
+ dkaudio: false
+ dksub: false
+ enaudio: false
+ ensub: false
+ extendedSearch: false
+ fiaudio: false
+ fisub: false
+ freeleech: "{{ if .Config.freeleech }}true{{ else }}false{{ end }}"
+ index: 0
+ limit: 100
+ noaudio: false
+ nosub: false
+ order: "{{ .Config.type }}"
+ page: search
+ searchText: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+ section: all
+ sort: "{{ .Config.sort }}"
+ stereoscopic: false
+ sweaudio: false
+ swesub: false
+ watchview: false
+
+ rows:
+ selector: $
+
+ fields:
+ category:
+ selector: category
+ title:
+ selector: name
+ id:
+ selector: id
+ details:
+ text: "{{ .Config.sitelink }}torrent/{{ .Result.id }}/"
+ download:
+ text: "{{ .Config.sitelink }}api/v1/torrents/download/{{ .Result.id }}"
+ imdbid:
+ selector: imdbid2
+ imdbidfull:
+ optional: true
+ selector: imdbid2
+ posternormal:
+ optional: true
+ selector: customcover
+ posterimdb:
+ optional: true
+ text: "{{ if .Result.imdbid }}{{ .Config.sitelink }}img/imdb/{{ .Result.imdbidfull }}.jpg{{ else }}{{ end }}"
+ poster:
+ text: "{{ if .Result.posterimdb }}{{ .Result.posterimdb }}{{ else }}{{ .Result.posternormal }}{{ end }}"
+ date:
+ # 2021-10-26 13:50:07
+ selector: added
+ filters:
+ - name: append
+ args: " +01:00" # CET
+ - name: dateparse
+ args: "2006-01-02 15:04:05 -07:00"
+ size:
+ selector: size
+ files:
+ selector: numfiles
+ grabs_optional:
+ optional: true
+ selector: timesCompleted
+ grabs:
+ text: "{{ if .Result.grabs_optional }}{{ .Result.grabs_optional }}{{ else }}0{{ end }}"
+ seeders:
+ selector: seeders
+ leechers:
+ selector: leechers
+ downloadvolumefactor:
+ # api returns 0=false, 1=true
+ selector: frileech
+ case:
+ 0: 1 # not free
+ 1: 0 # freeleech
+ uploadvolumefactor:
+ text: 1
+ minimumratio:
+ text: 1.1
+ minimumseedtime:
+ # 2 days (as seconds = 2 x 24 x 60 x 60)
+ text: 172800
+ titledesc:
+ optional: true
+ selector: title
+ yeardesc:
+ optional: true
+ selector: year
+ genresdesc:
+ optional: true
+ selector: genres
+ taglinedesc:
+ optional: true
+ selector: tagline
+ castdesc:
+ optional: true
+ selector: cast
+ ratingdesc:
+ optional: true
+ selector: rating
+ plotdesc:
+ optional: true
+ selector: plot
+ sectiondesc:
+ optional: true
+ selector: section
+ predatedesc:
+ selector: preDate
+ filters:
+ - name: re_replace
+ args: ["1970-01-01 01:00:00", ""]
+ p2ptag:
+ selector: p2p
+ case:
+ 0: ""
+ 1: P2P
+ packtag:
+ selector: pack
+ case:
+ 0: ""
+ 1: Pack
+ reqidtag:
+ selector: reqid
+ case:
+ 0: ""
+ "*": Request
+ sweaudiotag:
+ selector: sweaudio
+ case:
+ 0: ""
+ "*": "Swedish audio"
+ swesubtag:
+ selector: swesub
+ case:
+ 0: ""
+ "*": "Swedish subtitles"
+ dkaudiotag:
+ selector: dkaudio
+ case:
+ 0: ""
+ "*": "Danish audio"
+ dksubtag:
+ selector: dksub
+ case:
+ 0: ""
+ "*": "Danish subtitles"
+ enaudiotag:
+ selector: enaudio
+ case:
+ 0: ""
+ "*": "English audio"
+ ensubtag:
+ selector: ensub
+ case:
+ 0: ""
+ "*": "English subtitles"
+ noaudiotag:
+ selector: noaudio
+ case:
+ 0: ""
+ "*": "Norwegian audio"
+ nosubtag:
+ selector: nosub
+ case:
+ 0: ""
+ "*": "Norwegian subtitles"
+ tagdesc:
+ optional: true
+ text: "{{ if .Result.p2ptag }}{{ .Result.p2ptag }}, {{ else }}{{ end }}{{ if .Result.packtag }}{{ .Result.packtag }}, {{ else }}{{ end }}{{ if .Result.reqidtag }}{{ .Result.reqidtag }}, {{ else }}{{ end }}{{ if .Result.sweaudiotag }}{{ .Result.sweaudiotag }}, {{ else }}{{ end }}{{ if .Result.swesubtag }}{{ .Result.swesubtag }}, {{ else }}{{ end }}{{ if .Result.dkaudiotag }}{{ .Result.dkaudiotag }}, {{ else }}{{ end }}{{ if .Result.dksubtag }}{{ .Result.dksubtag }}, {{ else }}{{ end }}{{ if .Result.enaudiotag }}{{ .Result.enaudiotag }}, {{ else }}{{ end }}{{ if .Result.ensubtag }}{{ .Result.ensubtag }}, {{ else }}{{ end }}{{ if .Result.noaudiotag }}{{ .Result.noaudiotag }}, {{ else }}{{ end }}{{ if .Result.nosubtag }}{{ .Result.nosubtag }}{{ else }}{{ end }}"
+ filters:
+ - name: regexp
+ args: "(.+?), $"
+ description:
+ text: "{{ if .Result.titledesc }}Title: {{ .Result.titledesc }}{{ else }}{{ end }}{{ if .Result.yeardesc }}Year: {{ .Result.yeardesc }}{{ else }}{{ end }}{{ if .Result.genresdesc }}Genres: {{ .Result.genresdesc }}{{ else }}{{ end }}{{ if .Result.taglinedesc }}Tagline: {{ .Result.taglinedesc }}{{ else }}{{ end }}{{ if .Result.castdesc }}Cast: {{ .Result.castdesc }}{{ else }}{{ end }}{{ if .Result.ratingdesc }}Rating: {{ .Result.ratingdesc }}{{ else }}{{ end }}{{ if .Result.plotdesc }}Plot: {{ .Result.plotdesc }}{{ else }}{{ end }}{{ if .Result.tagdesc }}Tags: {{ .Result.tagdesc }}{{ else }}{{ end }}{{ if .Result.predatedesc }}PRE: {{ .Result.predatedesc }}{{ else }}{{ end }}{{ if .Result.sectiondesc }}Section: {{ .Result.sectiondesc }}{{ else }}{{ end }}"
+# json rartracker api v1
diff --git a/src/Jackett.Common/Indexers/CardigannIndexer.cs b/src/Jackett.Common/Indexers/CardigannIndexer.cs
index eaeabf286..224bbfee4 100644
--- a/src/Jackett.Common/Indexers/CardigannIndexer.cs
+++ b/src/Jackett.Common/Indexers/CardigannIndexer.cs
@@ -1383,7 +1383,7 @@ namespace Jackett.Common.Indexers
{
if (response.Status != HttpStatusCode.OK)
throw new Exception($"Error Parsing Json Response: Status={response.Status} Response={results}");
- if (response.Status == HttpStatusCode.OK && SearchPath.Response != null && SearchPath.Response.NoResultsMessage != null && SearchPath.Response.NoResultsMessage.Equals(results))
+ if (response.Status == HttpStatusCode.OK && SearchPath.Response != null && SearchPath.Response.NoResultsMessage != null && ((SearchPath.Response.NoResultsMessage.Equals(results)) || (SearchPath.Response.NoResultsMessage == String.Empty && results == String.Empty)))
continue;
var parsedJson = JToken.Parse(results);
if (parsedJson == null)
diff --git a/src/Jackett.Common/Indexers/SuperBits.cs b/src/Jackett.Common/Indexers/SuperBits.cs
deleted file mode 100644
index 5f3a4e2d0..000000000
--- a/src/Jackett.Common/Indexers/SuperBits.cs
+++ /dev/null
@@ -1,235 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-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;
-
-namespace Jackett.Common.Indexers
-{
- [ExcludeFromCodeCoverage]
- public class SuperBits : BaseWebIndexer
- {
- private string SearchUrl => SiteLink + "api/v1/torrents";
- private string LoginUrl => SiteLink + "api/v1/auth";
-
- private new ConfigurationDataCookie configData
- {
- get => (ConfigurationDataCookie)base.configData;
- set => base.configData = value;
- }
-
- public SuperBits(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps,
- ICacheService cs)
- : base(id: "superbits",
- name: "Superbits",
- description: "Superbits is a SWEDISH Private Torrent Tracker for MOVIES / TV / GENERAL",
- link: "https://superbits.org/",
- caps: new TorznabCapabilities
- {
- TvSearchParams = new List
- {
- TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep
- },
- MovieSearchParams = new List
- {
- MovieSearchParam.Q, MovieSearchParam.ImdbId
- },
- MusicSearchParams = new List
- {
- MusicSearchParam.Q
- },
- BookSearchParams = new List
- {
- BookSearchParam.Q
- }
- },
- configService: configService,
- client: w,
- logger: l,
- p: ps,
- cacheService: cs,
- configData: new ConfigurationDataCookie())
- {
- Encoding = Encoding.UTF8;
- Language = "sv-SW";
- Type = "private";
-
- AddCategoryMapping(1, TorznabCatType.MoviesDVD, "DVD-R Swesub");
- AddCategoryMapping(2, TorznabCatType.TV, "DVD-R TV");
- AddCategoryMapping(3, TorznabCatType.BooksEBook, "eBok");
- AddCategoryMapping(4, TorznabCatType.MoviesHD, "Film 1080");
- AddCategoryMapping(5, TorznabCatType.Movies3D, "Film 3D");
- AddCategoryMapping(6, TorznabCatType.MoviesHD, "Film 720");
- AddCategoryMapping(7, TorznabCatType.MoviesBluRay, "Film Bluray");
- AddCategoryMapping(24, TorznabCatType.MoviesUHD, "Film 4K");
- AddCategoryMapping(8, TorznabCatType.TV, "Svensk TV");
- AddCategoryMapping(9, TorznabCatType.AudioAudiobook, "Ljudböcker");
- AddCategoryMapping(10, TorznabCatType.AudioVideo, "Musikvideos");
- AddCategoryMapping(11, TorznabCatType.BooksMags, "E-tidningar");
- AddCategoryMapping(12, TorznabCatType.Audio, "MP3");
- AddCategoryMapping(13, TorznabCatType.Other, "Omslag");
- AddCategoryMapping(14, TorznabCatType.Other, "Övrigt");
- AddCategoryMapping(15, TorznabCatType.PCGames, "PC-Spel");
- AddCategoryMapping(16, TorznabCatType.PC0day, "Program");
- AddCategoryMapping(17, TorznabCatType.ConsolePS4, "Playstation");
- AddCategoryMapping(18, TorznabCatType.TV, "TV");
- AddCategoryMapping(19, TorznabCatType.ConsoleOther, "Nintendo");
- AddCategoryMapping(20, TorznabCatType.ConsoleXBox, "Xbox");
- AddCategoryMapping(21, TorznabCatType.MoviesSD, "Xvid");
- AddCategoryMapping(25, TorznabCatType.MoviesForeign, "Subpacks");
- AddCategoryMapping(22, TorznabCatType.XXX, "XXX");
- AddCategoryMapping(23, TorznabCatType.AudioLossless, "FLAC");
- AddCategoryMapping(26, TorznabCatType.TV, "TV DK");
- AddCategoryMapping(27, TorznabCatType.TV, "TV NO");
- AddCategoryMapping(28, TorznabCatType.TV, "TV FI");
- }
-
- public override async Task ApplyConfiguration(JToken configJson)
- {
- LoadValuesFromJson(configJson);
-
- // TODO: implement captcha
- CookieHeader = configData.Cookie.Value;
- try
- {
- var results = await PerformQuery(new TorznabQuery());
- if (results.Count() == 0)
- {
- throw new Exception("Found 0 results in the tracker");
- }
-
- IsConfigured = true;
- SaveConfig();
- return IndexerConfigurationStatus.Completed;
- }
- catch (Exception e)
- {
- IsConfigured = false;
- throw new Exception("Your cookie did not work: " + e.Message);
- }
- }
-
- protected override async Task> PerformQuery(TorznabQuery query)
- {
- // And this was option one from
- // https://github.com/Jackett/Jackett/pull/7166#discussion_r376817517
- var releases = new List();
- var queryCollection = new NameValueCollection();
- var searchString = query.GetQueryString();
- var searchUrl = SearchUrl;
-
- queryCollection.Add("extendedSearch", "false");
- queryCollection.Add("freeleech", "false");
- queryCollection.Add("index", "0");
- queryCollection.Add("limit", "100");
- queryCollection.Add("order", "desc");
- queryCollection.Add("page", "search");
- if (query.ImdbID != null)
- queryCollection.Add("searchText", query.ImdbID);
- else
- queryCollection.Add("searchText", searchString);
- queryCollection.Add("sort", "d");
- queryCollection.Add("section", "all");
- queryCollection.Add("stereoscopic", "false");
- queryCollection.Add("sweaudio", "false");
- queryCollection.Add("swesub", "false");
- queryCollection.Add("watchview", "false");
-
- searchUrl += "?" + queryCollection.GetQueryString();
- foreach (var cat in MapTorznabCapsToTrackers(query))
- searchUrl += "&categories[]=" + cat;
- var results = await RequestWithCookiesAsync(searchUrl, referer: SiteLink);
-
- try
- {
- //var json = JArray.Parse(results.Content);
- var json = JsonConvert.DeserializeObject(results.ContentString);
- foreach (var row in json ?? Enumerable.Empty())
- {
- var release = new ReleaseInfo();
- var descriptions = new List();
- var tags = new List();
-
- release.MinimumRatio = 1.1;
- release.MinimumSeedTime = 172800; // 48 hours
- release.Title = row.name;
- release.Category = MapTrackerCatToNewznab(row.category.ToString());
- release.Size = row.size;
- release.Seeders = row.seeders;
- release.Peers = row.leechers + release.Seeders;
- release.PublishDate = DateTime.ParseExact(row.added.ToString() + " +01:00", "yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture);
- release.Files = row.numfiles;
- release.Grabs = row.times_completed;
-
- release.Details = new Uri(SiteLink + "torrent/" + row.id.ToString() + "/");
- release.Guid = release.Details;
- release.Link = new Uri(SiteLink + "api/v1/torrents/download/" + row.id.ToString());
-
- if (row.frileech == 1)
- release.DownloadVolumeFactor = 0;
- else
- release.DownloadVolumeFactor = 1;
- release.UploadVolumeFactor = 1;
-
- if (!string.IsNullOrWhiteSpace(row.customcover.ToString()))
- release.Poster = new Uri(SiteLink + row.customcover);
-
- if (row.imdbid2 != null && row.imdbid2.ToString().StartsWith("tt"))
- {
- release.Imdb = ParseUtil.CoerceLong(row.imdbid2.ToString().Substring(2));
- descriptions.Add("Title: " + row.title);
- descriptions.Add("Year: " + row.year);
- descriptions.Add("Genres: " + row.genres);
- descriptions.Add("Tagline: " + row.tagline);
- descriptions.Add("Cast: " + row.cast);
- descriptions.Add("Rating: " + row.rating);
- descriptions.Add("Plot: " + row.plot);
-
- release.Poster = new Uri(SiteLink + "img/imdb/" + row.imdbid2 + ".jpg");
- }
-
- if ((int)row.p2p == 1)
- tags.Add("P2P");
- if ((int)row.pack == 1)
- tags.Add("Pack");
- if ((int)row.reqid != 0)
- tags.Add("Request");
- if ((int)row.sweaudio != 0)
- tags.Add("Swedish audio");
- if ((int)row.swesub != 0)
- tags.Add("Swedish subtitles");
-
- if (tags.Count > 0)
- descriptions.Add("Tags: " + string.Join(", ", tags));
-
- var preDate = row.preDate.ToString();
- if (!string.IsNullOrWhiteSpace(preDate) && preDate != "1970-01-01 01:00:00")
- descriptions.Add("PRE: " + preDate);
-
- descriptions.Add("Section: " + row.section);
-
- release.Description = string.Join("
\n", descriptions);
-
- releases.Add(release);
- }
- }
- catch (Exception ex)
- {
- OnParseError(results.ContentString, ex);
- }
-
- return releases;
- }
- }
-}