From b65ab8b4350f8ac221fc8b2fe8fbc655a5afdc0f Mon Sep 17 00:00:00 2001 From: Fuffenz Date: Fri, 23 Oct 2015 00:31:59 +0200 Subject: [PATCH 1/2] Basic GFTracker support --- src/Jackett/Content/logos/gftracker.png | Bin 0 -> 5466 bytes src/Jackett/Indexers/GFTracker.cs | 202 ++++++++++++++++++++++++ src/Jackett/Jackett.csproj | 4 +- 3 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 src/Jackett/Content/logos/gftracker.png create mode 100644 src/Jackett/Indexers/GFTracker.cs diff --git a/src/Jackett/Content/logos/gftracker.png b/src/Jackett/Content/logos/gftracker.png new file mode 100644 index 0000000000000000000000000000000000000000..126d34bf9a7434900f5e84da030f3eeb8b9152ba GIT binary patch literal 5466 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 GetConfigurationForSetup() + { + var loginPage = await RequestStringWithCookies(StartPageUrl, string.Empty); + CQ cq = loginPage.Content; + var result = new ConfigurationDataRecaptchaLogin(); + CQ recaptcha = cq.Find(".g-recaptcha").Attr("data-sitekey"); + if(recaptcha.Length != 0) // recaptcha not always present in login form, perhaps based on cloudflare uid or just phase of the moon + { + result.CookieHeader.Value = loginPage.Cookies; + result.Captcha.SiteKey = cq.Find(".g-recaptcha").Attr("data-sitekey"); + return result; + } else + { + var stdResult = new ConfigurationDataBasicLogin(); + stdResult.CookieHeader.Value = loginPage.Cookies; + return stdResult; + } + } + + public async Task ApplyConfiguration(JToken configJson) + { + configData.LoadValuesFromJson(configJson); + var pairs = new Dictionary { + { "username", configData.Username.Value }, + { "password", configData.Password.Value }, + { "g-recaptcha-response", configData.Captcha.Value } + }; + + if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie)) + { + CookieHeader = configData.Captcha.Cookie; + try + { + var results = await PerformQuery(new TorznabQuery()); + if (results.Count() == 0) + { + throw new Exception("Your cookie did not work"); + } + + SaveConfig(); + IsConfigured = true; + return IndexerConfigurationStatus.Completed; + } + catch (Exception e) + { + IsConfigured = false; + throw new Exception("Your cookie did not work: " + e.Message); + } + } + + var cookieJar = configData.CookieHeader.Value; + var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, configData.CookieHeader.Value, true, null, StartPageUrl); + cookieJar += response.Cookies.ToString(); + response = await RequestStringWithCookiesAndRetry(SearchUrl, cookieJar); + + await ConfigureIfOK(cookieJar, response.Content != null && response.Content.Contains("logout.php"), () => + { + CQ dom = response.Content; + var messageEl = dom["h2"].Last(); + messageEl.Children("a").Remove(); + messageEl.Children("style").Remove(); + 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 queryCollection = new NameValueCollection(); + + queryCollection.Add("view", "0"); + if (!string.IsNullOrWhiteSpace(searchString)) + { + queryCollection.Add("search", searchString); + } + + foreach (var cat in MapTorznabCapsToTrackers(query)) + { + queryCollection.Add(string.Format("c{0}", cat), "1"); + } + + var searchUrl = SearchUrl + "?" + queryCollection.GetQueryString(); + + var results = await RequestStringWithCookiesAndRetry(searchUrl, CookieHeader); + try + { + CQ dom = results.Content; + var rows = dom["#torrentBrowse > table > tbody > tr"]; + foreach (var row in rows.Skip(1)) + { + var release = new ReleaseInfo(); + CQ qRow = row.Cq(); + + //CQ qLink = qRow.Children().ElementAt(1).Cq().Children("a").ElementAt(1).Cq(); + CQ qLink; + CQ qTmp = qRow.Children().ElementAt(1).Cq().Find("a"); + if (qTmp.Length < 2) { + qLink = qRow.Children().ElementAt(1).Cq().Find("a").ElementAt(0).Cq(); + } else { + qLink = qRow.Children().ElementAt(1).Cq().Find("a").ElementAt(1).Cq(); + } + + release.MinimumRatio = 1; + release.MinimumSeedTime = 172800; + release.Title = qLink.Attr("title"); + release.Description = release.Title; + release.Guid = new Uri(SiteLink + qLink.Attr("href").TrimStart('/')); + release.Comments = release.Guid; + + qLink = qRow.Children().ElementAt(3).Cq().Children("a").First(); + release.Link = new Uri(string.Format("{0}{1}", SiteLink, qLink.Attr("href"))); + + var catUrl = qRow.Children().ElementAt(0).FirstElementChild.Cq().Attr("href"); + var catNum = catUrl.Split(new char[] { '=', '&' })[2].Replace("c", ""); + release.Category = MapTrackerCatToNewznab(catNum); + + var dateString = qRow.Children().ElementAt(6).Cq().Text().Trim(); + //var pubDate = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); + release.PublishDate = Jackett.Utils.DateTimeUtil.FromTimeAgo(dateString); + + var sizeStr = qRow.Children().ElementAt(7).Cq().Text().Split(new char[] { '/' })[0]; + release.Size = ReleaseInfo.GetBytes(sizeStr); + + release.Seeders = ParseUtil.CoerceInt(qRow.Children().ElementAt(8).Cq().Text().Split(new char[] { '/' })[0].Trim()); + release.Peers = ParseUtil.CoerceInt(qRow.Children().ElementAt(8).Cq().Text().Split(new char[] { '/' })[1].Trim()) + release.Seeders; + + releases.Add(release); + } + } + catch (Exception ex) + { + OnParseError(results.Content, ex); + } + + return releases; + } + } +} diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index 3e27aa3c8..0564f6098 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -186,6 +186,7 @@ + @@ -449,6 +450,7 @@ PreserveNewest + PreserveNewest @@ -635,4 +637,4 @@ - + \ No newline at end of file From a87cdc3443527145e54d9d692a87bf8363e9b695 Mon Sep 17 00:00:00 2001 From: Fuffenz Date: Fri, 23 Oct 2015 13:43:37 +0200 Subject: [PATCH 2/2] copy gftracker logo on release build --- src/Jackett/Jackett.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index 0564f6098..0180d809e 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -450,7 +450,9 @@ PreserveNewest - + + PreserveNewest + PreserveNewest