Exemple #1
0
    def initialize(self):
        self.session = Session()
        self.session.headers["User-Agent"] = "Subliminal/{}".format(
            __short_version__)

        # login
        if self.username is not None and self.password is not None:
            logger.debug("Logging in")
            url = self.server_url + "subscenter/accounts/login/"

            # retrieve CSRF token
            self.session.get(url)
            csrf_token = self.session.cookies["csrftoken"]

            # actual login
            data = {
                "username": self.username,
                "password": self.password,
                "csrfmiddlewaretoken": csrf_token
            }
            r = self.session.post(url, data, allow_redirects=False, timeout=10)

            if r.status_code != 302:
                raise AuthenticationError(self.username)

            logger.info("Logged in")
            self.logged_in = True
Exemple #2
0
    def initialize(self):
        self.session = Session()
        self.session.headers['User-Agent'] = 'Subliminal/{}'.format(__version__)

        # login
        if self.username is not None and self.password is not None:
            logger.info('Logging in')
            params = {
                'username': self.username,
                'password': self.password,
                'apikey': self.apikey
            }

            r = self.session.get(self.server_url + 'users/login', params=params, timeout=10)
            root = etree.fromstring(r.content)

            if root.find('status').text == 'fail':
                raise AuthenticationError(root.find('error/message').text)

            self.auth_code = root.find('data/user/authcode').text

            data = {
                'username': self.username,
                'passwd': self.password,
                'remember': 'yes',
                'option': 'com_user',
                'task': 'login',
                'silent': 'true'
            }
            r = self.session.post('http://www.italiansubs.net/index.php', data=data, timeout=30)
            r.raise_for_status()

            self.logged_in = True
Exemple #3
0
    def initialize(self):
        self.session = Session()
        self.session.headers[
            'User-Agent'] = 'Subliminal/%s' % __short_version__

        # login
        if self.username and self.password:
            logger.info('Logging in')
            data = {
                '_method': 'POST',
                'data[User][username]': self.username,
                'data[User][password]': self.password
            }
            r = self.session.post(self.server_url + 'login',
                                  data,
                                  allow_redirects=False,
                                  timeout=10)
            raise_for_status(r)

            soup = ParserBeautifulSoup(r.content, ['html.parser'])
            if soup.find('div', {'class': 'alert-error'},
                         string=re.compile(u'Usuário ou senha inválidos')):
                raise AuthenticationError(self.username)

            logger.debug('Logged in')
            self.logged_in = True
Exemple #4
0
 def login(self):
     try:
         r = self.session.post(self.server_url + 'login',
                               json={"username": self.username, "password": self.password},
                               allow_redirects=False,
                               timeout=10)
     except (ConnectionError, Timeout, ReadTimeout):
         raise ServiceUnavailable('Unknown Error, empty response: %s: %r' % (r.status_code, r))
     else:
         if r.status_code == 200:
             try:
                 self.token = r.json()['token']
             except ValueError:
                 raise ProviderError('Invalid JSON returned by provider')
             else:
                 self.session.headers.update({'Authorization': 'Beaker ' + self.token})
                 region.set("oscom_token", self.token)
                 return True
         elif r.status_code == 401:
             raise AuthenticationError('Login failed: {}'.format(r.reason))
         elif r.status_code == 429:
             raise TooManyRequests()
         else:
             raise ProviderError('Bad status code: {}'.format(r.status_code))
     finally:
         return False
Exemple #5
0
    def initialize(self):
        self.session = Session()
        self.session.headers['User-Agent'] = 'Subliminal/{}'.format(
            __short_version__)

        # login
        if self.username is not None and self.password is not None:
            logger.debug('Logging in')
            url = self.server_url + 'subscenter/accounts/login/'

            # retrieve CSRF token
            self.session.get(url)
            csrf_token = self.session.cookies['csrftoken']

            # actual login
            data = {
                'username': self.username,
                'password': self.password,
                'csrfmiddlewaretoken': csrf_token
            }
            r = self.session.post(url, data, allow_redirects=False, timeout=10)

            if r.status_code != 302:
                raise AuthenticationError(self.username)

            logger.info('Logged in')
            self.logged_in = True
