Extended providers to support multiple media types
- 'cat_ids' now support media type groups - 'type' extended to allow a list of support media types - Added 'searcher.get_search_title' to return a title for media to be used in searches.
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user