From dd98aa65924213ab302cf813bc2f110038bc4f6d Mon Sep 17 00:00:00 2001 From: ThomasAmpen Date: Mon, 22 Jun 2015 21:34:55 +0200 Subject: [PATCH] TorrentzSupport TorrentzSupport --- src/Jackett/Indexers/Torrentz.cs | 246 ++++++++++++++++++++++ src/Jackett/Jackett.csproj | 2 + src/Jackett/WebContent/logos/torrentz.png | Bin 0 -> 9072 bytes 3 files changed, 248 insertions(+) create mode 100644 src/Jackett/Indexers/Torrentz.cs create mode 100644 src/Jackett/WebContent/logos/torrentz.png diff --git a/src/Jackett/Indexers/Torrentz.cs b/src/Jackett/Indexers/Torrentz.cs new file mode 100644 index 000000000..c9109055a --- /dev/null +++ b/src/Jackett/Indexers/Torrentz.cs @@ -0,0 +1,246 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using System.Web; +using System.Windows.Forms; +using System.Xml; + +namespace Jackett.Indexers +{ + public class Torrentz : IndexerInterface + { + public event Action OnSaveConfigurationRequested; + + public event Action OnResultParsingError; + + public string DisplayName + { + get { return "Torrentz"; } + } + + public string DisplayDescription + { + get { return "Torrentz is a meta-search engine and a Multisearch. This means we just search other search engines."; } + } + + public Uri SiteLink + { + get { return new Uri(DefaultUrl); } + } + + const string DefaultUrl = "https://torrentz.eu"; + const string SearchUrl = DefaultUrl + "/feed_verifiedP?f={0}"; + string BaseUrl; + static string chromeUserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36"; + + CookieContainer cookies; + HttpClientHandler handler; + HttpClient client; + + public bool IsConfigured + { + get; + private set; + } + + public Torrentz() + { + IsConfigured = false; + cookies = new CookieContainer(); + handler = new HttpClientHandler + { + CookieContainer = cookies, + AllowAutoRedirect = true, + UseCookies = true, + }; + client = new HttpClient(handler); + } + + + + public Task GetConfigurationForSetup() + { + var config = new ConfigurationDataUrl(DefaultUrl); + return Task.FromResult(config); + + } + + public async Task ApplyConfiguration(JToken configJson) + { + var config = new ConfigurationDataUrl(DefaultUrl); + config.LoadValuesFromJson(configJson); + + var formattedUrl = config.GetFormattedHostUrl(); + var releases = await PerformQuery(new TorznabQuery(), formattedUrl); + if (releases.Length == 0) + throw new Exception("Could not find releases from this URL"); + + BaseUrl = formattedUrl; + + var configSaveData = new JObject(); + configSaveData["base_url"] = BaseUrl; + + if (OnSaveConfigurationRequested != null) + OnSaveConfigurationRequested(this, configSaveData); + + IsConfigured = true; + + } + + private WebClient getWebClient() + { + WebClient wc = new WebClient(); + WebHeaderCollection headers = new WebHeaderCollection(); + headers.Add("User-Agent", chromeUserAgent); + wc.Headers = headers; + return wc; + } + + async Task PerformQuery(TorznabQuery query, string baseUrl) + { + 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.Trim())); + + XmlDocument xmlDoc = new XmlDocument(); + string xml = string.Empty; + WebClient wc = getWebClient(); + + try + { + using (wc) + { + xml = wc.DownloadString(episodeSearchUrl); + xmlDoc.LoadXml(xml); + } + + ReleaseInfo release; + TorrentzDescription td; + + foreach (XmlNode node in xmlDoc.GetElementsByTagName("item")) + { + release = new ReleaseInfo(); + + release.MinimumRatio = 1; + release.MinimumSeedTime = 172800; + release.Title = node.SelectSingleNode("title").InnerText; + + release.Comments = new Uri(node.SelectSingleNode("link").InnerText); + release.Category = node.SelectSingleNode("category").InnerText; + release.Guid = new Uri(node.SelectSingleNode("guid").InnerText); + release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture); + + td = new TorrentzDescription(node.SelectSingleNode("description").InnerText); + release.Description = td.Description; + release.InfoHash = td.hash; + release.Size = td.Size; + release.Seeders = td.Seeders; + release.Peers = td.Peers; + release.MagnetUri = new Uri("https://torrage.com/torrent/" + td.hash.ToUpper() + ".torrent"); + releases.Add(release); + } + } + catch (Exception ex) + { + OnResultParsingError(this, xml, ex); + throw ex; + } + } + + return releases.ToArray(); + } + + + public void LoadFromSavedConfiguration(JToken jsonConfig) + { + BaseUrl = (string)jsonConfig["base_url"]; + IsConfigured = true; + } + + public async Task PerformQuery(TorznabQuery query) + { + return await PerformQuery(query, BaseUrl); + } + + public Task Download(Uri link) + { + throw new NotImplementedException(); + } + + } + + public class TorrentzDescription + { + public TorrentzDescription(string description) + { + this.Description = description; + if (null == description) + { + this.Description = ""; + this.Size = 0; + this.Peers = 0; + this.Seeders = 0; + this.hash = ""; + } + else + FillProperties(); + } + + private void FillProperties() + { + string description = this.Description; + int counter = 0; + while (description.Contains(" ")) + { + int nextSpace = description.IndexOf(": ") + 1; + int secondSpace; + if (counter != 0) + secondSpace = description.IndexOf(" ", nextSpace + 1); + else + secondSpace = description.IndexOf(": ", nextSpace + 2) - description.IndexOf(" ", nextSpace); + + string val; + if (secondSpace == -1) + { + val = description.Substring(nextSpace).Trim(); + description = string.Empty; + } + else + { + val = description.Substring(nextSpace, secondSpace - nextSpace).Trim(); + description = description.Substring(secondSpace); + } + + switch (counter) + { + case 0: + this.Size = ReleaseInfo.BytesFromMB(long.Parse(val.Substring(0, val.IndexOf(" ") - 1))); + break; + case 1: + this.Seeders = int.Parse(val.Contains(",") ? val.Remove(val.IndexOf(","), 1) : val); + break; + case 2: + this.Peers = int.Parse(val.Contains(",") ? val.Remove(val.IndexOf(","), 1) : val); + break; + case 3: + this.hash = val; + break; + } + counter++; + } + } + + public string Description { get; set; } + public long Size { get; set; } + public int Seeders { get; set; } + public int Peers { get; set; } + public string hash { get; set; } + } +} diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index de1e67018..2c895d48b 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -103,6 +103,7 @@ + Form @@ -222,6 +223,7 @@ PreserveNewest + PreserveNewest diff --git a/src/Jackett/WebContent/logos/torrentz.png b/src/Jackett/WebContent/logos/torrentz.png new file mode 100644 index 0000000000000000000000000000000000000000..6616e6d90ddd747d549e278e2640ddc84fbceb94 GIT binary patch literal 9072 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 literal 0 HcmV?d00001