Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
9 changes: 9 additions & 0 deletions monitorrent/plugin_managers.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
import os

import structlog

from monitorrent.db import DBSession, row2dict
from monitorrent.plugins import Topic
from monitorrent.plugins.status import Status
from monitorrent.plugins.notifiers import Notifier, NotifierType
from monitorrent.plugins.trackers import TrackerPluginBase, WithCredentialsMixin
from monitorrent.upgrade_manager import add_upgrade


log = structlog.get_logger()
plugins = dict()


def load_plugins(plugins_dir="plugins"):
file_dir = os.path.dirname(os.path.realpath(__file__))
module_names = []
for d, dirnames, files in os.walk(os.path.join(file_dir, plugins_dir)):
d = d[len(file_dir) + 1:]
for f in files:
if not f.endswith('.py') or f == '__init__.py':
continue
module_name = os.path.join("monitorrent", d, f[:-3]).replace(os.path.sep, '.')
__import__(module_name)
module_names.append(module_name)
log.info("Plugins loaded successfully", modules=module_names)


def register_plugin(type, name, instance, upgrade=None):
Expand Down Expand Up @@ -175,6 +183,7 @@ def __init__(self, clients=None, default_client_name=None):
list(self.clients.values())[0] if len(self.clients) > 0 else None)

def set_default(self, name):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👎

default_client = self.__get_default_client(name)
if default_client is None:
raise KeyError()
Expand Down
89 changes: 36 additions & 53 deletions monitorrent/plugins/clients/deluge.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import six
import base64

import structlog
from deluge_client import DelugeRPCClient
import pytz
from sqlalchemy import Column, Integer, String
Expand All @@ -9,6 +11,8 @@

from monitorrent.plugins.clients import DownloadStatus

log = structlog.get_logger()


class DelugeCredentials(Base):
__tablename__ = "deluge_credentials"
Expand Down Expand Up @@ -85,30 +89,21 @@ def check_connection(self):
client = self._get_client()
if not client:
return False
try:
client.connect()
return client.connected
except:
return False
client.connect()
return client.connected

def get_download_dir(self):
client = self._get_client()
if not client:
return None
try:
client.connect()
return client.call('core.get_config_value', 'move_completed_path').decode('utf-8')
except:
return None
client.connect()
return client.call('core.get_config_value', 'move_completed_path').decode('utf-8')

def find_torrent(self, torrent_hash):
client = self._get_client()
if not client:
return False
try:
client.connect()
except:
return False
client.connect()
torrent = client.call("core.get_torrent_status",
torrent_hash.lower(), ['time_added', 'name'])
if len(torrent) == 0:
Expand All @@ -129,61 +124,49 @@ def add_torrent(self, torrent, torrent_settings):
client = self._get_client()
if not client:
return False
try:
client.connect()
options = None
if torrent_settings is not None:
options = {}
if torrent_settings.download_dir is not None:
options['download_location'] = torrent_settings.download_dir
return client.call("core.add_torrent_file",
None, base64.b64encode(torrent), options)
except:
return False
client.connect()
options = None
if torrent_settings is not None:
options = {}
if torrent_settings.download_dir is not None:
options['download_location'] = torrent_settings.download_dir
return client.call("core.add_torrent_file",
None, base64.b64encode(torrent), options)

def remove_torrent(self, torrent_hash):
client = self._get_client()
if not client:
return False
try:
client.connect()
return client.call("core.remove_torrent",
torrent_hash.lower(), False)
except:
return False
client.connect()
return client.call("core.remove_torrent",
torrent_hash.lower(), False)

def get_download_status(self):
client = self._get_client()
if not client:
return False
try:
client.connect()
result = client.call("core.get_torrents_status",
{}, ['total_done', 'total_size', 'download_payload_rate',
'upload_payload_rate', 'state', 'progress'])
statuses = {}
for key, value in result.items():
statuses[key] = DownloadStatus(value[b'total_done'], value[b'total_size'],
value[b'download_payload_rate'], value[b'upload_payload_rate'])
return statuses
except:
return False
client.connect()
result = client.call("core.get_torrents_status",
{}, ['total_done', 'total_size', 'download_payload_rate',
'upload_payload_rate', 'state', 'progress'])
statuses = {}
for key, value in result.items():
statuses[key] = DownloadStatus(value[b'total_done'], value[b'total_size'],
value[b'download_payload_rate'], value[b'upload_payload_rate'])
return statuses

def get_download_status_by_hash(self, torrent_hash):
client = self._get_client()
lower_hash = torrent_hash.lower()
if not client:
return False
try:
client.connect()
result = client.call("core.get_torrents_status",
{'hash': lower_hash}, ['total_done', 'total_size', 'download_payload_rate',
'upload_payload_rate', 'state', 'progress'])
key, value = result.popitem()
return DownloadStatus(value[b'total_done'], value[b'total_size'],
value[b'download_payload_rate'], value[b'upload_payload_rate'])
except:
return False
client.connect()
result = client.call("core.get_torrents_status",
{'hash': lower_hash}, ['total_done', 'total_size', 'download_payload_rate',
'upload_payload_rate', 'state', 'progress'])
key, value = result.popitem()
return DownloadStatus(value[b'total_done'], value[b'total_size'],
value[b'download_payload_rate'], value[b'upload_payload_rate'])