Exemple #6
0
    def login(self):
        logger.debug('Legendasdivx.pt :: Logging in')
        try:
            # sleep for a 1 second before another request
            sleep(1)
            res = self.session.get(self.loginpage)
            res.raise_for_status()
            bsoup = ParserBeautifulSoup(res.content, ['lxml'])

            _allinputs = bsoup.findAll('input')
            data = {}
            # necessary to set 'sid' for POST request
            for field in _allinputs:
                data[field.get('name')] = field.get('value')

            # sleep for a 1 second before another request
            sleep(1)
            data['username'] = self.username
            data['password'] = self.password
            res = self.session.post(self.loginpage, data)
            res.raise_for_status()
            # make sure we're logged in
            logger.debug(
                'Legendasdivx.pt :: Logged in successfully: PHPSESSID: %s',
                self.session.cookies.get_dict()['PHPSESSID'])
            cj = self.session.cookies.copy()
            store_cks = ("PHPSESSID", "phpbb3_2z8zs_sid", "phpbb3_2z8zs_k",
                         "phpbb3_2z8zs_u", "lang")
            for cn in iter(self.session.cookies.keys()):
                if cn not in store_cks:
                    del cj[cn]
            # store session cookies on cache
            logger.debug(
                "Legendasdivx.pt :: Storing legendasdivx session cookies: %r",
                cj)
            region.set("legendasdivx_cookies2", cj)

        except KeyError:
            logger.error(
                "Legendasdivx.pt :: Couldn't get session ID, check your credentials"
            )
            raise AuthenticationError(
                "Legendasdivx.pt :: Couldn't get session ID, check your credentials"
            )
        except HTTPError as e:
            if "bloqueado" in res.text.lower():
                logger.error(
                    "LegendasDivx.pt :: Your IP is blocked on this server.")
                raise IPAddressBlocked(
                    "LegendasDivx.pt :: Your IP is blocked on this server.")
            logger.error("Legendasdivx.pt :: HTTP Error %s", e)
            raise TooManyRequests("Legendasdivx.pt :: HTTP Error %s", e)
        except Exception as e:
            logger.error("LegendasDivx.pt :: Uncaught error: %r", e)
            raise ServiceUnavailable("LegendasDivx.pt :: Uncaught error: %r",
                                     e)
Exemple #7
0
    def initialize(self):
        self.session = Session()
        self.session.headers[
            'User-Agent'] = 'Subliminal/%s' % subliminal.__short_version__

        if self.USE_ADDICTED_RANDOM_AGENTS:
            from .utils import FIRST_THOUSAND_OR_SO_USER_AGENTS as AGENT_LIST
            logger.debug("Addic7ed: using random user agents")
            self.session.headers['User-Agent'] = AGENT_LIST[randint(
                0,
                len(AGENT_LIST) - 1)]
            self.session.headers['Referer'] = self.server_url

        # login
        if self.username and self.password:
            ccks = region.get("addic7ed_cookies", expiration_time=86400)
            if ccks != NO_VALUE:
                try:
                    self.session.cookies._cookies.update(ccks)
                    r = self.session.get(self.server_url + 'panel.php',
                                         allow_redirects=False,
                                         timeout=10)
                    if r.status_code == 302:
                        logger.info('Addic7ed: Login expired')
                        region.delete("addic7ed_cookies")
                    else:
                        logger.info('Addic7ed: Reusing old login')
                        self.logged_in = True
                        return
                except:
                    pass

            logger.info('Addic7ed: Logging in')
            data = {
                'username': self.username,
                'password': self.password,
                'Submit': 'Log in'
            }
            r = self.session.post(
                self.server_url + 'dologin.php',
                data,
                allow_redirects=False,
                timeout=10,
                headers={"Referer": self.server_url + "login.php"})

            if "relax, slow down" in r.content:
                raise TooManyRequests(self.username)

            if r.status_code != 302:
                raise AuthenticationError(self.username)

            region.set("addic7ed_cookies", self.session.cookies._cookies)

            logger.debug('Addic7ed: Logged in')
            self.logged_in = True
