We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
IndexError sending to uTorrent
**Describe the bug**
Sending an magnet link to uTorret goes into error

**To Reproduce**
Steps to reproduce the behavior:
1. Just add an existing episode to the wanted category and click go

**Expected behavior**
An download into uTorrent

**Medusa (please complete the following information):**
 - OS: Windows 10
 - Branch: master
 - Commit: 4614efc77151ded92ef458a09dec39f8bd5acfc6 

**Logs:**
<details>

```
2018-09-10 10:48:55 DEBUG    SEARCHQUEUE-BACKLOG-80379 :: [4614efc] uTorrent: Exception raised when sending torrent Rarbg @ magnet:?xt=urn:btih:04a442a9f4ec4f968897faa4bce27f6b2d6f9083&dn=The.Big.Bang.Theory.S11E24.The.Bow.Tie.Asymmetry.720p.AMZN.WEBRip.DDP5.1.x264-NTb%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969/announce&tr=udp://tracker.zer0day.to:1337/announce&tr=udp://tracker.opentrackr.org:1337/announce&tr=http://tracker.opentrackr.org:1337/announce&tr=udp://p4p.arenabg.com:1337/announce&tr=http://p4p.arenabg.com:1337/announce&tr=udp://explodie.org:6969/announce&tr=udp://9.rarbg.com:2710/announce&tr=http://explodie.org:6969/announce&tr=http://tracker.dler.org:6969/announce&tr=udp://public.popcorn-tracker.org:6969/announce&tr=udp://tracker.internetwarriors.net:1337/announce&tr=udp://ipv4.tracker.harry.lu:80/announce&tr=http://ipv4.tracker.harry.lu:80/announce&tr=udp://mgtracker.org:2710/announce&tr=http://mgtracker.org:6969/announce&tr=udp://tracker.mg64.net:6969/announce&tr=http://tracker.mg64.net:6881/announce&tr=http://torrentsmd.com:8080/announce
Extra Info:
Episodes:
 u'The Big Bang Theory' - u'S11E24' - u'The Bow Tie Asymmetry'
location: u''
description: u'When Amy\u2019s parents and Sheldon\u2019s family arrive for the wedding, everybody is focused on making sure all goes according to plan \u2013 everyone except the bride and groom.'
subtitles: u''
subtitles_searchcount: 0
subtitles_lastsearch: u'0001-01-01 00:00:00'
airdate: 736824 (datetime.date(2018, 5, 10))
hasnfo: False
hastbn: False
status: 3
quality: 64
Quality: 720p WEB-DL
Name: The.Big.Bang.Theory.S11E24.The.Bow.Tie.Asymmetry.720p.AMZN.WEBRip.DDP5.1.x264-NTb[rartv]
Size: 770147134
Release Group: NTb
. Error: list index out of range
2018-09-10 10:48:55 ERROR    SEARCHQUEUE-BACKLOG-80379 :: [4614efc] uTorrent: Failed Sending Torrent
Traceback (most recent call last):
  File "C:\medusa\medusa\clients\torrent\generic.py", line 261, in send_torrent
    r_code = self._add_torrent_uri(result)
  File "C:\medusa\medusa\clients\torrent\utorrent_client.py", line 92, in _add_torrent_uri
    torrent_subfolder = get_torrent_subfolder(result)
  File "C:\medusa\medusa\clients\torrent\utorrent_client.py", line 27, in get_torrent_subfolder
    root_location = root_dirs[int(root_dirs[0]) + 1]
IndexError: list index out of range
```
</details>