register_plugin('client', 'deluge', DelugeClientPlugin())
117 changes: 51 additions & 66 deletions monitorrent/plugins/clients/qbittorrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,40 +111,34 @@ def find_torrent(self, torrent_hash):
if not parameters:
return False

try:
# qbittorrent uses case sensitive lower case hash
torrent_hash = torrent_hash.lower()
torrents = parameters['session'].get(parameters['target'] + "query/torrents")
array = json.loads(torrents.text)
torrent = next(torrent for torrent in array if torrent['hash'] == torrent_hash)
if torrent:
time = torrent.get('added_on', None)
result_date = None
if time is not None:
if isinstance(time, six.string_types):
result_date = dateutil.parser.parse(time).replace(tzinfo=reference.LocalTimezone())\
.astimezone(utc)
else:
result_date = datetime.fromtimestamp(time, utc)
return {
"name": torrent['name'],
"date_added": result_date
}
except Exception as e:
return False
# qbittorrent uses case sensitive lower case hash
torrent_hash = torrent_hash.lower()
torrents = parameters['session'].get(parameters['target'] + "query/torrents")
array = json.loads(torrents.text)
torrent = next(torrent for torrent in array if torrent['hash'] == torrent_hash)
if torrent:
time = torrent.get('added_on', None)
result_date = None
if time is not None:
if isinstance(time, six.string_types):
result_date = dateutil.parser.parse(time).replace(tzinfo=reference.LocalTimezone()) \
.astimezone(utc)
else:
result_date = datetime.fromtimestamp(time, utc)
return {
"name": torrent['name'],
"date_added": result_date
}

def get_download_dir(self):
parameters = self._get_params()
if not parameters:
return None

try:
response = parameters['session'].get(parameters['target'] + 'query/preferences')
response.raise_for_status()
result = response.json()
return six.text_type(result['save_path'])
except:
return None
response = parameters['session'].get(parameters['target'] + 'query/preferences')
response.raise_for_status()
result = response.json()
return six.text_type(result['save_path'])

def add_torrent(self, torrent, torrent_settings):
"""
Expand All @@ -154,60 +148,51 @@ def add_torrent(self, torrent, torrent_settings):
if not parameters:
return False

try:
files = {"torrents": BytesIO(torrent)}
data = None
if torrent_settings is not None:
data = {}
if torrent_settings.download_dir is not None:
data['savepath'] = torrent_settings.download_dir
r = parameters['session'].post(parameters['target'] + "command/upload", data=data, files=files)
return r.status_code == 200
except:
return False
files = {"torrents": BytesIO(torrent)}
data = None
if torrent_settings is not None:
data = {}
if torrent_settings.download_dir is not None:
data['savepath'] = torrent_settings.download_dir
r = parameters['session'].post(parameters['target'] + "command/upload", data=data, files=files)
return r.status_code == 200

# TODO switch to remove torrent with data
def remove_torrent(self, torrent_hash):
parameters = self._get_params()
if not parameters:
return False

try:
#qbittorrent uses case sensitive lower case hash
torrent_hash = torrent_hash.lower()
payload = {"hashes": torrent_hash}
r = parameters['session'].post(parameters['target'] + "command/delete", data=payload)
return r.status_code == 200
except:
return False
# qbittorrent uses case sensitive lower case hash
torrent_hash = torrent_hash.lower()
payload = {"hashes": torrent_hash}
r = parameters['session'].post(parameters['target'] + "command/delete", data=payload)
return r.status_code == 200

def get_download_status(self):
parameters = self._get_params()
if not parameters:
return False
try:
response = parameters['session'].get(parameters['target'] + "query/torrents/")
response.raise_for_status()
result = response.json()
torrents = {}
for torrent in result:
torrents[torrent['hash']] = DownloadStatus(torrent['progress'] * torrent['size'], torrent['size'], torrent['dlspeed'],
torrent['upspeed'])
return torrents
except:
return False
response = parameters['session'].get(parameters['target'] + "query/torrents/")
response.raise_for_status()
result = response.json()
torrents = {}
for torrent in result:
torrents[torrent['hash']] = DownloadStatus(torrent['progress'] * torrent['size'], torrent['size'],
torrent['dlspeed'],
torrent['upspeed'])
return torrents

def get_download_status_by_hash(self, torrent_hash):
parameters = self._get_params()
if not parameters:
return False
try:
torrent_hash = torrent_hash.lower()
response = parameters['session'].get(parameters['target'] + "query/propertiesGeneral/" + torrent_hash)
response.raise_for_status()
result = response.json()
return DownloadStatus(result['total_downloaded'], result['total_size'], result['dl_speed'], result['up_speed'])
except:
return False
torrent_hash = torrent_hash.lower()
response = parameters['session'].get(parameters['target'] + "query/propertiesGeneral/" + torrent_hash)
response.raise_for_status()
result = response.json()
return DownloadStatus(result['total_downloaded'], result['total_size'], result['dl_speed'],
result['up_speed'])


register_plugin('client', 'qbittorrent', QBittorrentClientPlugin())
Loading