diff --git a/src/Jackett/Content/logos/bitsoup.png b/src/Jackett/Content/logos/bitsoup.png new file mode 100644 index 000000000..65c0459e1 Binary files /dev/null and b/src/Jackett/Content/logos/bitsoup.png differ diff --git a/src/Jackett/Indexers/BitSoup.cs b/src/Jackett/Indexers/BitSoup.cs new file mode 100644 index 000000000..a0229f56c --- /dev/null +++ b/src/Jackett/Indexers/BitSoup.cs @@ -0,0 +1,245 @@ +using CsQuery; +using Jackett.Models; +using Jackett.Services; +using Jackett.Utils; +using Jackett.Utils.Clients; +using Newtonsoft.Json.Linq; +using NLog; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Web; +using Jackett.Models.IndexerConfig; + +namespace Jackett.Indexers +{ + public class BitSoup : BaseIndexer, IIndexer + { + private string BrowseUrl { get { return SiteLink + "browse.php"; } } + private string LoginUrl { get { return SiteLink + "takelogin.php"; } } + + new ConfigurationDataBasicLogin configData + { + get { return (ConfigurationDataBasicLogin)base.configData; } + set { base.configData = value; } + } + + public BitSoup(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps) + : base(name: "BitSoup", + description: "SoupieBits", + link: "https://www.bitsoup.me/", + caps: TorznabUtil.CreateDefaultTorznabTVCaps(), + manager: i, + client: wc, + logger: l, + p: ps, + configData: new ConfigurationDataBasicLogin()) + { + + //AddCategoryMapping("624", TorznabCatType.Console); + //AddCategoryMapping("307", TorznabCatType.ConsoleNDS); + //AddCategoryMapping("308", TorznabCatType.ConsolePSP); + AddCategoryMapping("35", TorznabCatType.ConsoleWii); + //AddCategoryMapping("309", TorznabCatType.ConsoleXbox); + AddCategoryMapping("12", TorznabCatType.ConsoleXbox360); + //AddCategoryMapping("305", TorznabCatType.ConsoleWiiwareVC); + //AddCategoryMapping("309", TorznabCatType.ConsoleXBOX360DLC); + AddCategoryMapping("38", TorznabCatType.ConsolePS3); + //AddCategoryMapping("239", TorznabCatType.ConsoleOther); + //AddCategoryMapping("245", TorznabCatType.ConsoleOther); + //AddCategoryMapping("246", TorznabCatType.ConsoleOther); + //AddCategoryMapping("626", TorznabCatType.ConsoleOther); + //AddCategoryMapping("628", TorznabCatType.ConsoleOther); + //AddCategoryMapping("630", TorznabCatType.ConsoleOther); + //AddCategoryMapping("307", TorznabCatType.Console3DS); + //AddCategoryMapping("308", TorznabCatType.ConsolePSVita); + //AddCategoryMapping("307", TorznabCatType.ConsoleWiiU); + //AddCategoryMapping("309", TorznabCatType.ConsoleXboxOne); + //AddCategoryMapping("308", TorznabCatType.ConsolePS4); + //AddCategoryMapping("631", TorznabCatType.Movies); + //AddCategoryMapping("631", TorznabCatType.MoviesForeign); + //AddCategoryMapping("455", TorznabCatType.MoviesOther); + //AddCategoryMapping("633", TorznabCatType.MoviesOther); + AddCategoryMapping("19", TorznabCatType.MoviesSD); + AddCategoryMapping("41", TorznabCatType.MoviesHD); + AddCategoryMapping("17", TorznabCatType.Movies3D); + AddCategoryMapping("80", TorznabCatType.MoviesBluRay); + AddCategoryMapping("20", TorznabCatType.MoviesDVD); + //AddCategoryMapping("631", TorznabCatType.MoviesWEBDL); + AddCategoryMapping("6", TorznabCatType.Audio); + //AddCategoryMapping("623", TorznabCatType.AudioMP3); + AddCategoryMapping("29", TorznabCatType.AudioVideo); + //AddCategoryMapping("402", TorznabCatType.AudioVideo); + AddCategoryMapping("5", TorznabCatType.AudioAudiobook); + //AddCategoryMapping("1", TorznabCatType.AudioLossless); + //AddCategoryMapping("403", TorznabCatType.AudioOther); + //AddCategoryMapping("642", TorznabCatType.AudioOther); + //AddCategoryMapping("1", TorznabCatType.AudioForeign); + //AddCategoryMapping("233", TorznabCatType.PC); + //AddCategoryMapping("236", TorznabCatType.PC); + //AddCategoryMapping("1", TorznabCatType.PC0day); + AddCategoryMapping("1", TorznabCatType.PCISO); + //AddCategoryMapping("235", TorznabCatType.PCMac); + //AddCategoryMapping("627", TorznabCatType.PCPhoneOther); + AddCategoryMapping("21", TorznabCatType.PCGames); + AddCategoryMapping("4", TorznabCatType.PCGames); + //AddCategoryMapping("625", TorznabCatType.PCPhoneIOS); + //AddCategoryMapping("625", TorznabCatType.PCPhoneAndroid); + AddCategoryMapping("45", TorznabCatType.TV); + //AddCategoryMapping("433", TorznabCatType.TV); + //AddCategoryMapping("639", TorznabCatType.TVWEBDL); + //AddCategoryMapping("433", TorznabCatType.TVWEBDL); + //AddCategoryMapping("639", TorznabCatType.TVFOREIGN); + //AddCategoryMapping("433", TorznabCatType.TVFOREIGN); + AddCategoryMapping("7", TorznabCatType.TVSD); + AddCategoryMapping("49", TorznabCatType.TVSD); + AddCategoryMapping("42", TorznabCatType.TVHD); + //AddCategoryMapping("433", TorznabCatType.TVHD); + //AddCategoryMapping("635", TorznabCatType.TVOTHER); + //AddCategoryMapping("636", TorznabCatType.TVSport); + AddCategoryMapping("23", TorznabCatType.TVAnime); + //AddCategoryMapping("634", TorznabCatType.TVDocumentary); + AddCategoryMapping("9", TorznabCatType.XXX); + //AddCategoryMapping("1", TorznabCatType.XXXDVD); + //AddCategoryMapping("1", TorznabCatType.XXXWMV); + //AddCategoryMapping("1", TorznabCatType.XXXXviD); + //AddCategoryMapping("1", TorznabCatType.XXXx264); + //AddCategoryMapping("1", TorznabCatType.XXXOther); + //AddCategoryMapping("1", TorznabCatType.XXXImageset); + //AddCategoryMapping("1", TorznabCatType.XXXPacks); + //AddCategoryMapping("340", TorznabCatType.Other); + //AddCategoryMapping("342", TorznabCatType.Other); + //AddCategoryMapping("344", TorznabCatType.Other); + //AddCategoryMapping("391", TorznabCatType.Other); + //AddCategoryMapping("392", TorznabCatType.Other); + //AddCategoryMapping("393", TorznabCatType.Other); + //AddCategoryMapping("394", TorznabCatType.Other); + //AddCategoryMapping("234", TorznabCatType.Other); + //AddCategoryMapping("638", TorznabCatType.Other); + //AddCategoryMapping("629", TorznabCatType.Other); + //AddCategoryMapping("1", TorznabCatType.OtherMisc); + //AddCategoryMapping("1", TorznabCatType.OtherHashed); + //AddCategoryMapping("408", TorznabCatType.Books); + AddCategoryMapping("24", TorznabCatType.BooksEbook); + //AddCategoryMapping("406", TorznabCatType.BooksComics); + //AddCategoryMapping("407", TorznabCatType.BooksComics); + //AddCategoryMapping("409", TorznabCatType.BooksComics); + //AddCategoryMapping("410", TorznabCatType.BooksMagazines); + //AddCategoryMapping("1", TorznabCatType.BooksTechnical); + //AddCategoryMapping("1", TorznabCatType.BooksOther); + //AddCategoryMapping("1", TorznabCatType.BooksForeign); + } + + public async Task ApplyConfiguration(JToken configJson) + { + configData.LoadValuesFromJson(configJson); + var pairs = new Dictionary { + { "username", configData.Username.Value }, + { "password", configData.Password.Value }, + { "returnto", "/" }, + { "login", "Log in!" } + }; + + var loginPage = await RequestStringWithCookies(SiteLink, string.Empty); + + var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, SiteLink, SiteLink, true); + await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () => + { + CQ dom = result.Content; + var messageEl = dom["body > div"].First(); + var errorMessage = messageEl.Text().Trim(); + throw new ExceptionWithConfigData(errorMessage, configData); + }); + return IndexerConfigurationStatus.RequiresTesting; + } + + public async Task> PerformQuery(TorznabQuery query) + { + var releases = new List(); + var searchString = query.GetQueryString(); + var searchUrl = BrowseUrl; + var trackerCats = MapTorznabCapsToTrackers(query); + var queryCollection = new NameValueCollection(); + + + + if (!string.IsNullOrWhiteSpace(searchString)) + { + queryCollection.Add("search", searchString); + queryCollection.Add("incldead", "0"); + queryCollection.Add("cat", "0"); + // Tracker cannot search multi categories + // so we either search "all" + // or do multiple searches + if (trackerCats.Count == 0) + { + searchUrl += "?" + queryCollection.GetQueryString(); + await ProcessPage(releases, searchUrl); + } else + { + foreach (var cat in trackerCats) + { + queryCollection.Remove("cat"); + queryCollection.Add("cat", cat); + searchUrl += "?" + queryCollection.GetQueryString(); + await ProcessPage(releases, searchUrl); + } + } + + } + else + { + queryCollection.Add("search", ""); + queryCollection.Add("cat", "0"); + searchUrl += "?" + queryCollection.GetQueryString(); + await ProcessPage(releases, searchUrl); + } + + return releases; + } + + private async Task ProcessPage(List releases, string searchUrl) + { + var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl); + var results = response.Content; + try + { + CQ dom = results; + + var rows = dom["table.koptekst tr"]; + foreach (var row in rows.Skip(1)) + { + var release = new ReleaseInfo(); + + release.Title = row.Cq().Find("td:eq(1) a").First().Text().Trim(); + + release.Link = new Uri(SiteLink + row.Cq().Find("td:eq(1) a").First().Attr("href")); + release.Description = release.Title; + var cat = row.Cq().Find("td:eq(0) a").First().Attr("href").Substring(15); + release.Category = MapTrackerCatToNewznab(cat); + + var added = row.Cq().Find("td:eq(7)").First().Text().Trim(); + release.PublishDate = DateTime.ParseExact(added, "yyyy-MM-ddH:mm:ss", CultureInfo.InvariantCulture); + + var sizeStr = row.Cq().Find("td:eq(8)").First().Text().Trim(); + release.Size = ReleaseInfo.GetBytes(sizeStr); + + release.Seeders = ParseUtil.CoerceInt(row.Cq().Find("td:eq(10)").First().Text().Trim()); + release.Peers = ParseUtil.CoerceInt(row.Cq().Find("td:eq(11)").First().Text().Trim()) + release.Seeders; + + releases.Add(release); + } + } + catch (Exception ex) + { + OnParseError(results, ex); + } + } + } +} diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index 4ed37bc95..ef02e8c34 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -187,6 +187,7 @@ + @@ -438,6 +439,7 @@ PreserveNewest + PreserveNewest