mirror of https://github.com/evilhero/mylar
204 lines
7.4 KiB
Python
Executable File
204 lines
7.4 KiB
Python
Executable File
import os
|
|
import re
|
|
from urlparse import urlparse
|
|
|
|
from lib.rtorrent import RTorrent
|
|
|
|
import mylar
|
|
from mylar import logger, helpers
|
|
|
|
class TorrentClient(object):
|
|
def __init__(self):
|
|
self.conn = None
|
|
|
|
def getVerifySsl(self, verify, ca_bundle):
|
|
# Ensure verification has been enabled
|
|
if not verify:
|
|
return False
|
|
|
|
# Use ca bundle if defined
|
|
if ca_bundle is not None and os.path.exists(ca_bundle):
|
|
return ca_bundle
|
|
|
|
# Use default ssl verification
|
|
return True
|
|
|
|
def connect(self, host, username, password, auth, verify, rpc_url, ca_bundle, test=False):
|
|
if self.conn is not None:
|
|
return self.conn
|
|
|
|
if not host:
|
|
return {'status': False, 'error': 'No host specified'}
|
|
|
|
url = host
|
|
if host.startswith('https:'):
|
|
ssl = True
|
|
else:
|
|
if not host.startswith('http://'):
|
|
url = 'http://' + url
|
|
ssl = False
|
|
|
|
#add on the slash ..
|
|
if not url.endswith('/'):
|
|
url += '/'
|
|
|
|
#url = helpers.cleanHost(host, protocol = True, ssl = ssl)
|
|
|
|
# Automatically add '+https' to 'httprpc' protocol if SSL is enabled
|
|
#if ssl is True and url.startswith('httprpc://'):
|
|
# url = url.replace('httprpc://', 'httprpc+https://')
|
|
#if ssl is False and not url.startswith('http://'):
|
|
# url = 'http://' + url
|
|
|
|
#parsed = urlparse(url)
|
|
|
|
# rpc_url is only used on http/https scgi pass-through
|
|
if rpc_url is not None:
|
|
url += rpc_url
|
|
|
|
#logger.fdebug(url)
|
|
|
|
if username and password:
|
|
try:
|
|
self.conn = RTorrent(
|
|
url,(auth, username, password),
|
|
verify_server=True,
|
|
verify_ssl=self.getVerifySsl(verify, ca_bundle)
|
|
)
|
|
except Exception as err:
|
|
logger.error('Make sure you have the right protocol specified for the rtorrent host. Failed to connect to rTorrent - error: %s.' % err)
|
|
return {'status': False, 'error': err}
|
|
else:
|
|
logger.fdebug('NO username %s / NO password %s' % (username, password))
|
|
try:
|
|
self.conn = RTorrent(
|
|
url, (auth, username, password),
|
|
verify_server=True,
|
|
verify_ssl=self.getVerifySsl(verify, ca_bundle)
|
|
)
|
|
except Exception as err:
|
|
logger.error('Failed to connect to rTorrent: %s' % err)
|
|
return {'status': False, 'error': err}
|
|
|
|
if test is True:
|
|
return {'status': True, 'version': self.conn.get_client_version()}
|
|
else:
|
|
return self.conn
|
|
|
|
def find_torrent(self, hash):
|
|
return self.conn.find_torrent(hash)
|
|
|
|
def get_torrent (self, torrent):
|
|
torrent_files = []
|
|
torrent_directory = os.path.normpath(torrent.directory)
|
|
try:
|
|
for f in torrent.get_files():
|
|
if not os.path.normpath(f.path).startswith(torrent_directory):
|
|
file_path = os.path.join(torrent_directory, f.path.lstrip('/'))
|
|
else:
|
|
file_path = f.path
|
|
|
|
torrent_files.append(file_path)
|
|
|
|
torrent_info = {
|
|
'hash': torrent.info_hash,
|
|
'name': torrent.name,
|
|
'label': torrent.get_custom1() if torrent.get_custom1() else '',
|
|
'folder': torrent_directory,
|
|
'completed': torrent.complete,
|
|
'files': torrent_files,
|
|
'upload_total': torrent.get_up_total(),
|
|
'download_total': torrent.get_down_total(),
|
|
'ratio': torrent.get_ratio(),
|
|
'total_filesize': torrent.get_size_bytes(),
|
|
'time_started': torrent.get_time_started()
|
|
}
|
|
|
|
except Exception:
|
|
raise
|
|
|
|
return torrent_info if torrent_info else False
|
|
|
|
def load_torrent(self, filepath):
|
|
start = bool(mylar.CONFIG.RTORRENT_STARTONLOAD)
|
|
|
|
if filepath.startswith('magnet'):
|
|
logger.fdebug('torrent magnet link set to : ' + filepath)
|
|
torrent_hash = re.findall('urn:btih:([\w]{32,40})', filepath)[0].upper()
|
|
# Send request to rTorrent
|
|
try:
|
|
#cannot verify_load magnet as it might take a very very long time for it to retrieve metadata
|
|
torrent = self.conn.load_magnet(filepath, torrent_hash, verify_load=True)
|
|
if not torrent:
|
|
logger.error('Unable to find the torrent, did it fail to load?')
|
|
return False
|
|
except Exception as err:
|
|
logger.error('Failed to send magnet to rTorrent: %s', err)
|
|
return False
|
|
else:
|
|
logger.info('Torrent successfully loaded into rtorrent using magnet link as source.')
|
|
else:
|
|
logger.fdebug('filepath to torrent file set to : ' + filepath)
|
|
try:
|
|
torrent = self.conn.load_torrent(filepath, verify_load=True)
|
|
if not torrent:
|
|
logger.error('Unable to find the torrent, did it fail to load?')
|
|
return False
|
|
except Exception as err:
|
|
logger.error('Failed to send torrent to rTorrent: %s', err)
|
|
return False
|
|
|
|
#we can cherrypick the torrents here if required and if it's a pack (0day instance)
|
|
#torrent.get_files() will return list of files in torrent
|
|
#f.set_priority(0,1,2)
|
|
#for f in torrent.get_files():
|
|
# logger.info('torrent_get_files: %s' % f)
|
|
# f.set_priority(0) #set them to not download just to see if this works...
|
|
#torrent.updated_priorities()
|
|
|
|
if mylar.CONFIG.RTORRENT_LABEL is not None:
|
|
torrent.set_custom(1, mylar.CONFIG.RTORRENT_LABEL)
|
|
logger.fdebug('Setting label for torrent to : ' + mylar.CONFIG.RTORRENT_LABEL)
|
|
|
|
if mylar.CONFIG.RTORRENT_DIRECTORY is not None:
|
|
torrent.set_directory(mylar.CONFIG.RTORRENT_DIRECTORY)
|
|
logger.fdebug('Setting directory for torrent to : ' + mylar.CONFIG.RTORRENT_DIRECTORY)
|
|
|
|
logger.info('Successfully loaded torrent.')
|
|
|
|
#note that if set_directory is enabled, the torrent has to be started AFTER it's loaded or else it will give chunk errors and not seed
|
|
if start:
|
|
logger.info('[' + str(start) + '] Now starting torrent.')
|
|
torrent.start()
|
|
else:
|
|
logger.info('[' + str(start) + '] Not starting torrent due to configuration setting.')
|
|
return True
|
|
|
|
def start_torrent(self, torrent):
|
|
return torrent.start()
|
|
|
|
def stop_torrent(self, torrent):
|
|
return torrent.stop()
|
|
|
|
def delete_torrent(self, torrent):
|
|
deleted = []
|
|
try:
|
|
for file_item in torrent.get_files():
|
|
file_path = os.path.join(torrent.directory, file_item.path)
|
|
os.unlink(file_path)
|
|
deleted.append(file_item.path)
|
|
|
|
if torrent.is_multi_file() and torrent.directory.endswith(torrent.name):
|
|
try:
|
|
for path, _, _ in os.walk(torrent.directory, topdown=False):
|
|
os.rmdir(path)
|
|
deleted.append(path)
|
|
except:
|
|
pass
|
|
except Exception:
|
|
raise
|
|
|
|
torrent.erase()
|
|
|
|
return deleted
|