We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[BUG] Flexget add to qbittorrent plugin will force recheck even if file is available
Qbittorrent allows you to buypass rechecking if the file exists. But it will sit there and verify every single file. 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `flexget/plugins/clients/qbittorrent.py`
Content:
```
1 import os
2 
3 from loguru import logger
4 from requests import Session
5 from requests.exceptions import RequestException
6 
7 from flexget import plugin
8 from flexget.event import event
9 from flexget.utils.template import RenderError
10 
11 logger = logger.bind(name='qbittorrent')
12 
13 
14 class OutputQBitTorrent:
15     """
16     Example:
17 
18       qbittorrent:
19         username: <USERNAME> (default: (none))
20         password: <PASSWORD> (default: (none))
21         host: <HOSTNAME> (default: localhost)
22         port: <PORT> (default: 8080)
23         use_ssl: <SSL> (default: False)
24         verify_cert: <VERIFY> (default: True)
25         path: <OUTPUT_DIR> (default: (none))
26         label: <LABEL> (default: (none))
27         maxupspeed: <torrent upload speed limit> (default: 0)
28         maxdownspeed: <torrent download speed limit> (default: 0)
29         add_paused: <ADD_PAUSED> (default: False)
30     """
31 
32     schema = {
33         'anyOf': [
34             {'type': 'boolean'},
35             {
36                 'type': 'object',
37                 'properties': {
38                     'username': {'type': 'string'},
39                     'password': {'type': 'string'},
40                     'host': {'type': 'string'},
41                     'port': {'type': 'integer'},
42                     'use_ssl': {'type': 'boolean'},
43                     'verify_cert': {'type': 'boolean'},
44                     'path': {'type': 'string'},
45                     'label': {'type': 'string'},
46                     'maxupspeed': {'type': 'integer'},
47                     'maxdownspeed': {'type': 'integer'},
48                     'fail_html': {'type': 'boolean'},
49                     'add_paused': {'type': 'boolean'},
50                 },
51                 'additionalProperties': False,
52             },
53         ]
54     }
55 
56     def __init__(self):
57         super().__init__()
58         self.session = Session()
59         self.api_url_login = None
60         self.api_url_upload = None
61         self.api_url_download = None
62         self.url = None
63         self.connected = False
64 
65     def _request(self, method, url, msg_on_fail=None, **kwargs):
66         try:
67             response = self.session.request(method, url, **kwargs)
68             if response.text == "Ok.":
69                 return response
70             msg = msg_on_fail if msg_on_fail else f'Failure. URL: {url}, data: {kwargs}'
71         except RequestException as e:
72             msg = str(e)
73         raise plugin.PluginError(f'Error when trying to send request to qBittorrent: {msg}')
74 
75     def check_api_version(self, msg_on_fail, verify=True):
76         try:
77             url = self.url + "/api/v2/app/webapiVersion"
78             response = self.session.request('get', url, verify=verify)
79             if response.status_code != 404:
80                 self.api_url_login = '/api/v2/auth/login'
81                 self.api_url_upload = '/api/v2/torrents/add'
82                 self.api_url_download = '/api/v2/torrents/add'
83                 return response
84 
85             url = self.url + "/version/api"
86             response = self.session.request('get', url, verify=verify)
87             if response.status_code != 404:
88                 self.api_url_login = '/login'
89                 self.api_url_upload = '/command/upload'
90                 self.api_url_download = '/command/download'
91                 return response
92 
93             msg = 'Failure. URL: {}'.format(url) if not msg_on_fail else msg_on_fail
94         except RequestException as e:
95             msg = str(e)
96         raise plugin.PluginError(
97             'Error when trying to send request to qBittorrent: {}'.format(msg)
98         )
99 
100     def connect(self, config):
101         """
102         Connect to qBittorrent Web UI. Username and password not necessary
103         if 'Bypass authentication for localhost' is checked and host is
104         'localhost'.
105         """
106         self.url = '{}://{}:{}'.format(
107             'https' if config['use_ssl'] else 'http', config['host'], config['port']
108         )
109         self.check_api_version('Check API version failed.', verify=config['verify_cert'])
110         if config.get('username') and config.get('password'):
111             data = {'username': config['username'], 'password': config['password']}
112             self._request(
113                 'post',
114                 self.url + self.api_url_login,
115                 data=data,
116                 msg_on_fail='Authentication failed.',
117                 verify=config['verify_cert'],
118             )
119         logger.debug('Successfully connected to qBittorrent')
120         self.connected = True
121 
122     def add_torrent_file(self, file_path, data, verify_cert):
123         if not self.connected:
124             raise plugin.PluginError('Not connected.')
125         multipart_data = {k: (None, v) for k, v in data.items()}
126         with open(file_path, 'rb') as f:
127             multipart_data['torrents'] = f
128             self._request(
129                 'post',
130                 self.url + self.api_url_upload,
131                 msg_on_fail='Failed to add file to qBittorrent',
132                 files=multipart_data,
133                 verify=verify_cert,
134             )
135         logger.debug('Added torrent file {} to qBittorrent', file_path)
136 
137     def add_torrent_url(self, url, data, verify_cert):
138         if not self.connected:
139             raise plugin.PluginError('Not connected.')
140         data['urls'] = url
141         multipart_data = {k: (None, v) for k, v in data.items()}
142         self._request(
143             'post',
144             self.url + self.api_url_download,
145             msg_on_fail='Failed to add file to qBittorrent',
146             files=multipart_data,
147             verify=verify_cert,
148         )
149         logger.debug('Added url {} to qBittorrent', url)
150 
151     @staticmethod
152     def prepare_config(config):
153         if isinstance(config, bool):
154             config = {'enabled': config}
155         config.setdefault('enabled', True)
156         config.setdefault('host', 'localhost')
157         config.setdefault('port', 8080)
158         config.setdefault('use_ssl', False)
159         config.setdefault('verify_cert', True)
160         config.setdefault('label', '')
161         config.setdefault('maxupspeed', 0)
162         config.setdefault('maxdownspeed', 0)
163         config.setdefault('fail_html', True)
164         return config
165 
166     def add_entries(self, task, config):
167         for entry in task.accepted:
168             form_data = {}
169             try:
170                 save_path = entry.render(entry.get('path', config.get('path', '')))
171                 if save_path:
172                     form_data['savepath'] = save_path
173             except RenderError as e:
174                 logger.error('Error setting path for {}: {}', entry['title'], e)
175 
176             label = entry.render(entry.get('label', config.get('label', '')))
177             if label:
178                 form_data['label'] = label  # qBittorrent v3.3.3-
179                 form_data['category'] = label  # qBittorrent v3.3.4+
180 
181             add_paused = entry.get('add_paused', config.get('add_paused'))
182             if add_paused:
183                 form_data['paused'] = 'true'
184 
185             maxupspeed = entry.get('maxupspeed', config.get('maxupspeed'))
186             if maxupspeed:
187                 form_data['upLimit'] = maxupspeed * 1024
188 
189             maxdownspeed = entry.get('maxdownspeed', config.get('maxdownspeed'))
190             if maxdownspeed:
191                 form_data['dlLimit'] = maxdownspeed * 1024
192 
193             is_magnet = entry['url'].startswith('magnet:')
194 
195             if task.manager.options.test:
196                 logger.info('Test mode.')
197                 logger.info('Would add torrent to qBittorrent with:')
198                 if not is_magnet:
199                     logger.info('File: {}', entry.get('file'))
200                 else:
201                     logger.info('Url: {}', entry.get('url'))
202                 logger.info('Save path: {}', form_data.get('savepath'))
203                 logger.info('Label: {}', form_data.get('label'))
204                 logger.info('Paused: {}', form_data.get('paused', 'false'))
205                 if maxupspeed:
206                     logger.info('Upload Speed Limit: {}', form_data.get('upLimit'))
207                 if maxdownspeed:
208                     logger.info('Download Speed Limit: {}', form_data.get('dlLimit'))
209                 continue
210 
211             if not is_magnet:
212                 if 'file' not in entry:
213                     entry.fail('File missing?')
214                     continue
215                 if not os.path.exists(entry['file']):
216                     tmp_path = os.path.join(task.manager.config_base, 'temp')
217                     logger.debug('entry: {}', entry)
218                     logger.debug('temp: {}', ', '.join(os.listdir(tmp_path)))
219                     entry.fail("Downloaded temp file '%s' doesn't exist!?" % entry['file'])
220                     continue
221                 self.add_torrent_file(entry['file'], form_data, config['verify_cert'])
222             else:
223                 self.add_torrent_url(entry['url'], form_data, config['verify_cert'])
224 
225     @plugin.priority(120)
226     def on_task_download(self, task, config):
227         """
228         Call download plugin to generate torrent files to load into
229         qBittorrent.
230         """
231         config = self.prepare_config(config)
232         if not config['enabled']:
233             return
234         if 'download' not in task.config:
235             download = plugin.get('download', self)
236             download.get_temp_files(task, handle_magnets=True, fail_html=config['fail_html'])
237 
238     @plugin.priority(135)
239     def on_task_output(self, task, config):
240         """Add torrents to qBittorrent at exit."""
241         if task.accepted:
242             config = self.prepare_config(config)
243             self.connect(config)
244             self.add_entries(task, config)
245 
246 
247 @event('plugin.register')
248 def register_plugin():
249     plugin.register(OutputQBitTorrent, 'qbittorrent', api_ver=2)
250
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/flexget/plugins/clients/qbittorrent.py b/flexget/plugins/clients/qbittorrent.py
--- a/flexget/plugins/clients/qbittorrent.py
+++ b/flexget/plugins/clients/qbittorrent.py
@@ -47,6 +47,7 @@
                     'maxdownspeed': {'type': 'integer'},
                     'fail_html': {'type': 'boolean'},
                     'add_paused': {'type': 'boolean'},
+                    'skip_check': {'type': 'boolean'},
                 },
                 'additionalProperties': False,
             },
@@ -182,6 +183,10 @@
             if add_paused:
                 form_data['paused'] = 'true'
 
+            skip_check = entry.get('skip_check', config.get('skip_check'))
+            if skip_check:
+                form_data['skip_checking'] = 'true'
+
             maxupspeed = entry.get('maxupspeed', config.get('maxupspeed'))
             if maxupspeed:
                 form_data['upLimit'] = maxupspeed * 1024
@@ -202,6 +207,7 @@
                 logger.info('Save path: {}', form_data.get('savepath'))
                 logger.info('Label: {}', form_data.get('label'))
                 logger.info('Paused: {}', form_data.get('paused', 'false'))
+                logger.info('Skip Hash Check: {}', form_data.get('skip_checking', 'false'))
                 if maxupspeed:
                     logger.info('Upload Speed Limit: {}', form_data.get('upLimit'))
                 if maxdownspeed:

{"golden_diff": "diff --git a/flexget/plugins/clients/qbittorrent.py b/flexget/plugins/clients/qbittorrent.py\n--- a/flexget/plugins/clients/qbittorrent.py\n+++ b/flexget/plugins/clients/qbittorrent.py\n@@ -47,6 +47,7 @@\n                     'maxdownspeed': {'type': 'integer'},\n                     'fail_html': {'type': 'boolean'},\n                     'add_paused': {'type': 'boolean'},\n+                    'skip_check': {'type': 'boolean'},\n                 },\n                 'additionalProperties': False,\n             },\n@@ -182,6 +183,10 @@\n             if add_paused:\n                 form_data['paused'] = 'true'\n \n+            skip_check = entry.get('skip_check', config.get('skip_check'))\n+            if skip_check:\n+                form_data['skip_checking'] = 'true'\n+\n             maxupspeed = entry.get('maxupspeed', config.get('maxupspeed'))\n             if maxupspeed:\n                 form_data['upLimit'] = maxupspeed * 1024\n@@ -202,6 +207,7 @@\n                 logger.info('Save path: {}', form_data.get('savepath'))\n                 logger.info('Label: {}', form_data.get('label'))\n                 logger.info('Paused: {}', form_data.get('paused', 'false'))\n+                logger.info('Skip Hash Check: {}', form_data.get('skip_checking', 'false'))\n                 if maxupspeed:\n                     logger.info('Upload Speed Limit: {}', form_data.get('upLimit'))\n                 if maxdownspeed:\n", "issue": "[BUG] Flexget add to qbittorrent plugin will force recheck even if file is available\nQbittorrent allows you to buypass rechecking if the file exists. But it will sit there and verify every single file. \n", "before_files": [{"content": "import os\n\nfrom loguru import logger\nfrom requests import Session\nfrom requests.exceptions import RequestException\n\nfrom flexget import plugin\nfrom flexget.event import event\nfrom flexget.utils.template import RenderError\n\nlogger = logger.bind(name='qbittorrent')\n\n\nclass OutputQBitTorrent:\n    \"\"\"\n    Example:\n\n      qbittorrent:\n        username: <USERNAME> (default: (none))\n        password: <PASSWORD> (default: (none))\n        host: <HOSTNAME> (default: localhost)\n        port: <PORT> (default: 8080)\n        use_ssl: <SSL> (default: False)\n        verify_cert: <VERIFY> (default: True)\n        path: <OUTPUT_DIR> (default: (none))\n        label: <LABEL> (default: (none))\n        maxupspeed: <torrent upload speed limit> (default: 0)\n        maxdownspeed: <torrent download speed limit> (default: 0)\n        add_paused: <ADD_PAUSED> (default: False)\n    \"\"\"\n\n    schema = {\n        'anyOf': [\n            {'type': 'boolean'},\n            {\n                'type': 'object',\n                'properties': {\n                    'username': {'type': 'string'},\n                    'password': {'type': 'string'},\n                    'host': {'type': 'string'},\n                    'port': {'type': 'integer'},\n                    'use_ssl': {'type': 'boolean'},\n                    'verify_cert': {'type': 'boolean'},\n                    'path': {'type': 'string'},\n                    'label': {'type': 'string'},\n                    'maxupspeed': {'type': 'integer'},\n                    'maxdownspeed': {'type': 'integer'},\n                    'fail_html': {'type': 'boolean'},\n                    'add_paused': {'type': 'boolean'},\n                },\n                'additionalProperties': False,\n            },\n        ]\n    }\n\n    def __init__(self):\n        super().__init__()\n        self.session = Session()\n        self.api_url_login = None\n        self.api_url_upload = None\n        self.api_url_download = None\n        self.url = None\n        self.connected = False\n\n    def _request(self, method, url, msg_on_fail=None, **kwargs):\n        try:\n            response = self.session.request(method, url, **kwargs)\n            if response.text == \"Ok.\":\n                return response\n            msg = msg_on_fail if msg_on_fail else f'Failure. URL: {url}, data: {kwargs}'\n        except RequestException as e:\n            msg = str(e)\n        raise plugin.PluginError(f'Error when trying to send request to qBittorrent: {msg}')\n\n    def check_api_version(self, msg_on_fail, verify=True):\n        try:\n            url = self.url + \"/api/v2/app/webapiVersion\"\n            response = self.session.request('get', url, verify=verify)\n            if response.status_code != 404:\n                self.api_url_login = '/api/v2/auth/login'\n                self.api_url_upload = '/api/v2/torrents/add'\n                self.api_url_download = '/api/v2/torrents/add'\n                return response\n\n            url = self.url + \"/version/api\"\n            response = self.session.request('get', url, verify=verify)\n            if response.status_code != 404:\n                self.api_url_login = '/login'\n                self.api_url_upload = '/command/upload'\n                self.api_url_download = '/command/download'\n                return response\n\n            msg = 'Failure. URL: {}'.format(url) if not msg_on_fail else msg_on_fail\n        except RequestException as e:\n            msg = str(e)\n        raise plugin.PluginError(\n            'Error when trying to send request to qBittorrent: {}'.format(msg)\n        )\n\n    def connect(self, config):\n        \"\"\"\n        Connect to qBittorrent Web UI. Username and password not necessary\n        if 'Bypass authentication for localhost' is checked and host is\n        'localhost'.\n        \"\"\"\n        self.url = '{}://{}:{}'.format(\n            'https' if config['use_ssl'] else 'http', config['host'], config['port']\n        )\n        self.check_api_version('Check API version failed.', verify=config['verify_cert'])\n        if config.get('username') and config.get('password'):\n            data = {'username': config['username'], 'password': config['password']}\n            self._request(\n                'post',\n                self.url + self.api_url_login,\n                data=data,\n                msg_on_fail='Authentication failed.',\n                verify=config['verify_cert'],\n            )\n        logger.debug('Successfully connected to qBittorrent')\n        self.connected = True\n\n    def add_torrent_file(self, file_path, data, verify_cert):\n        if not self.connected:\n            raise plugin.PluginError('Not connected.')\n        multipart_data = {k: (None, v) for k, v in data.items()}\n        with open(file_path, 'rb') as f:\n            multipart_data['torrents'] = f\n            self._request(\n                'post',\n                self.url + self.api_url_upload,\n                msg_on_fail='Failed to add file to qBittorrent',\n                files=multipart_data,\n                verify=verify_cert,\n            )\n        logger.debug('Added torrent file {} to qBittorrent', file_path)\n\n    def add_torrent_url(self, url, data, verify_cert):\n        if not self.connected:\n            raise plugin.PluginError('Not connected.')\n        data['urls'] = url\n        multipart_data = {k: (None, v) for k, v in data.items()}\n        self._request(\n            'post',\n            self.url + self.api_url_download,\n            msg_on_fail='Failed to add file to qBittorrent',\n            files=multipart_data,\n            verify=verify_cert,\n        )\n        logger.debug('Added url {} to qBittorrent', url)\n\n    @staticmethod\n    def prepare_config(config):\n        if isinstance(config, bool):\n            config = {'enabled': config}\n        config.setdefault('enabled', True)\n        config.setdefault('host', 'localhost')\n        config.setdefault('port', 8080)\n        config.setdefault('use_ssl', False)\n        config.setdefault('verify_cert', True)\n        config.setdefault('label', '')\n        config.setdefault('maxupspeed', 0)\n        config.setdefault('maxdownspeed', 0)\n        config.setdefault('fail_html', True)\n        return config\n\n    def add_entries(self, task, config):\n        for entry in task.accepted:\n            form_data = {}\n            try:\n                save_path = entry.render(entry.get('path', config.get('path', '')))\n                if save_path:\n                    form_data['savepath'] = save_path\n            except RenderError as e:\n                logger.error('Error setting path for {}: {}', entry['title'], e)\n\n            label = entry.render(entry.get('label', config.get('label', '')))\n            if label:\n                form_data['label'] = label  # qBittorrent v3.3.3-\n                form_data['category'] = label  # qBittorrent v3.3.4+\n\n            add_paused = entry.get('add_paused', config.get('add_paused'))\n            if add_paused:\n                form_data['paused'] = 'true'\n\n            maxupspeed = entry.get('maxupspeed', config.get('maxupspeed'))\n            if maxupspeed:\n                form_data['upLimit'] = maxupspeed * 1024\n\n            maxdownspeed = entry.get('maxdownspeed', config.get('maxdownspeed'))\n            if maxdownspeed:\n                form_data['dlLimit'] = maxdownspeed * 1024\n\n            is_magnet = entry['url'].startswith('magnet:')\n\n            if task.manager.options.test:\n                logger.info('Test mode.')\n                logger.info('Would add torrent to qBittorrent with:')\n                if not is_magnet:\n                    logger.info('File: {}', entry.get('file'))\n                else:\n                    logger.info('Url: {}', entry.get('url'))\n                logger.info('Save path: {}', form_data.get('savepath'))\n                logger.info('Label: {}', form_data.get('label'))\n                logger.info('Paused: {}', form_data.get('paused', 'false'))\n                if maxupspeed:\n                    logger.info('Upload Speed Limit: {}', form_data.get('upLimit'))\n                if maxdownspeed:\n                    logger.info('Download Speed Limit: {}', form_data.get('dlLimit'))\n                continue\n\n            if not is_magnet:\n                if 'file' not in entry:\n                    entry.fail('File missing?')\n                    continue\n                if not os.path.exists(entry['file']):\n                    tmp_path = os.path.join(task.manager.config_base, 'temp')\n                    logger.debug('entry: {}', entry)\n                    logger.debug('temp: {}', ', '.join(os.listdir(tmp_path)))\n                    entry.fail(\"Downloaded temp file '%s' doesn't exist!?\" % entry['file'])\n                    continue\n                self.add_torrent_file(entry['file'], form_data, config['verify_cert'])\n            else:\n                self.add_torrent_url(entry['url'], form_data, config['verify_cert'])\n\n    @plugin.priority(120)\n    def on_task_download(self, task, config):\n        \"\"\"\n        Call download plugin to generate torrent files to load into\n        qBittorrent.\n        \"\"\"\n        config = self.prepare_config(config)\n        if not config['enabled']:\n            return\n        if 'download' not in task.config:\n            download = plugin.get('download', self)\n            download.get_temp_files(task, handle_magnets=True, fail_html=config['fail_html'])\n\n    @plugin.priority(135)\n    def on_task_output(self, task, config):\n        \"\"\"Add torrents to qBittorrent at exit.\"\"\"\n        if task.accepted:\n            config = self.prepare_config(config)\n            self.connect(config)\n            self.add_entries(task, config)\n\n\n@event('plugin.register')\ndef register_plugin():\n    plugin.register(OutputQBitTorrent, 'qbittorrent', api_ver=2)\n", "path": "flexget/plugins/clients/qbittorrent.py"}], "after_files": [{"content": "import os\n\nfrom loguru import logger\nfrom requests import Session\nfrom requests.exceptions import RequestException\n\nfrom flexget import plugin\nfrom flexget.event import event\nfrom flexget.utils.template import RenderError\n\nlogger = logger.bind(name='qbittorrent')\n\n\nclass OutputQBitTorrent:\n    \"\"\"\n    Example:\n\n      qbittorrent:\n        username: <USERNAME> (default: (none))\n        password: <PASSWORD> (default: (none))\n        host: <HOSTNAME> (default: localhost)\n        port: <PORT> (default: 8080)\n        use_ssl: <SSL> (default: False)\n        verify_cert: <VERIFY> (default: True)\n        path: <OUTPUT_DIR> (default: (none))\n        label: <LABEL> (default: (none))\n        maxupspeed: <torrent upload speed limit> (default: 0)\n        maxdownspeed: <torrent download speed limit> (default: 0)\n        add_paused: <ADD_PAUSED> (default: False)\n    \"\"\"\n\n    schema = {\n        'anyOf': [\n            {'type': 'boolean'},\n            {\n                'type': 'object',\n                'properties': {\n                    'username': {'type': 'string'},\n                    'password': {'type': 'string'},\n                    'host': {'type': 'string'},\n                    'port': {'type': 'integer'},\n                    'use_ssl': {'type': 'boolean'},\n                    'verify_cert': {'type': 'boolean'},\n                    'path': {'type': 'string'},\n                    'label': {'type': 'string'},\n                    'maxupspeed': {'type': 'integer'},\n                    'maxdownspeed': {'type': 'integer'},\n                    'fail_html': {'type': 'boolean'},\n                    'add_paused': {'type': 'boolean'},\n                    'skip_check': {'type': 'boolean'},\n                },\n                'additionalProperties': False,\n            },\n        ]\n    }\n\n    def __init__(self):\n        super().__init__()\n        self.session = Session()\n        self.api_url_login = None\n        self.api_url_upload = None\n        self.api_url_download = None\n        self.url = None\n        self.connected = False\n\n    def _request(self, method, url, msg_on_fail=None, **kwargs):\n        try:\n            response = self.session.request(method, url, **kwargs)\n            if response.text == \"Ok.\":\n                return response\n            msg = msg_on_fail if msg_on_fail else f'Failure. URL: {url}, data: {kwargs}'\n        except RequestException as e:\n            msg = str(e)\n        raise plugin.PluginError(f'Error when trying to send request to qBittorrent: {msg}')\n\n    def check_api_version(self, msg_on_fail, verify=True):\n        try:\n            url = self.url + \"/api/v2/app/webapiVersion\"\n            response = self.session.request('get', url, verify=verify)\n            if response.status_code != 404:\n                self.api_url_login = '/api/v2/auth/login'\n                self.api_url_upload = '/api/v2/torrents/add'\n                self.api_url_download = '/api/v2/torrents/add'\n                return response\n\n            url = self.url + \"/version/api\"\n            response = self.session.request('get', url, verify=verify)\n            if response.status_code != 404:\n                self.api_url_login = '/login'\n                self.api_url_upload = '/command/upload'\n                self.api_url_download = '/command/download'\n                return response\n\n            msg = 'Failure. URL: {}'.format(url) if not msg_on_fail else msg_on_fail\n        except RequestException as e:\n            msg = str(e)\n        raise plugin.PluginError(\n            'Error when trying to send request to qBittorrent: {}'.format(msg)\n        )\n\n    def connect(self, config):\n        \"\"\"\n        Connect to qBittorrent Web UI. Username and password not necessary\n        if 'Bypass authentication for localhost' is checked and host is\n        'localhost'.\n        \"\"\"\n        self.url = '{}://{}:{}'.format(\n            'https' if config['use_ssl'] else 'http', config['host'], config['port']\n        )\n        self.check_api_version('Check API version failed.', verify=config['verify_cert'])\n        if config.get('username') and config.get('password'):\n            data = {'username': config['username'], 'password': config['password']}\n            self._request(\n                'post',\n                self.url + self.api_url_login,\n                data=data,\n                msg_on_fail='Authentication failed.',\n                verify=config['verify_cert'],\n            )\n        logger.debug('Successfully connected to qBittorrent')\n        self.connected = True\n\n    def add_torrent_file(self, file_path, data, verify_cert):\n        if not self.connected:\n            raise plugin.PluginError('Not connected.')\n        multipart_data = {k: (None, v) for k, v in data.items()}\n        with open(file_path, 'rb') as f:\n            multipart_data['torrents'] = f\n            self._request(\n                'post',\n                self.url + self.api_url_upload,\n                msg_on_fail='Failed to add file to qBittorrent',\n                files=multipart_data,\n                verify=verify_cert,\n            )\n        logger.debug('Added torrent file {} to qBittorrent', file_path)\n\n    def add_torrent_url(self, url, data, verify_cert):\n        if not self.connected:\n            raise plugin.PluginError('Not connected.')\n        data['urls'] = url\n        multipart_data = {k: (None, v) for k, v in data.items()}\n        self._request(\n            'post',\n            self.url + self.api_url_download,\n            msg_on_fail='Failed to add file to qBittorrent',\n            files=multipart_data,\n            verify=verify_cert,\n        )\n        logger.debug('Added url {} to qBittorrent', url)\n\n    @staticmethod\n    def prepare_config(config):\n        if isinstance(config, bool):\n            config = {'enabled': config}\n        config.setdefault('enabled', True)\n        config.setdefault('host', 'localhost')\n        config.setdefault('port', 8080)\n        config.setdefault('use_ssl', False)\n        config.setdefault('verify_cert', True)\n        config.setdefault('label', '')\n        config.setdefault('maxupspeed', 0)\n        config.setdefault('maxdownspeed', 0)\n        config.setdefault('fail_html', True)\n        return config\n\n    def add_entries(self, task, config):\n        for entry in task.accepted:\n            form_data = {}\n            try:\n                save_path = entry.render(entry.get('path', config.get('path', '')))\n                if save_path:\n                    form_data['savepath'] = save_path\n            except RenderError as e:\n                logger.error('Error setting path for {}: {}', entry['title'], e)\n\n            label = entry.render(entry.get('label', config.get('label', '')))\n            if label:\n                form_data['label'] = label  # qBittorrent v3.3.3-\n                form_data['category'] = label  # qBittorrent v3.3.4+\n\n            add_paused = entry.get('add_paused', config.get('add_paused'))\n            if add_paused:\n                form_data['paused'] = 'true'\n\n            skip_check = entry.get('skip_check', config.get('skip_check'))\n            if skip_check:\n                form_data['skip_checking'] = 'true'\n\n            maxupspeed = entry.get('maxupspeed', config.get('maxupspeed'))\n            if maxupspeed:\n                form_data['upLimit'] = maxupspeed * 1024\n\n            maxdownspeed = entry.get('maxdownspeed', config.get('maxdownspeed'))\n            if maxdownspeed:\n                form_data['dlLimit'] = maxdownspeed * 1024\n\n            is_magnet = entry['url'].startswith('magnet:')\n\n            if task.manager.options.test:\n                logger.info('Test mode.')\n                logger.info('Would add torrent to qBittorrent with:')\n                if not is_magnet:\n                    logger.info('File: {}', entry.get('file'))\n                else:\n                    logger.info('Url: {}', entry.get('url'))\n                logger.info('Save path: {}', form_data.get('savepath'))\n                logger.info('Label: {}', form_data.get('label'))\n                logger.info('Paused: {}', form_data.get('paused', 'false'))\n                logger.info('Skip Hash Check: {}', form_data.get('skip_checking', 'false'))\n                if maxupspeed:\n                    logger.info('Upload Speed Limit: {}', form_data.get('upLimit'))\n                if maxdownspeed:\n                    logger.info('Download Speed Limit: {}', form_data.get('dlLimit'))\n                continue\n\n            if not is_magnet:\n                if 'file' not in entry:\n                    entry.fail('File missing?')\n                    continue\n                if not os.path.exists(entry['file']):\n                    tmp_path = os.path.join(task.manager.config_base, 'temp')\n                    logger.debug('entry: {}', entry)\n                    logger.debug('temp: {}', ', '.join(os.listdir(tmp_path)))\n                    entry.fail(\"Downloaded temp file '%s' doesn't exist!?\" % entry['file'])\n                    continue\n                self.add_torrent_file(entry['file'], form_data, config['verify_cert'])\n            else:\n                self.add_torrent_url(entry['url'], form_data, config['verify_cert'])\n\n    @plugin.priority(120)\n    def on_task_download(self, task, config):\n        \"\"\"\n        Call download plugin to generate torrent files to load into\n        qBittorrent.\n        \"\"\"\n        config = self.prepare_config(config)\n        if not config['enabled']:\n            return\n        if 'download' not in task.config:\n            download = plugin.get('download', self)\n            download.get_temp_files(task, handle_magnets=True, fail_html=config['fail_html'])\n\n    @plugin.priority(135)\n    def on_task_output(self, task, config):\n        \"\"\"Add torrents to qBittorrent at exit.\"\"\"\n        if task.accepted:\n            config = self.prepare_config(config)\n            self.connect(config)\n            self.add_entries(task, config)\n\n\n@event('plugin.register')\ndef register_plugin():\n    plugin.register(OutputQBitTorrent, 'qbittorrent', api_ver=2)\n", "path": "flexget/plugins/clients/qbittorrent.py"}]}