From 2abf4f0ee63c486f215c8da192d6b3b104f61d3d Mon Sep 17 00:00:00 2001 From: kaso17 Date: Wed, 7 Sep 2016 14:00:25 +0200 Subject: [PATCH] Add Torrent-Syndikat tracker --- README.md | 1 + src/Jackett/Content/logos/torrentsyndikat.png | Bin 0 -> 3616 bytes src/Jackett/Indexers/TorrentSyndikat.cs | 202 ++++++++++++++++++ src/Jackett/Jackett.csproj | 4 + 4 files changed, 207 insertions(+) create mode 100644 src/Jackett/Content/logos/torrentsyndikat.png create mode 100644 src/Jackett/Indexers/TorrentSyndikat.cs diff --git a/README.md b/README.md index 7cd35eeaa..f7847b7b0 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/ * TorrentDay * TorrentLeech * TorrentShack + * Torrent-Syndikat * TransmitheNet * TV Chaos UK * World-In-HD diff --git a/src/Jackett/Content/logos/torrentsyndikat.png b/src/Jackett/Content/logos/torrentsyndikat.png new file mode 100644 index 0000000000000000000000000000000000000000..93e9d976b53d2afaa350b7fc738fe5b7359c886d GIT binary patch literal 3616 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 ApplyConfiguration(JToken configJson) + { + configData.LoadValuesFromJson(configJson); + + var result1 = await RequestStringWithCookies(CaptchaUrl); + var json1 = JObject.Parse(result1.Content); + var captchaSelection = json1["images"][0]["hash"]; + + var pairs = new Dictionary { + { "username", configData.Username.Value }, + { "password", configData.Password.Value }, + { "captchaSelection", (string)captchaSelection }, + { "submitme", "X" } + }; + + var result2 = await RequestLoginAndFollowRedirect(LoginUrl, pairs, result1.Cookies, true, null, null, true); + + await ConfigureIfOK(result2.Cookies, result2.Content.Contains("/logout.php"), () => + { + var errorMessage = result2.Content; + throw new ExceptionWithConfigData(errorMessage, configData); + }); + return IndexerConfigurationStatus.RequiresTesting; + } + + public async Task> PerformQuery(TorznabQuery query) + { + List releases = new List(); + + var searchString = query.GetQueryString(); + var searchUrl = SearchUrl; + var queryCollection = new NameValueCollection(); + queryCollection.Add("searchin", "title"); + queryCollection.Add("incldead", "1"); + queryCollection.Add("rel_type", "0"); // Alle + if (!string.IsNullOrWhiteSpace(searchString)) + { + // use AND+wildcard operator to avoid getting to many useless results + var searchStringArray = Regex.Split(searchString.Trim(), "[ _.-]+", RegexOptions.Compiled).ToList(); + searchStringArray = searchStringArray.Where(x => x.Length >= 3).ToList(); // remove words with less than 3 characters + searchStringArray = searchStringArray.Select(x => "+" + x + "*").ToList(); // add AND operators+wildcards + var searchStringFinal = String.Join(" ", searchStringArray); + queryCollection.Add("search", searchStringFinal); + } + + foreach (var cat in MapTorznabCapsToTrackers(query)) + { + queryCollection.Add("c" + cat, "1"); + } + + searchUrl += "?" + queryCollection.GetQueryString(); + + var results = await RequestStringWithCookiesAndRetry(searchUrl); + try + { + CQ dom = results.Content; + var rows = dom["table.torrent_table > tbody > tr"]; + foreach (var row in rows.Skip(1)) + { + var release = new ReleaseInfo(); + release.MinimumRatio = 1; + release.MinimumSeedTime = 96*60*60; + + var qRow = row.Cq(); + + var catStr = row.ChildElements.ElementAt(0).FirstElementChild.GetAttribute("href").Split('=')[1]; + release.Category = MapTrackerCatToNewznab(catStr); + + var qLink = row.ChildElements.ElementAt(2).FirstElementChild.Cq(); + release.Link = new Uri(SiteLink + qLink.Attr("href")); + var torrentId = qLink.Attr("href").Split('=').Last(); + + var descCol = row.ChildElements.ElementAt(1); + var qCommentLink = descCol.FirstElementChild.Cq(); + var torrentTag = descCol.Cq().Find("span.torrent-tag"); + var torrentTags = torrentTag.Elements.Select(x => x.InnerHTML).ToList(); + release.Title = qCommentLink.Text(); + release.Description = String.Join(", ", torrentTags); + release.Comments = new Uri(SiteLink + "/" + qCommentLink.Attr("href").Replace("&hit=1", "")); + release.Guid = release.Comments; + + var torrent_details = descCol.ChildElements.Last(); + var dateStr = torrent_details.ChildNodes.ElementAt(torrent_details.ChildNodes.Length-3).Cq().Text().Replace(" von ", "").Trim(); + DateTime dateGerman; + if (dateStr.StartsWith("Heute ")) + dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStr.Split(' ')[1]); + else if (dateStr.StartsWith("Gestern ")) + dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStr.Split(' ')[1]) - TimeSpan.FromDays(1); + else + dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified); + + DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz); + release.PublishDate = pubDateUtc.ToLocalTime(); + + var sizeStr = row.ChildElements.ElementAt(5).Cq().Text(); + release.Size = ReleaseInfo.GetBytes(sizeStr); + + release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text()); + release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(8).Cq().Text()) + 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 5688686d3..34f7d76f2 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -160,6 +160,7 @@ + @@ -428,6 +429,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest