def _get_auth(self): self.auth = None if self.auth is not None: return self.auth if not self.host: return tp_kwargs = {} if sickbeard.TORRENT_AUTH_TYPE != 'none': tp_kwargs['authtype'] = sickbeard.TORRENT_AUTH_TYPE if not sickbeard.TORRENT_VERIFY_CERT: tp_kwargs['check_ssl_cert'] = False 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) return self.auth
def connect(self, host, username, password, auth, rpc_url, rtorr_ssl, rtorr_verify): if self.conn is not None: return self.conn if not host: return False url = self.cleanHost(host, protocol=True, ssl=rtorr_ssl) # Automatically add '+https' to 'httprpc' protocol if SSL is enabled if rtorr_ssl and url.startswith('httprpc://'): url = url.replace('httprpc://', 'httprpc+https://') parsed = urlparse(url) # rpc_url is only used on http/https scgi pass-through if parsed.scheme in ['http', 'https']: url += rpc_url if username and password: try: self.conn = RTorrent( url, (auth, username, password), verify_server=True, verify_ssl=self.getVerifySsl(rtorr_verify)) except: return False else: try: self.conn = RTorrent(host) except: return False return self.conn
def _get_auth(self): self.auth = None if self.host: try: if self.host.startswith('scgi:'): self.username = self.password = None self.auth = RTorrent(self.host, self.username, self.password) except (AssertionError, xmlrpclib.ProtocolError): pass return self.auth
def connect(self, host, username, password): if self.conn is not None: return self.conn if not host: return False if username and password: self.conn = RTorrent(host, username, password) else: self.conn = RTorrent(host) return self.conn
def _get_auth(self): self.auth = None if self.auth is not None: return self.auth if not self.host: return if self.username and self.password: self.auth = RTorrent(self.host, self.username, self.password) else: self.auth = RTorrent(self.host, None, None, True) return self.auth
def connect(self, host, username, password): if self.conn is not None: return self.conn if not host: return False if username and password: self.conn = RTorrent( host, username, password ) else: self.conn = RTorrent(host) return self.conn
def connect(self, host, username, password, auth, verify, ssl, rpc_url, ca_bundle): if self.conn is not None: return self.conn if not host: return False 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://') parsed = urlparse(url) # rpc_url is only used on http/https scgi pass-through if parsed.scheme in ['http', 'https']: 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('Failed to connect to rTorrent: %s', err) return False 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 False return self.conn
def _get_auth(self): self.auth = None if self.host: try: if self.host and self.host.startswith('scgi:'): self.username = self.password = None self.auth = RTorrent(self.host, self.username, self.password, True) except (AssertionError, xmlrpclib.ProtocolError) as e: pass return self.auth
def _get_auth(self): self.auth = None if self.auth is not None: return self.auth if not self.host: return tp_kwargs = {} if sickbeard.TORRENT_AUTH_TYPE is not 'none': tp_kwargs['authtype'] = sickbeard.TORRENT_AUTH_TYPE if not sickbeard.TORRENT_VERIFY_CERT: tp_kwargs['check_ssl_cert'] = False 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) return self.auth
class TorrentClient(object): def __init__(self): self.conn = None def getVerifySsl(self, rtorr_verify): #rtorr_verify = 0 # Ensure verification has been enabled if not rtorr_verify: return False # Use default ssl verification return True def connect(self, host, username, password, auth, rpc_url, rtorr_ssl, rtorr_verify): if self.conn is not None: return self.conn if not host: return False url = self.cleanHost(host, protocol=True, ssl=rtorr_ssl) # Automatically add '+https' to 'httprpc' protocol if SSL is enabled if rtorr_ssl and url.startswith('httprpc://'): url = url.replace('httprpc://', 'httprpc+https://') parsed = urlparse(url) # rpc_url is only used on http/https scgi pass-through if parsed.scheme in ['http', 'https']: url += rpc_url if username and password: try: self.conn = RTorrent( url, (auth, username, password), verify_server=True, verify_ssl=self.getVerifySsl(rtorr_verify)) except: return False else: try: self.conn = RTorrent(host) except: return False return self.conn def find_torrent(self, hash=None, filepath=None): return self.conn.find_torrent(info_hash=hash, filepath=filepath) def get_files(self, hash): a = self.conn.get_files(hash) return a def get_torrent(self, torrent): if not torrent: return False 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, rtorr_label, start, applylabel=None, rtorr_dir=None): print('filepath to torrent file set to : ' + filepath) torrent = self.conn.load_torrent(filepath, verify_load=True) if not torrent: return False if rtorr_label: torrent.set_custom(1, rtorr_label) print('Setting label for torrent to : ' + rtorr_label) if all([applylabel is True, rtorr_label is not None]): new_location = os.path.join(rtorr_dir, rtorr_label) torrent.set_directory(new_location) print('Setting directory for torrent to : %s' % new_location) print('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: print('[' + str(start) + '] Now starting torrent.') torrent.start() else: print('[' + 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 def cleanHost(self, host, protocol=True, ssl=False, username=None, password=None): """ Return a cleaned up host with given url options set taken verbatim from CouchPotato Changes protocol to https if ssl is set to True and http if ssl is set to false. >>> cleanHost("localhost:80", ssl=True) 'https://*****:*****@localhost:80/' Output without scheme (protocol) can be forced with protocol=False >>> cleanHost("localhost:80", protocol=False) 'localhost:80' """ if not '://' in host and protocol: host = ('https://' if ssl else 'http://') + host if not protocol: host = host.split('://', 1)[-1] if protocol and username and password: try: auth = re.findall('^(?:.+?//)(.+?):(.+?)@(?:.+)$', host) if auth: log.error( 'Cleanhost error: auth already defined in url: %s, please remove BasicAuth from url.', host) else: host = host.replace('://', '://%s:%s@' % (username, password), 1) except: pass host = host.rstrip('/ ') if protocol: host += '/' return host
class rTorrentAPI(GenericClient): def __init__(self, host=None, username=None, password=None): super(rTorrentAPI, self).__init__('rTorrent', host, username, password) def _get_auth(self): self.auth = None if self.auth is not None: return self.auth if not self.host: return if self.username and self.password: self.auth = RTorrent(self.host, self.username, self.password) else: self.auth = RTorrent(self.host, None, None, True) return self.auth def _add_torrent_uri(self, result): filedata = None if not self.auth: return False if not result: return False try: # Send magnet to rTorrent torrent = self.auth.load_magnet(result.url, result.hash) if not torrent: return False # Set label if sickbeard.TORRENT_LABEL: torrent.set_custom(1, sickbeard.TORRENT_LABEL.lower()) if sickbeard.TORRENT_PATH: torrent.set_directory(sickbeard.TORRENT_PATH) # Start torrent torrent.start() return True except: return False def _add_torrent_file(self, result): filedata = None if not self.auth: return False if not result: return False # group_name = 'sb_test'.lower() ##### Use provider instead of _test # if not self._set_torrent_ratio(group_name): # return False # Send request to rTorrent try: # Send torrent to rTorrent torrent = self.auth.load_torrent(result.content) if not torrent: return False # Set label if sickbeard.TORRENT_LABEL: torrent.set_custom(1, sickbeard.TORRENT_LABEL.lower()) if sickbeard.TORRENT_PATH: torrent.set_directory(sickbeard.TORRENT_PATH) # Set Ratio Group # torrent.set_visible(group_name) # Start torrent torrent.start() return True except: return False def _set_torrent_ratio(self, name): # if not name: # return False # # if not self.auth: # return False # # views = self.auth.get_views() # # if name not in views: # self.auth.create_group(name) # group = self.auth.get_group(name) # ratio = int(float(sickbeard.TORRENT_RATIO) * 100) # # try: # if ratio > 0: # # # Explicitly set all group options to ensure it is setup correctly # group.set_upload('1M') # group.set_min(ratio) # group.set_max(ratio) # group.set_command('d.stop') # group.enable() # else: # # Reset group action and disable it # group.set_command() # group.disable() # # except: # return False return True def testAuthentication(self): try: self._get_auth() if self.auth is not None: return True, 'Success: Connected and Authenticated' else: return False, 'Error: Unable to get ' + self.name + ' Authentication, check your config!' except Exception: return False, 'Error: Unable to connect to ' + self.name
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, ssl, rpc_url, ca_bundle): if self.conn is not None: return self.conn if not host: return False 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://') parsed = urlparse(url) # rpc_url is only used on http/https scgi pass-through if parsed.scheme in ['http', 'https']: 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('Failed to connect to rTorrent: %s', err) return False 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 False 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
class TorrentClient(object): def __init__(self): self.conn = None def connect(self, host, username, password): if self.conn is not None: return self.conn if not host: return False if username and password: self.conn = RTorrent(host, username, password) else: self.conn = RTorrent(host) 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.RTORRENT_STARTONLOAD) logger.info('filepath to torrent file set to : ' + filepath) torrent = self.conn.load_torrent(filepath, verify_load=True) if not torrent: return False if mylar.RTORRENT_LABEL: torrent.set_custom(1, mylar.RTORRENT_LABEL) logger.info('Setting label for torrent to : ' + mylar.RTORRENT_LABEL) if mylar.RTORRENT_DIRECTORY: torrent.set_directory(mylar.RTORRENT_DIRECTORY) logger.info('Setting directory for torrent to : ' + mylar.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
class RtorrentAPI(GenericClient): def __init__(self, host=None, username=None, password=None): if host and host.startswith('scgi:'): username = password = None super(RtorrentAPI, self).__init__('rTorrent', host, username, password) def _get_auth(self): self.auth = None if self.host: try: if self.host.startswith('scgi:'): self.username = self.password = None self.auth = RTorrent(self.host, self.username, self.password) except (AssertionError, xmlrpclib.ProtocolError): pass return self.auth def _add_torrent(self, cmd, data): torrent = None if self.auth: try: if self.auth.has_local_id(data.hash): logger.log( '%s: Item already exists %s' % (self.name, data.name), logger.WARNING) raise params = { 'start': not sickbeard.TORRENT_PAUSED, 'extra': ([], ['d.set_custom1=%s' % sickbeard.TORRENT_LABEL])[any( [sickbeard.TORRENT_LABEL])] + ([], ['d.set_directory=%s' % sickbeard.TORRENT_PATH])[any( [sickbeard.TORRENT_PATH])] or None } # Send magnet to rTorrent if 'file' == cmd: torrent = self.auth.load_torrent(data.content, **params) elif 'magnet' == cmd: torrent = self.auth.load_magnet(data.url, data.hash, **params) if torrent and sickbeard.TORRENT_LABEL: label = torrent.get_custom(1) if sickbeard.TORRENT_LABEL != label: logger.log( '%s: could not change custom1 category \'%s\' to \'%s\' for %s' % (self.name, label, sickbeard.TORRENT_LABEL, torrent.name), logger.WARNING) except (Exception, BaseException): pass return any([torrent]) def _add_torrent_file(self, result): return result and self._add_torrent('file', result) or False def _add_torrent_uri(self, result): return result and self._add_torrent('magnet', result) or False # def _set_torrent_ratio(self, name): # if not name: # return False # # if not self.auth: # return False # # views = self.auth.get_views() # # if name not in views: # self.auth.create_group(name) # group = self.auth.get_group(name) # ratio = int(float(sickbeard.TORRENT_RATIO) * 100) # # try: # if ratio > 0: # # # Explicitly set all group options to ensure it is setup correctly # group.set_upload('1M') # group.set_min(ratio) # group.set_max(ratio) # group.set_command('d.stop') # group.enable() # else: # # Reset group action and disable it # group.set_command() # group.disable() # # except: # return False # return True def test_authentication(self): try: if not self._get_auth(): return False, 'Error: Unable to get %s authentication, check your config!' % self.name return True, 'Success: Connected and Authenticated' except (StandardError, Exception): return False, 'Error: Unable to connect to %s' % self.name
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
class TorrentClient(object): def __init__(self): self.conn = None def getVerifySsl(self): # Ensure verification has been enabled if not mylar.RTORRENT_VERIFY: return False # Use ca bundle if defined if mylar.RTORRENT_CA_BUNDLE and os.path.exists(ca_bundle): return mylar.RTORRENT_CA_BUNDLE # Use default ssl verification return True def connect(self, host, username, password, auth): if self.conn is not None: return self.conn if not host: return False url = helpers.cleanHost(host, protocol=True, ssl=mylar.RTORRENT_SSL) # Automatically add '+https' to 'httprpc' protocol if SSL is enabled if mylar.RTORRENT_SSL and url.startswith('httprpc://'): url = url.replace('httprpc://', 'httprpc+https://') parsed = urlparse(url) # rpc_url is only used on http/https scgi pass-through if parsed.scheme in ['http', 'https']: url += mylar.RTORRENT_RPC_URL logger.info(url) if username and password: try: self.conn = RTorrent(url, (auth, username, password), verify_server=True, verify_ssl=self.getVerifySsl()) except: return False else: try: self.conn = RTorrent(host) except: return False 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.RTORRENT_STARTONLOAD) logger.info('filepath to torrent file set to : ' + filepath) torrent = self.conn.load_torrent(filepath, verify_load=True) if not torrent: return False if mylar.RTORRENT_LABEL: torrent.set_custom(1, mylar.RTORRENT_LABEL) logger.info('Setting label for torrent to : ' + mylar.RTORRENT_LABEL) if mylar.RTORRENT_DIRECTORY: torrent.set_directory(mylar.RTORRENT_DIRECTORY) logger.info('Setting directory for torrent to : ' + mylar.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
class Client(GenericClient): def __init__(self, host=None, username=None, password=None): super(Client, self).__init__('rTorrent', host, username, password) def _get_auth(self): self.auth = None if self.auth is not None: return self.auth if not self.host: return tp_kwargs = {} if sickbeard.TORRENT_AUTH_TYPE != 'none': tp_kwargs['authtype'] = sickbeard.TORRENT_AUTH_TYPE if not sickbeard.TORRENT_VERIFY_CERT: tp_kwargs['check_ssl_cert'] = False 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) return self.auth def _add_torrent_uri(self, result): if not self.auth: return False if not result: return False try: # Send magnet to rTorrent torrent = self.auth.load_magnet(result.url, result.hash) if not torrent: return False # Set label label = sickbeard.TORRENT_LABEL if result.show.is_anime: label = sickbeard.TORRENT_LABEL_ANIME if label: torrent.set_custom(1, label) if sickbeard.TORRENT_PATH: torrent.set_directory(sickbeard.TORRENT_PATH) if not sickbeard.TORRENT_PAUSED: # Start torrent torrent.start() return True except Exception as error: logger.log( 'Error while sending torrent: {error}'.format(error=ex(error)), logger.WARNING) return False def _add_torrent_file(self, result): if not self.auth: return False if not result: return False # group_name = 'sb_test'.lower() ##### Use provider instead of _test # if not self._set_torrent_ratio(group_name): # return False # Send request to rTorrent try: # Send torrent to rTorrent torrent = self.auth.load_torrent(result.content) if not torrent: return False # Set label label = sickbeard.TORRENT_LABEL if result.show.is_anime: label = sickbeard.TORRENT_LABEL_ANIME if label: torrent.set_custom(1, label) if sickbeard.TORRENT_PATH: torrent.set_directory(sickbeard.TORRENT_PATH) # Set Ratio Group # torrent.set_visible(group_name) if not sickbeard.TORRENT_PAUSED: # Start torrent torrent.start() return True except Exception as error: logger.log( 'Error while sending torrent: {error}'.format(error=ex(error)), logger.WARNING) return False def _set_torrent_ratio(self, name): # if not name: # return False # # if not self.auth: # return False # # views = self.auth.get_views() # # if name not in views: # self.auth.create_group(name) # group = self.auth.get_group(name) # ratio = int(float(sickbeard.TORRENT_RATIO) * 100) # # try: # if ratio > 0: # # # Explicitly set all group options to ensure it is setup correctly # group.set_upload('1M') # group.set_min(ratio) # group.set_max(ratio) # group.set_command('d.stop') # group.enable() # else: # # Reset group action and disable it # group.set_command() # group.disable() # # except: # return False return True def testAuthentication(self): try: self._get_auth() if self.auth is not None: return True, 'Success: Connected and Authenticated' else: return False, 'Error: Unable to get {name} Authentication, check your config!'.format( name=self.name) except Exception: return False, 'Error: Unable to connect to {name}'.format( name=self.name)
class RtorrentAPI(GenericClient): def __init__(self, host=None, username=None, password=None): if host and host.startswith('scgi:'): username = password = None super(RtorrentAPI, self).__init__('rTorrent', host, username, password) # self.url = self.host def _get_auth(self): self.auth = None if self.host: try: if self.host and self.host.startswith('scgi:'): self.username = self.password = None self.auth = RTorrent(self.host, self.username, self.password, True) except (AssertionError, xmlrpclib.ProtocolError) as e: pass return self.auth def _add_torrent(self, cmd, **kwargs): torrent = None if self.auth: try: # Send magnet to rTorrent if 'file' == cmd: torrent = self.auth.load_torrent(kwargs['file']) elif 'magnet' == cmd: torrent = self.auth.load_magnet(kwargs['uri'], kwargs['btih']) if torrent: if sickbeard.TORRENT_LABEL: torrent.set_custom(1, sickbeard.TORRENT_LABEL) if sickbeard.TORRENT_PATH: torrent.set_directory(sickbeard.TORRENT_PATH) torrent.start() except (StandardError, Exception) as e: pass return any([torrent]) def _add_torrent_file(self, result): if result: return self._add_torrent('file', file=result.content) return False def _add_torrent_uri(self, result): if result: return self._add_torrent('magnet', uri=result.url, btih=result.hash) return False #def _set_torrent_ratio(self, name): # if not name: # return False # # if not self.auth: # return False # # views = self.auth.get_views() # # if name not in views: # self.auth.create_group(name) # group = self.auth.get_group(name) # ratio = int(float(sickbeard.TORRENT_RATIO) * 100) # # try: # if ratio > 0: # # # Explicitly set all group options to ensure it is setup correctly # group.set_upload('1M') # group.set_min(ratio) # group.set_max(ratio) # group.set_command('d.stop') # group.enable() # else: # # Reset group action and disable it # group.set_command() # group.disable() # # except: # return False # return True def test_authentication(self): try: self._get_auth() if None is self.auth: return False, 'Error: Unable to get %s authentication, check your config!' % self.name return True, 'Success: Connected and Authenticated' except (StandardError, Exception): return False, 'Error: Unable to connect to %s' % self.name
class TorrentClient(object): def __init__(self): self.conn = None def connect(self, host, username, password): if self.conn is not None: return self.conn if not host: return False if username and password: self.conn = RTorrent( host, username, password ) else: self.conn = RTorrent(host) 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.RTORRENT_STARTONLOAD) logger.info('filepath to torrent file set to : ' + filepath) torrent = self.conn.load_torrent(filepath, verify_load=True) if not torrent: return False if mylar.RTORRENT_LABEL: torrent.set_custom(1, mylar.RTORRENT_LABEL) logger.info('Setting label for torrent to : ' + mylar.RTORRENT_LABEL) if mylar.RTORRENT_DIRECTORY: torrent.set_directory(mylar.RTORRENT_DIRECTORY) logger.info('Setting directory for torrent to : ' + mylar.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
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 parsed.scheme in ['http', 'https'] and rpc_url is not None: url += rpc_url logger.fdebug(url) if username and password: try: # logger.debug('SECURE: username and password') if parsed.scheme == 'https': newurl = url.replace( 'https://', 'https://%s:%s@' % (username, password)) elif parsed.scheme == 'http': newurl = url.replace( 'http://', 'http://%s:%s@' % (username, password)) else: newurl = url logger.fdebug('NEWURL: %s' % newurl.replace(password, '[REDACTED]')) authinfo = tuple(([auth, username, password])) self.conn = RTorrent( url, authinfo, verify_server=True, verify_ssl=False #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