{"action":"created","comment":{"url":"https://api.github.com/repos/Sonarr/Sonarr/pulls/comments/46774575","id":46774575,"diff_hunk":"@@ -0,0 +1,248 @@\n+﻿using System;\n+using System.Linq;\n+using System.Collections.Generic;\n+using NzbDrone.Common.Disk;\n+using NzbDrone.Common.Extensions;\n+using NzbDrone.Common.Http;\n+using NzbDrone.Core.Configuration;\n+using NzbDrone.Core.MediaFiles.TorrentInfo;\n+using NLog;\n+using NzbDrone.Core.Validation;\n+using FluentValidation.Results;\n+using System.Net;\n+using NzbDrone.Core.Parser.Model;\n+using NzbDrone.Core.RemotePathMappings;\n+\n+namespace NzbDrone.Core.Download.Clients.QBittorrent\n+{\n+    public class QBittorrent : TorrentClientBase<QBittorrentSettings>\n+    {\n+        private readonly IQBittorrentProxy _proxy;\n+\n+        public QBittorrent(IQBittorrentProxy proxy,\n+                           ITorrentFileInfoReader torrentFileInfoReader,\n+                           IHttpClient httpClient,\n+                           IConfigService configService,\n+                           IDiskProvider diskProvider,\n+                           IRemotePathMappingService remotePathMappingService,\n+                           Logger logger)\n+            : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, logger)\n+        {\n+            _proxy = proxy;\n+        }\n+\n+        protected override string AddFromMagnetLink(RemoteEpisode remoteEpisode, string hash, string magnetLink)\n+        {\n+            _proxy.AddTorrentFromUrl(magnetLink, Settings);\n+\n+            if (Settings.TvCategory.Length > 0)\n+            {\n+                _proxy.SetTorrentLabel(hash.ToLower(), Settings.TvCategory, Settings);\n+            }\n+\n+            var isRecentEpisode = remoteEpisode.IsRecentEpisode();\n+\n+            if (isRecentEpisode && Settings.RecentTvPriority == (int)QBittorrentPriority.First ||\n+                !isRecentEpisode && Settings.OlderTvPriority == (int)QBittorrentPriority.First)\n+            {\n+                _proxy.MoveTorrentToTopInQueue(hash, Settings);\n+            }\n+\n+            return hash;\n+        }\n+\n+        protected override string AddFromTorrentFile(RemoteEpisode remoteEpisode, string hash, string filename, Byte[] fileContent)\n+        {\n+            _proxy.AddTorrentFromFile(filename, fileContent, Settings);\n+\n+            if (Settings.TvCategory.Length > 0)\n+            {\n+                _proxy.SetTorrentLabel(hash.ToLower(), Settings.TvCategory, Settings);\n+            }\n+\n+            var isRecentEpisode = remoteEpisode.IsRecentEpisode();\n+\n+            if (isRecentEpisode && Settings.RecentTvPriority == (int)QBittorrentPriority.First ||\n+                !isRecentEpisode && Settings.OlderTvPriority == (int)QBittorrentPriority.First)\n+            {\n+                _proxy.MoveTorrentToTopInQueue(hash, Settings);\n+            }\n+\n+            return hash;\n+        }\n+\n+        public override string Name\n+        {\n+            get\n+            {\n+                return \"qBittorrent\";\n+            }\n+        }\n+\n+        public override IEnumerable<DownloadClientItem> GetItems()\n+        {\n+            List<QBittorrentTorrent> torrents;\n+\n+            try\n+            {\n+                torrents = _proxy.GetTorrents(Settings);\n+            }\n+            catch (DownloadClientException ex)\n+            {\n+                _logger.ErrorException(ex.Message, ex);\n+                return Enumerable.Empty<DownloadClientItem>();\n+            }\n+\n+            var queueItems = new List<DownloadClientItem>();\n+\n+            foreach (var torrent in torrents)\n+            {\n+                var item = new DownloadClientItem();\n+                item.DownloadId = torrent.Hash;\n+                item.Title = torrent.Name;\n+                item.TotalSize = torrent.Size;\n+                item.DownloadClient = Definition.Name;\n+                item.RemainingSize = (long)(torrent.Size * (1.0 - torrent.Progress));\n+                item.RemainingTime = TimeSpan.FromSeconds(torrent.Eta);","path":"src/NzbDrone.Core/Download/Clients/qBittorrent/QBittorrent.cs","position":106,"original_position":106,"commit_id":"0f313a11bf70ce70851d73a4dcc304850cab1332","original_commit_id":"0f313a11bf70ce70851d73a4dcc304850cab1332","user":{"login":"markus101","id":413544,"avatar_url":"https://avatars.githubusercontent.com/u/413544?v=3","gravatar_id":"","url":"https://api.github.com/users/markus101","html_url":"https://github.com/markus101","followers_url":"https://api.github.com/users/markus101/followers","following_url":"https://api.github.com/users/markus101/following{/other_user}","gists_url":"https://api.github.com/users/markus101/gists{/gist_id}","starred_url":"https://api.github.com/users/markus101/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/markus101/subscriptions","organizations_url":"https://api.github.com/users/markus101/orgs","repos_url":"https://api.github.com/users/markus101/repos","events_url":"https://api.github.com/users/markus101/events{/privacy}","received_events_url":"https://api.github.com/users/markus101/received_events","type":"User","site_admin":false},"body":"The item need a category set so Sonarr can track things it didn't grab","created_at":"2015-12-06T19:26:38Z","updated_at":"2015-12-06T19:26:38Z","html_url":"https://github.com/Sonarr/Sonarr/pull/779#discussion_r46774575","pull_request_url":"https://api.github.com/repos/Sonarr/Sonarr/pulls/779","_links":{"self":{"href":"https://api.github.com/repos/Sonarr/Sonarr/pulls/comments/46774575"},"html":{"href":"https://github.com/Sonarr/Sonarr/pull/779#discussion_r46774575"},"pull_request":{"href":"https://api.github.com/repos/Sonarr/Sonarr/pulls/779"}}},"pull_request":{"url":"https://api.github.com/repos/Sonarr/Sonarr/pulls/779","id":44070720,"html_url":"https://github.com/Sonarr/Sonarr/pull/779","diff_url":"https://github.com/Sonarr/Sonarr/pull/779.diff","patch_url":"https://github.com/Sonarr/Sonarr/pull/779.patch","issue_url":"https://api.github.com/repos/Sonarr/Sonarr/issues/779","number":779,"state":"open","locked":false,"title":"Download client for qBittorrent","user":{"login":"cbodley","id":1928002,"avatar_url":"https://avatars.githubusercontent.com/u/1928002?v=3","gravatar_id":"","url":"https://api.github.com/users/cbodley","html_url":"https://github.com/cbodley","followers_url":"https://api.github.com/users/cbodley/followers","following_url":"https://api.github.com/users/cbodley/following{/other_user}","gists_url":"https://api.github.com/users/cbodley/gists{/gist_id}","starred_url":"https://api.github.com/users/cbodley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cbodley/subscriptions","organizations_url":"https://api.github.com/users/cbodley/orgs","repos_url":"https://api.github.com/users/cbodley/repos","events_url":"https://api.github.com/users/cbodley/events{/privacy}","received_events_url":"https://api.github.com/users/cbodley/received_events","type":"User","site_admin":false},"body":"I had experimented with a qBittorrent plugin a few months ago, but I wasn't able to get it working well because their Web UI API (https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-Documentation) didn't have a way to set labels. I've been tracking their \"[Web UI] Labels implementation\" pull request at https://github.com/qbittorrent/qBittorrent/pull/3444, and it looks like it may merge in the near future.\r\n\r\nI updated my prototype to make use of the setLabel command it introduces, so I wanted to share it with you ahead of time for feedback.","created_at":"2015-09-03T05:32:26Z","updated_at":"2015-12-06T19:26:38Z","closed_at":null,"merged_at":null,"merge_commit_sha":"98bec4183e60f0621e5edea20dae1b809f420e6b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Sonarr/Sonarr/pulls/779/commits","review_comments_url":"https://api.github.com/repos/Sonarr/Sonarr/pulls/779/comments","review_comment_url":"https://api.github.com/repos/Sonarr/Sonarr/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Sonarr/Sonarr/issues/779/comments","statuses_url":"https://api.github.com/repos/Sonarr/Sonarr/statuses/0f313a11bf70ce70851d73a4dcc304850cab1332","head":{"label":"cbodley:qbittorrent","ref":"qbittorrent","sha":"0f313a11bf70ce70851d73a4dcc304850cab1332","user":{"login":"cbodley","id":1928002,"avatar_url":"https://avatars.githubusercontent.com/u/1928002?v=3","gravatar_id":"","url":"https://api.github.com/users/cbodley","html_url":"https://github.com/cbodley","followers_url":"https://api.github.com/users/cbodley/followers","following_url":"https://api.github.com/users/cbodley/following{/other_user}","gists_url":"https://api.github.com/users/cbodley/gists{/gist_id}","starred_url":"https://api.github.com/users/cbodley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cbodley/subscriptions","organizations_url":"https://api.github.com/users/cbodley/orgs","repos_url":"https://api.github.com/users/cbodley/repos","events_url":"https://api.github.com/users/cbodley/events{/privacy}","received_events_url":"https://api.github.com/users/cbodley/received_events","type":"User","site_admin":false},"repo":{"id":41841495,"name":"Sonarr","full_name":"cbodley/Sonarr","owner":{"login":"cbodley","id":1928002,"avatar_url":"https://avatars.githubusercontent.com/u/1928002?v=3","gravatar_id":"","url":"https://api.github.com/users/cbodley","html_url":"https://github.com/cbodley","followers_url":"https://api.github.com/users/cbodley/followers","following_url":"https://api.github.com/users/cbodley/following{/other_user}","gists_url":"https://api.github.com/users/cbodley/gists{/gist_id}","starred_url":"https://api.github.com/users/cbodley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cbodley/subscriptions","organizations_url":"https://api.github.com/users/cbodley/orgs","repos_url":"https://api.github.com/users/cbodley/repos","events_url":"https://api.github.com/users/cbodley/events{/privacy}","received_events_url":"https://api.github.com/users/cbodley/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/cbodley/Sonarr","description":"Smart PVR for newsgroup and bittorrent users.","fork":true,"url":"https://api.github.com/repos/cbodley/Sonarr","forks_url":"https://api.github.com/repos/cbodley/Sonarr/forks","keys_url":"https://api.github.com/repos/cbodley/Sonarr/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cbodley/Sonarr/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cbodley/Sonarr/teams","hooks_url":"https://api.github.com/repos/cbodley/Sonarr/hooks","issue_events_url":"https://api.github.com/repos/cbodley/Sonarr/issues/events{/number}","events_url":"https://api.github.com/repos/cbodley/Sonarr/events","assignees_url":"https://api.github.com/repos/cbodley/Sonarr/assignees{/user}","branches_url":"https://api.github.com/repos/cbodley/Sonarr/branches{/branch}","tags_url":"https://api.github.com/repos/cbodley/Sonarr/tags","blobs_url":"https://api.github.com/repos/cbodley/Sonarr/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cbodley/Sonarr/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cbodley/Sonarr/git/refs{/sha}","trees_url":"https://api.github.com/repos/cbodley/Sonarr/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cbodley/Sonarr/statuses/{sha}","languages_url":"https://api.github.com/repos/cbodley/Sonarr/languages","stargazers_url":"https://api.github.com/repos/cbodley/Sonarr/stargazers","contributors_url":"https://api.github.com/repos/cbodley/Sonarr/contributors","subscribers_url":"https://api.github.com/repos/cbodley/Sonarr/subscribers","subscription_url":"https://api.github.com/repos/cbodley/Sonarr/subscription","commits_url":"https://api.github.com/repos/cbodley/Sonarr/commits{/sha}","git_commits_url":"https://api.github.com/repos/cbodley/Sonarr/git/commits{/sha}","comments_url":"https://api.github.com/repos/cbodley/Sonarr/comments{/number}","issue_comment_url":"https://api.github.com/repos/cbodley/Sonarr/issues/comments{/number}","contents_url":"https://api.github.com/repos/cbodley/Sonarr/contents/{+path}","compare_url":"https://api.github.com/repos/cbodley/Sonarr/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cbodley/Sonarr/merges","archive_url":"https://api.github.com/repos/cbodley/Sonarr/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cbodley/Sonarr/downloads","issues_url":"https://api.github.com/repos/cbodley/Sonarr/issues{/number}","pulls_url":"https://api.github.com/repos/cbodley/Sonarr/pulls{/number}","milestones_url":"https://api.github.com/repos/cbodley/Sonarr/milestones{/number}","notifications_url":"https://api.github.com/repos/cbodley/Sonarr/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cbodley/Sonarr/labels{/name}","releases_url":"https://api.github.com/repos/cbodley/Sonarr/releases{/id}","created_at":"2015-09-03T04:13:04Z","updated_at":"2015-09-03T04:13:09Z","pushed_at":"2015-12-05T16:56:39Z","git_url":"git://github.com/cbodley/Sonarr.git","ssh_url":"git@github.com:cbodley/Sonarr.git","clone_url":"https://github.com/cbodley/Sonarr.git","svn_url":"https://github.com/cbodley/Sonarr","homepage":"https://sonarr.tv","size":202176,"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":"develop"}},"base":{"label":"Sonarr:develop","ref":"develop","sha":"dc176a83b3bea6838cc57fce01896e6c85e3b41a","user":{"login":"Sonarr","id":1082903,"avatar_url":"https://avatars.githubusercontent.com/u/1082903?v=3","gravatar_id":"","url":"https://api.github.com/users/Sonarr","html_url":"https://github.com/Sonarr","followers_url":"https://api.github.com/users/Sonarr/followers","following_url":"https://api.github.com/users/Sonarr/following{/other_user}","gists_url":"https://api.github.com/users/Sonarr/gists{/gist_id}","starred_url":"https://api.github.com/users/Sonarr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Sonarr/subscriptions","organizations_url":"https://api.github.com/users/Sonarr/orgs","repos_url":"https://api.github.com/users/Sonarr/repos","events_url":"https://api.github.com/users/Sonarr/events{/privacy}","received_events_url":"https://api.github.com/users/Sonarr/received_events","type":"Organization","site_admin":false},"repo":{"id":2465723,"name":"Sonarr","full_name":"Sonarr/Sonarr","owner":{"login":"Sonarr","id":1082903,"avatar_url":"https://avatars.githubusercontent.com/u/1082903?v=3","gravatar_id":"","url":"https://api.github.com/users/Sonarr","html_url":"https://github.com/Sonarr","followers_url":"https://api.github.com/users/Sonarr/followers","following_url":"https://api.github.com/users/Sonarr/following{/other_user}","gists_url":"https://api.github.com/users/Sonarr/gists{/gist_id}","starred_url":"https://api.github.com/users/Sonarr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Sonarr/subscriptions","organizations_url":"https://api.github.com/users/Sonarr/orgs","repos_url":"https://api.github.com/users/Sonarr/repos","events_url":"https://api.github.com/users/Sonarr/events{/privacy}","received_events_url":"https://api.github.com/users/Sonarr/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Sonarr/Sonarr","description":"Smart PVR for newsgroup and bittorrent users.","fork":false,"url":"https://api.github.com/repos/Sonarr/Sonarr","forks_url":"https://api.github.com/repos/Sonarr/Sonarr/forks","keys_url":"https://api.github.com/repos/Sonarr/Sonarr/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Sonarr/Sonarr/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Sonarr/Sonarr/teams","hooks_url":"https://api.github.com/repos/Sonarr/Sonarr/hooks","issue_events_url":"https://api.github.com/repos/Sonarr/Sonarr/issues/events{/number}","events_url":"https://api.github.com/repos/Sonarr/Sonarr/events","assignees_url":"https://api.github.com/repos/Sonarr/Sonarr/assignees{/user}","branches_url":"https://api.github.com/repos/Sonarr/Sonarr/branches{/branch}","tags_url":"https://api.github.com/repos/Sonarr/Sonarr/tags","blobs_url":"https://api.github.com/repos/Sonarr/Sonarr/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Sonarr/Sonarr/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Sonarr/Sonarr/git/refs{/sha}","trees_url":"https://api.github.com/repos/Sonarr/Sonarr/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Sonarr/Sonarr/statuses/{sha}","languages_url":"https://api.github.com/repos/Sonarr/Sonarr/languages","stargazers_url":"https://api.github.com/repos/Sonarr/Sonarr/stargazers","contributors_url":"https://api.github.com/repos/Sonarr/Sonarr/contributors","subscribers_url":"https://api.github.com/repos/Sonarr/Sonarr/subscribers","subscription_url":"https://api.github.com/repos/Sonarr/Sonarr/subscription","commits_url":"https://api.github.com/repos/Sonarr/Sonarr/commits{/sha}","git_commits_url":"https://api.github.com/repos/Sonarr/Sonarr/git/commits{/sha}","comments_url":"https://api.github.com/repos/Sonarr/Sonarr/comments{/number}","issue_comment_url":"https://api.github.com/repos/Sonarr/Sonarr/issues/comments{/number}","contents_url":"https://api.github.com/repos/Sonarr/Sonarr/contents/{+path}","compare_url":"https://api.github.com/repos/Sonarr/Sonarr/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Sonarr/Sonarr/merges","archive_url":"https://api.github.com/repos/Sonarr/Sonarr/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Sonarr/Sonarr/downloads","issues_url":"https://api.github.com/repos/Sonarr/Sonarr/issues{/number}","pulls_url":"https://api.github.com/repos/Sonarr/Sonarr/pulls{/number}","milestones_url":"https://api.github.com/repos/Sonarr/Sonarr/milestones{/number}","notifications_url":"https://api.github.com/repos/Sonarr/Sonarr/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Sonarr/Sonarr/labels{/name}","releases_url":"https://api.github.com/repos/Sonarr/Sonarr/releases{/id}","created_at":"2011-09-27T05:57:16Z","updated_at":"2015-12-06T03:23:29Z","pushed_at":"2015-12-06T19:05:32Z","git_url":"git://github.com/Sonarr/Sonarr.git","ssh_url":"git@github.com:Sonarr/Sonarr.git","clone_url":"https://github.com/Sonarr/Sonarr.git","svn_url":"https://github.com/Sonarr/Sonarr","homepage":"https://sonarr.tv","size":204312,"stargazers_count":1021,"watchers_count":1021,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":269,"mirror_url":null,"open_issues_count":390,"forks":269,"open_issues":390,"watchers":1021,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/Sonarr/Sonarr/pulls/779"},"html":{"href":"https://github.com/Sonarr/Sonarr/pull/779"},"issue":{"href":"https://api.github.com/repos/Sonarr/Sonarr/issues/779"},"comments":{"href":"https://api.github.com/repos/Sonarr/Sonarr/issues/779/comments"},"review_comments":{"href":"https://api.github.com/repos/Sonarr/Sonarr/pulls/779/comments"},"review_comment":{"href":"https://api.github.com/repos/Sonarr/Sonarr/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Sonarr/Sonarr/pulls/779/commits"},"statuses":{"href":"https://api.github.com/repos/Sonarr/Sonarr/statuses/0f313a11bf70ce70851d73a4dcc304850cab1332"}}}}