**Additional context**
Add any other context about the problem here.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `medusa/clients/torrent/utorrent_client.py`
Content:
```
1 # coding=utf-8
2 
3 """uTorrent Client."""
4 
5 from __future__ import unicode_literals
6 
7 import logging
8 import os
9 import re
10 from collections import OrderedDict
11 
12 from medusa import app
13 from medusa.clients.torrent.generic import GenericClient
14 from medusa.logger.adapters.style import BraceAdapter
15 
16 from requests.compat import urljoin
17 from requests.exceptions import RequestException
18 
19 log = BraceAdapter(logging.getLogger(__name__))
20 log.logger.addHandler(logging.NullHandler())
21 
22 
23 def get_torrent_subfolder(result):
24     """Retrieve the series destination-subfolder required for uTorrent WebUI 'start' action."""
25     # Get the subfolder name the user has assigned to that series
26     root_dirs = app.ROOT_DIRS
27     root_location = root_dirs[int(root_dirs[0]) + 1]
28     torrent_path = result.series.raw_location
29 
30     if not root_location == torrent_path:
31         # Subfolder is under root, but possibly not directly under
32         if torrent_path.startswith(root_location):
33             torrent_subfolder = torrent_path.replace(root_location, '')
34         # Subfolder is NOT under root, use it too (WebUI limitation)
35         else:
36             torrent_subfolder = os.path.basename(torrent_path)
37     # Use the series name if there is no subfolder defined
38     else:
39         torrent_subfolder = result.series.name
40 
41     log.debug('Show {name}: torrent download destination folder is: {path} (sub-folder: {sub})',
42               {'name': result.series.name, 'path': torrent_path, 'sub': torrent_subfolder})
43 
44     return torrent_subfolder
45 
46 
47 class UTorrentAPI(GenericClient):
48     """uTorrent API class."""
49 
50     def __init__(self, host=None, username=None, password=None):
51         """Constructor.
52 
53         :param host:
54         :type host: string
55         :param username:
56         :type username: string
57         :param password:
58         :type password: string
59         """
60         super(UTorrentAPI, self).__init__('uTorrent', host, username, password)
61         self.url = urljoin(self.host, 'gui/')
62 
63     def _request(self, method='get', params=None, data=None, files=None, cookies=None):
64         if cookies:
65             log.debug('{name}: Received unused argument: cookies={value!r}',
66                       {'name': self.name, 'value': cookies})
67 
68         # "token" must be the first parameter: https://goo.gl/qTxf9x
69         ordered_params = OrderedDict({
70             'token': self.auth,
71         })
72         ordered_params.update(params)
73 
74         return super(UTorrentAPI, self)._request(method=method, params=ordered_params, data=data, files=files)
75 
76     def _get_auth(self):
77         try:
78             self.response = self.session.get(urljoin(self.url, 'token.html'), verify=False)
79         except RequestException as error:
80             log.warning('Unable to authenticate with uTorrent client: {0!r}', error)
81             return None
82 
83         if not self.response.status_code == 404:
84             self.auth = re.findall('<div.*?>(.*?)</', self.response.text)[0]
85             return self.auth
86 
87         return None
88 
89     def _add_torrent_uri(self, result):
90         """Send an 'add-url' download request to uTorrent when search provider is using a magnet link."""
91         # Set proper subfolder as download destination for uTorrent torrent
92         torrent_subfolder = get_torrent_subfolder(result)
93 
94         return self._request(params={
95             'action': 'add-url',
96             # limit the param length to 1024 chars (uTorrent bug)
97             's': result.url[:1024],
98             'path': torrent_subfolder,
99         })
100 
101     def _add_torrent_file(self, result):
102         """Send an 'add-file' download request to uTorrent when the search provider is using a .torrent file."""
103         # Set proper subfolder as download destination for uTorrent torrent
104         torrent_subfolder = get_torrent_subfolder(result)
105 
106         return self._request(
107             method='post',
108             params={
109                 'action': 'add-file',
110                 'path': torrent_subfolder,
111             },
112             files={
113                 'torrent_file': (
114                     '{name}.torrent'.format(name=result.name),
115                     result.content,
116                 ),
117             }
118         )
119 
120     def _set_torrent_label(self, result):
121         """Send a 'setprop' request to uTorrent to set a label for the torrent, optionally - the show name."""
122         torrent_new_label = result.series.name
123 
124         if result.series.is_anime and app.TORRENT_LABEL_ANIME:
125             label = app.TORRENT_LABEL_ANIME
126         else:
127             label = app.TORRENT_LABEL
128 
129         label = label.replace('%N', torrent_new_label)
130 
131         log.debug('Torrent label is now set to {path}', {'path': label})
132 
133         return self._request(
134             params={
135                 'action': 'setprops',
136                 'hash': result.hash,
137                 's': 'label',
138                 'v': label,
139             }
140         )
141 
142     def _set_torrent_ratio(self, result):
143         ratio = result.ratio or None
144 
145         if ratio:
146             if self._request(params={
147                 'action': 'setprops',
148                 'hash': result.hash,
149                 's': 'seed_override',
150                 'v': '1',
151             }):
152                 return self._request(params={
153                     'action': 'setprops',
154                     'hash': result.hash,
155                     's': 'seed_ratio',
156                     'v': float(ratio) * 10,
157                 })
158             else:
159                 return False
160 
161         return True
162 
163     def _set_torrent_seed_time(self, result):
164         #  Allow 0 - as unlimitted, and "-1" - that is used to disable
165         if float(app.TORRENT_SEED_TIME) >= 0:
166             if self._request(params={
167                 'action': 'setprops',
168                 'hash': result.hash,
169                 's': 'seed_override',
170                 'v': '1',
171             }):
172                 return self._request(params={
173                     'action': 'setprops',
174                     'hash': result.hash,
175                     's': 'seed_time',
176                     'v': 3600 * float(app.TORRENT_SEED_TIME),
177                 })
178             else:
179                 return False
180         else:
181             return True
182 
183     def _set_torrent_priority(self, result):
184         return True if result.priority != 1 else self._request(params={
185             'action': 'queuetop',
186             'hash': result.hash,
187         })
188 
189     def _set_torrent_pause(self, result):
190         return self._request(params={
191             #  "stop" torrent, can always be resumed!
192             'action': 'stop' if app.TORRENT_PAUSED else 'start',
193             'hash': result.hash,
194         })
195 
196     def remove_torrent(self, info_hash):
197         """Remove torrent from client using given info_hash.
198 
199         :param info_hash:
200         :type info_hash: string
201         :return
202         :rtype: bool
203         """
204         return self._request(params={
205             'action': 'removedatatorrent',
206             'hash': info_hash,
207         })
208 
209 
210 api = UTorrentAPI
211
```
--- 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/medusa/clients/torrent/utorrent_client.py b/medusa/clients/torrent/utorrent_client.py
--- a/medusa/clients/torrent/utorrent_client.py
+++ b/medusa/clients/torrent/utorrent_client.py
@@ -24,10 +24,11 @@
     """Retrieve the series destination-subfolder required for uTorrent WebUI 'start' action."""
     # Get the subfolder name the user has assigned to that series
     root_dirs = app.ROOT_DIRS
