Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added "back" exception handling for the download clients. #9774

Merged
merged 3 commits into from
Aug 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions medusa/clients/nzb/nzbget.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from medusa import app
from medusa.common import Quality
from medusa.helper.common import try_int
from medusa.helper.exceptions import DownloadClientConnectionException
from medusa.logger.adapters.style import BraceAdapter

import ttl_cache
Expand Down Expand Up @@ -56,7 +57,7 @@ def nzb_connection(url):
return False


def test_authentication(host, username, password, use_https):
def test_authentication(host=None, username=None, password=None, use_https=False):
"""
Test NZBget client connection.

Expand Down Expand Up @@ -197,10 +198,13 @@ def _get_nzb_queue():
)

if not nzb_connection(url):
return False
raise DownloadClientConnectionException('Error while fetching nzbget queue')

nzb_get_rpc = ServerProxy(url)
nzb_groups = nzb_get_rpc.listgroups()
try:
nzb_groups = nzb_get_rpc.listgroups()
except ConnectionRefusedError as error:
raise DownloadClientConnectionException(f'Error while fetching nzbget history. Error: {error}')

return nzb_groups

Expand All @@ -216,10 +220,13 @@ def _get_nzb_history():
)

if not nzb_connection(url):
return False
raise DownloadClientConnectionException('Error while fetching nzbget history')

nzb_get_rpc = ServerProxy(url)
nzb_groups = nzb_get_rpc.history()
try:
nzb_groups = nzb_get_rpc.history()
except ConnectionRefusedError as error:
raise DownloadClientConnectionException(f'Error while fetching nzbget history. Error: {error}')

return nzb_groups

Expand Down
18 changes: 14 additions & 4 deletions medusa/clients/nzb/sab.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,19 @@

from medusa import app
from medusa.helper.common import sanitize_filename
from medusa.helper.exceptions import DownloadClientConnectionException
from medusa.logger.adapters.style import BraceAdapter
from medusa.session.core import ClientSession
from medusa.session.core import MedusaSession

from requests.compat import urljoin
from requests.exceptions import ConnectionError

import ttl_cache

log = BraceAdapter(logging.getLogger(__name__))
log.logger.addHandler(logging.NullHandler())

session = ClientSession()
session = MedusaSession()


def send_nzb(nzb):
Expand Down Expand Up @@ -209,7 +211,11 @@ def _get_nzb_queue(host=None):
'limit': 100
}

data = session.get_json(url, params=params, verify=False)
try:
data = session.get_json(url, params=params, verify=False)
except ConnectionError as error:
raise DownloadClientConnectionException(f'Error while fetching sabnzbd queue. Error: {error}')

if not data:
log.info('Error connecting to sab, no data returned')
else:
Expand All @@ -234,7 +240,11 @@ def _get_nzb_history(host=None):
'limit': 100
}

data = session.get_json(url, params=params, verify=False)
try:
data = session.get_json(url, params=params, verify=False)
except ConnectionError as error:
raise DownloadClientConnectionException(f'Error while fetching sabnzbd history. Error: {error}')

if not data:
log.info('Error connecting to sab, no data returned')
else:
Expand Down
12 changes: 8 additions & 4 deletions medusa/clients/torrent/deluge.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from medusa import app
from medusa.clients.torrent.generic import GenericClient
from medusa.helper.exceptions import DownloadClientConnectionException
from medusa.helpers import (
get_extension,
is_already_processed_media,
Expand Down Expand Up @@ -215,7 +216,6 @@ def _get_auth(self):
{'name': self.name})
return None

self._torrent_properties('e4d44da9e71a8f4411bc3fd82aad7689cfa0f07f')
return self.auth

def _add_torrent_uri(self, result):
Expand Down Expand Up @@ -489,9 +489,13 @@ def _torrent_properties(self, info_hash):
})

log.debug('Checking {client} torrent {hash} status.', {'client': self.name, 'hash': info_hash})
if not self._request(method='post', data=post_data) or self.response.json()['error']:
log.warning('Error while fetching torrent {hash} status.', {'hash': info_hash})
return

try:
if not self._request(method='post', data=post_data) or self.response.json()['error']:
log.warning('Error while fetching torrent {hash} status.', {'hash': info_hash})
return
except RequestException as error:
raise DownloadClientConnectionException(f'Error while fetching torrent info_hash {info_hash}. Error: {error}')

return self.response.json()['result']

Expand Down
8 changes: 5 additions & 3 deletions medusa/clients/torrent/deluged.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
from medusa import app
from medusa.clients.torrent.deluge import read_torrent_status
from medusa.clients.torrent.generic import GenericClient
from medusa.helper.exceptions import DownloadClientConnectionException
from medusa.logger.adapters.style import BraceAdapter
from medusa.schedulers.download_handler import ClientStatus

from requests.exceptions import RequestException

log = BraceAdapter(logging.getLogger(__name__))
log.logger.addHandler(logging.NullHandler())
Expand Down Expand Up @@ -231,8 +233,7 @@ def get_status(self, info_hash):
```
"""
if not self.connect():
log.warning('Error while fetching torrents status')
return
raise DownloadClientConnectionException(f'Error while fetching torrent info_hash {info_hash}')