Exemple #8
0
    def logout(self):
        logger.info("Titulky.com: Logging out")

        res = self.session.get(self.logout_url,
                               allow_redirects=False,
                               timeout=self.timeout)

        # If the response is a redirect and doesnt point to an error message page, then we are logged out
        if res.status_code == 302 and 'msg_type=i' in res.headers['Location']:
            return True
        else:
            raise AuthenticationError("Logout failed.")
Exemple #9
0
    def query(self, language, size, name, hash):
        params = {
            'postAction': 'CheckSub',
            'ua': self.username,
            'ap': self.password,
            'fs': size,
            'fh': hash,
            'fn': os.path.basename(name),
            'n24pref': 1
        }

        response = self.session.post(self.api_url, data=params, timeout=10)
        response.raise_for_status()

        response_content = response.content.split(b'||', 1)
        n24_data = response_content[0].decode()

        if n24_data[:2] != 'OK':
            if n24_data[:11] == 'login error':
                raise AuthenticationError('Login failed')
            logger.error('Unknown response: %s', response.content)
            return None

        n24_status = n24_data[:4]
        if n24_status == 'OK-0':
            logger.info('No subtitles found')
            return None

        subtitle_info = dict(p.split(':', 1) for p in n24_data.split('|')[1:])
        logger.debug('Subtitle info: %s', subtitle_info)

        if n24_status == 'OK-1':
            logger.info('No subtitles found but got video info')
            return None
        elif n24_status == 'OK-2':
            logger.info('Found subtitles')
        elif n24_status == 'OK-3':
            logger.info('Found subtitles but not from Napisy24 database')
            return None

        subtitle_content = response_content[1]

        subtitle = Napisy24Subtitle(language, hash,
                                    'tt%s' % subtitle_info['imdb'].zfill(7),
                                    subtitle_info['napisId'])
        with ZipFile(BytesIO(subtitle_content)) as zf:
            subtitle.content = fix_line_ending(
                zf.open(zf.namelist()[0]).read())

        return subtitle
Exemple #10
0
    def initialize(self):
        self.session = Session()
        self.session.headers['User-Agent'] = self._get_user_agent()

        # login
        if self.username and self.password:
            logger.info('Logging in')
            data = {'username': self.username, 'password': self.password, 'Submit': 'Log in'}
            r = self.session.post(self.server_url + 'dologin.php', data, allow_redirects=False, timeout=10)

            if r.status_code != 302:
                raise AuthenticationError(self.username)

            logger.debug('Logged in')
            self.logged_in = True
Exemple #11
0
    def login(self):
        logger.info("Titulky.com: Logging in")

        self.session.get(self.server_url)

        data = {'LoginName': self.username, 'LoginPassword': self.password}
        res = self.session.post(self.server_url,
                                data,
                                allow_redirects=False,
                                timeout=self.timeout)

        # If the response is a redirect and doesnt point to an error message page, then we are logged in
        if res.status_code == 302 and 'msg_type=i' in res.headers['Location']:
            return True
        else:
            raise AuthenticationError("Login failed")
