{"action":"created","comment":{"url":"https://api.github.com/repos/zone117x/Jackett/pulls/comments/34423436","id":34423436,"diff_hunk":"@@ -0,0 +1,233 @@\n+﻿using CsQuery;\n+using Newtonsoft.Json.Linq;\n+using System;\n+using System.Collections.Generic;\n+using System.Globalization;\n+using System.Linq;\n+using System.Net;\n+using System.Net.Http;\n+using System.Text;\n+using System.Threading.Tasks;\n+using System.Web;\n+\n+namespace Jackett.Indexers\n+{\n+    public class HDTorrents : IndexerInterface\n+    {\n+        public event Action<IndexerInterface, JToken> OnSaveConfigurationRequested;\n+\n+        public event Action<IndexerInterface, string, Exception> OnResultParsingError;\n+\n+        const string DefaultUrl = \"https://hd-torrents.org\";\n+        string BaseUrl;\n+        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\";\n+        private string SearchUrl = \"https://hd-torrents.org/torrents.php?search={0}&active=1&options=0&category%5B%5D=59&category%5B%5D=60&category%5B%5D=30&category%5B%5D=38&page={1}\";\n+        private static string LoginUrl = DefaultUrl + \"/login.php\";\n+        private static string LoginPostUrl = DefaultUrl + \"/login.php?returnto=index.php\";\n+        private const int MAXPAGES = 3;\n+\n+        CookieContainer cookies;\n+        HttpClientHandler handler;\n+        HttpClient client;\n+\n+        public HDTorrents()\n+        {\n+            IsConfigured = false;\n+            cookies = new CookieContainer();\n+            handler = new HttpClientHandler\n+            {\n+                CookieContainer = cookies,\n+                AllowAutoRedirect = true,\n+                UseCookies = true,\n+            };\n+            client = new HttpClient(handler);\n+        }\n+\n+        public string DisplayName\n+        {\n+            get { return \"HD-Torrents\"; }\n+        }\n+\n+        public string DisplayDescription\n+        {\n+            get { return \"HD-Torrents is a private torrent website with HD torrents and strict rules on their content.\"; }\n+        }\n+\n+        public Uri SiteLink\n+        {\n+            get { return new Uri(DefaultUrl); }\n+        }\n+\n+        public bool IsConfigured\n+        {\n+            get;\n+            private set;\n+        }\n+\n+        public Task<ConfigurationData> GetConfigurationForSetup()\n+        {\n+            var config = new ConfigurationDataBasicLogin();\n+            return Task.FromResult<ConfigurationData>(config);\n+        }\n+\n+        HttpRequestMessage CreateHttpRequest(string url)\n+        {\n+            var message = new HttpRequestMessage();\n+            message.Method = HttpMethod.Get;\n+            message.RequestUri = new Uri(url);\n+            message.Headers.UserAgent.ParseAdd(ChromeUserAgent);\n+            return message;\n+        }\n+\n+        public async Task ApplyConfiguration(JToken configJson)\n+        {\n+            var config = new ConfigurationDataBasicLogin();\n+            config.LoadValuesFromJson(configJson);\n+\n+            var startMessage = CreateHttpRequest(LoginUrl);\n+            var results = await (await client.SendAsync(startMessage)).Content.ReadAsStringAsync();\n+\n+\n+            var pairs = new Dictionary<string, string> {\n+\t\t\t\t{ \"uid\", config.Username.Value },\n+\t\t\t\t{ \"pwd\", config.Password.Value }\n+\t\t\t};\n+\n+            var content = new FormUrlEncodedContent(pairs);\n+\n+            var loginRequest = CreateHttpRequest(LoginUrl);\n+            loginRequest.Method = HttpMethod.Post;\n+            loginRequest.Content = content;\n+            loginRequest.Headers.Referrer = new Uri(\"https://hd-torrents.org/torrents.php\");\n+\n+            var response = await client.SendAsync(loginRequest);\n+            var responseContent = await response.Content.ReadAsStringAsync();\n+\n+            if (!responseContent.Contains(\"If your browser doesn't have javascript enabled\"))\n+            {\n+                var errorMessage = \"Couldn't login\";\n+                throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config);\n+            }\n+            else\n+            {\n+                var configSaveData = new JObject();\n+                cookies.DumpToJson(SiteLink, configSaveData);\n+\n+                if (OnSaveConfigurationRequested != null)\n+                    OnSaveConfigurationRequested(this, configSaveData);\n+\n+                IsConfigured = true;\n+            }\n+        }\n+\n+        public void LoadFromSavedConfiguration(JToken jsonConfig)\n+        {\n+            cookies.FillFromJson(SiteLink, jsonConfig);\n+            IsConfigured = true;\n+        }\n+\n+        async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query, string baseUrl)\n+        {\n+            List<ReleaseInfo> releases = new List<ReleaseInfo>();\n+            List<string> searchurls = new List<string>();\n+\n+            foreach (var title in query.ShowTitles ?? new string[] { string.Empty })\n+            {\n+                var searchString = title + \" \" + query.GetEpisodeSearchString();\n+                for (int page = 0; page < MAXPAGES; page++)\n+                    searchurls.Add(string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim()), page));\n+            }\n+\n+            foreach (string SearchUrl in searchurls)\n+            {\n+                var results = await client.GetStringAsync(SearchUrl);\n+                try\n+                {\n+                    CQ dom = results;\n+                    ReleaseInfo release;\n+\n+                    int rowCount = 0;\n+                    var rows = dom[\".mainblockcontenttt > tbody > tr\"];\n+                    foreach (var row in rows)\n+                    {\n+                        CQ qRow = row.Cq();\n+                        if (rowCount < 2 || qRow.Children().Count() != 12) //skip 2 rows because there's an empty row & a title/sort row\n+                        {\n+                            rowCount++;\n+                            continue;\n+                        }\n+\n+                        release = new ReleaseInfo();\n+                        long imdbid;\n+                        long? size;\n+                        int seeders, peers;\n+\n+                        release.Title = qRow.Find(\"td.mainblockcontent b a\").Text();\n+                        release.Description = release.Title;\n+\n+                        if (0 != qRow.Find(\"td.mainblockcontent u\").Length && long.TryParse(qRow.Find(\"td.mainblockcontent u\").Parent().First().Attr(\"href\").Replace(\"http://www.imdb.com/title/tt\", \"\").Replace(\"/\", \"\"), out imdbid))\n+                            release.Imdb = imdbid;\n+\n+                        release.MinimumRatio = 1;\n+                        release.MinimumSeedTime = 172800;\n+\n+                        release.MagnetUri = new Uri(DefaultUrl + \"/\" + qRow.Find(\"td.mainblockcontent\").Get(3).FirstChild.GetAttribute(\"href\"));\n+\n+                        if (int.TryParse(qRow.Find(\"td\").Get(9).FirstChild.FirstChild.InnerText, out seeders))\n+                            release.Seeders = seeders;\n+                        if (int.TryParse(qRow.Find(\"td\").Get(10).FirstChild.FirstChild.InnerText, out peers))\n+                            release.Peers = peers;\n+\n+                        string fullSize = qRow.Find(\"td.mainblockcontent\").Get(6).InnerText;\n+                        string[] sizeSplit = fullSize.Split(' ');\n+                        switch (sizeSplit[1].ToLower())\n+                        {\n+                            case \"kb\":\n+                                size = ReleaseInfo.BytesFromKB(float.Parse(sizeSplit[0], CultureInfo.InvariantCulture));","path":"src/Jackett/Indexers/HDTorrents.cs","position":186,"original_position":186,"commit_id":"5744e6ff086ac4db4429c73fe45d45b90ab49642","original_commit_id":"5744e6ff086ac4db4429c73fe45d45b90ab49642","user":{"login":"damwthomas","id":8473754,"avatar_url":"https://avatars.githubusercontent.com/u/8473754?v=3","gravatar_id":"","url":"https://api.github.com/users/damwthomas","html_url":"https://github.com/damwthomas","followers_url":"https://api.github.com/users/damwthomas/followers","following_url":"https://api.github.com/users/damwthomas/following{/other_user}","gists_url":"https://api.github.com/users/damwthomas/gists{/gist_id}","starred_url":"https://api.github.com/users/damwthomas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/damwthomas/subscriptions","organizations_url":"https://api.github.com/users/damwthomas/orgs","repos_url":"https://api.github.com/users/damwthomas/repos","events_url":"https://api.github.com/users/damwthomas/events{/privacy}","received_events_url":"https://api.github.com/users/damwthomas/received_events","type":"User","site_admin":false},"body":"OH yes, I'm sorry","created_at":"2015-07-12T17:11:43Z","updated_at":"2015-07-12T17:11:43Z","html_url":"https://github.com/zone117x/Jackett/pull/79#discussion_r34423436","pull_request_url":"https://api.github.com/repos/zone117x/Jackett/pulls/79","_links":{"self":{"href":"https://api.github.com/repos/zone117x/Jackett/pulls/comments/34423436"},"html":{"href":"https://github.com/zone117x/Jackett/pull/79#discussion_r34423436"},"pull_request":{"href":"https://api.github.com/repos/zone117x/Jackett/pulls/79"}}},"pull_request":{"url":"https://api.github.com/repos/zone117x/Jackett/pulls/79","id":39620271,"html_url":"https://github.com/zone117x/Jackett/pull/79","diff_url":"https://github.com/zone117x/Jackett/pull/79.diff","patch_url":"https://github.com/zone117x/Jackett/pull/79.patch","issue_url":"https://api.github.com/repos/zone117x/Jackett/issues/79","number":79,"state":"open","locked":false,"title":"HDTorrents","user":{"login":"damwthomas","id":8473754,"avatar_url":"https://avatars.githubusercontent.com/u/8473754?v=3","gravatar_id":"","url":"https://api.github.com/users/damwthomas","html_url":"https://github.com/damwthomas","followers_url":"https://api.github.com/users/damwthomas/followers","following_url":"https://api.github.com/users/damwthomas/following{/other_user}","gists_url":"https://api.github.com/users/damwthomas/gists{/gist_id}","starred_url":"https://api.github.com/users/damwthomas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/damwthomas/subscriptions","organizations_url":"https://api.github.com/users/damwthomas/orgs","repos_url":"https://api.github.com/users/damwthomas/repos","events_url":"https://api.github.com/users/damwthomas/events{/privacy}","received_events_url":"https://api.github.com/users/damwthomas/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-07-09T19:40:03Z","updated_at":"2015-07-12T17:11:43Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5a8180519e02e6d402d9c74c8a234c56008f316e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/zone117x/Jackett/pulls/79/commits","review_comments_url":"https://api.github.com/repos/zone117x/Jackett/pulls/79/comments","review_comment_url":"https://api.github.com/repos/zone117x/Jackett/pulls/comments{/number}","comments_url":"https://api.github.com/repos/zone117x/Jackett/issues/79/comments","statuses_url":"https://api.github.com/repos/zone117x/Jackett/statuses/5744e6ff086ac4db4429c73fe45d45b90ab49642","head":{"label":"damwthomas:master","ref":"master","sha":"5744e6ff086ac4db4429c73fe45d45b90ab49642","user":{"login":"damwthomas","id":8473754,"avatar_url":"https://avatars.githubusercontent.com/u/8473754?v=3","gravatar_id":"","url":"https://api.github.com/users/damwthomas","html_url":"https://github.com/damwthomas","followers_url":"https://api.github.com/users/damwthomas/followers","following_url":"https://api.github.com/users/damwthomas/following{/other_user}","gists_url":"https://api.github.com/users/damwthomas/gists{/gist_id}","starred_url":"https://api.github.com/users/damwthomas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/damwthomas/subscriptions","organizations_url":"https://api.github.com/users/damwthomas/orgs","repos_url":"https://api.github.com/users/damwthomas/repos","events_url":"https://api.github.com/users/damwthomas/events{/privacy}","received_events_url":"https://api.github.com/users/damwthomas/received_events","type":"User","site_admin":false},"repo":{"id":37825383,"name":"Jackett","full_name":"damwthomas/Jackett","owner":{"login":"damwthomas","id":8473754,"avatar_url":"https://avatars.githubusercontent.com/u/8473754?v=3","gravatar_id":"","url":"https://api.github.com/users/damwthomas","html_url":"https://github.com/damwthomas","followers_url":"https://api.github.com/users/damwthomas/followers","following_url":"https://api.github.com/users/damwthomas/following{/other_user}","gists_url":"https://api.github.com/users/damwthomas/gists{/gist_id}","starred_url":"https://api.github.com/users/damwthomas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/damwthomas/subscriptions","organizations_url":"https://api.github.com/users/damwthomas/orgs","repos_url":"https://api.github.com/users/damwthomas/repos","events_url":"https://api.github.com/users/damwthomas/events{/privacy}","received_events_url":"https://api.github.com/users/damwthomas/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/damwthomas/Jackett","description":"User any tracker with Sonarr","fork":true,"url":"https://api.github.com/repos/damwthomas/Jackett","forks_url":"https://api.github.com/repos/damwthomas/Jackett/forks","keys_url":"https://api.github.com/repos/damwthomas/Jackett/keys{/key_id}","collaborators_url":"https://api.github.com/repos/damwthomas/Jackett/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/damwthomas/Jackett/teams","hooks_url":"https://api.github.com/repos/damwthomas/Jackett/hooks","issue_events_url":"https://api.github.com/repos/damwthomas/Jackett/issues/events{/number}","events_url":"https://api.github.com/repos/damwthomas/Jackett/events","assignees_url":"https://api.github.com/repos/damwthomas/Jackett/assignees{/user}","branches_url":"https://api.github.com/repos/damwthomas/Jackett/branches{/branch}","tags_url":"https://api.github.com/repos/damwthomas/Jackett/tags","blobs_url":"https://api.github.com/repos/damwthomas/Jackett/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/damwthomas/Jackett/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/damwthomas/Jackett/git/refs{/sha}","trees_url":"https://api.github.com/repos/damwthomas/Jackett/git/trees{/sha}","statuses_url":"https://api.github.com/repos/damwthomas/Jackett/statuses/{sha}","languages_url":"https://api.github.com/repos/damwthomas/Jackett/languages","stargazers_url":"https://api.github.com/repos/damwthomas/Jackett/stargazers","contributors_url":"https://api.github.com/repos/damwthomas/Jackett/contributors","subscribers_url":"https://api.github.com/repos/damwthomas/Jackett/subscribers","subscription_url":"https://api.github.com/repos/damwthomas/Jackett/subscription","commits_url":"https://api.github.com/repos/damwthomas/Jackett/commits{/sha}","git_commits_url":"https://api.github.com/repos/damwthomas/Jackett/git/commits{/sha}","comments_url":"https://api.github.com/repos/damwthomas/Jackett/comments{/number}","issue_comment_url":"https://api.github.com/repos/damwthomas/Jackett/issues/comments{/number}","contents_url":"https://api.github.com/repos/damwthomas/Jackett/contents/{+path}","compare_url":"https://api.github.com/repos/damwthomas/Jackett/compare/{base}...{head}","merges_url":"https://api.github.com/repos/damwthomas/Jackett/merges","archive_url":"https://api.github.com/repos/damwthomas/Jackett/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/damwthomas/Jackett/downloads","issues_url":"https://api.github.com/repos/damwthomas/Jackett/issues{/number}","pulls_url":"https://api.github.com/repos/damwthomas/Jackett/pulls{/number}","milestones_url":"https://api.github.com/repos/damwthomas/Jackett/milestones{/number}","notifications_url":"https://api.github.com/repos/damwthomas/Jackett/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/damwthomas/Jackett/labels{/name}","releases_url":"https://api.github.com/repos/damwthomas/Jackett/releases{/id}","created_at":"2015-06-21T20:48:51Z","updated_at":"2015-06-21T20:48:51Z","pushed_at":"2015-07-12T16:55:34Z","git_url":"git://github.com/damwthomas/Jackett.git","ssh_url":"git@github.com:damwthomas/Jackett.git","clone_url":"https://github.com/damwthomas/Jackett.git","svn_url":"https://github.com/damwthomas/Jackett","homepage":"","size":954,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"zone117x:master","ref":"master","sha":"3b22973b6dafc8ea694c9eb2dbcd4e3dffe1ff9e","user":{"login":"zone117x","id":1447546,"avatar_url":"https://avatars.githubusercontent.com/u/1447546?v=3","gravatar_id":"","url":"https://api.github.com/users/zone117x","html_url":"https://github.com/zone117x","followers_url":"https://api.github.com/users/zone117x/followers","following_url":"https://api.github.com/users/zone117x/following{/other_user}","gists_url":"https://api.github.com/users/zone117x/gists{/gist_id}","starred_url":"https://api.github.com/users/zone117x/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zone117x/subscriptions","organizations_url":"https://api.github.com/users/zone117x/orgs","repos_url":"https://api.github.com/users/zone117x/repos","events_url":"https://api.github.com/users/zone117x/events{/privacy}","received_events_url":"https://api.github.com/users/zone117x/received_events","type":"User","site_admin":false},"repo":{"id":33851326,"name":"Jackett","full_name":"zone117x/Jackett","owner":{"login":"zone117x","id":1447546,"avatar_url":"https://avatars.githubusercontent.com/u/1447546?v=3","gravatar_id":"","url":"https://api.github.com/users/zone117x","html_url":"https://github.com/zone117x","followers_url":"https://api.github.com/users/zone117x/followers","following_url":"https://api.github.com/users/zone117x/following{/other_user}","gists_url":"https://api.github.com/users/zone117x/gists{/gist_id}","starred_url":"https://api.github.com/users/zone117x/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zone117x/subscriptions","organizations_url":"https://api.github.com/users/zone117x/orgs","repos_url":"https://api.github.com/users/zone117x/repos","events_url":"https://api.github.com/users/zone117x/events{/privacy}","received_events_url":"https://api.github.com/users/zone117x/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/zone117x/Jackett","description":"User any tracker with Sonarr","fork":false,"url":"https://api.github.com/repos/zone117x/Jackett","forks_url":"https://api.github.com/repos/zone117x/Jackett/forks","keys_url":"https://api.github.com/repos/zone117x/Jackett/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zone117x/Jackett/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zone117x/Jackett/teams","hooks_url":"https://api.github.com/repos/zone117x/Jackett/hooks","issue_events_url":"https://api.github.com/repos/zone117x/Jackett/issues/events{/number}","events_url":"https://api.github.com/repos/zone117x/Jackett/events","assignees_url":"https://api.github.com/repos/zone117x/Jackett/assignees{/user}","branches_url":"https://api.github.com/repos/zone117x/Jackett/branches{/branch}","tags_url":"https://api.github.com/repos/zone117x/Jackett/tags","blobs_url":"https://api.github.com/repos/zone117x/Jackett/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zone117x/Jackett/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zone117x/Jackett/git/refs{/sha}","trees_url":"https://api.github.com/repos/zone117x/Jackett/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zone117x/Jackett/statuses/{sha}","languages_url":"https://api.github.com/repos/zone117x/Jackett/languages","stargazers_url":"https://api.github.com/repos/zone117x/Jackett/stargazers","contributors_url":"https://api.github.com/repos/zone117x/Jackett/contributors","subscribers_url":"https://api.github.com/repos/zone117x/Jackett/subscribers","subscription_url":"https://api.github.com/repos/zone117x/Jackett/subscription","commits_url":"https://api.github.com/repos/zone117x/Jackett/commits{/sha}","git_commits_url":"https://api.github.com/repos/zone117x/Jackett/git/commits{/sha}","comments_url":"https://api.github.com/repos/zone117x/Jackett/comments{/number}","issue_comment_url":"https://api.github.com/repos/zone117x/Jackett/issues/comments{/number}","contents_url":"https://api.github.com/repos/zone117x/Jackett/contents/{+path}","compare_url":"https://api.github.com/repos/zone117x/Jackett/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zone117x/Jackett/merges","archive_url":"https://api.github.com/repos/zone117x/Jackett/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zone117x/Jackett/downloads","issues_url":"https://api.github.com/repos/zone117x/Jackett/issues{/number}","pulls_url":"https://api.github.com/repos/zone117x/Jackett/pulls{/number}","milestones_url":"https://api.github.com/repos/zone117x/Jackett/milestones{/number}","notifications_url":"https://api.github.com/repos/zone117x/Jackett/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zone117x/Jackett/labels{/name}","releases_url":"https://api.github.com/repos/zone117x/Jackett/releases{/id}","created_at":"2015-04-13T06:19:13Z","updated_at":"2015-07-09T22:36:31Z","pushed_at":"2015-07-12T16:55:35Z","git_url":"git://github.com/zone117x/Jackett.git","ssh_url":"git@github.com:zone117x/Jackett.git","clone_url":"https://github.com/zone117x/Jackett.git","svn_url":"https://github.com/zone117x/Jackett","homepage":"","size":1493,"stargazers_count":44,"watchers_count":44,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":13,"mirror_url":null,"open_issues_count":16,"forks":13,"open_issues":16,"watchers":44,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/zone117x/Jackett/pulls/79"},"html":{"href":"https://github.com/zone117x/Jackett/pull/79"},"issue":{"href":"https://api.github.com/repos/zone117x/Jackett/issues/79"},"comments":{"href":"https://api.github.com/repos/zone117x/Jackett/issues/79/comments"},"review_comments":{"href":"https://api.github.com/repos/zone117x/Jackett/pulls/79/comments"},"review_comment":{"href":"https://api.github.com/repos/zone117x/Jackett/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/zone117x/Jackett/pulls/79/commits"},"statuses":{"href":"https://api.github.com/repos/zone117x/Jackett/statuses/5744e6ff086ac4db4429c73fe45d45b90ab49642"}}}}