From f4ad01dda78b15d447e5b45170a5c1bcb18d0014 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 12 Jul 2015 20:01:02 -0600 Subject: [PATCH] Implemented BeyondHD --- src/Jackett/ConfigurationDataCookie.cs | 45 ++++++ src/Jackett/Indexers/BeyondHD.cs | 180 ++++++++++++++++++++++ src/Jackett/Indexers/SceneTime.cs | 2 +- src/Jackett/Jackett.csproj | 5 + src/Jackett/WebContent/logos/beyondhd.png | Bin 0 -> 30183 bytes 5 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 src/Jackett/ConfigurationDataCookie.cs create mode 100644 src/Jackett/Indexers/BeyondHD.cs create mode 100644 src/Jackett/WebContent/logos/beyondhd.png diff --git a/src/Jackett/ConfigurationDataCookie.cs b/src/Jackett/ConfigurationDataCookie.cs new file mode 100644 index 000000000..c184dfc5a --- /dev/null +++ b/src/Jackett/ConfigurationDataCookie.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Jackett +{ + + public class ConfigurationDataCookie : ConfigurationData + { + public StringItem Cookie { get; private set; } + public DisplayItem CookieHint { get; private set; } + public DisplayItem CookieExample { get; private set; } + + public ConfigurationDataCookie() + { + Cookie = new StringItem { Name = "Cookie" }; + CookieHint = new DisplayItem( + "
  1. Login to BeyondHD in your browser
  2. Open the developer console, go the network tab
  3. Find 'cookie' in the request headers
  4. Copy & paste it to here
") + { + Name = "CookieHint" + }; + CookieExample = new DisplayItem( + "Example cookie header (usually longer than this):
PHPSESSID=8rk27odm; ipsconnect_63ad9c=1; more_stuff=etc;") + { + Name = "CookieExample" + }; + } + + public override Item[] GetItems() + { + return new Item[] { Cookie, CookieHint, CookieExample }; + } + + public string CookieHeader + { + get + { + return Cookie.Value.Trim().TrimStart(new char[] { '"' }).TrimEnd(new char[] { '"' }); + } + } + } + +} diff --git a/src/Jackett/Indexers/BeyondHD.cs b/src/Jackett/Indexers/BeyondHD.cs new file mode 100644 index 000000000..f8c4fe955 --- /dev/null +++ b/src/Jackett/Indexers/BeyondHD.cs @@ -0,0 +1,180 @@ +using CsQuery; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Web; + +namespace Jackett.Indexers +{ + public class BeyondHD : IndexerInterface + { + public event Action OnSaveConfigurationRequested; + + public event Action OnResultParsingError; + + public string DisplayName + { + get { return "BeyondHD"; } + } + + public string DisplayDescription + { + get { return "Without BeyondHD, your HDTV is just a TV"; } + } + + public Uri SiteLink + { + get { return new Uri(BaseUrl); } + } + + public bool IsConfigured { get; private set; } + + const string BaseUrl = "https://beyondhd.me"; + const string SearchUrl = BaseUrl + "/browse.php?c40=1&c44=1&c48=1&c89=1&c46=1&c45=1&searchin=title&incldead=0&search={0}"; + const string DownloadUrl = BaseUrl + "/download.php?torrent={0}"; + + CookieContainer cookies; + HttpClientHandler handler; + HttpClient client; + + public BeyondHD() + { + IsConfigured = false; + cookies = new CookieContainer(); + handler = new HttpClientHandler + { + CookieContainer = cookies, + AllowAutoRedirect = true, + UseCookies = true, + }; + client = new HttpClient(handler); + } + + public Task GetConfigurationForSetup() + { + var config = new ConfigurationDataCookie(); + return Task.FromResult(config); + } + + public async Task ApplyConfiguration(JToken configJson) + { + var config = new ConfigurationDataCookie(); + config.LoadValuesFromJson(configJson); + + var jsonCookie = new JObject(); + jsonCookie["cookie_header"] = config.CookieHeader; + cookies.FillFromJson(new Uri(BaseUrl), jsonCookie); + + var responseContent = await client.GetStringAsync(BaseUrl); + + if (!responseContent.Contains("logout.php")) + { + CQ dom = responseContent; + throw new ExceptionWithConfigData("Invalid cookie header", (ConfigurationData)config); + } + else + { + var configSaveData = new JObject(); + cookies.DumpToJson(SiteLink, configSaveData); + + if (OnSaveConfigurationRequested != null) + OnSaveConfigurationRequested(this, configSaveData); + + IsConfigured = true; + } + + } + + public void LoadFromSavedConfiguration(JToken jsonConfig) + { + cookies.FillFromJson(new Uri(BaseUrl), jsonConfig); + IsConfigured = true; + } + + public async Task PerformQuery(TorznabQuery query) + { + List releases = new List(); + + foreach (var title in query.ShowTitles ?? new string[] { string.Empty }) + { + var searchString = title + " " + query.GetEpisodeSearchString(); + var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); + var results = await client.GetStringAsync(episodeSearchUrl); + + try + { + CQ dom = results; + var rows = dom["table.torrenttable > tbody > tr.browse_color"]; + foreach (var row in rows) + { + var release = new ReleaseInfo(); + release.MinimumRatio = 1; + release.MinimumSeedTime = 172800; + + var qRow = row.Cq(); + + var qLink = row.ChildElements.ElementAt(2).FirstChild.Cq(); + release.Link = new Uri(BaseUrl + "/" + qLink.Attr("href")); + var torrentID = qLink.Attr("href").Split('=').Last(); + + var descCol = row.ChildElements.ElementAt(3); + var qCommentLink = descCol.FirstChild.Cq(); + release.Title = qCommentLink.Text(); + release.Description = release.Title; + release.Comments = new Uri(BaseUrl + "/" + qCommentLink.Attr("href")); + release.Guid = release.Comments; + + var dateStr = descCol.ChildElements.Last().Cq().Text().Split('|').Last().ToLowerInvariant().Replace("ago.", "").Trim(); + var dateParts = dateStr.Split(new char[] { ' ', ' ' }, StringSplitOptions.RemoveEmptyEntries); + var timeSpan = TimeSpan.Zero; + for (var i = 0; i < dateParts.Length / 2; i++) + { + var timeVal = ParseUtil.CoerceInt(dateParts[i * 2]); + var timeUnit = dateParts[i * 2 + 1]; + if (timeUnit.Contains("year")) + timeSpan += TimeSpan.FromDays(365 * timeVal); + else if (timeUnit.Contains("month")) + timeSpan += TimeSpan.FromDays(30 * timeVal); + else if (timeUnit.Contains("day")) + timeSpan += TimeSpan.FromDays(timeVal); + else if (timeUnit.Contains("hour")) + timeSpan += TimeSpan.FromHours(timeVal); + else if (timeUnit.Contains("min")) + timeSpan += TimeSpan.FromMinutes(timeVal); + } + release.PublishDate = DateTime.SpecifyKind(DateTime.Now - timeSpan, DateTimeKind.Local); + + var sizeEl = row.ChildElements.ElementAt(7); + var sizeVal = ParseUtil.CoerceFloat(sizeEl.ChildNodes.First().NodeValue); + var sizeUnit = sizeEl.ChildNodes.Last().NodeValue; + + release.Size = ReleaseInfo.GetBytes(sizeUnit, sizeVal); + + release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(9).Cq().Text()); + release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(10).Cq().Text()) + release.Seeders; + + releases.Add(release); + + } + } + + catch (Exception ex) + { + OnResultParsingError(this, results, ex); + throw ex; + } + } + return releases.ToArray(); + } + + public Task Download(Uri link) + { + return client.GetByteArrayAsync(link); + } + } +} diff --git a/src/Jackett/Indexers/SceneTime.cs b/src/Jackett/Indexers/SceneTime.cs index 6aab040f2..853faaffc 100644 --- a/src/Jackett/Indexers/SceneTime.cs +++ b/src/Jackett/Indexers/SceneTime.cs @@ -33,6 +33,7 @@ namespace Jackett.Indexers get { return new Uri(BaseUrl); } } + public bool IsConfigured { get; private set; } const string BaseUrl = "https://www.scenetime.com"; const string LoginUrl = BaseUrl + "/takelogin.php"; @@ -43,7 +44,6 @@ namespace Jackett.Indexers HttpClientHandler handler; HttpClient client; - public bool IsConfigured { get; private set; } public SceneTime() { diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index 8a65654b8..532f6f42f 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -87,6 +87,7 @@ + @@ -94,6 +95,7 @@ + @@ -164,6 +166,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/src/Jackett/WebContent/logos/beyondhd.png b/src/Jackett/WebContent/logos/beyondhd.png new file mode 100644 index 0000000000000000000000000000000000000000..c52f810b35af30a035c66bc1d1ca07723e2729dd GIT binary patch literal 30183 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 S2Nm)EvZTco#0o_8U;clZx3^jV literal 0 HcmV?d00001