Exemple #12
0
    def initialize(self):
        self.session = Session()
        self.session.headers['User-Agent'] = 'Subliminal/%s' % __version__

        # login
        if self.username is not None and self.password is not None:
            logger.info('Logging in')
            params = {
                'username': self.username,
                'password': self.password,
                'apikey': self.apikey
            }

            r = self.session.get(self.server_url + 'users/login',
                                 params=params,
                                 allow_redirects=False,
                                 timeout=10)
            root = ElementTree.fromstring(r.content)

            if root.find('status').text == 'fail':
                raise AuthenticationError(root.find('error/message').text)

            self.auth_code = root.find('data/user/authcode').text

            r = self.session.get('https://www.italiansubs.net/',
                                 allow_redirects=True,
                                 timeout=30)
            form = re.search(r'<form.*?id="form-login".*?>.*?</form>', r.text,
                             re.DOTALL)
            input_matcher = re.finditer(
                '<input.*?name="(.*?)".*?value="(.*?)".*?/>', form.group())

            data = {}

            for inputMatch in input_matcher:
                data[inputMatch.group(1)] = inputMatch.group(2)
            data['username'] = self.username
            data['passwd'] = self.password

            r = self.session.post('https://www.italiansubs.net/index.php',
                                  data=data,
                                  allow_redirects=True,
                                  timeout=30)
            r.raise_for_status()

            self.logged_in = True
Exemple #13
0
 def initialize(self):
     self.session = Session()
     self.session.headers['User-Agent'] = 'Subliminal/{}'.format(__short_version__)
     
     # login
     if self.username and self.password:
         logger.info('Logging in')
         self.session.get(self.server_url)
         data = {'Login': self.username,
                 'Password': self.password}
         r = self.session.post(self.server_url, data, allow_redirects=False, timeout=10)
         
         if 'BadLogin' in r.content:
             raise AuthenticationError(self.username)
         
         logger.debug('Logged in')
         self.logged_in = True
Exemple #14
0
    def initialize(self):
        self.session = Session()
        self.session.headers["User-Agent"] = "Subliminal/%s" % __version__

        # login
        if self.username is not None and self.password is not None:
            logger.info("Logging in")
            params = {
                "username": self.username,
                "password": self.password,
                "apikey": self.apikey
            }

            r = self.session.get(self.server_url + "users/login",
                                 params=params,
                                 allow_redirects=False,
                                 timeout=10)
            root = ElementTree.fromstring(r.content)

            if root.find("status").text == "fail":
                raise AuthenticationError(root.find("error/message").text)

            self.auth_code = root.find("data/user/authcode").text

            r = self.session.get("https://www.italiansubs.net/",
                                 allow_redirects=True,
                                 timeout=30)
            form = re.search(r'<form.*?id="form-login".*?>.*?</form>', r.text,
                             re.DOTALL)
            input_matcher = re.finditer(
                '<input.*?name="(.*?)".*?value="(.*?)".*?/>', form.group())

            data = {}

            for inputMatch in input_matcher:
                data[inputMatch.group(1)] = inputMatch.group(2)
            data["username"] = self.username
            data["passwd"] = self.password

            r = self.session.post("https://www.italiansubs.net/index.php",
                                  data=data,
                                  allow_redirects=True,
                                  timeout=30)
            r.raise_for_status()

            self.logged_in = True
Exemple #15
0
    def initialize(self):
        self.session = Session()
        self.session.headers['User-Agent'] = 'Subliminal/{}'.format(__short_version__)

        # login
        if self.username and self.password:
            logger.info('Logging in')
            self.session.get(self.server_url + self.sign_in_url)
            data = {'username': self.username,
                    'password': self.password,
                    'csrfmiddlewaretoken': self.session.cookies['csrftoken']}
            r = self.session.post(self.server_url + self.sign_in_url, data, allow_redirects=False, timeout=10)

            if r.status_code != 302:
                raise AuthenticationError(self.username)

            logger.debug('Logged in')
            self.logged_in = True
Exemple #16
0
    def login(self):
        if not self.get_encryption_salt():
            return False
        if not self.encrypt_password():
            return False
        data = {
            "request": {
                "Email": self.username,
                "Password": self.encrypted_password
            }
        }
        logger.debug("Trying to log in using: {}".format(json.dumps(data)))
        r = self.session.post(self.URL_SERVER + self.URI_LOGIN_POST, json=data)
        r_result = r.json()
        login_results = ""
        if 'd' in r_result:
            try:
                login_results = json.loads(r_result['d'])
            except ValueError:
                logger.error("Could not process JSON from login response")
                return False

        if 'IsSuccess' not in login_results:
            logger.error("Login response is different than expected")
            return False

        if not login_results['IsSuccess']:
            logger.error("Wrong username or password!")
            raise AuthenticationError('Wrong username or password!')
            return False

        if not r.cookies or type(r.cookies) is not RequestsCookieJar:
            logger.error("Could not get the cookie response of the login")
            return False

        if 'Login' not in r.cookies.keys():
            logger.error("Could not found login cookie!")
            return False

        logger.info("Connected successfully to Ktuvit!")
        return True
