From dfd68d16aa750a2903192a3fa594e8821bdb7881 Mon Sep 17 00:00:00 2001 From: zone117x <zone117x@gmail.com> Date: Sat, 25 Apr 2015 20:32:03 -0600 Subject: [PATCH] Added TorrentLeech --- src/Jackett/Indexers/TorrentLeech.cs | 164 ++++++++++++++++++ src/Jackett/Jackett.csproj | 4 + src/Jackett/WebContent/logos/torrentleech.png | Bin 0 -> 24303 bytes 3 files changed, 168 insertions(+) create mode 100644 src/Jackett/Indexers/TorrentLeech.cs create mode 100644 src/Jackett/WebContent/logos/torrentleech.png diff --git a/src/Jackett/Indexers/TorrentLeech.cs b/src/Jackett/Indexers/TorrentLeech.cs new file mode 100644 index 00000000..eb15fa91 --- /dev/null +++ b/src/Jackett/Indexers/TorrentLeech.cs @@ -0,0 +1,164 @@ +using CsQuery; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Globalization; +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 TorrentLeech : IndexerInterface + { + + public event Action<IndexerInterface, JToken> OnSaveConfigurationRequested; + + public string DisplayName + { + get { return "TorrentLeech"; } + } + + public string DisplayDescription + { + get { return "This is what happens when you seed"; } + } + + public Uri SiteLink + { + get { return new Uri(BaseUrl); } + } + + const string BaseUrl = "http://www.torrentleech.org"; + const string LoginUrl = BaseUrl + "/user/account/login/"; + const string SearchUrl = BaseUrl + "/torrents/browse/index/query/{0}/categories/2%2C26%2C27%2C32/orderby/added?"; + + public bool IsConfigured { get; private set; } + + + CookieContainer cookies; + HttpClientHandler handler; + HttpClient client; + + public TorrentLeech() + { + IsConfigured = false; + cookies = new CookieContainer(); + handler = new HttpClientHandler + { + CookieContainer = cookies, + AllowAutoRedirect = true, + UseCookies = true, + }; + client = new HttpClient(handler); + } + + public Task<ConfigurationData> GetConfigurationForSetup() + { + var config = new ConfigurationDataBasicLogin(); + return Task.FromResult<ConfigurationData>(config); + } + + public async Task ApplyConfiguration(JToken configJson) + { + var config = new ConfigurationDataBasicLogin(); + config.LoadValuesFromJson(configJson); + + var pairs = new Dictionary<string, string> { + { "username", config.Username.Value }, + { "password", config.Password.Value }, + { "remember_me", "on" }, + { "login", "submit" } + }; + + var content = new FormUrlEncodedContent(pairs); + + var response = await client.PostAsync(LoginUrl, content); + var responseContent = await response.Content.ReadAsStringAsync(); + + if (!responseContent.Contains("/user/account/logout")) + { + CQ dom = responseContent; + var messageEl = dom[".ui-state-error"].Last(); + var errorMessage = messageEl.Text().Trim(); + throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config); + } + else + { + var configSaveData = new JObject(); + configSaveData["cookies"] = cookies.ToJson(SiteLink); + + if (OnSaveConfigurationRequested != null) + OnSaveConfigurationRequested(this, configSaveData); + + IsConfigured = true; + } + } + + public void LoadFromSavedConfiguration(JToken jsonConfig) + { + cookies.FillFromJson(new Uri(BaseUrl), (JArray)jsonConfig["cookies"]); + IsConfigured = true; + } + + public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query) + { + List<ReleaseInfo> releases = new List<ReleaseInfo>(); + + + 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); + CQ dom = results; + + CQ qRows = dom["#torrenttable > tbody > tr"]; + + foreach (var row in qRows) + { + var release = new ReleaseInfo(); + + var qRow = row.Cq(); + + var debug = qRow.Html(); + + release.MinimumRatio = 1; + release.MinimumSeedTime = 172800; + + CQ qLink = qRow.Find(".title > a").First(); + release.Guid = new Uri(BaseUrl + qLink.Attr("href")); + release.Comments = release.Guid; + release.Title = qLink.Text(); + release.Description = release.Title; + + release.Link = new Uri(BaseUrl + qRow.Find(".quickdownload > a").Attr("href")); + + var dateString = qRow.Find(".name").First()[0].ChildNodes[4].NodeValue.Replace(" on", "").Trim(); + //"2015-04-25 23:38:12" + //"yyyy-MMM-dd hh:mm:ss" + release.PublishDate = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); + + var sizeStringParts = qRow.Children().ElementAt(4).InnerText.Split(' '); + release.Size = ReleaseInfo.GetBytes(sizeStringParts[1], float.Parse(sizeStringParts[0])); + + release.Seeders = int.Parse(qRow.Find(".seeders").Text()); + release.Peers = int.Parse(qRow.Find(".leechers").Text()); + + releases.Add(release); + } + + } + + return releases.ToArray(); + } + + public Task<byte[]> Download(Uri link) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Jackett/Jackett.csproj b/src/Jackett/Jackett.csproj index bfd48e2d..8e1b8343 100644 --- a/src/Jackett/Jackett.csproj +++ b/src/Jackett/Jackett.csproj @@ -96,6 +96,7 @@ <Compile Include="Indexers\MoreThanTV.cs" /> <Compile Include="Indexers\Strike.cs" /> <Compile Include="Indexers\ThePirateBay.cs" /> + <Compile Include="Indexers\TorrentLeech.cs" /> <Compile Include="Main.cs"> <SubType>Form</SubType> </Compile> @@ -202,6 +203,9 @@ <Content Include="WebContent\logos\thepiratebay.png"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="WebContent\logos\torrentleech.png"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> <Content Include="WebContent\setup_indexer.html"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> diff --git a/src/Jackett/WebContent/logos/torrentleech.png b/src/Jackett/WebContent/logos/torrentleech.png new file mode 100644 index 0000000000000000000000000000000000000000..49dda625b3ca1217f1516e94f85ca3b1e0b0ee91 GIT binary patch literal 24303 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 V9KZ0;qZD**sHdx+%Q~loCIH1>fl2@X literal 0 HcmV?d00001 -- GitLab