diff --git a/couchpotato/core/downloaders/blackhole.py b/couchpotato/core/downloaders/blackhole.py index 5d4e54b..22ed9ad 100644 --- a/couchpotato/core/downloaders/blackhole.py +++ b/couchpotato/core/downloaders/blackhole.py @@ -20,8 +20,7 @@ class Blackhole(DownloaderBase): status_support = False def download(self, data = None, media = None, filedata = None): - """ - Send a torrent/nzb file to the downloader + """ Send a torrent/nzb file to the downloader :param data: dict returned from provider Contains the release information @@ -39,10 +38,13 @@ class Blackhole(DownloaderBase): if not data: data = {} directory = self.conf('directory') + + # The folder needs to exist if not directory or not os.path.isdir(directory): log.error('No directory set for blackhole %s download.', data.get('protocol')) else: try: + # Filedata can be empty, which probably means it a magnet link if not filedata or len(filedata) < 50: try: if data.get('protocol') == 'torrent_magnet': @@ -51,13 +53,16 @@ class Blackhole(DownloaderBase): except: log.error('Failed download torrent via magnet url: %s', traceback.format_exc()) + # If it's still empty, don't know what to do! if not filedata or len(filedata) < 50: log.error('No nzb/torrent available: %s', data.get('url')) return False + # Create filename with imdb id and other nice stuff file_name = self.createFileName(data, filedata, media) full_path = os.path.join(directory, file_name) + # People want thinks nice and tidy, create a subdir if self.conf('create_subdir'): try: new_path = os.path.splitext(full_path)[0] @@ -68,6 +73,8 @@ class Blackhole(DownloaderBase): log.error('Couldnt create sub dir, reverting to old one: %s', full_path) try: + + # Make sure the file doesn't exist yet, no need in overwriting it if not os.path.isfile(full_path): log.info('Downloading %s to %s.', (data.get('protocol'), full_path)) with open(full_path, 'wb') as f: @@ -89,6 +96,10 @@ class Blackhole(DownloaderBase): return False def test(self): + """ Test and see if the directory is writable + :return: boolean + """ + directory = self.conf('directory') if directory and os.path.isdir(directory): @@ -103,6 +114,10 @@ class Blackhole(DownloaderBase): return False def getEnabledProtocol(self): + """ What protocols is this downloaded used for + :return: list with protocols + """ + if self.conf('use_for') == 'both': return super(Blackhole, self).getEnabledProtocol() elif self.conf('use_for') == 'torrent': @@ -111,6 +126,12 @@ class Blackhole(DownloaderBase): return ['nzb'] def isEnabled(self, manual = False, data = None): + """ Check if protocol is used (and enabled) + :param manual: The user has clicked to download a link through the webUI + :param data: dict returned from provider + Contains the release information + :return: boolean + """ if not data: data = {} for_protocol = ['both'] if data and 'torrent' in data.get('protocol'): diff --git a/couchpotato/core/downloaders/deluge.py b/couchpotato/core/downloaders/deluge.py index 1230cd6..3bcbfb6 100644 --- a/couchpotato/core/downloaders/deluge.py +++ b/couchpotato/core/downloaders/deluge.py @@ -25,6 +25,11 @@ class Deluge(DownloaderBase): drpc = None def connect(self, reconnect = False): + """ Connect to the delugeRPC, re-use connection when already available + :param reconnect: force reconnect + :return: DelugeRPC instance + """ + # Load host from config and split out port. host = cleanHost(self.conf('host'), protocol = False).split(':') @@ -42,6 +47,20 @@ class Deluge(DownloaderBase): return self.drpc def download(self, data = None, media = None, filedata = None): + """ Send a torrent/nzb file to the downloader + + :param data: dict returned from provider + Contains the release information + :param media: media dict with information + Used for creating the filename when possible + :param filedata: downloaded torrent/nzb filedata + The file gets downloaded in the searcher and send to this function + This is done to have failed checking before using the downloader, so the downloader + doesn't need to worry about that + :return: boolean + One faile returns false, but the downloaded should log his own errors + """ + if not media: media = {} if not data: data = {} @@ -96,11 +115,21 @@ class Deluge(DownloaderBase): return self.downloadReturnId(remote_torrent) def test(self): + """ Check if connection works + :return: bool + """ if self.connect(True) and self.drpc.test(): return True return False def getAllDownloadStatus(self, ids): + """ Get status of all active downloads + + :param ids: list of (mixed) downloader ids + Used to match the releases for this downloader as there could be + other downloaders active that it should ignore + :return: list of releases + """ log.debug('Checking Deluge download status.') diff --git a/couchpotato/core/downloaders/hadouken.py b/couchpotato/core/downloaders/hadouken.py index 98a2b21..c7dddbe 100644 --- a/couchpotato/core/downloaders/hadouken.py +++ b/couchpotato/core/downloaders/hadouken.py @@ -40,8 +40,7 @@ class Hadouken(DownloaderBase): return True def download(self, data = None, media = None, filedata = None): - """ - Send a torrent/nzb file to the downloader + """ Send a torrent/nzb file to the downloader :param data: dict returned from provider Contains the release information @@ -110,6 +109,14 @@ class Hadouken(DownloaderBase): return False def getAllDownloadStatus(self, ids): + """ Get status of all active downloads + + :param ids: list of (mixed) downloader ids + Used to match the releases for this downloader as there could be + other downloaders active that it should ignore + :return: list of releases + """ + log.debug('Checking Hadouken download status.') if not self.connect(): diff --git a/couchpotato/core/downloaders/nzbget.py b/couchpotato/core/downloaders/nzbget.py index 2f3e686..9fbed73 100644 --- a/couchpotato/core/downloaders/nzbget.py +++ b/couchpotato/core/downloaders/nzbget.py @@ -23,8 +23,7 @@ class NZBGet(DownloaderBase): rpc = 'xmlrpc' def download(self, data = None, media = None, filedata = None): - """ - Send a torrent/nzb file to the downloader + """ Send a torrent/nzb file to the downloader :param data: dict returned from provider Contains the release information @@ -86,6 +85,10 @@ class NZBGet(DownloaderBase): return False def test(self): + """ Check if connection works + :return: bool + """ + rpc = self.getRPC() try: @@ -106,6 +109,13 @@ class NZBGet(DownloaderBase): return True def getAllDownloadStatus(self, ids): + """ Get status of all active downloads + + :param ids: list of (mixed) downloader ids + Used to match the releases for this downloader as there could be + other downloaders active that it should ignore + :return: list of releases + """ log.debug('Checking NZBGet download status.') diff --git a/couchpotato/core/downloaders/nzbvortex.py b/couchpotato/core/downloaders/nzbvortex.py index df3e371..f98f0f9 100644 --- a/couchpotato/core/downloaders/nzbvortex.py +++ b/couchpotato/core/downloaders/nzbvortex.py @@ -24,8 +24,7 @@ class NZBVortex(DownloaderBase): session_id = None def download(self, data = None, media = None, filedata = None): - """ - Send a torrent/nzb file to the downloader + """ Send a torrent/nzb file to the downloader :param data: dict returned from provider Contains the release information @@ -60,6 +59,10 @@ class NZBVortex(DownloaderBase): return False def test(self): + """ Check if connection works + :return: bool + """ + try: login_result = self.login() except: @@ -68,6 +71,13 @@ class NZBVortex(DownloaderBase): return login_result def getAllDownloadStatus(self, ids): + """ Get status of all active downloads + + :param ids: list of (mixed) downloader ids + Used to match the releases for this downloader as there could be + other downloaders active that it should ignore + :return: list of releases + """ raw_statuses = self.call('nzb') diff --git a/couchpotato/core/downloaders/pneumatic.py b/couchpotato/core/downloaders/pneumatic.py index 957a76d..df53fe6 100644 --- a/couchpotato/core/downloaders/pneumatic.py +++ b/couchpotato/core/downloaders/pneumatic.py @@ -19,8 +19,7 @@ class Pneumatic(DownloaderBase): status_support = False def download(self, data = None, media = None, filedata = None): - """ - Send a torrent/nzb file to the downloader + """ Send a torrent/nzb file to the downloader :param data: dict returned from provider Contains the release information @@ -78,6 +77,10 @@ class Pneumatic(DownloaderBase): return False def test(self): + """ Check if connection works + :return: bool + """ + directory = self.conf('directory') if directory and os.path.isdir(directory): diff --git a/couchpotato/core/downloaders/qbittorrent_.py b/couchpotato/core/downloaders/qbittorrent_.py index a9e8cf4..9cfae4d 100644 --- a/couchpotato/core/downloaders/qbittorrent_.py +++ b/couchpotato/core/downloaders/qbittorrent_.py @@ -41,14 +41,17 @@ class qBittorrent(DownloaderBase): return self.qb def test(self): + """ Check if connection works + :return: bool + """ + if self.connect(): return True return False def download(self, data = None, media = None, filedata = None): - """ - Send a torrent/nzb file to the downloader + """ Send a torrent/nzb file to the downloader :param data: dict returned from provider Contains the release information @@ -110,6 +113,14 @@ class qBittorrent(DownloaderBase): return 'busy' def getAllDownloadStatus(self, ids): + """ Get status of all active downloads + + :param ids: list of (mixed) downloader ids + Used to match the releases for this downloader as there could be + other downloaders active that it should ignore + :return: list of releases + """ + log.debug('Checking qBittorrent download status.') if not self.connect(): diff --git a/couchpotato/core/downloaders/rtorrent_.py b/couchpotato/core/downloaders/rtorrent_.py index 4de952f..d754022 100644 --- a/couchpotato/core/downloaders/rtorrent_.py +++ b/couchpotato/core/downloaders/rtorrent_.py @@ -84,6 +84,10 @@ class rTorrent(DownloaderBase): return self.rt def test(self): + """ Check if connection works + :return: bool + """ + if self.connect(True): return True @@ -94,8 +98,7 @@ class rTorrent(DownloaderBase): def download(self, data = None, media = None, filedata = None): - """ - Send a torrent/nzb file to the downloader + """ Send a torrent/nzb file to the downloader :param data: dict returned from provider Contains the release information @@ -176,6 +179,14 @@ class rTorrent(DownloaderBase): return 'completed' def getAllDownloadStatus(self, ids): + """ Get status of all active downloads + + :param ids: list of (mixed) downloader ids + Used to match the releases for this downloader as there could be + other downloaders active that it should ignore + :return: list of releases + """ + log.debug('Checking rTorrent download status.') if not self.connect(): diff --git a/couchpotato/core/downloaders/sabnzbd.py b/couchpotato/core/downloaders/sabnzbd.py index d6e3e1d..4859209 100644 --- a/couchpotato/core/downloaders/sabnzbd.py +++ b/couchpotato/core/downloaders/sabnzbd.py @@ -84,6 +84,11 @@ class Sabnzbd(DownloaderBase): return False def test(self): + """ Check if connection works + Return message if an old version of SAB is used + :return: bool + """ + try: sab_data = self.call({ 'mode': 'version', @@ -104,6 +109,13 @@ class Sabnzbd(DownloaderBase): return True def getAllDownloadStatus(self, ids): + """ Get status of all active downloads + + :param ids: list of (mixed) downloader ids + Used to match the releases for this downloader as there could be + other downloaders active that it should ignore + :return: list of releases + """ log.debug('Checking SABnzbd download status.') diff --git a/couchpotato/core/downloaders/synology.py b/couchpotato/core/downloaders/synology.py index 3e4ead2..b5327cc 100644 --- a/couchpotato/core/downloaders/synology.py +++ b/couchpotato/core/downloaders/synology.py @@ -65,6 +65,10 @@ class Synology(DownloaderBase): return self.downloadReturnId('') if response else False def test(self): + """ Check if connection works + :return: bool + """ + host = cleanHost(self.conf('host'), protocol = False).split(':') try: srpc = SynologyRPC(host[0], host[1], self.conf('username'), self.conf('password')) diff --git a/couchpotato/core/downloaders/transmission.py b/couchpotato/core/downloaders/transmission.py index 8f27491..697f22a 100644 --- a/couchpotato/core/downloaders/transmission.py +++ b/couchpotato/core/downloaders/transmission.py @@ -103,11 +103,22 @@ class Transmission(DownloaderBase): return self.downloadReturnId(data['hashString']) def test(self): + """ Check if connection works + :return: bool + """ + if self.connect() and self.trpc.get_session(): return True return False def getAllDownloadStatus(self, ids): + """ Get status of all active downloads + + :param ids: list of (mixed) downloader ids + Used to match the releases for this downloader as there could be + other downloaders active that it should ignore + :return: list of releases + """ log.debug('Checking Transmission download status.') diff --git a/couchpotato/core/downloaders/utorrent.py b/couchpotato/core/downloaders/utorrent.py index f4535ca..847eaf1 100644 --- a/couchpotato/core/downloaders/utorrent.py +++ b/couchpotato/core/downloaders/utorrent.py @@ -135,6 +135,10 @@ class uTorrent(DownloaderBase): return self.downloadReturnId(torrent_hash) def test(self): + """ Check if connection works + :return: bool + """ + if self.connect(): build_version = self.utorrent_api.get_build() if not build_version: @@ -146,6 +150,13 @@ class uTorrent(DownloaderBase): return False def getAllDownloadStatus(self, ids): + """ Get status of all active downloads + + :param ids: list of (mixed) downloader ids + Used to match the releases for this downloader as there could be + other downloaders active that it should ignore + :return: list of releases + """ log.debug('Checking uTorrent download status.')