Exemple #17
0
    def log_in(self):
        login_params = dict(username=self.username,
                            password=self.password,
                            json=True)
        try:
            response = self.session.post(self.api_gettoken_url,
                                         params=login_params)
            if response.status_code == request_codes.ok:
                resp_json = response.json()
                self.login_token = resp_json.get('Token')
                self.user_id = resp_json.get('UserId')
                self.token_exp = dateutil.parser.parse(
                    resp_json.get('ExpirationDate'))

                region.set("titlovi_token",
                           [self.user_id, self.login_token, self.token_exp])
                logger.debug('New token obtained')

            elif response.status_code == request_codes.unauthorized:
                raise AuthenticationError('Login failed')

        except RequestException as e:
            logger.error(e)
Exemple #18
0
    def initialize(self):
        self.session = Session()

        # login
        if self.email and self.hashed_password:
            logger.info("Logging in")

            data = {
                "request": {
                    "Email": self.email,
                    "Password": self.hashed_password
                }
            }

            self.session.headers["Accept-Encoding"] = "gzip"
            self.session.headers["Accept-Language"] = "en-us,en;q=0.5"
            self.session.headers["Pragma"] = "no-cache"
            self.session.headers["Cache-Control"] = "no-cache"
            self.session.headers["Content-Type"] = "application/json"
            self.session.headers["User-Agent"]: os.environ.get(
                "SZ_USER_AGENT", "Sub-Zero/2")

            r = self.session.post(
                self.server_url + self.sign_in_url,
                json=data,
                allow_redirects=False,
                timeout=10,
            )

            if r.content:
                is_success = False
                try:
                    is_success = self.parse_d_response(
                        r, "IsSuccess", False,
                        "Authentication to the provider")
                except json.decoder.JSONDecodeError:
                    logger.info("Failed to Login to Ktuvit")
                if not is_success:
                    error_message = ''
                    try:
                        error_message = self.parse_d_response(
                            r, "ErrorMessage", "[None]")
                    except json.decode.JSONDecoderError:
                        raise AuthenticationError(
                            "Error Logging in to Ktuvit Provider: " +
                            str(r.content))
                    raise AuthenticationError(
                        "Error Logging in to Ktuvit Provider: " +
                        error_message)
                else:
                    cookie_split = r.headers["set-cookie"].split("Login="******"Login Failed, didn't receive valid cookie in response"
                        )

                    self.login_cookie = cookie_split[1].split(";")[0]
                    logger.debug("Logged in with cookie: " + self.login_cookie)

                    self.logged_in = True
