diff --git a/couchpotato/core/helpers/variable.py b/couchpotato/core/helpers/variable.py index d93c9417..77b110a4 100644 --- a/couchpotato/core/helpers/variable.py +++ b/couchpotato/core/helpers/variable.py @@ -1,3 +1,4 @@ +import collections from couchpotato.core.helpers.encoding import simplifyString, toSafeString, ss from couchpotato.core.logger import CPLog import hashlib @@ -163,6 +164,11 @@ def natsortKey(s): def natcmp(a, b): return cmp(natsortKey(a), natsortKey(b)) +def toIterable(value): + if isinstance(value, collections.Iterable): + return value + return [value] + def getTitle(library_dict): try: try: diff --git a/couchpotato/core/media/movie/searcher/main.py b/couchpotato/core/media/movie/searcher/main.py index 79d2ed84..3b552e1f 100644 --- a/couchpotato/core/media/movie/searcher/main.py +++ b/couchpotato/core/media/movie/searcher/main.py @@ -32,6 +32,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase): addEvent('movie.searcher.correct_movie', self.correctMovie) addEvent('movie.searcher.try_next_release', self.tryNextRelease) addEvent('movie.searcher.could_be_released', self.couldBeReleased) + addEvent('searcher.get_search_title', self.getSearchTitle) addApiView('movie.searcher.try_next', self.tryNextReleaseView, docs = { 'desc': 'Marks the snatched results as ignored and try the next best release', @@ -434,5 +435,9 @@ class MovieSearcher(SearcherBase, MovieTypeBase): log.error('Failed searching for next release: %s', traceback.format_exc()) return False + def getSearchTitle(self, media): + if media['type'] == 'movie': + return getTitle(media['library']) + class SearchSetupError(Exception): pass diff --git a/couchpotato/core/media/show/searcher/main.py b/couchpotato/core/media/show/searcher/main.py index 178c71d2..21c1d953 100644 --- a/couchpotato/core/media/show/searcher/main.py +++ b/couchpotato/core/media/show/searcher/main.py @@ -17,12 +17,27 @@ class ShowSearcher(Plugin): super(ShowSearcher, self).__init__() addEvent('show.searcher.single', self.single) + addEvent('searcher.get_search_title', self.getSearchTitle) - def _get_search_protocols(self): - try: - return fireEvent('searcher.protocols', single = True) - except SearchSetupError: - return None + def _lookupMedia(self, media): + db = get_session() + + media_library = db.query(Media).filter_by(id = media['id']).first().library + + show = None + season = None + episode = None + + if media['type'] == 'episode': + show = media_library.parent.parent + season = media_library.parent + episode = media_library + + if media['type'] == 'season': + show = media_library.parent + season = media_library + + return show, season, episode def single(self, media, search_protocols = None): if media['type'] == 'show': @@ -30,8 +45,10 @@ class ShowSearcher(Plugin): return # Find out search type - search_protocols = self._get_search_protocols() if not search_protocols else None - if search_protocols is None: + try: + if not search_protocols: + search_protocols = fireEvent('searcher.protocols', single = True) + except SearchSetupError: return done_status = fireEvent('status.get', 'done', single = True) @@ -54,18 +71,7 @@ class ShowSearcher(Plugin): #fireEvent('episode.delete', episode['id'], single = True) return - media_library = db.query(Media).filter_by(id = media['id']).first().library - - show = None - season = None - episode = None - if media['type'] == 'episode': - show = media_library.parent.parent - season = media_library.parent - episode = media_library - if media['type'] == 'season': - show = media_library.parent - season = media_library + show, season, episode = self._lookupMedia(media) fireEvent('notify.frontend', type = 'show.searcher.started.%s' % media['id'], data = True, message = 'Searching for "%s"' % default_title) @@ -96,3 +102,24 @@ class ShowSearcher(Plugin): results += protocol_results log.info('%d results found' % len(results)) + + def getSearchTitle(self, media): + if media['type'] not in ['season', 'episode']: + return None + + show, season, episode = self._lookupMedia(media) + + if show is None: + return None + + name = '' + if season is not None: + name = ' S%02d' % season.season_number + + if episode is not None: + name += 'E%02d' % episode.episode_number + + return ''.join([ + getTitle(show), + name + ]) diff --git a/couchpotato/core/providers/base.py b/couchpotato/core/providers/base.py index e6a9cb00..d652b384 100644 --- a/couchpotato/core/providers/base.py +++ b/couchpotato/core/providers/base.py @@ -1,6 +1,6 @@ from couchpotato.core.event import addEvent, fireEvent from couchpotato.core.helpers.variable import tryFloat, mergeDicts, md5, \ - possibleTitles, getTitle + possibleTitles, toIterable from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin from couchpotato.environment import Env @@ -114,7 +114,9 @@ class YarrProvider(Provider): def __init__(self): addEvent('provider.enabled_protocols', self.getEnabledProtocol) addEvent('provider.belongs_to', self.belongsTo) - addEvent('provider.search.%s.%s' % (self.protocol, self.type), self.search) + + for type in toIterable(self.type): + addEvent('provider.search.%s.%s' % (self.protocol, type), self.search) def getEnabledProtocol(self): if self.isEnabled(): @@ -183,7 +185,7 @@ class YarrProvider(Provider): return 'try_next' - def search(self, movie, quality): + def search(self, media, quality): if self.isDisabled(): return [] @@ -195,15 +197,15 @@ class YarrProvider(Provider): # Create result container imdb_results = hasattr(self, '_search') - results = ResultList(self, movie, quality, imdb_results = imdb_results) + results = ResultList(self, media, quality, imdb_results = imdb_results) # Do search based on imdb id if imdb_results: - self._search(movie, quality, results) + self._search(media, quality, results) # Search possible titles else: - for title in possibleTitles(getTitle(movie['library'])): - self._searchOnTitle(title, movie, quality, results) + for title in possibleTitles(fireEvent('searcher.get_search_title', media, single = True)): + self._searchOnTitle(title, media, quality, results) return results @@ -244,9 +246,16 @@ class YarrProvider(Provider): return 0 - def getCatId(self, identifier): + def getCatId(self, identifier, media_type = 'movie'): - for cats in self.cat_ids: + cat_ids = self.cat_ids + + if type(toIterable(cat_ids[0][0])[0]) is str: + for group_type, group_cat_ids in cat_ids: + if media_type in toIterable(group_type): + cat_ids = group_cat_ids + + for cats in cat_ids: ids, qualities = cats if identifier in qualities: return ids diff --git a/couchpotato/core/providers/torrent/iptorrents/main.py b/couchpotato/core/providers/torrent/iptorrents/main.py index d22f4bdd..37173753 100644 --- a/couchpotato/core/providers/torrent/iptorrents/main.py +++ b/couchpotato/core/providers/torrent/iptorrents/main.py @@ -10,6 +10,8 @@ log = CPLog(__name__) class IPTorrents(TorrentProvider): + type = ['movie', 'season', 'episode'] + urls = { 'test' : 'http://www.iptorrents.com/', 'base_url' : 'http://www.iptorrents.com', @@ -19,16 +21,26 @@ class IPTorrents(TorrentProvider): } cat_ids = [ - ([48], ['720p', '1080p', 'bd50']), - ([72], ['cam', 'ts', 'tc', 'r5', 'scr']), - ([7], ['dvdrip', 'brrip']), - ([6], ['dvdr']), + ('movie', [ + ([48], ['720p', '1080p', 'bd50']), + ([72], ['cam', 'ts', 'tc', 'r5', 'scr']), + ([7], ['dvdrip', 'brrip']), + ([6], ['dvdr']), + ]), + (['season'], [ + ([65], ['hdtv', '480p', '720p', '1080p']), + ]), + (['episode'], [ + ([5], ['720p', '1080p']), + ([78], ['480p']), + ([4, 79], ['hdtv']) + ]) ] http_time_between_calls = 1 #seconds cat_backup_id = None - def _searchOnTitle(self, title, movie, quality, results): + def _searchOnTitle(self, title, media, quality, results): freeleech = '' if not self.conf('freeleech') else '&free=on' @@ -36,7 +48,16 @@ class IPTorrents(TorrentProvider): current_page = 1 while current_page <= pages and not self.shuttingDown(): - url = self.urls['search'] % (self.getCatId(quality['identifier'])[0], freeleech, tryUrlencode('%s %s' % (title.replace(':', ''), movie['library']['year'])), current_page) + query = title.replace(':', '') + if media['type'] == 'movie': + query = '%s %s' % (title.replace(':', ''), media['library']['year']) + + cat_id = self.getCatId(quality['identifier'], media['type'])[0] + if not cat_id: + log.warning('Unable to find category for quality %s and media type %s', (quality['identifier'], media['type'])) + return + + url = self.urls['search'] % (cat_id, freeleech, tryUrlencode(query), current_page) data = self.getHTMLData(url, opener = self.login_opener) if data: