Browse Source

Merge branch 'develop'

pull/3356/merge
Ruud 9 years ago
parent
commit
4057790470
  1. 2
      couchpotato/core/_base/updater/main.py
  2. 44
      couchpotato/core/downloaders/hadouken.py
  3. 23
      couchpotato/core/downloaders/rtorrent_.py
  4. 2
      couchpotato/core/downloaders/sabnzbd.py
  5. 3
      couchpotato/core/downloaders/transmission.py
  6. 4
      couchpotato/core/media/_base/providers/nzb/omgwtfnzbs.py
  7. 6
      couchpotato/core/media/_base/providers/torrent/iptorrents.py
  8. 2
      couchpotato/core/media/_base/providers/torrent/passthepopcorn.py
  9. 10
      couchpotato/core/media/movie/providers/torrent/iptorrents.py
  10. 3
      couchpotato/core/notifications/boxcar2.py
  11. 2
      couchpotato/core/plugins/quality/main.py
  12. 36
      libs/rtorrent/__init__.py

2
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())

44
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):

23
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,13 +158,21 @@ class rTorrent(DownloaderBase):
# Try download magnet torrents
if data.get('protocol') == 'torrent_magnet':
filedata = self.magnetToTorrent(data.get('url'))
# 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 filedata is False:
if not torrent:
log.error('Unable to find the torrent, did it fail to load?')
return False
data['protocol'] = 'torrent'
except Exception as err:
log.error('Failed to send magnet to rTorrent: %s', err)
return False
if data.get('protocol') == 'torrent':
info = bdecode(filedata)["info"]
torrent_hash = sha1(bencode(info)).hexdigest().upper()
@ -179,6 +189,11 @@ class rTorrent(DownloaderBase):
log.error('Unable to find the torrent, did it fail to load?')
return False
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'

2
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

3
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'))

4
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 <a href="https://omgwtfnzbs.org/" target="_blank">OMGWTFNZBs</a>',
'description': 'See <a href="https://omgwtfnzbs.me/" target="_blank">OMGWTFNZBs</a>',
'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': [

6
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):

2
couchpotato/core/media/_base/providers/torrent/passthepopcorn.py

@ -204,7 +204,7 @@ config = [{
'tab': 'searcher',
'list': 'torrent_providers',
'name': 'PassThePopcorn',
'description': '<a href="https://passthepopcorn.me">PassThePopcorn.me</a>',
'description': '<a href="https://passthepopcorn.me" target="_blank">PassThePopcorn.me</a>',
'wizard': True,
'icon': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAARklEQVQoz2NgIAP8BwMiGWRpIN1JNWn/t6T9f5'
'32+W8GkNt7vzz9UkfarZVpb68BuWlbnqW1nU7L2DMx7eCoBlpqGOppCQB83zIgIg+wWQAAAABJRU5ErkJggg==',

10
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):

3
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)

2
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': []},

36
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)

Loading…
Cancel
Save