Exemple #19
0
    def initialize(self):
        self.session = Session()
        self.session.headers[
            'User-Agent'] = 'Subliminal/%s' % subliminal.__short_version__

        from .utils import FIRST_THOUSAND_OR_SO_USER_AGENTS as AGENT_LIST
        logger.debug("Addic7ed: using random user agents")
        self.session.headers['User-Agent'] = AGENT_LIST[randint(
            0,
            len(AGENT_LIST) - 1)]
        self.session.headers['Referer'] = self.server_url

        # login
        if self.username and self.password:

            def check_verification(cache_region):
                try:
                    rr = self.session.get(self.server_url + 'panel.php',
                                          allow_redirects=False,
                                          timeout=10,
                                          headers={"Referer": self.server_url})
                    if rr.status_code == 302:
                        logger.info('Addic7ed: Login expired')
                        cache_region.delete("addic7ed_data")
                    else:
                        logger.info('Addic7ed: Re-using old login')
                        self.logged_in = True
                        return True
                except ConnectionError as e:
                    logger.debug(
                        "Addic7ed: There was a problem reaching the server: %s."
                        % e)
                    raise IPAddressBlocked(
                        "Addic7ed: Your IP is temporarily blocked.")

            if load_verification("addic7ed",
                                 self.session,
                                 callback=check_verification):
                return

            logger.info('Addic7ed: Logging in')
            data = {
                'username': self.username,
                'password': self.password,
                'Submit': 'Log in',
                'url': '',
                'remember': 'true'
            }

            tries = 0
            while tries <= 3:
                tries += 1
                r = self.session.get(self.server_url + 'login.php',
                                     timeout=10,
                                     headers={"Referer": self.server_url})
                if "g-recaptcha" in r.text or "grecaptcha" in r.text:
                    logger.info(
                        'Addic7ed: Solving captcha. This might take a couple of minutes, but should only '
                        'happen once every so often')

                    for g, s in (("g-recaptcha-response",
                                  r'g-recaptcha.+?data-sitekey=\"(.+?)\"'),
                                 ("recaptcha_response",
                                  r'grecaptcha.execute\(\'(.+?)\',')):
                        site_key = re.search(s, r.text).group(1)
                        if site_key:
                            break
                    if not site_key:
                        logger.error("Addic7ed: Captcha site-key not found!")
                        return

                    pitcher = pitchers.get_pitcher()(
                        "Addic7ed",
                        self.server_url + 'login.php',
                        site_key,
                        user_agent=self.session.headers["User-Agent"],
                        cookies=self.session.cookies.get_dict(),
                        is_invisible=True)

                    result = pitcher.throw()
                    if not result:
                        if tries >= 3:
                            raise Exception(
                                "Addic7ed: Couldn't solve captcha!")
                        logger.info(
                            "Addic7ed: Couldn't solve captcha! Retrying")
                        continue

                    data[g] = result

                r = self.session.post(
                    self.server_url + 'dologin.php',
                    data,
                    allow_redirects=False,
                    timeout=10,
                    headers={"Referer": self.server_url + "login.php"})

                if "relax, slow down" in r.text:
                    raise TooManyRequests(self.username)

                if "Wrong password" in r.text or "doesn't exist" in r.text:
                    raise AuthenticationError(self.username)

                if r.status_code != 302:
                    if tries >= 3:
                        logger.error(
                            "Addic7ed: Something went wrong when logging in")
                        raise AuthenticationError(self.username)
                    logger.info(
                        "Addic7ed: Something went wrong when logging in; retrying"
                    )
                    continue
                break

            store_verification("addic7ed", self.session)

            logger.debug('Addic7ed: Logged in')
            self.logged_in = True