torrent = self.drpc._torrent_properties(info_hash)
if not torrent:
Expand Down Expand Up @@ -312,7 +313,6 @@ def test(self):
"""
try:
self.connect()
# self._torrent_properties('e4d44da9e71a8f4411bc3fd82aad7689cfa0f07f')
except Exception:
return False
else:
Expand Down Expand Up @@ -539,6 +539,8 @@ def _torrent_properties(self, info_hash):
torrent_data = self.client.core.get_torrent_status(
info_hash, ('name', 'hash', 'progress', 'state', 'ratio', 'stop_ratio',
'is_seed', 'is_finished', 'paused', 'files', 'download_location'))
except RequestException as error:
raise DownloadClientConnectionException(f'Error while fetching torrent info_hash {info_hash}. Error: {error}')
except Exception:
log.warning('Error while fetching torrent {hash} status.', {'hash': info_hash})
return
Expand Down
47 changes: 33 additions & 14 deletions medusa/clients/torrent/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
import certifi

from medusa import app, db
from medusa.helper.common import http_code_description
from medusa.logger.adapters.style import BraceAdapter
from medusa.session.core import ClientSession

import requests


log = BraceAdapter(logging.getLogger(__name__))
log.logger.addHandler(logging.NullHandler())
Expand Down Expand Up @@ -54,27 +57,43 @@ def __init__(self, name, host=None, username=None, password=None, torrent_path=N

def _request(self, method='get', params=None, data=None, files=None, cookies=None):

self.response = self.session.request(
method, self.url, params=params, data=data, files=files, timeout=60, cookies=cookies,
verify=self.verify if app.TORRENT_VERIFY_CERT else False
)
if not self.response:
log.warning('{name} {method} call to {url} failed!', {
'name': self.name, 'method': method.upper(), 'url': self.url
})
self.message = f'Connect to {self.name} on "{self.host}" failed!'
try:
self.response = self.session.request(
method, self.url, params=params, data=data, files=files, timeout=60, cookies=cookies,
verify=self.verify if app.TORRENT_VERIFY_CERT else False
)
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidURL) as error:
log.warning('{name}: Invalid Host: {error}', {'name': self.name, 'error': error})
return False
if self.response.status_code >= 400:
log.warning('{name}: Unable to reach torrent client. Reason: {reason}', {
'name': self.name, 'reason': self.response.reason
})
self.message = f'Failed to connect to {self.name} reason: {self.response.reason}'
except requests.exceptions.RequestException as error:
log.warning('{name}: Error occurred during request: {error}',
{'name': self.name, 'error': error})
# We want to raise connection errors for the download_handler. As we need to know
# explicitely if there was a connection error when untracking tracked torrents/nzb.
raise
except Exception as error:
log.error('{name}: Unknown exception raised when sending torrent to'
' {name}: {error}', {'name': self.name, 'error': error})
return False

if self.response.status_code == 401:
log.error('{name}: Invalid Username or Password,'
' check your config', {'name': self.name})
return False

code_description = http_code_description(self.response.status_code)

if code_description is not None:
log.info('{name}: {code}',
{'name': self.name, 'code': code_description})
return False

log.debug('{name}: Response to {method} request is {response}', {
'name': self.name,
'method': method.upper(),
'response': self.response.text[0:1024] + '...' if len(self.response.text) > 1027 else self.response.text
})

return True

def _get_auth(self):
Expand Down
14 changes: 11 additions & 3 deletions medusa/clients/torrent/qbittorrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@

from medusa import app
from medusa.clients.torrent.generic import GenericClient
from medusa.helper.exceptions import DownloadClientConnectionException
from medusa.logger.adapters.style import BraceAdapter
from medusa.schedulers.download_handler import ClientStatus

from requests.auth import HTTPDigestAuth
from requests.compat import urljoin
from requests.exceptions import RequestException

import ttl_cache

Expand Down Expand Up @@ -293,6 +295,9 @@ def remove_torrent_data(self, info_hash):
def _get_torrents(self, filter=None, category=None, sort=None):
"""Get all torrents from qbittorrent api."""
params = {}
if not self.api:
raise DownloadClientConnectionException('Error while fetching torrent. Not authenticated.')

if self.api >= (2, 0, 0):
self.url = urljoin(self.host, 'api/v2/torrents/info')
if filter:
Expand All @@ -304,9 +309,12 @@ def _get_torrents(self, filter=None, category=None, sort=None):
else:
self.url = urljoin(self.host, 'json/torrents')

if not self._request(method='get', params=params, cookies=self.session.cookies):
log.warning('Error while fetching torrents.')
return []
try:
if not self._request(method='get', params=params, cookies=self.session.cookies):
log.warning('Error while fetching torrents.')
return []
except RequestException as error:
raise DownloadClientConnectionException(f'Error while fetching torrent. Error: {error}')

return self.response.json()

Expand Down
34 changes: 26 additions & 8 deletions medusa/clients/torrent/rtorrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from medusa import app
from medusa.clients.torrent.generic import GenericClient
from medusa.helper.exceptions import DownloadClientConnectionException
from medusa.logger.adapters.style import BraceAdapter
from medusa.schedulers.download_handler import ClientStatus

Expand Down Expand Up @@ -51,10 +52,13 @@ def _get_auth(self):
if app.SSL_CA_BUNDLE:
tp_kwargs['check_ssl_cert'] = app.SSL_CA_BUNDLE

if self.username and self.password:
self.auth = RTorrent(self.host, self.username, self.password, True, tp_kwargs=tp_kwargs)
else:
self.auth = RTorrent(self.host, None, None, True)
try:
if self.username and self.password:
self.auth = RTorrent(self.host, self.username, self.password, True, tp_kwargs=tp_kwargs)
else:
self.auth = RTorrent(self.host, None, None, True)
except Exception as error: # No request/connection specific exception thrown.
raise DownloadClientConnectionException(f'Unable to authenticate with rtorrent client: {error}')

return self.auth

Expand Down Expand Up @@ -82,7 +86,11 @@ def _add_torrent_uri(self, result):
try:
params = self._get_params(result)
# Send magnet to rTorrent and start it
torrent = self.auth.load_magnet(result.url, result.hash, start=True, params=params)
try:
torrent = self.auth.load_magnet(result.url, result.hash, start=True, params=params)
except DownloadClientConnectionException:
return False

if not torrent:
return False

Expand All @@ -101,7 +109,11 @@ def _add_torrent_file(self, result):
try:
params = self._get_params(result)
# Send torrent to rTorrent and start it
torrent = self.auth.load_torrent(result.content, start=True, params=params)
try:
torrent = self.auth.load_torrent(result.content, start=True, params=params)
except DownloadClientConnectionException:
return False

if not torrent:
return False

Expand Down Expand Up @@ -132,7 +144,10 @@ def test_authentication(self):
def pause_torrent(self, info_hash):
"""Get torrent and pause."""
log.info('Pausing {client} torrent {hash} status.', {'client': self.name, 'hash': info_hash})
torrent = self.auth.find_torrent(info_hash.upper())
try:
torrent = self.auth.find_torrent(info_hash.upper())
except DownloadClientConnectionException:
return False

if not torrent:
log.debug('Could not locate torrent with {hash} status.', {'hash': info_hash})
Expand All @@ -143,7 +158,10 @@ def pause_torrent(self, info_hash):
def remove_torrent(self, info_hash):
"""Get torrent and remove."""
log.info('Removing {client} torrent {hash} status.', {'client': self.name, 'hash': info_hash})
torrent = self.auth.find_torrent(info_hash.upper())
try:
torrent = self.auth.find_torrent(info_hash.upper())
except DownloadClientConnectionException:
return False

if not torrent:
log.debug('Could not locate torrent with {hash} status.', {'hash': info_hash})
Expand Down
4 changes: 2 additions & 2 deletions medusa/clients/torrent/transmission.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from medusa import app
from medusa.clients.torrent.generic import GenericClient
from medusa.helper.exceptions import DownloadClientConnectionException
from medusa.logger.adapters.style import BraceAdapter
from medusa.schedulers.download_handler import ClientStatus

Expand Down Expand Up @@ -308,8 +309,7 @@ def _torrent_properties(self, info_hash):
post_data = json.dumps({'arguments': return_params, 'method': 'torrent-get'})

if not self._request(method='post', data=post_data) or not self.check_response():
log.warning('Error while fetching torrent {hash} status.', {'hash': info_hash})
return
raise DownloadClientConnectionException(f'Error while fetching torrent {info_hash} status.')

torrent = self.response.json()['arguments']['torrents']
if not torrent:
Expand Down
11 changes: 7 additions & 4 deletions medusa/clients/torrent/utorrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from medusa import app
from medusa.clients.torrent.generic import GenericClient
from medusa.helper.exceptions import DownloadClientConnectionException
from medusa.logger.adapters.style import BraceAdapter
from medusa.schedulers.download_handler import ClientStatus

Expand Down Expand Up @@ -251,11 +252,13 @@ def _get_torrents(self):
info_hash, it will get all torrents for each info_hash. We might want to cache this one.
"""
params = {'list': 1}
if not self._request(params=params):
log.warning('Error while fetching torrents.')
return []

json_response = self.response.json()
try:
self._request(params=params)
json_response = self.response.json()
except RequestException as error:
raise DownloadClientConnectionException(f'Error while fetching torrent. Error: {error}')

if json_response.get('torrents'):
return json_response['torrents']
return []
Expand Down
Loading