from cgi import parse_header
import logging

from cached_property import cached_property
import requests

__all__ = [
    'LOG_NAME',
    'TORRENT_PATH_INDEX',
    'UnexpectedruTorrentError',
    'ruTorrentClient',
]

LOG_NAME = 'xirvik-rutorrent'
TORRENT_PATH_INDEX = 25


class UnexpectedruTorrentError(Exception):
    pass


class ruTorrentClient:
    host = None
    name = None
    password = None
    _log = logging.getLogger(LOG_NAME)

    def __init__(self, host, name, password):
        self.host = host
        self.name = name
        self.password = password

    @cached_property
    def http_prefix(self):
        return 'https://{host:s}'.format(host=self.host)

    @cached_property
    def multirpc_action_uri(self):
        return ('{}/rtorrent/plugins/multirpc/'
                'action.php'.format(self.http_prefix))

    @cached_property
    def datadir_action_uri(self):
        return ('{}/rtorrent/plugins/datadir/'
                'action.php'.format(self.http_prefix))

    @cached_property
    def _add_torrent_uri(self):
        return '{}/rtorrent/php/addtorrent.php?'.format(host=self.host)

    @cached_property
    def auth(self):
        return (self.name, self.password,)

    def add_torrent(self, filepath, start_now=True):
        data = {}

        if not start_now:
            data['torrents_start_stopped'] = 'on'

        with open(filepath, 'rb') as f:
            files = dict(torrent_file=f)
            r = requests.post(self._add_torrent_uri,
                              data=data,
                              auth=self.auth,
                              files=files)

            r.raise_for_status()

    def list_torrents(self):
        data = {
            'mode': 'list',
            'cmd': 'd.custom=addtime',
        }
        r = requests.post(self.multirpc_action_uri, data=data, auth=self.auth)

        r.raise_for_status()

        return r.json()['t']

    def get_torrent(self, hash):
        source_torrent_uri = ('{}/rtorrent/plugins/source/action.php'
                              '?hash={}'.format(self.http_prefix, hash))

        r = requests.get(self.source_torrent_uri, auth=self.auth, stream=True)

        r.raise_for_status()

        fn = parse_header(r.headers['content-disposition'])[1]['filename']

        return r, fn

    def move_torrent(self, hash, target_dir, fast_resume=True):
        data = {
            'hash': hash,
            'datadir': target_dir,
            'move_addpath': '1',
            'move_datafiles': '1',
            'move_fastresume': '1' if fast_resume else '0',
        }
        r = requests.post(self.datadir_action_uri, data=data, auth=self.auth)

        r.raise_for_status()

        json = r.json()

        if 'errors' in json and len(json['errors']):
            raise UnexpectedruTorrentError(str(json['errors']))

    def set_label(self, hash, label):
        data = {
            'mode': 'setlabel',
            'hash': hash,
            'v': label,
            's': 'label',
        }
        r = requests.post(self.multirpc_action_uri, data=data, auth=self.auth)

        r.raise_for_status()

@@ -82,16 +82,84 @@
 roperty%0A
+from requests.adapters import HTTPAdapter%0Afrom urllib3 import Retry%0A
 import r
@@ -167,16 +167,17 @@
 quests%0A%0A
+%0A
 __all__ 
@@ -503,16 +503,61 @@
 OG_NAME)
+%0A    _http_adapter = None%0A    _session = None
 %0A%0A    de
@@ -593,16 +593,32 @@
 password
+, max_retries=10
 ):%0A     
@@ -694,16 +694,399 @@
 password
+%0A        retry = Retry(connect=max_retries,%0A                      read=max_retries,%0A                      redirect=False,%0A                      backoff_factor=1)%0A        self._http_adapter = HTTPAdapter(max_retries=retry)%0A        self._session = requests.Session()%0A        self._session.mount('http://', self._http_adapter)%0A        self._session.mount('https://', self._http_adapter)
 %0A%0A    @c
@@ -1956,32 +1956,37 @@
         r = 
-requests
+self._session
 .post(self._
@@ -2298,32 +2298,37 @@
         r = 
-requests
+self._session
 .post(self.m
@@ -2624,24 +2624,29 @@
     r = 
-requests
+self._session
 .get(sel
@@ -3113,32 +3113,37 @@
         r = 
-requests
+self._session
 .post(self.d
@@ -3547,24 +3547,29 @@
     r = 
-requests
+self._session
 .post(se

Use Retry from urllib3 with max_retries option with HTTPAdapter