diff --git a/src/Jackett.Common/Definitions/scenehd.yml b/src/Jackett.Common/Definitions/scenehd.yml deleted file mode 100644 index 733c1954d..000000000 --- a/src/Jackett.Common/Definitions/scenehd.yml +++ /dev/null @@ -1,109 +0,0 @@ ---- - site: scenehd - name: SceneHD - description: "SceneHD is Private site for HD TV / MOVIES" - language: en-us - type: private - encoding: UTF-8 - links: - - https://scenehd.org/ - certificates: - - 81cc4e41b6f8ff656ca0e2396ee6d63383198bf1 # self signed - - caps: - categorymappings: - - {id: 2, cat: Movies/UHD, desc: "Movie/2160"} - - {id: 1, cat: Movies/HD, desc: "Movie/1080"} - - {id: 4, cat: Movies/HD, desc: "Movie/720"} - - {id: 8, cat: Movies/Bluray, desc: "Movie/BD5/9"} - - {id: 6, cat: TV/UHD, desc: "TV/2160"} - - {id: 5, cat: TV/HD, desc: "TV/1080"} - - {id: 7, cat: TV/HD, desc: "TV/720"} - - {id: 22, cat: Movies/Bluray, desc: "Bluray/Complete"} - - {id: 10, cat: XXX, desc: "XXX"} - - {id: 16, cat: Movies/Other, desc: "Subpacks"} - - {id: 13, cat: Audio/Video, desc: "MVID"} - - {id: 9, cat: Other, desc: "Other"} - - modes: - search: [q] - movie-search: [q, imdbid] - tv-search: [q, season, ep, imdbid] - - settings: - - name: cookie - type: text - label: Cookie - - login: - method: cookie - test: - path: browse.php - - search: - paths: - - path: browse.php - inputs: - $raw: "{{range .Categories}}categories[{{.}}]=1&{{end}}" - search: "{{if .Query.IMDBID}}{{else}}{{ .Keywords }}{{end}}" - imdb: "{{if .Query.IMDBID}}{{ .Query.IMDBIDShort }}{{else}}{{end}}" - rows: - selector: table.browse > tbody > tr - fields: - download: - selector: td.browse_dl > a - attribute: href - title: - selector: td.browse_name > a[href^="details.php?id="] - category: - selector: td.browse_cat a - attribute: href - filters: - - name: querystring - args: cat - imdb: - selector: td.browse_imdb > a.catlink - optional: true - attribute: href - details: - selector: td.browse_name > a[href^="details.php?id="] - attribute: href - files: - selector: a[href*="&filelist"] - filters: - - name: replace - args: ["Files", ""] - size: - selector: td.browse_centernowrap:has(a[href*="&filelist"]) - remove: small - date: - selector: td:nth-child(8) - filters: - - name: append - args: " +0200" - - name: dateparse - args: "2006-01-0215:04:05 -0700" - grabs: - selector: td:nth-child(9) - filters: - - name: regexp - args: ([\d,]+) - seeders: - selector: td:nth-child(10) - filters: - - name: split - args: ["/", 0] - leechers: # some torrents have extra partial seeders: 18 / 0 (3) - selector: td:nth-child(10) - filters: - - name: split - args: ["/", 1] - - name: split - args: [" ", 0] - downloadvolumefactor: - case: - a.freetorrent: "0" - "*": "1" - uploadvolumefactor: - case: - "*": "1" diff --git a/src/Jackett.Common/Indexers/SceneHD.cs b/src/Jackett.Common/Indexers/SceneHD.cs new file mode 100644 index 000000000..3e86f8503 --- /dev/null +++ b/src/Jackett.Common/Indexers/SceneHD.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +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.Linq; +using NLog; + +namespace Jackett.Common.Indexers +{ + public class SceneHD : BaseWebIndexer + { + private string SearchUrl { get { return SiteLink + "browse.php"; } } + + private new ConfigurationDataCookie configData + { + get { return (ConfigurationDataCookie)base.configData; } + set { base.configData = value; } + } + + public SceneHD(IIndexerConfigurationService configService, WebClient c, Logger l, IProtectionService ps) + : base(name: "SceneHD", + description: "SceneHD is Private site for HD TV / MOVIES", + link: "https://scenehd.org/", + configService: configService, + caps: new TorznabCapabilities(), + client: c, + logger: l, + p: ps, + configData: new ConfigurationDataCookie()) + { + Encoding = Encoding.UTF8; + Language = "en-us"; + Type = "private"; + TorznabCaps.SupportsImdbSearch = true; + webclient.EmulateBrowser = false; + webclient.AddTrustedCertificate(new Uri(SiteLink).Host, "81CC4E41B6F8FF656CA0E2396EE6D63383198BF1"); + + AddCategoryMapping(2, TorznabCatType.MoviesUHD, "Movie/2160"); + AddCategoryMapping(1, TorznabCatType.MoviesHD, "Movie/1080"); + AddCategoryMapping(4, TorznabCatType.MoviesHD, "Movie/720"); + AddCategoryMapping(8, TorznabCatType.MoviesBluRay, "Movie/BD5/9"); + AddCategoryMapping(6, TorznabCatType.TVUHD, "TV/2160"); + AddCategoryMapping(5, TorznabCatType.TVHD, "TV/1080"); + AddCategoryMapping(7, TorznabCatType.TVHD, "TV/720"); + AddCategoryMapping(22, TorznabCatType.MoviesBluRay, "Bluray/Complete"); + AddCategoryMapping(10, TorznabCatType.XXX, "XXX"); + AddCategoryMapping(16, TorznabCatType.MoviesOther, "Subpacks"); + AddCategoryMapping(13, TorznabCatType.AudioVideo, "MVID"); + AddCategoryMapping(9, TorznabCatType.Other, "Other"); + } + + 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("Your cookie did not work"); + } + + 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) + { + TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday); + TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday); + TimeSpan delta = new TimeSpan(1, 0, 0); + TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition); + TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment }; + TimeZoneInfo Tz = TimeZoneInfo.CreateCustomTimeZone("custom", new TimeSpan(1, 0, 0), "custom", "custom", "custom", adjustments); + + var releases = new List(); + + NameValueCollection qParams = new NameValueCollection(); + qParams.Add("api", ""); + if(query.ImdbIDShort != null) + qParams.Add("imdb", query.ImdbIDShort); + else + qParams.Add("search", query.SearchTerm); + + foreach (var cat in MapTorznabCapsToTrackers(query)) + { + qParams.Add("categories["+cat+"]", "1"); + } + + string urlSearch = SearchUrl; + urlSearch += "?" + qParams.GetQueryString(); + + var response = await RequestStringWithCookiesAndRetry(urlSearch); + if (response.IsRedirect) + throw new Exception("not logged in"); + + try + { + var jsonContent = JArray.Parse(response.Content); + var sitelink = new Uri(SiteLink); + + foreach (var item in jsonContent) + { + var release = new ReleaseInfo(); + + var id = item.Value("id"); + release.Title = item.Value("name"); + + var imdbid = item.Value("imdbid"); + if (!string.IsNullOrEmpty(imdbid)) + release.Imdb = long.Parse(imdbid); + + var category = item.Value("category"); + release.Category = MapTrackerCatToNewznab(category); + + release.Link = new Uri(sitelink, "/download.php?id=" + id); + release.Comments = new Uri(sitelink, "/details.php?id=" + id); + release.Guid = release.Comments; + + var dateStr = item.Value("added"); + var dateTime = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified); + var pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateTime, Tz); + release.PublishDate = pubDateUtc; + + release.Grabs = item.Value("times_completed"); + release.Files = item.Value("numfiles"); + release.Seeders = item.Value("seeders"); + release.Peers = item.Value("leechers") + release.Seeders; + var size = item.Value("size"); + release.Size = ReleaseInfo.GetBytes(size); + var is_freeleech = item.Value("is_freeleech"); + + if (is_freeleech == 1) + release.DownloadVolumeFactor = 0; + else + release.DownloadVolumeFactor = 1; + release.UploadVolumeFactor = 1; + + releases.Add(release); + } + } + catch (Exception ex) + { + OnParseError(response.Content, ex); + } + + return releases; + } + } +} diff --git a/src/Jackett.Updater/Program.cs b/src/Jackett.Updater/Program.cs index 928958f84..22f824c2e 100644 --- a/src/Jackett.Updater/Program.cs +++ b/src/Jackett.Updater/Program.cs @@ -257,6 +257,7 @@ namespace Jackett.Updater "Definitions/eotforum.yml", "Definitions/nexttorrent.yml", "Definitions/torrentsmd.yml", + "Definitions/scenehd.yml", // migrated to C# (use JSON API) "appsettings.Development.json", "CurlSharp.dll", "CurlSharp.pdb",