diff --git a/couchpotato/core/downloaders/base.py b/couchpotato/core/downloaders/base.py index bb57cca..3bcf1f3 100644 --- a/couchpotato/core/downloaders/base.py +++ b/couchpotato/core/downloaders/base.py @@ -15,7 +15,6 @@ class Downloader(Provider): protocol = [] http_time_between_calls = 0 status_support = True - testable = False torrent_sources = [ 'http://torrage.com/torrent/%s.torrent', @@ -44,7 +43,6 @@ class Downloader(Provider): addEvent('download.remove_failed', self._removeFailed) addEvent('download.pause', self._pause) addEvent('download.process_complete', self._processComplete) - addApiView('download.%s.is_testable' % self.getName().lower(), self.isTestable) addApiView('download.%s.test' % self.getName().lower(), self._test) def getEnabledProtocol(self): @@ -162,14 +160,11 @@ class Downloader(Provider): (d_manual and manual or d_manual is False) and \ (not data or self.isCorrectProtocol(data.get('protocol'))) - def isTestable(self): - return {'success': self.testable} - def _test(self): t = self.test() - if isinstance(t,tuple): - return {'success': t[0], 'msg': t[1] } - return {'success': t } + if isinstance(t, tuple): + return {'success': t[0], 'msg': t[1]} + return {'success': t} def test(self): return False diff --git a/couchpotato/core/downloaders/blackhole/main.py b/couchpotato/core/downloaders/blackhole/main.py index 8449d09..9a01835 100644 --- a/couchpotato/core/downloaders/blackhole/main.py +++ b/couchpotato/core/downloaders/blackhole/main.py @@ -1,5 +1,6 @@ from __future__ import with_statement from couchpotato.core.downloaders.base import Downloader +from couchpotato.core.helpers.encoding import sp from couchpotato.core.logger import CPLog from couchpotato.environment import Env import os @@ -67,6 +68,20 @@ class Blackhole(Downloader): return False + def test(self): + directory = self.conf('directory') + if directory and os.path.isdir(directory): + + test_file = sp(os.path.join(directory, 'couchpotato_test.txt')) + + # Check if folder is writable + self.createFile(test_file, 'This is a test file') + if os.path.isfile(test_file): + os.remove(test_file) + return True + + return False + def getEnabledProtocol(self): if self.conf('use_for') == 'both': return super(Blackhole, self).getEnabledProtocol() diff --git a/couchpotato/core/downloaders/deluge/main.py b/couchpotato/core/downloaders/deluge/main.py index 3d72be7..5930095 100644 --- a/couchpotato/core/downloaders/deluge/main.py +++ b/couchpotato/core/downloaders/deluge/main.py @@ -19,7 +19,6 @@ class Deluge(Downloader): protocol = ['torrent', 'torrent_magnet'] log = CPLog(__name__) drpc = None - testable = True def connect(self, reconnect = False): # Load host from config and split out port. @@ -33,11 +32,6 @@ class Deluge(Downloader): return self.drpc - def test(self): - if self.connect(True) and self.drpc.test(): - return True - return False - def download(self, data = None, media = None, filedata = None): if not media: media = {} if not data: data = {} @@ -92,6 +86,11 @@ class Deluge(Downloader): log.info('Torrent sent to Deluge successfully.') return self.downloadReturnId(remote_torrent) + def test(self): + if self.connect(True) and self.drpc.test(): + return True + return False + def getAllDownloadStatus(self, ids): log.debug('Checking Deluge download status.') diff --git a/couchpotato/core/downloaders/nzbget/main.py b/couchpotato/core/downloaders/nzbget/main.py index 8b9c88d..3dad867 100644 --- a/couchpotato/core/downloaders/nzbget/main.py +++ b/couchpotato/core/downloaders/nzbget/main.py @@ -16,30 +16,7 @@ log = CPLog(__name__) class NZBGet(Downloader): protocol = ['nzb'] - rpc = 'xmlrpc' - testable = True - - def test(self): - url = cleanHost(host = self.conf('host'), ssl = self.conf('ssl'), username = self.conf('username'), password = self.conf('password')) + self.rpc - rpc = xmlrpclib.ServerProxy(url) - - try: - if rpc.writelog('INFO', 'CouchPotato connected to test connection'): - log.debug('Successfully connected to NZBGet') - else: - log.info('Successfully connected to NZBGet, but unable to send a message') - except socket.error: - log.error('NZBGet is not responding. Please ensure that NZBGet is running and host setting is correct.') - return False - except xmlrpclib.ProtocolError as e: - if e.errcode == 401: - log.error('Password is incorrect.') - else: - log.error('Protocol Error: %s', e) - return False - - return True def download(self, data = None, media = None, filedata = None): if not media: media = {} @@ -53,8 +30,7 @@ class NZBGet(Downloader): nzb_name = ss('%s.nzb' % self.createNzbName(data, media)) - url = cleanHost(host = self.conf('host'), ssl = self.conf('ssl'), username = self.conf('username'), password = self.conf('password')) + self.rpc - rpc = xmlrpclib.ServerProxy(url) + rpc = self.getRPC() try: if rpc.writelog('INFO', 'CouchPotato connected to drop off %s.' % nzb_name): @@ -90,12 +66,31 @@ class NZBGet(Downloader): log.error('NZBGet could not add %s to the queue.', nzb_name) return False + def test(self): + rpc = self.getRPC() + + try: + if rpc.writelog('INFO', 'CouchPotato connected to test connection'): + log.debug('Successfully connected to NZBGet') + else: + log.info('Successfully connected to NZBGet, but unable to send a message') + except socket.error: + log.error('NZBGet is not responding. Please ensure that NZBGet is running and host setting is correct.') + return False + except xmlrpclib.ProtocolError as e: + if e.errcode == 401: + log.error('Password is incorrect.') + else: + log.error('Protocol Error: %s', e) + return False + + return True + def getAllDownloadStatus(self, ids): log.debug('Checking NZBGet download status.') - url = cleanHost(host = self.conf('host'), ssl = self.conf('ssl'), username = self.conf('username'), password = self.conf('password')) + self.rpc - rpc = xmlrpclib.ServerProxy(url) + rpc = self.getRPC() try: if rpc.writelog('INFO', 'CouchPotato connected to check status'): @@ -180,8 +175,7 @@ class NZBGet(Downloader): log.info('%s failed downloading, deleting...', release_download['name']) - url = cleanHost(host = self.conf('host'), ssl = self.conf('ssl'), username = self.conf('username'), password = self.conf('password')) + self.rpc - rpc = xmlrpclib.ServerProxy(url) + rpc = self.getRPC() try: if rpc.writelog('INFO', 'CouchPotato connected to delete some history'): @@ -216,3 +210,7 @@ class NZBGet(Downloader): return False return True + + def getRPC(self): + url = cleanHost(host = self.conf('host'), ssl = self.conf('ssl'), username = self.conf('username'), password = self.conf('password')) + self.rpc + return xmlrpclib.ServerProxy(url) diff --git a/couchpotato/core/downloaders/nzbvortex/main.py b/couchpotato/core/downloaders/nzbvortex/main.py index e02f7c1..d1525c8 100644 --- a/couchpotato/core/downloaders/nzbvortex/main.py +++ b/couchpotato/core/downloaders/nzbvortex/main.py @@ -24,15 +24,6 @@ class NZBVortex(Downloader): protocol = ['nzb'] api_level = None session_id = None - testable = True - - def test(self): - try: - login_result = self.login() - except: - return False - - return login_result def download(self, data = None, media = None, filedata = None): if not media: media = {} @@ -51,6 +42,14 @@ class NZBVortex(Downloader): log.error('Something went wrong sending the NZB file: %s', traceback.format_exc()) return False + def test(self): + try: + login_result = self.login() + except: + return False + + return login_result + def getAllDownloadStatus(self, ids): raw_statuses = self.call('nzb') diff --git a/couchpotato/core/downloaders/pneumatic/main.py b/couchpotato/core/downloaders/pneumatic/main.py index 6af22d2..bc1f6d0 100644 --- a/couchpotato/core/downloaders/pneumatic/main.py +++ b/couchpotato/core/downloaders/pneumatic/main.py @@ -1,5 +1,6 @@ from __future__ import with_statement from couchpotato.core.downloaders.base import Downloader +from couchpotato.core.helpers.encoding import sp from couchpotato.core.logger import CPLog import os import traceback @@ -56,3 +57,17 @@ class Pneumatic(Downloader): log.info('Failed to download file %s: %s', (data.get('name'), traceback.format_exc())) return False return False + + def test(self): + directory = self.conf('directory') + if directory and os.path.isdir(directory): + + test_file = sp(os.path.join(directory, 'couchpotato_test.txt')) + + # Check if folder is writable + self.createFile(test_file, 'This is a test file') + if os.path.isfile(test_file): + os.remove(test_file) + return True + + return False diff --git a/couchpotato/core/downloaders/rtorrent/main.py b/couchpotato/core/downloaders/rtorrent/main.py index fed2bfe..c5850f9 100755 --- a/couchpotato/core/downloaders/rtorrent/main.py +++ b/couchpotato/core/downloaders/rtorrent/main.py @@ -19,7 +19,6 @@ class rTorrent(Downloader): protocol = ['torrent', 'torrent_magnet'] rt = None - testable = True error_msg = '' # Migration url to host options @@ -49,7 +48,7 @@ class rTorrent(Downloader): self.rt = None return True - def connect(self): + def connect(self, reconnect = False): # Already connected? if not reconnect and self.rt is not None: return self.rt diff --git a/couchpotato/core/downloaders/sabnzbd/main.py b/couchpotato/core/downloaders/sabnzbd/main.py index 9eea8c9..ba58c09 100644 --- a/couchpotato/core/downloaders/sabnzbd/main.py +++ b/couchpotato/core/downloaders/sabnzbd/main.py @@ -15,27 +15,6 @@ log = CPLog(__name__) class Sabnzbd(Downloader): protocol = ['nzb'] - testable = True - - def test(self): - try: - sab_data = self.call({ - 'mode': 'version', - }) - v = sab_data.split('.') - if int(v[0]) == 0 and int(v[1]) < 7: - return False, 'Your Sabnzbd client is too old, please update to newest version.' - - # the version check will work even with wrong api key, so we need the next check as well - sab_data = self.call({ - 'mode': 'qstatus', - }) - if not sab_data: - return False - except: - return False - - return True def download(self, data = None, media = None, filedata = None): if not media: media = {} @@ -85,6 +64,26 @@ class Sabnzbd(Downloader): log.error('Error getting data from SABNZBd: %s', sab_data) return False + def test(self): + try: + sab_data = self.call({ + 'mode': 'version', + }) + v = sab_data.split('.') + if int(v[0]) == 0 and int(v[1]) < 7: + return False, 'Your Sabnzbd client is too old, please update to newest version.' + + # the version check will work even with wrong api key, so we need the next check as well + sab_data = self.call({ + 'mode': 'qstatus', + }) + if not sab_data: + return False + except: + return False + + return True + def getAllDownloadStatus(self, ids): log.debug('Checking SABnzbd download status.') diff --git a/couchpotato/core/downloaders/synology/main.py b/couchpotato/core/downloaders/synology/main.py index 7fb0ee5..7e5b609 100644 --- a/couchpotato/core/downloaders/synology/main.py +++ b/couchpotato/core/downloaders/synology/main.py @@ -13,17 +13,6 @@ class Synology(Downloader): protocol = ['nzb', 'torrent', 'torrent_magnet'] status_support = False - testable = True - - def test(self): - host = cleanHost(self.conf('host'), protocol = False).split(':') - try: - srpc = SynologyRPC(host[0], host[1], self.conf('username'), self.conf('password')) - test_result = srpc.test() - except: - return False - - return test_result def download(self, data = None, media = None, filedata = None): if not media: media = {} @@ -56,6 +45,16 @@ class Synology(Downloader): finally: return self.downloadReturnId('') if response else False + def test(self): + host = cleanHost(self.conf('host'), protocol = False).split(':') + try: + srpc = SynologyRPC(host[0], host[1], self.conf('username'), self.conf('password')) + test_result = srpc.test() + except: + return False + + return test_result + def getEnabledProtocol(self): if self.conf('use_for') == 'both': return super(Synology, self).getEnabledProtocol() diff --git a/couchpotato/core/downloaders/transmission/main.py b/couchpotato/core/downloaders/transmission/main.py index d64c270..4c42bf0 100644 --- a/couchpotato/core/downloaders/transmission/main.py +++ b/couchpotato/core/downloaders/transmission/main.py @@ -18,7 +18,6 @@ class Transmission(Downloader): protocol = ['torrent', 'torrent_magnet'] log = CPLog(__name__) trpc = None - testable = True def connect(self, reconnect = False): # Load host from config and split out port. @@ -32,11 +31,6 @@ class Transmission(Downloader): return self.trpc - def test(self): - if self.connect(True) and self.trpc.get_session(): - return True - return False - def download(self, data = None, media = None, filedata = None): if not media: media = {} if not data: data = {} @@ -89,6 +83,11 @@ class Transmission(Downloader): log.info('Torrent sent to Transmission successfully.') return self.downloadReturnId(remote_torrent['torrent-added']['hashString']) + def test(self): + if self.connect(True) and self.trpc.get_session(): + return True + return False + def getAllDownloadStatus(self, ids): log.debug('Checking Transmission download status.') diff --git a/couchpotato/core/downloaders/utorrent/main.py b/couchpotato/core/downloaders/utorrent/main.py index e1a111e..6a5e425 100644 --- a/couchpotato/core/downloaders/utorrent/main.py +++ b/couchpotato/core/downloaders/utorrent/main.py @@ -1,6 +1,5 @@ from base64 import b16encode, b32decode from bencode import bencode as benc, bdecode -from couchpotato.api import addApiView from couchpotato.core.downloaders.base import Downloader, ReleaseDownloadList from couchpotato.core.helpers.encoding import isInt, ss, sp from couchpotato.core.helpers.variable import tryInt, tryFloat, cleanHost @@ -25,7 +24,6 @@ class uTorrent(Downloader): protocol = ['torrent', 'torrent_magnet'] utorrent_api = None - testable = True status_flags = { 'STARTED' : 1, 'CHECKING' : 2, @@ -48,17 +46,6 @@ class uTorrent(Downloader): return self.utorrent_api - def test(self): - if self.connect(): - build_version = self.utorrent_api.get_build() - if not build_version: - return False - if build_version < 25406: # This build corresponds to version 3.0.0 stable - return False, 'Your uTorrent client is too old, please update to newest version.' - return True - - return False - def download(self, data = None, media = None, filedata = None): if not media: media = {} if not data: data = {} @@ -128,6 +115,17 @@ class uTorrent(Downloader): return self.downloadReturnId(torrent_hash) + def test(self): + if self.connect(): + build_version = self.utorrent_api.get_build() + if not build_version: + return False + if build_version < 25406: # This build corresponds to version 3.0.0 stable + return False, 'Your uTorrent client is too old, please update to newest version.' + return True + + return False + def getAllDownloadStatus(self, ids): log.debug('Checking uTorrent download status.') diff --git a/couchpotato/static/scripts/misc/downloaders.js b/couchpotato/static/scripts/misc/downloaders.js index 8d03c24..5127275 100644 --- a/couchpotato/static/scripts/misc/downloaders.js +++ b/couchpotato/static/scripts/misc/downloaders.js @@ -27,48 +27,41 @@ var DownloadersBase = new Class({ if(button_name.contains('Downloaders')) return; - Api.request('download.'+plugin_name+'.is_testable', { - 'onComplete': function(json){ - if(json.success){ - // Only add test button if downloader is testable - new Element('.ctrlHolder.test_button').adopt( - new Element('a.button', { - 'text': button_name, - 'events': { - 'click': function(){ - var button = fieldset.getElement('.test_button .button'); - button.set('text', 'Connecting...'); - - Api.request('download.'+plugin_name+'.test', { - 'onComplete': function(json){ - - button.set('text', button_name); - - if(json.success){ - var message = new Element('span.success', { - 'text': 'Connection successful' - }).inject(button, 'after') - } - else { - var msg_text = 'Connection failed. Check logs for details.'; - if(json.hasOwnProperty('msg')) msg_text = json.msg; - var message = new Element('span.failed', { - 'text': msg_text - }).inject(button, 'after') - } - - (function(){ - message.destroy(); - }).delay(3000) - } - }); - } - } - }) - ).inject(fieldset); - } - } - }); + new Element('.ctrlHolder.test_button').adopt( + new Element('a.button', { + 'text': button_name, + 'events': { + 'click': function(){ + var button = fieldset.getElement('.test_button .button'); + button.set('text', 'Connecting...'); + + Api.request('download.'+plugin_name+'.test', { + 'onComplete': function(json){ + + button.set('text', button_name); + + if(json.success){ + var message = new Element('span.success', { + 'text': 'Connection successful' + }).inject(button, 'after') + } + else { + var msg_text = 'Connection failed. Check logs for details.'; + if(json.hasOwnProperty('msg')) msg_text = json.msg; + var message = new Element('span.failed', { + 'text': msg_text + }).inject(button, 'after') + } + + (function(){ + message.destroy(); + }).delay(3000) + } + }); + } + } + }) + ).inject(fieldset); }, @@ -79,4 +72,4 @@ var DownloadersBase = new Class({ }); -window.Downloaders = new DownloadersBase(); \ No newline at end of file +window.Downloaders = new DownloadersBase();