Exemple #20
0
    def initialize(self):
        self.session = Session()
        self.session.headers['User-Agent'] = 'Subliminal/%s' % subliminal.__short_version__

        from .utils import FIRST_THOUSAND_OR_SO_USER_AGENTS as AGENT_LIST
        logger.debug("Addic7ed: using random user agents")
        self.session.headers['User-Agent'] = AGENT_LIST[randint(0, len(AGENT_LIST) - 1)]
        self.session.headers['Referer'] = self.server_url

        # login
        if self.username and self.password:
            def check_verification(cache_region):
                rr = self.session.get(self.server_url + 'panel.php', allow_redirects=False, timeout=10,
                                      headers={"Referer": self.server_url})
                if rr.status_code == 302:
                    logger.info('Addic7ed: Login expired')
                    cache_region.delete("addic7ed_data")
                else:
                    logger.info('Addic7ed: Re-using old login')
                    self.logged_in = True
                    return True

            if load_verification("addic7ed", self.session, callback=check_verification):
                return

            logger.info('Addic7ed: Logging in')
            data = {'username': self.username, 'password': self.password, 'Submit': 'Log in', 'url': '',
                    'remember': 'true'}

            tries = 0
            while tries < 3:
                r = self.session.get(self.server_url + 'login.php', timeout=10, headers={"Referer": self.server_url})
                if "grecaptcha" in r.content:
                    logger.info('Addic7ed: Solving captcha. This might take a couple of minutes, but should only '
                                'happen once every so often')

                    site_key = re.search(r'grecaptcha.execute\(\'(.+?)\',', r.content).group(1)
                    if not site_key:
                        logger.error("Addic7ed: Captcha site-key not found!")
                        return

                    pitcher = pitchers.get_pitcher()("Addic7ed", self.server_url + 'login.php', site_key,
                                                     user_agent=self.session.headers["User-Agent"],
                                                     cookies=self.session.cookies.get_dict(),
                                                     is_invisible=True)

                    result = pitcher.throw()
                    if not result:
                        raise Exception("Addic7ed: Couldn't solve captcha!")

                    data["recaptcha_response"] = result

                r = self.session.post(self.server_url + 'dologin.php', data, allow_redirects=False, timeout=10,
                                      headers={"Referer": self.server_url + "login.php"})

                if "relax, slow down" in r.content:
                    raise TooManyRequests(self.username)

                if r.status_code != 302:
                    if "User <b></b> doesn't exist" in r.content and tries <= 2:
                        logger.info("Addic7ed: Error, trying again. (%s/%s)", tries+1, 3)
                        tries += 1
                        continue

                    raise AuthenticationError(self.username)
                break

            store_verification("addic7ed", self.session)

            logger.debug('Addic7ed: Logged in')
            self.logged_in = True
Exemple #21
0
def checked(fn,
            raise_api_limit=False,
            validate_token=False,
            validate_json=False,
            json_key_name=None,
            validate_content=False):
    """Run :fn: and check the response status before returning it.

    :param fn: the function to make an API call to OpenSubtitles.com.
    :param raise_api_limit: if True we wait a little bit longer before running the call again.
    :param validate_token: test if token is valid and return 401 if not.
    :param validate_json: test if response is valid json.
    :param json_key_name: test if returned json contain a specific key.
    :param validate_content: test if response have a content (used with download).
    :return: the response.

    """
    response = None
    try:
        try:
            response = fn()
        except APIThrottled:
            if not raise_api_limit:
                logger.info(
                    "API request limit hit, waiting and trying again once.")
                time.sleep(2)
                return checked(fn, raise_api_limit=True)
            raise
        except (ConnectionError, Timeout, ReadTimeout):
            raise ServiceUnavailable(
                f'Unknown Error, empty response: {response.status_code}: {response}'
            )
        except Exception:
            logging.exception('Unhandled exception raised.')
            raise ProviderError('Unhandled exception raised. Check log.')
        else:
            status_code = response.status_code
    except Exception:
        status_code = None
    else:
        if status_code == 401:
            if validate_token:
                return 401
            else:
                raise AuthenticationError(f'Login failed: {response.reason}')
        elif status_code == 403:
            raise ProviderError("Bazarr API key seems to be in problem")
        elif status_code == 406:
            raise DownloadLimitExceeded("Daily download limit reached")
        elif status_code == 410:
            raise ProviderError("Download as expired")
        elif status_code == 429:
            raise TooManyRequests()
        elif status_code == 502:
            # this one should deal with Bad Gateway issue on their side.
            raise APIThrottled()
        elif 500 <= status_code <= 599:
            raise ProviderError(response.reason)

        if status_code != 200:
            raise ProviderError(f'Bad status code: {response.status_code}')

        if validate_json:
            try:
                json_test = response.json()
            except JSONDecodeError:
                raise ProviderError('Invalid JSON returned by provider')
            else:
                if json_key_name not in json_test:
                    raise ProviderError(
                        f'Invalid JSON returned by provider: no {json_key_name} key in returned json.'
                    )

        if validate_content:
            if not hasattr(response, 'content'):
                logging.error('Download link returned no content attribute.')
                return False
            elif not response.content:
                logging.error(
                    f'This download link returned empty content: {response.url}'
                )
                return False

    return response