From 63dd7fa7c00368a87901414a4c8cbb5dcec97b24 Mon Sep 17 00:00:00 2001 From: Ruud Date: Sun, 19 May 2013 22:10:51 +0200 Subject: [PATCH 01/14] New PTP-config for more accurate hits Conflicts: couchpotato/core/providers/torrent/passthepopcorn/main.py --- .../torrent/passthepopcorn/__init__.py | 32 +++++++++++++++++++ .../providers/torrent/passthepopcorn/main.py | 29 +++++++++++++++-- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/couchpotato/core/providers/torrent/passthepopcorn/__init__.py b/couchpotato/core/providers/torrent/passthepopcorn/__init__.py index a9f687c3..098c5356 100644 --- a/couchpotato/core/providers/torrent/passthepopcorn/__init__.py +++ b/couchpotato/core/providers/torrent/passthepopcorn/__init__.py @@ -38,6 +38,38 @@ config = [{ 'name': 'passkey', 'default': '', }, + { + 'name': 'prefer_golden', + 'advanced': True, + 'type': 'bool', + 'label': 'Prefer golden', + 'default': 1, + 'description': 'Favors Golden Popcorn-releases over all other releases.' + }, + { + 'name': 'prefer_scene', + 'advanced': True, + 'type': 'bool', + 'label': 'Prefer scene', + 'default': 0, + 'description': 'Favors scene-releases over non-scene releases.' + }, + { + 'name': 'require_approval', + 'advanced': True, + 'type': 'bool', + 'label': 'Require approval', + 'default': 0, + 'description': 'Require staff-approval for releases to be accepted.' + }, + { + 'name': 'require_bluray', + 'advanced': True, + 'type': 'bool', + 'label': 'Require Blu-ray', + 'default': 0, + 'description': 'Require source to be Blu-ray for releases to be accepted.' + }, { 'name': 'extra_score', 'advanced': True, diff --git a/couchpotato/core/providers/torrent/passthepopcorn/main.py b/couchpotato/core/providers/torrent/passthepopcorn/main.py index 3f2d16d3..d911b616 100644 --- a/couchpotato/core/providers/torrent/passthepopcorn/main.py +++ b/couchpotato/core/providers/torrent/passthepopcorn/main.py @@ -103,11 +103,18 @@ class PassThePopcorn(TorrentProvider): for torrent in ptpmovie['Torrents']: torrent_id = tryInt(torrent['Id']) torrentdesc = '%s %s %s' % (torrent['Resolution'], torrent['Source'], torrent['Codec']) + torrentscore = 0 if 'GoldenPopcorn' in torrent and torrent['GoldenPopcorn']: torrentdesc += ' HQ' + if self.conf('prefer_golden'): + torrentscore += 100 + log.debug('Config: Prefer Golden Popcorn is active, awarding torrent 100 points') if 'Scene' in torrent and torrent['Scene']: torrentdesc += ' Scene' + if self.conf('prefer_scene'): + torrentscore += 50 + log.debug('Config: Prefer Scene release is active, awarding torrent 50 points') if 'RemasterTitle' in torrent and torrent['RemasterTitle']: torrentdesc += self.htmlToASCII(' %s' % torrent['RemasterTitle']) @@ -115,18 +122,21 @@ class PassThePopcorn(TorrentProvider): torrent_name = re.sub('[^A-Za-z0-9\-_ \(\).]+', '', '%s (%s) - %s' % (movie_title, ptpmovie['Year'], torrentdesc)) def extra_check(item): - return self.torrentMeetsQualitySpec(item, type) + return self.torrentMeetsQualitySpec(item, quality_id) results.append({ 'id': torrent_id, 'name': torrent_name, + 'Source': torrent['Source'], + 'Checked': 'true' if torrent['Checked'] else 'false', + 'Resolution': torrent['Resolution'], 'url': '%s?action=download&id=%d&authkey=%s&torrent_pass=%s' % (self.urls['torrent'], torrent_id, authkey, passkey), 'detail_url': self.urls['detail'] % torrent_id, 'date': tryInt(time.mktime(parse(torrent['UploadTime']).timetuple())), 'size': tryInt(torrent['Size']) / (1024 * 1024), 'seeders': tryInt(torrent['Seeders']), 'leechers': tryInt(torrent['Leechers']), - 'score': 50 if torrent['GoldenPopcorn'] else 0, + 'score': torrentscore, 'extra_check': extra_check, 'download': self.loginDownload, }) @@ -167,7 +177,17 @@ class PassThePopcorn(TorrentProvider): if not quality in self.post_search_filters: return True - for field, specs in self.post_search_filters[quality].items(): + reqs = self.post_search_filters[quality].copy() + + if self.conf('require_bluray'): + reqs['Source'] = ['Blu-ray'] + log.debug('Config: Require Blu-ray source is activated') + + if self.conf('require_approval'): + reqs['Checked'] = ['true'] + log.debug('Config: Require staff-approval activated') + + for field, specs in reqs.items(): matches_one = False seen_one = False @@ -182,11 +202,14 @@ class PassThePopcorn(TorrentProvider): return False else: # a positive rule; if any of the possible positive values match the field, return True + log.debug('Checking if torrents field %s equals %s' % (field, spec)) seen_one = True if torrent[field] == spec: + log.debug('Torrent satisfied %s == %s' % (field, spec)) matches_one = True if seen_one and not matches_one: + log.debug('Torrent did not satisfy requirements, ignoring') return False return True From 40aeca0740426d7821a722e32acc93820cbef9f0 Mon Sep 17 00:00:00 2001 From: Ruud Date: Sun, 19 May 2013 22:18:01 +0200 Subject: [PATCH 02/14] PTP extra scoring --- .../core/providers/torrent/passthepopcorn/__init__.py | 8 -------- .../core/providers/torrent/passthepopcorn/main.py | 10 ++-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/couchpotato/core/providers/torrent/passthepopcorn/__init__.py b/couchpotato/core/providers/torrent/passthepopcorn/__init__.py index 098c5356..a535034a 100644 --- a/couchpotato/core/providers/torrent/passthepopcorn/__init__.py +++ b/couchpotato/core/providers/torrent/passthepopcorn/__init__.py @@ -62,14 +62,6 @@ config = [{ 'default': 0, 'description': 'Require staff-approval for releases to be accepted.' }, - { - 'name': 'require_bluray', - 'advanced': True, - 'type': 'bool', - 'label': 'Require Blu-ray', - 'default': 0, - 'description': 'Require source to be Blu-ray for releases to be accepted.' - }, { 'name': 'extra_score', 'advanced': True, diff --git a/couchpotato/core/providers/torrent/passthepopcorn/main.py b/couchpotato/core/providers/torrent/passthepopcorn/main.py index d911b616..a4bb0429 100644 --- a/couchpotato/core/providers/torrent/passthepopcorn/main.py +++ b/couchpotato/core/providers/torrent/passthepopcorn/main.py @@ -108,13 +108,11 @@ class PassThePopcorn(TorrentProvider): if 'GoldenPopcorn' in torrent and torrent['GoldenPopcorn']: torrentdesc += ' HQ' if self.conf('prefer_golden'): - torrentscore += 100 - log.debug('Config: Prefer Golden Popcorn is active, awarding torrent 100 points') + torrentscore += 200 if 'Scene' in torrent and torrent['Scene']: torrentdesc += ' Scene' if self.conf('prefer_scene'): torrentscore += 50 - log.debug('Config: Prefer Scene release is active, awarding torrent 50 points') if 'RemasterTitle' in torrent and torrent['RemasterTitle']: torrentdesc += self.htmlToASCII(' %s' % torrent['RemasterTitle']) @@ -179,13 +177,9 @@ class PassThePopcorn(TorrentProvider): reqs = self.post_search_filters[quality].copy() - if self.conf('require_bluray'): - reqs['Source'] = ['Blu-ray'] - log.debug('Config: Require Blu-ray source is activated') - if self.conf('require_approval'): - reqs['Checked'] = ['true'] log.debug('Config: Require staff-approval activated') + reqs['Checked'] = ['true'] for field, specs in reqs.items(): matches_one = False From 161e0de8d548759f1575847c5e5576e8bf697dd3 Mon Sep 17 00:00:00 2001 From: Ruud Date: Sun, 19 May 2013 22:51:32 +0200 Subject: [PATCH 03/14] Don't need makedir in Transmission --- couchpotato/core/downloaders/transmission/main.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/couchpotato/core/downloaders/transmission/main.py b/couchpotato/core/downloaders/transmission/main.py index e9466205..6094e89b 100644 --- a/couchpotato/core/downloaders/transmission/main.py +++ b/couchpotato/core/downloaders/transmission/main.py @@ -36,12 +36,7 @@ class Transmission(Downloader): if len(self.conf('directory', default = '')) > 0: folder_name = self.createFileName(data, filedata, movie)[:-len(data.get('type')) - 1] - folder_path = os.path.join(self.conf('directory', default = ''), folder_name).rstrip(os.path.sep) - - # Create the empty folder to download too - self.makeDir(folder_path) - - params['download-dir'] = folder_path + params['download-dir'] = os.path.join(self.conf('directory', default = ''), folder_name).rstrip(os.path.sep) torrent_params = {} if self.conf('ratio'): @@ -93,11 +88,13 @@ class Transmission(Downloader): 'fields': ['id', 'name', 'hashString', 'percentDone', 'status', 'eta', 'isFinished', 'downloadDir', 'uploadRatio'] } queue = trpc.get_alltorrents(return_params) - except Exception, err: log.error('Failed getting queue: %s', err) return False + if not queue: + return [] + statuses = StatusList(self) # Get torrents status From c18563e34b94069e6539e837280e1cb9806fcea8 Mon Sep 17 00:00:00 2001 From: Ruud Date: Sun, 19 May 2013 23:12:22 +0200 Subject: [PATCH 04/14] uTorrent cleanup --- couchpotato/core/downloaders/utorrent/main.py | 57 +++++++------------ 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/couchpotato/core/downloaders/utorrent/main.py b/couchpotato/core/downloaders/utorrent/main.py index aa8a8121..364fe11e 100644 --- a/couchpotato/core/downloaders/utorrent/main.py +++ b/couchpotato/core/downloaders/utorrent/main.py @@ -106,36 +106,6 @@ class uTorrent(Downloader): return False statuses = StatusList(self) - download_folder = '' - settings_dict = {} - - try: - data = self.utorrent_api.get_settings() - utorrent_settings = json.loads(data) - - # Create settings dict - for item in utorrent_settings['settings']: - if item[1] == 0: # int - settings_dict[item[0]] = int(item[2] if not item[2].strip() == '' else '0') - elif item[1] == 1: # bool - settings_dict[item[0]] = True if item[2] == 'true' else False - elif item[1] == 2: # string - settings_dict[item[0]] = item[2] - - log.debug('uTorrent settings: %s, %s', (settings_dict['dir_completed_download_flag'], settings_dict['dir_active_download_flag'])) - - # Get the download path from the uTorrent settings - if settings_dict['dir_completed_download_flag']: - download_folder = settings_dict['dir_completed_download'] - elif settings_dict['dir_active_download_flag']: - download_folder = settings_dict['dir_active_download'] - else: - log.info('No download folder set in uTorrent. Please set a download folder') - return False - - except Exception, err: - log.error('Failed to get settings from uTorrent: %s', err) - return False # Get torrents for item in queue.get('torrents', []): @@ -145,18 +115,13 @@ class uTorrent(Downloader): if item[21] == 'Finished' or item[21] == 'Seeding': status = 'completed' - if settings_dict['dir_add_label']: - release_folder = os.path.join(download_folder, item[11], item[2]) - else: - release_folder = os.path.join(download_folder, item[2]) - statuses.append({ 'id': item[0], 'name': item[2], 'status': status, 'original_status': item[1], 'timeleft': str(timedelta(seconds = item[10])), - 'folder': release_folder, + 'folder': item[26], }) return statuses @@ -236,4 +201,22 @@ class uTorrentAPI(object): def get_settings(self): action = "action=getsettings" - return self._request(action) + settings_dict = {} + try: + utorrent_settings = json.loads(self._request(action)) + + # Create settings dict + for item in utorrent_settings['settings']: + if item[1] == 0: # int + settings_dict[item[0]] = int(item[2] if not item[2].strip() == '' else '0') + elif item[1] == 1: # bool + settings_dict[item[0]] = True if item[2] == 'true' else False + elif item[1] == 2: # string + settings_dict[item[0]] = item[2] + + #log.debug('uTorrent settings: %s', settings_dict) + + except Exception, err: + log.error('Failed to get settings from uTorrent: %s', err) + + return settings_dict From 965bd79a86ed06a58334b9aaa41b1c75b87e9726 Mon Sep 17 00:00:00 2001 From: Ruud Date: Sun, 19 May 2013 23:20:32 +0200 Subject: [PATCH 05/14] Cleanup import --- couchpotato/core/downloaders/utorrent/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/couchpotato/core/downloaders/utorrent/main.py b/couchpotato/core/downloaders/utorrent/main.py index 364fe11e..f49859ab 100644 --- a/couchpotato/core/downloaders/utorrent/main.py +++ b/couchpotato/core/downloaders/utorrent/main.py @@ -9,7 +9,6 @@ from multipartpost import MultipartPostHandler import cookielib import httplib import json -import os import re import time import urllib From 315f1b02076a10b8a78c36c5b89194b86a9f7c29 Mon Sep 17 00:00:00 2001 From: Ruud Date: Thu, 23 May 2013 07:35:11 +0200 Subject: [PATCH 06/14] Add r6 to quality list --- couchpotato/core/plugins/quality/main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/couchpotato/core/plugins/quality/main.py b/couchpotato/core/plugins/quality/main.py index f300e592..22afe475 100644 --- a/couchpotato/core/plugins/quality/main.py +++ b/couchpotato/core/plugins/quality/main.py @@ -8,7 +8,6 @@ from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin from couchpotato.core.settings.model import Quality, Profile, ProfileType from sqlalchemy.sql.expression import or_ -import os.path import re import time @@ -25,7 +24,7 @@ class QualityPlugin(Plugin): {'identifier': 'dvdr', 'size': (3000, 10000), 'label': 'DVD-R', 'alternative': [], 'allow': [], 'ext':['iso', 'img'], 'tags': ['pal', 'ntsc', 'video_ts', 'audio_ts']}, {'identifier': 'dvdrip', 'size': (600, 2400), 'label': 'DVD-Rip', 'width': 720, 'alternative': ['dvdrip'], 'allow': [], 'ext':['avi', 'mpg', 'mpeg'], 'tags': [('dvd', 'rip'), ('dvd', 'xvid'), ('dvd', 'divx')]}, {'identifier': 'scr', 'size': (600, 1600), 'label': 'Screener', 'alternative': ['screener', 'dvdscr', 'ppvrip', 'dvdscreener'], 'allow': ['dvdr', 'dvd'], 'ext':['avi', 'mpg', 'mpeg']}, - {'identifier': 'r5', 'size': (600, 1000), 'label': 'R5', 'alternative': [], 'allow': ['dvdr'], 'ext':['avi', 'mpg', 'mpeg']}, + {'identifier': 'r5', 'size': (600, 1000), 'label': 'R5', 'alternative': ['r6'], 'allow': ['dvdr'], 'ext':['avi', 'mpg', 'mpeg']}, {'identifier': 'tc', 'size': (600, 1000), 'label': 'TeleCine', 'alternative': ['telecine'], 'allow': [], 'ext':['avi', 'mpg', 'mpeg']}, {'identifier': 'ts', 'size': (600, 1000), 'label': 'TeleSync', 'alternative': ['telesync', 'hdts'], 'allow': [], 'ext':['avi', 'mpg', 'mpeg']}, {'identifier': 'cam', 'size': (600, 1000), 'label': 'Cam', 'alternative': ['camrip', 'hdcam'], 'allow': [], 'ext':['avi', 'mpg', 'mpeg']} From 29343478655ee712ba7c97f467bd98a22648380c Mon Sep 17 00:00:00 2001 From: Ruud Date: Sun, 26 May 2013 14:20:05 +0200 Subject: [PATCH 07/14] Send user-agent on login --- couchpotato/core/plugins/base.py | 5 +++-- couchpotato/core/providers/base.py | 9 ++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/couchpotato/core/plugins/base.py b/couchpotato/core/plugins/base.py index 9330631d..32472cac 100644 --- a/couchpotato/core/plugins/base.py +++ b/couchpotato/core/plugins/base.py @@ -28,6 +28,7 @@ class Plugin(object): _needs_shutdown = False + user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20130519 Firefox/24.0' http_last_use = {} http_time_between_calls = 0 http_failed_request = {} @@ -106,7 +107,7 @@ class Plugin(object): # Fill in some headers headers['Referer'] = headers.get('Referer', urlparse(url).hostname) headers['Host'] = headers.get('Host', urlparse(url).hostname) - headers['User-Agent'] = headers.get('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0.2) Gecko/20100101 Firefox/10.0.2') + headers['User-Agent'] = headers.get('User-Agent', self.user_agent) headers['Accept-encoding'] = headers.get('Accept-encoding', 'gzip') host = urlparse(url).hostname @@ -138,7 +139,7 @@ class Plugin(object): response = opener.open(request, timeout = timeout) else: - log.info('Opening url: %s, params: %s', (url, [x for x in params.iterkeys()])) + log.info('Opening url: %s, params: %s', (url, [x for x in params.iterkeys()] if isinstance(params, dict) else 'with data')) data = tryUrlencode(params) if len(params) > 0 else None request = urllib2.Request(url, data, headers) diff --git a/couchpotato/core/providers/base.py b/couchpotato/core/providers/base.py index 72bf42a6..e3709aa9 100644 --- a/couchpotato/core/providers/base.py +++ b/couchpotato/core/providers/base.py @@ -104,7 +104,7 @@ class YarrProvider(Provider): try: cookiejar = cookielib.CookieJar() opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar)) - opener.addheaders = [] + opener.addheaders = [('User-Agent', self.user_agent)] urllib2.install_opener(opener) log.info2('Logging into %s', self.urls['login']) f = opener.open(self.urls['login'], self.getLoginParams()) @@ -114,9 +114,12 @@ class YarrProvider(Provider): if self.loginSuccess(output): self.login_opener = opener return True - except: - log.error('Failed to login %s: %s', (self.getName(), traceback.format_exc())) + error = 'unknown' + except: + error = traceback.format_exc() + + log.error('Failed to login %s: %s', (self.getName(), error)) return False def loginSuccess(self, output): From fcad9e0be5fd4e21f24eed0d89e4bcac9a563c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20K=C3=A5berg?= Date: Wed, 22 May 2013 11:02:59 +0200 Subject: [PATCH 08/14] fireAsync made optional --- couchpotato/core/plugins/renamer/main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/couchpotato/core/plugins/renamer/main.py b/couchpotato/core/plugins/renamer/main.py index dd0ea46b..7ca29cba 100644 --- a/couchpotato/core/plugins/renamer/main.py +++ b/couchpotato/core/plugins/renamer/main.py @@ -62,11 +62,14 @@ class Renamer(Plugin): def scanView(self): params = getParams() + async = tryInt(params.get('async', None)) movie_folder = params.get('movie_folder', None) downloader = params.get('downloader', None) download_id = params.get('download_id', None) - fireEventAsync('renamer.scan', + fire_handle = fireEvent if not async else fireEventAsync + + fire_handle('renamer.scan', movie_folder = movie_folder, download_info = {'id': download_id, 'downloader': downloader} if download_id else None ) From b76397f98ed78d79a60ad32b9cc987771ecb100d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20K=C3=A5berg?= Date: Wed, 22 May 2013 11:45:19 +0200 Subject: [PATCH 09/14] addApiView explenation --- couchpotato/core/plugins/renamer/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/couchpotato/core/plugins/renamer/main.py b/couchpotato/core/plugins/renamer/main.py index 7ca29cba..d46c5c16 100644 --- a/couchpotato/core/plugins/renamer/main.py +++ b/couchpotato/core/plugins/renamer/main.py @@ -4,7 +4,7 @@ from couchpotato.core.event import addEvent, fireEvent, fireEventAsync from couchpotato.core.helpers.encoding import toUnicode, ss from couchpotato.core.helpers.request import getParams, jsonified from couchpotato.core.helpers.variable import getExt, mergeDicts, getTitle, \ - getImdb, link, symlink + getImdb, link, symlink, tryInt from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin from couchpotato.core.settings.model import Library, File, Profile, Release, \ @@ -25,10 +25,10 @@ class Renamer(Plugin): checking_snatched = False def __init__(self): - addApiView('renamer.scan', self.scanView, docs = { 'desc': 'For the renamer to check for new files to rename in a folder', 'params': { + 'async': {'desc': 'Optional: Set to 1 if you dont want to fire the renamer.scan asynchronous.'}, 'movie_folder': {'desc': 'Optional: The folder of the movie to scan. Keep empty for default renamer folder.'}, 'downloader' : {'desc': 'Optional: The downloader this movie has been downloaded with'}, 'download_id': {'desc': 'Optional: The downloader\'s nzb/torrent ID'}, @@ -706,4 +706,4 @@ Remove it if you want it to be renamed (again, or at least let it try again) return download_info def downloadIsTorrent(self, download_info): - return download_info and download_info.get('type') in ['torrent', 'torrent_magnet'] + return download_info and download_info.get('type') in ['torrent', 'torrent_magnet'] \ No newline at end of file From d9ce2906a060417cb93e139d059c58b2b5736466 Mon Sep 17 00:00:00 2001 From: Ruud Date: Sun, 26 May 2013 14:24:59 +0200 Subject: [PATCH 10/14] Fix line ending --- couchpotato/core/plugins/renamer/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/couchpotato/core/plugins/renamer/main.py b/couchpotato/core/plugins/renamer/main.py index d46c5c16..7ab9f450 100644 --- a/couchpotato/core/plugins/renamer/main.py +++ b/couchpotato/core/plugins/renamer/main.py @@ -706,4 +706,4 @@ Remove it if you want it to be renamed (again, or at least let it try again) return download_info def downloadIsTorrent(self, download_info): - return download_info and download_info.get('type') in ['torrent', 'torrent_magnet'] \ No newline at end of file + return download_info and download_info.get('type') in ['torrent', 'torrent_magnet'] From 2612b50d06a0d65f7c2553e3a5477108b82e683a Mon Sep 17 00:00:00 2001 From: Ronald Pompa Date: Wed, 22 May 2013 01:10:59 +0200 Subject: [PATCH 11/14] created hdbits torrent provider --- .../core/providers/torrent/hdbits/__init__.py | 37 ++++++++++ .../core/providers/torrent/hdbits/hdbits.py | 71 +++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 couchpotato/core/providers/torrent/hdbits/__init__.py create mode 100644 couchpotato/core/providers/torrent/hdbits/hdbits.py diff --git a/couchpotato/core/providers/torrent/hdbits/__init__.py b/couchpotato/core/providers/torrent/hdbits/__init__.py new file mode 100644 index 00000000..50b42120 --- /dev/null +++ b/couchpotato/core/providers/torrent/hdbits/__init__.py @@ -0,0 +1,37 @@ +from .main import HDBits + +def start(): + return HDBits() + +config = [{ + 'name': 'hdbits', + 'groups': [ + { + 'tab': 'searcher', + 'subtab': 'providers', + 'list': 'torrent_providers', + 'name': 'HDBits', + 'description': 'See HDBits', + 'options': [ + { + 'name': 'enabled', + 'type': 'enabler', + 'default': False, + }, + { + 'name': 'username', + 'default': '', + }, + { + 'name': 'password', + 'default': '', + 'type': 'password', + }, + { + 'name': 'passkey', + 'default': '', + }, + ], + }, + ], +}] diff --git a/couchpotato/core/providers/torrent/hdbits/hdbits.py b/couchpotato/core/providers/torrent/hdbits/hdbits.py new file mode 100644 index 00000000..8f4a8028 --- /dev/null +++ b/couchpotato/core/providers/torrent/hdbits/hdbits.py @@ -0,0 +1,71 @@ +from couchpotato.core.helpers.encoding import tryUrlencode +from couchpotato.core.helpers.variable import tryInt +from couchpotato.core.logger import CPLog +from couchpotato.core.providers.torrent.base import TorrentProvider +import traceback +from bs4 import BeautifulSoup +import requests + +log = CPLog(__name__) + +class HDBits(TorrentProvider): + + urls = { + 'test' : 'http://www.hdbits.org/', + 'login' : 'https://hdbits.org/login/dologin/', + 'detail' : 'http://www.hdbits.org/details.php?id=%s&source=browse', + 'search' : 'http://www.hdbits.org/json_search.php?imdb=%s', + 'download' : 'http://hdbits.org/download.php/%s.torrent?id=%s&passkey=%s&source=details.browse', + } + + http_time_between_calls = 1 #seconds + + def login(self): + try: + self.login_opener = requests.Session() + payload = {'uname': self.conf('username'), 'password': self.conf('password'), 'lol': self._getLoginSecret()} + self.login_opener.post(self.urls['login'], data=payload) + + return True + except: + log.error('Failed to login') + + return False + + def _search(self, movie, quality, results): + log.debug('Session response: %s' % (self.response.cookies)) + if not self.login_opener and not self.login(): + return + + imdb_id = movie['library']['identifier'] + search = self.login_opener.get(self.urls['search'] % (imdb_id)) + + j = search.json + try: + for result in j: + url = self.urls['download'] % (result['title'], result['id'], self.conf('passkey')) + detail = self.urls['detail'] % result['id'] + + results.append({ + 'id': result['id'], + 'name': result['title'], + 'url': url, + 'detail_url': detail, + 'size': self.parseSize(result['size']), + 'seeders': tryInt(result['seeder']), + 'leechers': tryInt(result['leecher']) + }) + + log.debug('Results: %s' % (results)) + + except: + log.error('Failed getting results from %s: %s', (self.getName(), traceback.format_exc())) + + def _getLoginSecret(self): + r = requests.get('https://hdbits.org/json_search.php') + bs = BeautifulSoup(r.text) + secret = bs.find('input', attrs = {'name': 'lol'})['value'] + + log.debug('Secret key: %s' % (secret)) + + return secret From f9471f9b9b9c8b950e073a6994ea0a0f51e9262a Mon Sep 17 00:00:00 2001 From: Ruud Date: Sun, 26 May 2013 15:16:55 +0200 Subject: [PATCH 12/14] HDBits cleanup --- .../core/providers/torrent/hdbits/__init__.py | 8 +++ .../core/providers/torrent/hdbits/hdbits.py | 71 ------------------- .../core/providers/torrent/hdbits/main.py | 55 ++++++++++++++ 3 files changed, 63 insertions(+), 71 deletions(-) delete mode 100644 couchpotato/core/providers/torrent/hdbits/hdbits.py create mode 100644 couchpotato/core/providers/torrent/hdbits/main.py diff --git a/couchpotato/core/providers/torrent/hdbits/__init__.py b/couchpotato/core/providers/torrent/hdbits/__init__.py index 50b42120..8a9fc80e 100644 --- a/couchpotato/core/providers/torrent/hdbits/__init__.py +++ b/couchpotato/core/providers/torrent/hdbits/__init__.py @@ -31,6 +31,14 @@ config = [{ 'name': 'passkey', 'default': '', }, + { + 'name': 'extra_score', + 'advanced': True, + 'label': 'Extra Score', + 'type': 'int', + 'default': 0, + 'description': 'Starting score for each release found via this provider.', + }, ], }, ], diff --git a/couchpotato/core/providers/torrent/hdbits/hdbits.py b/couchpotato/core/providers/torrent/hdbits/hdbits.py deleted file mode 100644 index 8f4a8028..00000000 --- a/couchpotato/core/providers/torrent/hdbits/hdbits.py +++ /dev/null @@ -1,71 +0,0 @@ -from couchpotato.core.helpers.encoding import tryUrlencode -from couchpotato.core.helpers.variable import tryInt -from couchpotato.core.logger import CPLog -from couchpotato.core.providers.torrent.base import TorrentProvider -import traceback -from bs4 import BeautifulSoup -import requests - -log = CPLog(__name__) - -class HDBits(TorrentProvider): - - urls = { - 'test' : 'http://www.hdbits.org/', - 'login' : 'https://hdbits.org/login/dologin/', - 'detail' : 'http://www.hdbits.org/details.php?id=%s&source=browse', - 'search' : 'http://www.hdbits.org/json_search.php?imdb=%s', - 'download' : 'http://hdbits.org/download.php/%s.torrent?id=%s&passkey=%s&source=details.browse', - } - - http_time_between_calls = 1 #seconds - - def login(self): - try: - self.login_opener = requests.Session() - payload = {'uname': self.conf('username'), 'password': self.conf('password'), 'lol': self._getLoginSecret()} - self.login_opener.post(self.urls['login'], data=payload) - - return True - except: - log.error('Failed to login') - - return False - - def _search(self, movie, quality, results): - log.debug('Session response: %s' % (self.response.cookies)) - if not self.login_opener and not self.login(): - return - - imdb_id = movie['library']['identifier'] - search = self.login_opener.get(self.urls['search'] % (imdb_id)) - - j = search.json - try: - for result in j: - url = self.urls['download'] % (result['title'], result['id'], self.conf('passkey')) - detail = self.urls['detail'] % result['id'] - - results.append({ - 'id': result['id'], - 'name': result['title'], - 'url': url, - 'detail_url': detail, - 'size': self.parseSize(result['size']), - 'seeders': tryInt(result['seeder']), - 'leechers': tryInt(result['leecher']) - }) - - log.debug('Results: %s' % (results)) - - except: - log.error('Failed getting results from %s: %s', (self.getName(), traceback.format_exc())) - - def _getLoginSecret(self): - r = requests.get('https://hdbits.org/json_search.php') - bs = BeautifulSoup(r.text) - secret = bs.find('input', attrs = {'name': 'lol'})['value'] - - log.debug('Secret key: %s' % (secret)) - - return secret diff --git a/couchpotato/core/providers/torrent/hdbits/main.py b/couchpotato/core/providers/torrent/hdbits/main.py new file mode 100644 index 00000000..218c3691 --- /dev/null +++ b/couchpotato/core/providers/torrent/hdbits/main.py @@ -0,0 +1,55 @@ +from bs4 import BeautifulSoup +from couchpotato.core.helpers.encoding import tryUrlencode +from couchpotato.core.helpers.variable import tryInt +from couchpotato.core.logger import CPLog +from couchpotato.core.providers.torrent.base import TorrentProvider +import traceback + +log = CPLog(__name__) + + +class HDBits(TorrentProvider): + + urls = { + 'test' : 'https://hdbits.org/', + 'login' : 'https://hdbits.org/login/doLogin/', + 'detail' : 'https://hdbits.org/details.php?id=%s&source=browse', + 'search' : 'https://hdbits.org/json_search.php?imdb=%s', + 'download' : 'https://hdbits.org/download.php/%s.torrent?id=%s&passkey=%s&source=details.browse', + } + + http_time_between_calls = 1 #seconds + + def _search(self, movie, quality, results): + + data = self.getJsonData(self.urls['search'] % movie['library']['identifier'], opener = self.login_opener) + + if data: + try: + for result in data: + results.append({ + 'id': result['id'], + 'name': result['title'], + 'url': self.urls['download'] % (result['title'], result['id'], self.conf('passkey')), + 'detail_url': self.urls['detail'] % result['id'], + 'size': self.parseSize(result['size']), + 'seeders': tryInt(result['seeder']), + 'leechers': tryInt(result['leecher']) + }) + + except: + log.error('Failed getting results from %s: %s', (self.getName(), traceback.format_exc())) + + def getLoginParams(self): + data = self.getHTMLData('https://hdbits.org/login') + bs = BeautifulSoup(data) + secret = bs.find('input', attrs = {'name': 'lol'})['value'] + + return tryUrlencode({ + 'uname': self.conf('username'), + 'password': self.conf('password'), + 'lol': secret + }) + + def loginSuccess(self, output): + return '/logout.php' in output.lower() From e065ead9b3f887012231d1527797995aaa50a2c5 Mon Sep 17 00:00:00 2001 From: Ruud Date: Sun, 26 May 2013 21:50:20 +0200 Subject: [PATCH 13/14] Api on subdomain --- .../core/providers/movie/couchpotatoapi/main.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/couchpotato/core/providers/movie/couchpotatoapi/main.py b/couchpotato/core/providers/movie/couchpotatoapi/main.py index 24a4be7b..4aba28ca 100644 --- a/couchpotato/core/providers/movie/couchpotatoapi/main.py +++ b/couchpotato/core/providers/movie/couchpotatoapi/main.py @@ -14,13 +14,13 @@ log = CPLog(__name__) class CouchPotatoApi(MovieProvider): urls = { - 'search': 'https://couchpota.to/api/search/%s/', - 'info': 'https://couchpota.to/api/info/%s/', - 'is_movie': 'https://couchpota.to/api/ismovie/%s/', - 'eta': 'https://couchpota.to/api/eta/%s/', - 'suggest': 'https://couchpota.to/api/suggest/', - 'updater': 'https://couchpota.to/api/updater/?%s', - 'messages': 'https://couchpota.to/api/messages/?%s', + 'search': 'https://api.couchpota.to/search/%s/', + 'info': 'https://api.couchpota.to/info/%s/', + 'is_movie': 'https://api.couchpota.to/ismovie/%s/', + 'eta': 'https://api.couchpota.to/eta/%s/', + 'suggest': 'https://api.couchpota.to/suggest/', + 'updater': 'https://api.couchpota.to/updater/?%s', + 'messages': 'https://api.couchpota.to/messages/?%s', } http_time_between_calls = 0 api_version = 1 From e1bc223de07fb0e61004dda10fe75dfa42d6a7e3 Mon Sep 17 00:00:00 2001 From: Ruud Date: Tue, 28 May 2013 21:13:15 +0200 Subject: [PATCH 14/14] Get year with default --- couchpotato/core/providers/movie/themoviedb/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/couchpotato/core/providers/movie/themoviedb/main.py b/couchpotato/core/providers/movie/themoviedb/main.py index 43eb22b3..f5fb8ef4 100644 --- a/couchpotato/core/providers/movie/themoviedb/main.py +++ b/couchpotato/core/providers/movie/themoviedb/main.py @@ -37,7 +37,7 @@ class TheMovieDb(MovieProvider): if raw: try: results = self.parseMovie(raw) - log.info('Found: %s', results['titles'][0] + ' (' + str(results['year']) + ')') + log.info('Found: %s', results['titles'][0] + ' (' + str(results.get('year', 0)) + ')') self.setCache(cache_key, results) return results @@ -81,7 +81,7 @@ class TheMovieDb(MovieProvider): if nr == limit: break - log.info('Found: %s', [result['titles'][0] + ' (' + str(result['year']) + ')' for result in results]) + log.info('Found: %s', [result['titles'][0] + ' (' + str(result.get('year', 0)) + ')' for result in results]) self.setCache(cache_key, results) return results