-    root_location = root_dirs[int(root_dirs[0]) + 1]
+    if root_dirs:
+        root_location = root_dirs[int(root_dirs[0]) + 1]
     torrent_path = result.series.raw_location
 
-    if not root_location == torrent_path:
+    if root_dirs and root_location != torrent_path:
         # Subfolder is under root, but possibly not directly under
         if torrent_path.startswith(root_location):
             torrent_subfolder = torrent_path.replace(root_location, '')

{"golden_diff": "diff --git a/medusa/clients/torrent/utorrent_client.py b/medusa/clients/torrent/utorrent_client.py\n--- a/medusa/clients/torrent/utorrent_client.py\n+++ b/medusa/clients/torrent/utorrent_client.py\n@@ -24,10 +24,11 @@\n     \"\"\"Retrieve the series destination-subfolder required for uTorrent WebUI 'start' action.\"\"\"\n     # Get the subfolder name the user has assigned to that series\n     root_dirs = app.ROOT_DIRS\n-    root_location = root_dirs[int(root_dirs[0]) + 1]\n+    if root_dirs:\n+        root_location = root_dirs[int(root_dirs[0]) + 1]\n     torrent_path = result.series.raw_location\n \n-    if not root_location == torrent_path:\n+    if root_dirs and root_location != torrent_path:\n         # Subfolder is under root, but possibly not directly under\n         if torrent_path.startswith(root_location):\n             torrent_subfolder = torrent_path.replace(root_location, '')\n", "issue": "IndexError sending to uTorrent\n**Describe the bug**\r\nSending an magnet link to uTorret goes into error\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Just add an existing episode to the wanted category and click go\r\n\r\n**Expected behavior**\r\nAn download into uTorrent\r\n\r\n**Medusa (please complete the following information):**\r\n - OS: Windows 10\r\n - Branch: master\r\n - Commit: 4614efc77151ded92ef458a09dec39f8bd5acfc6 \r\n\r\n**Logs:**\r\n<details>\r\n\r\n```\r\n2018-09-10 10:48:55 DEBUG    SEARCHQUEUE-BACKLOG-80379 :: [4614efc] uTorrent: Exception raised when sending torrent Rarbg @ magnet:?xt=urn:btih:04a442a9f4ec4f968897faa4bce27f6b2d6f9083&dn=The.Big.Bang.Theory.S11E24.The.Bow.Tie.Asymmetry.720p.AMZN.WEBRip.DDP5.1.x264-NTb%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969/announce&tr=udp://tracker.zer0day.to:1337/announce&tr=udp://tracker.opentrackr.org:1337/announce&tr=http://tracker.opentrackr.org:1337/announce&tr=udp://p4p.arenabg.com:1337/announce&tr=http://p4p.arenabg.com:1337/announce&tr=udp://explodie.org:6969/announce&tr=udp://9.rarbg.com:2710/announce&tr=http://explodie.org:6969/announce&tr=http://tracker.dler.org:6969/announce&tr=udp://public.popcorn-tracker.org:6969/announce&tr=udp://tracker.internetwarriors.net:1337/announce&tr=udp://ipv4.tracker.harry.lu:80/announce&tr=http://ipv4.tracker.harry.lu:80/announce&tr=udp://mgtracker.org:2710/announce&tr=http://mgtracker.org:6969/announce&tr=udp://tracker.mg64.net:6969/announce&tr=http://tracker.mg64.net:6881/announce&tr=http://torrentsmd.com:8080/announce\r\nExtra Info:\r\nEpisodes:\r\n u'The Big Bang Theory' - u'S11E24' - u'The Bow Tie Asymmetry'\r\nlocation: u''\r\ndescription: u'When Amy\\u2019s parents and Sheldon\\u2019s family arrive for the wedding, everybody is focused on making sure all goes according to plan \\u2013 everyone except the bride and groom.'\r\nsubtitles: u''\r\nsubtitles_searchcount: 0\r\nsubtitles_lastsearch: u'0001-01-01 00:00:00'\r\nairdate: 736824 (datetime.date(2018, 5, 10))\r\nhasnfo: False\r\nhastbn: False\r\nstatus: 3\r\nquality: 64\r\nQuality: 720p WEB-DL\r\nName: The.Big.Bang.Theory.S11E24.The.Bow.Tie.Asymmetry.720p.AMZN.WEBRip.DDP5.1.x264-NTb[rartv]\r\nSize: 770147134\r\nRelease Group: NTb\r\n. Error: list index out of range\r\n2018-09-10 10:48:55 ERROR    SEARCHQUEUE-BACKLOG-80379 :: [4614efc] uTorrent: Failed Sending Torrent\r\nTraceback (most recent call last):\r\n  File \"C:\\medusa\\medusa\\clients\\torrent\\generic.py\", line 261, in send_torrent\r\n    r_code = self._add_torrent_uri(result)\r\n  File \"C:\\medusa\\medusa\\clients\\torrent\\utorrent_client.py\", line 92, in _add_torrent_uri\r\n    torrent_subfolder = get_torrent_subfolder(result)\r\n  File \"C:\\medusa\\medusa\\clients\\torrent\\utorrent_client.py\", line 27, in get_torrent_subfolder\r\n    root_location = root_dirs[int(root_dirs[0]) + 1]\r\nIndexError: list index out of range\r\n```\r\n</details>\r\n\r\n**Additional context**\r\nAdd any other context about the problem here.\r\n\n", "before_files": [{"content": "# coding=utf-8\n\n\"\"\"uTorrent Client.\"\"\"\n\nfrom __future__ import unicode_literals\n\nimport logging\nimport os\nimport re\nfrom collections import OrderedDict\n\nfrom medusa import app\nfrom medusa.clients.torrent.generic import GenericClient\nfrom medusa.logger.adapters.style import BraceAdapter\n\nfrom requests.compat import urljoin\nfrom requests.exceptions import RequestException\n\nlog = BraceAdapter(logging.getLogger(__name__))\nlog.logger.addHandler(logging.NullHandler())\n\n\ndef get_torrent_subfolder(result):\n    \"\"\"Retrieve the series destination-subfolder required for uTorrent WebUI 'start' action.\"\"\"\n    # Get the subfolder name the user has assigned to that series\n    root_dirs = app.ROOT_DIRS\n    root_location = root_dirs[int(root_dirs[0]) + 1]\n    torrent_path = result.series.raw_location\n\n    if not root_location == torrent_path:\n        # Subfolder is under root, but possibly not directly under\n        if torrent_path.startswith(root_location):\n            torrent_subfolder = torrent_path.replace(root_location, '')\n        # Subfolder is NOT under root, use it too (WebUI limitation)\n        else:\n            torrent_subfolder = os.path.basename(torrent_path)\n    # Use the series name if there is no subfolder defined\n    else:\n        torrent_subfolder = result.series.name\n\n    log.debug('Show {name}: torrent download destination folder is: {path} (sub-folder: {sub})',\n              {'name': result.series.name, 'path': torrent_path, 'sub': torrent_subfolder})\n\n    return torrent_subfolder\n\n\nclass UTorrentAPI(GenericClient):\n    \"\"\"uTorrent API class.\"\"\"\n\n    def __init__(self, host=None, username=None, password=None):\n        \"\"\"Constructor.\n\n        :param host:\n        :type host: string\n        :param username:\n        :type username: string\n        :param password:\n        :type password: string\n        \"\"\"\n        super(UTorrentAPI, self).__init__('uTorrent', host, username, password)\n        self.url = urljoin(self.host, 'gui/')\n\n    def _request(self, method='get', params=None, data=None, files=None, cookies=None):\n        if cookies:\n            log.debug('{name}: Received unused argument: cookies={value!r}',\n                      {'name': self.name, 'value': cookies})\n\n        # \"token\" must be the first parameter: https://goo.gl/qTxf9x\n        ordered_params = OrderedDict({\n            'token': self.auth,\n        })\n        ordered_params.update(params)\n\n        return super(UTorrentAPI, self)._request(method=method, params=ordered_params, data=data, files=files)\n\n    def _get_auth(self):\n        try:\n            self.response = self.session.get(urljoin(self.url, 'token.html'), verify=False)\n        except RequestException as error:\n            log.warning('Unable to authenticate with uTorrent client: {0!r}', error)\n            return None\n\n        if not self.response.status_code == 404:\n            self.auth = re.findall('<div.*?>(.*?)</', self.response.text)[0]\n            return self.auth\n\n        return None\n\n    def _add_torrent_uri(self, result):\n        \"\"\"Send an 'add-url' download request to uTorrent when search provider is using a magnet link.\"\"\"\n        # Set proper subfolder as download destination for uTorrent torrent\n        torrent_subfolder = get_torrent_subfolder(result)\n\n        return self._request(params={\n            'action': 'add-url',\n            # limit the param length to 1024 chars (uTorrent bug)\n            's': result.url[:1024],\n            'path': torrent_subfolder,\n        })\n\n    def _add_torrent_file(self, result):\n        \"\"\"Send an 'add-file' download request to uTorrent when the search provider is using a .torrent file.\"\"\"\n        # Set proper subfolder as download destination for uTorrent torrent\n        torrent_subfolder = get_torrent_subfolder(result)\n\n        return self._request(\n            method='post',\n            params={\n                'action': 'add-file',\n                'path': torrent_subfolder,\n            },\n            files={\n                'torrent_file': (\n                    '{name}.torrent'.format(name=result.name),\n                    result.content,\n                ),\n            }\n        )\n\n    def _set_torrent_label(self, result):\n        \"\"\"Send a 'setprop' request to uTorrent to set a label for the torrent, optionally - the show name.\"\"\"\n        torrent_new_label = result.series.name\n\n        if result.series.is_anime and app.TORRENT_LABEL_ANIME:\n            label = app.TORRENT_LABEL_ANIME\n        else:\n            label = app.TORRENT_LABEL\n\n        label = label.replace('%N', torrent_new_label)\n\n        log.debug('Torrent label is now set to {path}', {'path': label})\n\n        return self._request(\n            params={\n                'action': 'setprops',\n                'hash': result.hash,\n                's': 'label',\n                'v': label,\n            }\n        )\n\n    def _set_torrent_ratio(self, result):\n        ratio = result.ratio or None\n\n        if ratio:\n            if self._request(params={\n                'action': 'setprops',\n                'hash': result.hash,\n                's': 'seed_override',\n                'v': '1',\n            }):\n                return self._request(params={\n                    'action': 'setprops',\n                    'hash': result.hash,\n                    's': 'seed_ratio',\n                    'v': float(ratio) * 10,\n                })\n            else:\n                return False\n\n        return True\n\n    def _set_torrent_seed_time(self, result):\n        #  Allow 0 - as unlimitted, and \"-1\" - that is used to disable\n        if float(app.TORRENT_SEED_TIME) >= 0:\n            if self._request(params={\n                'action': 'setprops',\n                'hash': result.hash,\n                's': 'seed_override',\n                'v': '1',\n            }):\n                return self._request(params={\n                    'action': 'setprops',\n                    'hash': result.hash,\n                    's': 'seed_time',\n                    'v': 3600 * float(app.TORRENT_SEED_TIME),\n                })\n            else:\n                return False\n        else:\n            return True\n\n    def _set_torrent_priority(self, result):\n        return True if result.priority != 1 else self._request(params={\n            'action': 'queuetop',\n            'hash': result.hash,\n        })\n\n    def _set_torrent_pause(self, result):\n        return self._request(params={\n            #  \"stop\" torrent, can always be resumed!\n            'action': 'stop' if app.TORRENT_PAUSED else 'start',\n            'hash': result.hash,\n        })\n\n    def remove_torrent(self, info_hash):\n        \"\"\"Remove torrent from client using given info_hash.\n\n        :param info_hash:\n        :type info_hash: string\n        :return\n        :rtype: bool\n        \"\"\"\n        return self._request(params={\n            'action': 'removedatatorrent',\n            'hash': info_hash,\n        })\n\n\napi = UTorrentAPI\n", "path": "medusa/clients/torrent/utorrent_client.py"}], "after_files": [{"content": "# coding=utf-8\n\n\"\"\"uTorrent Client.\"\"\"\n\nfrom __future__ import unicode_literals\n\nimport logging\nimport os\nimport re\nfrom collections import OrderedDict\n\nfrom medusa import app\nfrom medusa.clients.torrent.generic import GenericClient\nfrom medusa.logger.adapters.style import BraceAdapter\n\nfrom requests.compat import urljoin\nfrom requests.exceptions import RequestException\n\nlog = BraceAdapter(logging.getLogger(__name__))\nlog.logger.addHandler(logging.NullHandler())\n\n\ndef get_torrent_subfolder(result):\n    \"\"\"Retrieve the series destination-subfolder required for uTorrent WebUI 'start' action.\"\"\"\n    # Get the subfolder name the user has assigned to that series\n    root_dirs = app.ROOT_DIRS\n    if root_dirs:\n        root_location = root_dirs[int(root_dirs[0]) + 1]\n    torrent_path = result.series.raw_location\n\n    if root_dirs and root_location != torrent_path:\n        # Subfolder is under root, but possibly not directly under\n        if torrent_path.startswith(root_location):\n            torrent_subfolder = torrent_path.replace(root_location, '')\n        # Subfolder is NOT under root, use it too (WebUI limitation)\n        else:\n            torrent_subfolder = os.path.basename(torrent_path)\n    # Use the series name if there is no subfolder defined\n    else:\n        torrent_subfolder = result.series.name\n\n    log.debug('Show {name}: torrent download destination folder is: {path} (sub-folder: {sub})',\n              {'name': result.series.name, 'path': torrent_path, 'sub': torrent_subfolder})\n\n    return torrent_subfolder\n\n\nclass UTorrentAPI(GenericClient):\n    \"\"\"uTorrent API class.\"\"\"\n\n    def __init__(self, host=None, username=None, password=None):\n        \"\"\"Constructor.\n\n        :param host:\n        :type host: string\n        :param username:\n        :type username: string\n        :param password:\n        :type password: string\n        \"\"\"\n        super(UTorrentAPI, self).__init__('uTorrent', host, username, password)\n        self.url = urljoin(self.host, 'gui/')\n\n    def _request(self, method='get', params=None, data=None, files=None, cookies=None):\n        if cookies:\n            log.debug('{name}: Received unused argument: cookies={value!r}',\n                      {'name': self.name, 'value': cookies})\n\n        # \"token\" must be the first parameter: https://goo.gl/qTxf9x\n        ordered_params = OrderedDict({\n            'token': self.auth,\n        })\n        ordered_params.update(params)\n\n        return super(UTorrentAPI, self)._request(method=method, params=ordered_params, data=data, files=files)\n\n    def _get_auth(self):\n        try:\n            self.response = self.session.get(urljoin(self.url, 'token.html'), verify=False)\n        except RequestException as error:\n            log.warning('Unable to authenticate with uTorrent client: {0!r}', error)\n            return None\n\n        if not self.response.status_code == 404:\n            self.auth = re.findall('<div.*?>(.*?)</', self.response.text)[0]\n            return self.auth\n\n        return None\n\n    def _add_torrent_uri(self, result):\n        \"\"\"Send an 'add-url' download request to uTorrent when search provider is using a magnet link.\"\"\"\n        # Set proper subfolder as download destination for uTorrent torrent\n        torrent_subfolder = get_torrent_subfolder(result)\n\n        return self._request(params={\n            'action': 'add-url',\n            # limit the param length to 1024 chars (uTorrent bug)\n            's': result.url[:1024],\n            'path': torrent_subfolder,\n        })\n\n    def _add_torrent_file(self, result):\n        \"\"\"Send an 'add-file' download request to uTorrent when the search provider is using a .torrent file.\"\"\"\n        # Set proper subfolder as download destination for uTorrent torrent\n        torrent_subfolder = get_torrent_subfolder(result)\n\n        return self._request(\n            method='post',\n            params={\n                'action': 'add-file',\n                'path': torrent_subfolder,\n            },\n            files={\n                'torrent_file': (\n                    '{name}.torrent'.format(name=result.name),\n                    result.content,\n                ),\n            }\n        )\n\n    def _set_torrent_label(self, result):\n        \"\"\"Send a 'setprop' request to uTorrent to set a label for the torrent, optionally - the show name.\"\"\"\n        torrent_new_label = result.series.name\n\n        if result.series.is_anime and app.TORRENT_LABEL_ANIME:\n            label = app.TORRENT_LABEL_ANIME\n        else:\n            label = app.TORRENT_LABEL\n\n        label = label.replace('%N', torrent_new_label)\n\n        log.debug('Torrent label is now set to {path}', {'path': label})\n\n        return self._request(\n            params={\n                'action': 'setprops',\n                'hash': result.hash,\n                's': 'label',\n                'v': label,\n            }\n        )\n\n    def _set_torrent_ratio(self, result):\n        ratio = result.ratio or None\n\n        if ratio:\n            if self._request(params={\n                'action': 'setprops',\n                'hash': result.hash,\n                's': 'seed_override',\n                'v': '1',\n            }):\n                return self._request(params={\n                    'action': 'setprops',\n                    'hash': result.hash,\n                    's': 'seed_ratio',\n                    'v': float(ratio) * 10,\n                })\n            else:\n                return False\n\n        return True\n\n    def _set_torrent_seed_time(self, result):\n        #  Allow 0 - as unlimitted, and \"-1\" - that is used to disable\n        if float(app.TORRENT_SEED_TIME) >= 0:\n            if self._request(params={\n                'action': 'setprops',\n                'hash': result.hash,\n                's': 'seed_override',\n                'v': '1',\n            }):\n                return self._request(params={\n                    'action': 'setprops',\n                    'hash': result.hash,\n                    's': 'seed_time',\n                    'v': 3600 * float(app.TORRENT_SEED_TIME),\n                })\n            else:\n                return False\n        else:\n            return True\n\n    def _set_torrent_priority(self, result):\n        return True if result.priority != 1 else self._request(params={\n            'action': 'queuetop',\n            'hash': result.hash,\n        })\n\n    def _set_torrent_pause(self, result):\n        return self._request(params={\n            #  \"stop\" torrent, can always be resumed!\n            'action': 'stop' if app.TORRENT_PAUSED else 'start',\n            'hash': result.hash,\n        })\n\n    def remove_torrent(self, info_hash):\n        \"\"\"Remove torrent from client using given info_hash.\n\n        :param info_hash:\n        :type info_hash: string\n        :return\n        :rtype: bool\n        \"\"\"\n        return self._request(params={\n            'action': 'removedatatorrent',\n            'hash': info_hash,\n        })\n\n\napi = UTorrentAPI\n", "path": "medusa/clients/torrent/utorrent_client.py"}]}