Merge branch 'refs/heads/develop' into nosql

This commit is contained in:
Ruud
2014-02-24 22:54:04 +01:00
18 changed files with 269 additions and 34 deletions
@@ -49,6 +49,7 @@ class ClientScript(Plugin):
'scripts/page/settings.js',
'scripts/page/about.js',
'scripts/page/manage.js',
'scripts/misc/downloaders.js',
],
}
+11
View File
@@ -1,4 +1,5 @@
from base64 import b32decode, b16encode
from couchpotato.api import addApiView
from couchpotato.core.event import addEvent
from couchpotato.core.helpers.variable import mergeDicts
from couchpotato.core.logger import CPLog
@@ -42,6 +43,7 @@ class Downloader(Provider):
addEvent('download.remove_failed', self._removeFailed)
addEvent('download.pause', self._pause)
addEvent('download.process_complete', self._processComplete)
addApiView('download.%s.test' % self.getName().lower(), self._test)
def getEnabledProtocol(self):
for download_protocol in self.protocol:
@@ -158,6 +160,15 @@ class Downloader(Provider):
(d_manual and manual or d_manual is False) and \
(not data or self.isCorrectProtocol(data.get('protocol')))
def _test(self):
t = self.test()
if isinstance(t, tuple):
return {'success': t[0], 'msg': t[1]}
return {'success': t}
def test(self):
return False
def _pause(self, release_download, pause = True):
if self.isDisabled(manual = True, data = {}):
return
@@ -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()
+14 -2
View File
@@ -20,14 +20,14 @@ class Deluge(Downloader):
log = CPLog(__name__)
drpc = None
def connect(self):
def connect(self, reconnect = False):
# Load host from config and split out port.
host = cleanHost(self.conf('host'), protocol = False).split(':')
if not isInt(host[1]):
log.error('Config properties are not filled in correctly, port is missing.')
return False
if not self.drpc:
if not self.drpc or reconnect:
self.drpc = DelugeRPC(host[0], port = host[1], username = self.conf('username'), password = self.conf('password'))
return self.drpc
@@ -86,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.')
@@ -178,6 +183,13 @@ class DelugeRPC(object):
self.client = DelugeClient()
self.client.connect(self.host, int(self.port), self.username, self.password)
def test(self):
try:
self.connect()
except:
return False
return True
def add_torrent_magnet(self, torrent, options):
torrent_id = False
try:
+27 -7
View File
@@ -16,7 +16,6 @@ log = CPLog(__name__)
class NZBGet(Downloader):
protocol = ['nzb']
rpc = 'xmlrpc'
def download(self, data = None, media = None, filedata = None):
@@ -31,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):
@@ -68,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'):
@@ -158,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'):
@@ -194,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)
@@ -42,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')
@@ -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
+20 -3
View File
@@ -20,6 +20,7 @@ class rTorrent(Downloader):
protocol = ['torrent', 'torrent_magnet']
rt = None
error_msg = ''
# Migration url to host options
def __init__(self):
@@ -48,9 +49,9 @@ class rTorrent(Downloader):
self.rt = None
return True
def connect(self):
def connect(self, reconnect = False):
# Already connected?
if self.rt is not None:
if not reconnect and self.rt is not None:
return self.rt
url = cleanHost(self.conf('host'), protocol = True, ssl = self.conf('ssl'))
@@ -69,9 +70,25 @@ class rTorrent(Downloader):
else:
self.rt = RTorrent(url)
self.error_msg = ''
try:
self.rt._verify_conn()
except AssertionError as e:
self.error_msg = e.message
self.rt = None
return self.rt
def updateProviderGroup(self, name, data):
def test(self):
if self.connect(True):
return True
if self.error_msg:
return False, 'Connection failed: ' + self.error_msg
return False
def _update_provider_group(self, name, data):
if data.get('seed_time'):
log.info('seeding time ignored, not supported')
@@ -64,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.')
@@ -45,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()
@@ -147,3 +157,6 @@ class SynologyRPC(object):
self._logout()
return result
def test(self):
return bool(self._login())
@@ -19,14 +19,14 @@ class Transmission(Downloader):
log = CPLog(__name__)
trpc = None
def connect(self):
def connect(self, reconnect = False):
# Load host from config and split out port.
host = cleanHost(self.conf('host'), protocol = False).split(':')
if not isInt(host[1]):
log.error('Config properties are not filled in correctly, port is missing.')
return False
if not self.trpc:
if not self.trpc or reconnect:
self.trpc = TransmissionRPC(host[0], port = host[1], rpc_url = self.conf('rpc_url').strip('/ '), username = self.conf('username'), password = self.conf('password'))
return self.trpc
@@ -83,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.')
@@ -115,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.')
@@ -322,3 +333,10 @@ class uTorrentAPI(object):
def get_files(self, hash):
action = 'action=getfiles&hash=%s' % hash
return self._request(action)
def get_build(self):
data = self._request('')
if not data:
return False
response = json.loads(data)
return int(response.get('build'))
@@ -12,12 +12,12 @@ log = CPLog(__name__)
class ILoveTorrents(TorrentProvider):
urls = {
'download': 'http://www.ilovetorrents.me/%s',
'detail': 'http://www.ilovetorrents.me/%s',
'search': 'http://www.ilovetorrents.me/browse.php?search=%s&page=%s&cat=%s',
'test': 'http://www.ilovetorrents.me/',
'login': 'http://www.ilovetorrents.me/takelogin.php',
'login_check': 'http://www.ilovetorrents.me'
'download': 'https://www.ilovetorrents.me/%s',
'detail': 'https//www.ilovetorrents.me/%s',
'search': 'https://www.ilovetorrents.me/browse.php?search=%s&page=%s&cat=%s',
'test': 'https://www.ilovetorrents.me/',
'login': 'https://www.ilovetorrents.me/takelogin.php',
'login_check': 'https://www.ilovetorrents.me'
}
cat_ids = [
@@ -11,11 +11,11 @@ log = CPLog(__name__)
class IPTorrents(TorrentProvider):
urls = {
'test': 'http://www.iptorrents.com/',
'base_url': 'http://www.iptorrents.com',
'login': 'http://www.iptorrents.com/torrents/',
'login_check': 'http://www.iptorrents.com/inbox.php',
'search': 'http://www.iptorrents.com/torrents/?l%d=1%s&q=%s&qf=ti&p=%d',
'test': 'https://www.iptorrents.com/',
'base_url': 'https://www.iptorrents.com',
'login': 'https://www.iptorrents.com/torrents/',
'login_check': 'https://www.iptorrents.com/inbox.php',
'search': 'https://www.iptorrents.com/torrents/?l%d=1%s&q=%s&qf=ti&p=%d',
}
cat_ids = [
@@ -31,15 +31,13 @@ class ThePirateBay(TorrentMagnetProvider):
proxy_list = [
'https://tpb.ipredator.se',
'https://thepiratebay.se',
'https://depiraatbaai.be',
'https://piratereverse.info',
'https://tpb.pirateparty.org.uk',
'https://argumentomteemigreren.nl',
'https://livepirate.com',
'http://pirateproxy.ca',
'http://tpb.al',
'http://www.tpb.gr',
'http://nl.tpb.li',
'http://proxybay.eu',
'https://www.getpirate.com',
'https://tpb.partipirate.org',
'https://tpb.piraten.lu',
'https://kuiken.co',
'http://pirateproxy.ca',
]
def _searchOnTitle(self, title, movie, quality, results):
@@ -11,7 +11,7 @@ config = [{
'tab': 'searcher',
'list': 'torrent_providers',
'name': 'TorrentShack',
'description': 'See <a href="http://www.torrentshack.net/">TorrentShack</a>',
'description': 'See <a href="https://www.torrentshack.net/">TorrentShack</a>',
'options': [
{
'name': 'enabled',
@@ -0,0 +1,75 @@
var DownloadersBase = new Class({
Implements: [Events],
initialize: function(){
var self = this;
// Add test buttons to settings page
App.addEvent('load', self.addTestButtons.bind(self));
},
// Downloaders setting tests
addTestButtons: function(){
var self = this;
var setting_page = App.getPage('Settings');
setting_page.addEvent('create', function(){
Object.each(setting_page.tabs.downloaders.groups, self.addTestButton.bind(self))
})
},
addTestButton: function(fieldset, plugin_name){
var self = this,
button_name = self.testButtonName(fieldset);
if(button_name.contains('Downloaders')) return;
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);
},
testButtonName: function(fieldset){
var name = String(fieldset.getElement('h2').innerHTML).substring(0,String(fieldset.getElement('h2').innerHTML).indexOf("<span"));
return 'Test '+name;
},
});
window.Downloaders = new DownloadersBase();
+7
View File
@@ -111,6 +111,13 @@ class RTorrent:
"Error: Minimum rTorrent version required is {0}".format(
MIN_RTORRENT_VERSION_STR)
def test_connection(self):
try:
self._verify_conn()
except:
return False
return True
def _meets_version_requirement(self):
return self._get_client_version_tuple() >= MIN_RTORRENT_VERSION