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