diff --git a/couchpotato/core/_base/updater/main.py b/couchpotato/core/_base/updater/main.py
index 0ad60c0..ae9f037 100644
--- a/couchpotato/core/_base/updater/main.py
+++ b/couchpotato/core/_base/updater/main.py
@@ -98,7 +98,7 @@ class Updater(Plugin):
if self.conf('notification'):
info = self.updater.info()
version_date = datetime.fromtimestamp(info['update_version']['date'])
- fireEvent('updater.updated', 'Updated to a new version with hash "%s", this version is from %s' % (info['update_version']['hash'], version_date), data = info)
+ fireEvent('updater.updated', 'CouchPotato: Updated to a new version with hash "%s", this version is from %s' % (info['update_version']['hash'], version_date), data = info)
except:
log.error('Failed notifying for update: %s', traceback.format_exc())
diff --git a/couchpotato/core/downloaders/hadouken.py b/couchpotato/core/downloaders/hadouken.py
index b2057d5..f96a374 100644
--- a/couchpotato/core/downloaders/hadouken.py
+++ b/couchpotato/core/downloaders/hadouken.py
@@ -371,29 +371,29 @@ class TorrentItemv5(TorrentItem):
self.obj = obj
def info_hash(self):
- return self.obj['infoHash']
+ return self.obj[0]
def save_path(self):
- return self.obj['savePath']
+ return self.obj[26]
def name(self):
- return self.obj['name']
+ return self.obj[2]
def state(self):
- return self.obj['state']
+ return self.obj[1]
def get_status(self):
- if self.obj['isSeeding'] and self.obj['isFinished'] and self.obj['isPaused']:
+ if self.obj[1] == 32:
return 'completed'
- if self.obj['isSeeding']:
+ if self.obj[1] == 1:
return 'seeding'
return 'busy'
def get_seed_ratio(self):
- up = self.obj['uploadedBytesTotal']
- down = self.obj['downloadedBytesTotal']
+ up = self.obj[6]
+ down = self.obj[5]
if up > 0 and down > 0:
return up / down
@@ -402,28 +402,29 @@ class TorrentItemv5(TorrentItem):
class HadoukenAPIv5(HadoukenAPI):
+
def add_file(self, data, params):
- return self.rpc.invoke('session.addTorrentFile', [b64encode(data), params])
+ return self.rpc.invoke('webui.addTorrent', ['file', b64encode(data), params])
def add_magnet_link(self, link, params):
- return self.rpc.invoke('session.addTorrentUri', [link, params])
+ return self.rpc.invoke('webui.addTorrent', ['url', link, params])
def get_by_hash_list(self, infoHashList):
- torrents = self.rpc.invoke('session.getTorrents')
+ torrents = self.rpc.invoke('webui.list', None)
result = []
- for torrent in torrents.values():
- if torrent['infoHash'] in infoHashList:
+ for torrent in torrents['torrents']:
+ if torrent[0] in infoHashList:
result.append(TorrentItemv5(torrent))
return result
def get_files_by_hash(self, infoHash):
- files = self.rpc.invoke('torrent.getFiles', [infoHash])
+ files = self.rpc.invoke('webui.getFiles', [infoHash])
result = []
- for file in files:
- result.append(file['path'])
+ for file in files['files'][1]:
+ result.append(file[0])
return result
@@ -437,12 +438,15 @@ class HadoukenAPIv5(HadoukenAPI):
def pause(self, infoHash, pause):
if pause:
- return self.rpc.invoke('torrent.pause', [infoHash])
+ return self.rpc.invoke('webui.perform', ['pause', infoHash])
- return self.rpc.invoke('torrent.resume', [infoHash])
+ return self.rpc.invoke('webui.perform', ['resume', infoHash])
- def remove(self, infoHash, remove_data = False):
- return self.rpc.invoke('session.removeTorrent', [infoHash, remove_data])
+ def remove(self, infoHash, remove_data=False):
+ if remove_data:
+ return self.rpc.invoke('webui.perform', ['removedata', infoHash])
+
+ return self.rpc.invoke('webui.perform', ['remove', infoHash])
class TorrentItemv4(TorrentItem):
diff --git a/couchpotato/core/downloaders/rtorrent_.py b/couchpotato/core/downloaders/rtorrent_.py
index a9e8e6a..4902cff 100644
--- a/couchpotato/core/downloaders/rtorrent_.py
+++ b/couchpotato/core/downloaders/rtorrent_.py
@@ -3,6 +3,7 @@ from datetime import timedelta
from hashlib import sha1
from urlparse import urlparse
import os
+import re
from couchpotato.core._base.downloader.main import DownloaderBase, ReleaseDownloadList
from couchpotato.core.event import addEvent
@@ -146,6 +147,7 @@ class rTorrent(DownloaderBase):
if not self.connect():
return False
+ torrent_hash = 0
torrent_params = {}
if self.conf('label'):
torrent_params['label'] = self.conf('label')
@@ -156,29 +158,42 @@ class rTorrent(DownloaderBase):
# Try download magnet torrents
if data.get('protocol') == 'torrent_magnet':
- filedata = self.magnetToTorrent(data.get('url'))
-
- if filedata is False:
+ # Send magnet to rTorrent
+ torrent_hash = re.findall('urn:btih:([\w]{32,40})', data.get('url'))[0].upper()
+ # Send request to rTorrent
+ try:
+ torrent = self.rt.load_magnet(data.get('url'), torrent_hash)
+
+ if not torrent:
+ log.error('Unable to find the torrent, did it fail to load?')
+ return False
+
+ except Exception as err:
+ log.error('Failed to send magnet to rTorrent: %s', err)
return False
- data['protocol'] = 'torrent'
+ if data.get('protocol') == 'torrent':
+ info = bdecode(filedata)["info"]
+ torrent_hash = sha1(bencode(info)).hexdigest().upper()
- info = bdecode(filedata)["info"]
- torrent_hash = sha1(bencode(info)).hexdigest().upper()
+ # Convert base 32 to hex
+ if len(torrent_hash) == 32:
+ torrent_hash = b16encode(b32decode(torrent_hash))
- # Convert base 32 to hex
- if len(torrent_hash) == 32:
- torrent_hash = b16encode(b32decode(torrent_hash))
+ # Send request to rTorrent
+ try:
+ # Send torrent to rTorrent
+ torrent = self.rt.load_torrent(filedata, verify_retries=10)
- # Send request to rTorrent
- try:
- # Send torrent to rTorrent
- torrent = self.rt.load_torrent(filedata, verify_retries=10)
+ if not torrent:
+ log.error('Unable to find the torrent, did it fail to load?')
+ return False
- if not torrent:
- log.error('Unable to find the torrent, did it fail to load?')
+ except Exception as err:
+ log.error('Failed to send torrent to rTorrent: %s', err)
return False
+ try:
# Set label
if self.conf('label'):
torrent.set_custom(1, self.conf('label'))
@@ -191,10 +206,12 @@ class rTorrent(DownloaderBase):
torrent.start()
return self.downloadReturnId(torrent_hash)
+
except Exception as err:
log.error('Failed to send torrent to rTorrent: %s', err)
return False
+
def getTorrentStatus(self, torrent):
if not torrent.complete:
return 'busy'
diff --git a/couchpotato/core/downloaders/sabnzbd.py b/couchpotato/core/downloaders/sabnzbd.py
index c9bb7cc..0f82618 100644
--- a/couchpotato/core/downloaders/sabnzbd.py
+++ b/couchpotato/core/downloaders/sabnzbd.py
@@ -95,7 +95,7 @@ class Sabnzbd(DownloaderBase):
'mode': 'version',
})
v = sab_data.split('.')
- if int(v[0]) == 0 and int(v[1]) < 7:
+ if sab_data != 'develop' and 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
diff --git a/couchpotato/core/downloaders/transmission.py b/couchpotato/core/downloaders/transmission.py
index 78f8fd7..f40b955 100644
--- a/couchpotato/core/downloaders/transmission.py
+++ b/couchpotato/core/downloaders/transmission.py
@@ -67,7 +67,8 @@ class Transmission(DownloaderBase):
}
if self.conf('directory'):
- if os.path.isdir(self.conf('directory')):
+ host = cleanHost(self.conf('host')).rstrip('/').rsplit(':', 1)
+ if os.path.isdir(self.conf('directory')) or not (host[0] == '127.0.0.1' or host[0] == 'localhost'):
params['download-dir'] = self.conf('directory').rstrip(os.path.sep)
else:
log.error('Download directory from Transmission settings: %s doesn\'t exist', self.conf('directory'))
diff --git a/couchpotato/core/media/_base/providers/nzb/omgwtfnzbs.py b/couchpotato/core/media/_base/providers/nzb/omgwtfnzbs.py
index e87d783..6d4d0a2 100644
--- a/couchpotato/core/media/_base/providers/nzb/omgwtfnzbs.py
+++ b/couchpotato/core/media/_base/providers/nzb/omgwtfnzbs.py
@@ -12,7 +12,7 @@ log = CPLog(__name__)
class Base(NZBProvider, RSS):
urls = {
- 'search': 'https://api.omgwtfnzbs.org/json/?%s',
+ 'search': 'https://api.omgwtfnzbs.me/json/?%s',
}
http_time_between_calls = 1 # Seconds
@@ -61,7 +61,7 @@ config = [{
'tab': 'searcher',
'list': 'nzb_providers',
'name': 'OMGWTFNZBs',
- 'description': 'See OMGWTFNZBs',
+ 'description': 'See OMGWTFNZBs',
'wizard': True,
'icon': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAIAAADAAbR1AAADbElEQVR4AZ2UW0ybZRiAy/OvdHaLYvB0YTRIFi7GkM44zRLmIfNixkWdiRMyYoxRE8/TC7MYvXCGEBmr3mxLwVMwY0wYA7e6Wso4lB6h/U9taSlMGIfBXLYlJMyo0S///2dJI5lxN8/F2/f9nu9737e/jYmXr6KTbN9BGG9HE/NotQ76UWziNzrXFiETk/5ARUNH+7+0kW7fSgTl0VKGOLZzidOkmuuIo7q2oTArNLPIzhdIkqXkerFOm2CaD/5bcKrjIL2c3fkhPxOq93Kcb91v46fV9TQKF4TgV/TbUsQtzfCaK6jMOd5DJrguSIIhexmqqVxN0FXbRR8/ND/LYTTj6J7nl2gnL47OkDW4KJhnQHCa6JpKVNJGA3OC58nwBJoZ//ebbIyKpBxjrr0o1q1FMRkrKXZnHWF85VvxMrJxibwhGyd0f5bLnKzqJs1k0Sfo+EU8hdAUvkbcwKEgs2D0OiV4jmmD1zb+Tp6er0JMMvDxPo5xev9zTBF683NS+N56n1YiB95B5crr93KRuKhKI0tb0Kw2mgLLqTjLEWO8424i9IvURaYeOckwf3+/yCC9e3bQQ/MuD+Monk0k+XFXMUfx7z5EEP+XlXi5tLlMxH8zLppw7idJrugcus30kC86gc7UrQqjLIukM8zWHOACeU+TiMxXN6ExVOkgz4lvPEzice1GIVhxhG4CrZvpl6TH55giKWqXGLy9hZh5aUtgDSew/msSyCKpl+DDNfxJc8NBIsxUxUnz14O/oONu+IIIvso9TLBQ1SY5rUhuSzUhAqJ2mRXBLDOCeUtgUZXsaObT8BffhUJPqWgiV+3zKKzYH0ClvTRLhD77HIqVkyh5jThnivehoG+qJctIRSPn6bxvO4FCgTl9c1DmbpjLajbQFE8aW5SU3rg+zOPGUjTUF9NFpLEbH2c/KmGYlY69/GQJVtGMSUcEp9eCbB1nctbxHTLRdTUkGDf+B02uGWRG3OvpJ/zSMwzif+oxVBID3cQKBavLCiPmB2PM2UuSCUPgrX4VDb97AwEG67bh4+KTOlncvu3M31BwA5rLHbCfEjwkNDky9e/SSbSxnD46Pg0RJtpXRvhmBSZHpRjWtKwFybjuQeXaKxto4WjLZZZvVmC17pZLJFkwxm5++PS2Mrwc7nyIMYZe/IzoP5d6QgEybqTXAAAAAElFTkSuQmCC',
'options': [
diff --git a/couchpotato/core/media/_base/providers/torrent/iptorrents.py b/couchpotato/core/media/_base/providers/torrent/iptorrents.py
index b25e29b..1197838 100644
--- a/couchpotato/core/media/_base/providers/torrent/iptorrents.py
+++ b/couchpotato/core/media/_base/providers/torrent/iptorrents.py
@@ -16,9 +16,9 @@ class Base(TorrentProvider):
urls = {
'test': 'https://iptorrents.eu/',
'base_url': 'https://iptorrents.eu',
- 'login': 'https://iptorrents.eu/',
+ 'login': 'https://iptorrents.eu/take_login.php',
'login_check': 'https://iptorrents.eu/oldinbox.php',
- 'search': 'https://iptorrents.eu/t?%s%%s&q=%s&qf=#torrents&p=%%d',
+ 'search': 'https://iptorrents.eu/t?%s%%s&q=%s&qf=ti#torrents&p=%%d',
}
http_time_between_calls = 1 # Seconds
@@ -36,7 +36,7 @@ class Base(TorrentProvider):
log.warning('Unable to find category ids for identifier "%s"', quality.get('identifier'))
return None
- return self.urls['search'] % ("&".join(("l%d=" % x) for x in cat_ids), tryUrlencode(query).replace('%', '%%'))
+ return self.urls['search'] % ("&".join(("%d=" % x) for x in cat_ids), tryUrlencode(query).replace('%', '%%'))
def _searchOnTitle(self, title, media, quality, results):
diff --git a/couchpotato/core/media/_base/providers/torrent/passthepopcorn.py b/couchpotato/core/media/_base/providers/torrent/passthepopcorn.py
index ee01836..d4db814 100644
--- a/couchpotato/core/media/_base/providers/torrent/passthepopcorn.py
+++ b/couchpotato/core/media/_base/providers/torrent/passthepopcorn.py
@@ -204,7 +204,7 @@ config = [{
'tab': 'searcher',
'list': 'torrent_providers',
'name': 'PassThePopcorn',
- 'description': 'PassThePopcorn.me',
+ 'description': 'PassThePopcorn.me',
'wizard': True,
'icon': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAARklEQVQoz2NgIAP8BwMiGWRpIN1JNWn/t6T9f5'
'32+W8GkNt7vzz9UkfarZVpb68BuWlbnqW1nU7L2DMx7eCoBlpqGOppCQB83zIgIg+wWQAAAABJRU5ErkJggg==',
diff --git a/couchpotato/core/media/movie/providers/torrent/iptorrents.py b/couchpotato/core/media/movie/providers/torrent/iptorrents.py
index 84a52f5..68365b8 100644
--- a/couchpotato/core/media/movie/providers/torrent/iptorrents.py
+++ b/couchpotato/core/media/movie/providers/torrent/iptorrents.py
@@ -11,10 +11,12 @@ class IPTorrents(MovieProvider, Base):
cat_ids = [
([87], ['3d']),
- ([48], ['720p', '1080p', 'bd50']),
- ([72], ['cam', 'ts', 'tc', 'r5', 'scr']),
- ([7, 48, 20], ['dvdrip', 'brrip']),
- ([6], ['dvdr']),
+ ([48], ['720p', '1080p']),
+ ([89], ['bd50']),
+ ([96], ['cam', 'ts', 'tc', 'r5', 'scr']),
+ ([48, 20, 90], ['brrip']),
+ ([7, 77], ['dvdrip']),
+ ([6], ['dvdr'])
]
def buildUrl(self, title, media, quality):
diff --git a/couchpotato/core/notifications/boxcar2.py b/couchpotato/core/notifications/boxcar2.py
index 04ce4f3..c6f49e6 100644
--- a/couchpotato/core/notifications/boxcar2.py
+++ b/couchpotato/core/notifications/boxcar2.py
@@ -10,6 +10,7 @@ autoload = 'Boxcar2'
class Boxcar2(Notification):
url = 'https://new.boxcar.io/api/notifications'
+ LOGO_URL = 'https://raw.githubusercontent.com/CouchPotato/CouchPotatoServer/master/couchpotato/static/images/notify.couch.small.png'
def notify(self, message = '', data = None, listener = None):
if not data: data = {}
@@ -27,6 +28,8 @@ class Boxcar2(Notification):
'user_credentials': self.conf('token'),
'notification[title]': toUnicode('%s - %s' % (self.default_title, message)),
'notification[long_message]': toUnicode(long_message),
+ 'notification[icon_url]': self.LOGO_URL,
+ 'notification[source_name]': 'CouchPotato',
}
self.urlopen(self.url, data = data)
diff --git a/couchpotato/core/plugins/quality/main.py b/couchpotato/core/plugins/quality/main.py
index 8bdd383..f2cd100 100644
--- a/couchpotato/core/plugins/quality/main.py
+++ b/couchpotato/core/plugins/quality/main.py
@@ -27,7 +27,7 @@ class QualityPlugin(Plugin):
{'identifier': 'bd50', 'hd': True, 'allow_3d': True, 'size': (20000, 60000), 'median_size': 40000, 'label': 'BR-Disk', 'alternative': ['bd25', ('br', 'disk')], 'allow': ['1080p'], 'ext':['iso', 'img'], 'tags': ['bdmv', 'certificate', ('complete', 'bluray'), 'avc', 'mvc']},
{'identifier': '1080p', 'hd': True, 'allow_3d': True, 'size': (4000, 20000), 'median_size': 10000, 'label': '1080p', 'width': 1920, 'height': 1080, 'alternative': [], 'allow': [], 'ext':['mkv', 'm2ts', 'ts'], 'tags': ['m2ts', 'x264', 'h264', '1080']},
{'identifier': '720p', 'hd': True, 'allow_3d': True, 'size': (3000, 10000), 'median_size': 5500, 'label': '720p', 'width': 1280, 'height': 720, 'alternative': [], 'allow': [], 'ext':['mkv', 'ts'], 'tags': ['x264', 'h264', '720']},
- {'identifier': 'brrip', 'hd': True, 'allow_3d': True, 'size': (700, 7000), 'median_size': 2000, 'label': 'BR-Rip', 'alternative': ['bdrip', ('br', 'rip'), 'hdtv', 'hdrip'], 'allow': ['720p', '1080p'], 'ext':['mp4', 'avi'], 'tags': ['webdl', ('web', 'dl')]},
+ {'identifier': 'brrip', 'hd': True, 'allow_3d': True, 'size': (700, 7000), 'median_size': 2000, 'label': 'BR-Rip', 'alternative': ['bdrip', ('br', 'rip'), 'hdtv', 'hdrip'], 'allow': ['720p', '1080p', '2160p'], 'ext':['mp4', 'avi'], 'tags': ['webdl', ('web', 'dl')]},
{'identifier': 'dvdr', 'size': (3000, 10000), 'median_size': 4500, 'label': 'DVD-R', 'alternative': ['br2dvd', ('dvd', 'r')], 'allow': [], 'ext':['iso', 'img', 'vob'], 'tags': ['pal', 'ntsc', 'video_ts', 'audio_ts', ('dvd', 'r'), 'dvd9']},
{'identifier': 'dvdrip', 'size': (600, 2400), 'median_size': 1500, 'label': 'DVD-Rip', 'width': 720, 'alternative': [('dvd', 'rip')], 'allow': [], 'ext':['avi'], 'tags': [('dvd', 'rip'), ('dvd', 'xvid'), ('dvd', 'divx')]},
{'identifier': 'scr', 'size': (600, 1600), 'median_size': 700, 'label': 'Screener', 'alternative': ['screener', 'dvdscr', 'ppvrip', 'dvdscreener', 'hdscr', 'webrip', ('web', 'rip')], 'allow': ['dvdr', 'dvdrip', '720p', '1080p'], 'ext':[], 'tags': []},
diff --git a/libs/rtorrent/__init__.py b/libs/rtorrent/__init__.py
old mode 100755
new mode 100644
index f283d92..0d64e81
--- a/libs/rtorrent/__init__.py
+++ b/libs/rtorrent/__init__.py
@@ -129,6 +129,42 @@ class RTorrent:
return(func_name)
+ def load_magnet(self, magneturl, info_hash, start=False, verbose=False, verify_load=True, verify_retries=3):
+
+ p = self._get_conn()
+
+ info_hash = info_hash.upper()
+
+ func_name = self._get_load_function("url", start, verbose)
+
+ # load magnet
+ getattr(p, func_name)(magneturl)
+
+ if verify_load:
+ i = 0
+ while i < verify_retries:
+ for torrent in self.get_torrents():
+ if torrent.info_hash != info_hash:
+ continue
+ time.sleep(1)
+ i += 1
+
+ # Resolve magnet to torrent
+ torrent.start()
+
+ assert info_hash in [t.info_hash for t in self.torrents],\
+ "Adding magnet was unsuccessful."
+
+ i = 0
+ while i < verify_retries:
+ for torrent in self.get_torrents():
+ if torrent.info_hash == info_hash:
+ if str(info_hash) not in str(torrent.name):
+ time.sleep(1)
+ i += 1
+
+ return(torrent)
+
def load_torrent(self, torrent, start=False, verbose=False, verify_load=True, verify_retries=3):
"""
Loads torrent into rTorrent (with various enhancements)