Merge pull request #2523 from fuzeman/tv_searcher

[TV] Merge fixes, removed get_media_searcher_id event
This commit is contained in:
Ruud Burger
2013-11-25 07:38:08 -08:00
10 changed files with 27 additions and 135 deletions

View File

@@ -167,7 +167,7 @@ def natcmp(a, b):
return cmp(natsortKey(a), natsortKey(b))
def toIterable(value):
if isinstance(value, collections.Iterable):
if type(value) in [list, tuple]:
return value
return [value]

View File

@@ -24,8 +24,6 @@ class Searcher(SearcherBase):
addEvent('searcher.correct_year', self.correctYear)
addEvent('searcher.correct_name', self.correctName)
addEvent('searcher.correct_words', self.correctWords)
addEvent('searcher.try_download_result', self.tryDownloadResult)
addEvent('searcher.download', self.download)
addEvent('searcher.search', self.search)
addApiView('searcher.full_search', self.searchAllView, docs = {
@@ -52,116 +50,11 @@ class Searcher(SearcherBase):
progress = fireEvent('searcher.progress', merge = True)
return progress
def tryDownloadResult(self, results, media, quality_type, manual = False):
ignored_status, failed_status = fireEvent('status.get', ['ignored', 'failed'], single = True)
for rel in results:
if not quality_type.get('finish', False) and quality_type.get('wait_for', 0) > 0 and rel.get('age') <= quality_type.get('wait_for', 0):
log.info('Ignored, waiting %s days: %s', (quality_type.get('wait_for'), rel['name']))
continue
if rel['status_id'] in [ignored_status.get('id'), failed_status.get('id')]:
log.info('Ignored: %s', rel['name'])
continue
if rel['score'] <= 0:
log.info('Ignored, score to low: %s', rel['name'])
continue
downloaded = fireEvent('searcher.download', data = rel, media = media, manual = manual, single = True)
if downloaded is True:
return True
elif downloaded != 'try_next':
break
return False
def download(self, data, media, manual = False):
# TODO what is this for?
#if not data.get('protocol'):
# data['protocol'] = data['type']
# data['type'] = 'movie'
# Test to see if any downloaders are enabled for this type
downloader_enabled = fireEvent('download.enabled', manual, data, single = True)
if downloader_enabled:
snatched_status, active_status, done_status = fireEvent('status.get', ['snatched', 'active', 'done'], single = True)
# Download release to temp
filedata = None
if data.get('download') and (ismethod(data.get('download')) or isfunction(data.get('download'))):
filedata = data.get('download')(url = data.get('url'), nzb_id = data.get('id'))
if filedata == 'try_next':
return filedata
download_result = fireEvent('download', data = data, movie = media, manual = manual, filedata = filedata, single = True)
log.debug('Downloader result: %s', download_result)
if download_result:
try:
# Mark release as snatched
db = get_session()
rls = db.query(Release).filter_by(identifier = md5(data['url'])).first()
if rls:
renamer_enabled = Env.setting('enabled', 'renamer')
rls.status_id = done_status.get('id') if not renamer_enabled else snatched_status.get('id')
# Save download-id info if returned
if isinstance(download_result, dict):
for key in download_result:
rls_info = ReleaseInfo(
identifier = 'download_%s' % key,
value = toUnicode(download_result.get(key))
)
rls.info.append(rls_info)
db.commit()
log_movie = '%s (%s) in %s' % (getTitle(media['library']), media['library']['year'], rls.quality.label)
snatch_message = 'Snatched "%s": %s' % (data.get('name'), log_movie)
log.info(snatch_message)
fireEvent('%s.snatched' % data['type'], message = snatch_message, data = rls.to_dict())
# If renamer isn't used, mark media done
if not renamer_enabled:
try:
if media['status_id'] == active_status.get('id'):
for profile_type in media['profile']['types']:
if profile_type['quality_id'] == rls.quality.id and profile_type['finish']:
log.info('Renamer disabled, marking media as finished: %s', log_movie)
# Mark release done
rls.status_id = done_status.get('id')
rls.last_edit = int(time.time())
db.commit()
# Mark media done
mdia = db.query(Media).filter_by(id = media['id']).first()
mdia.status_id = done_status.get('id')
mdia.last_edit = int(time.time())
db.commit()
except:
log.error('Failed marking media finished, renamer disabled: %s', traceback.format_exc())
except:
log.error('Failed marking media finished: %s', traceback.format_exc())
return True
log.info('Tried to download, but none of the "%s" downloaders are enabled or gave an error', (data.get('protocol')))
return False
def search(self, protocols, media, quality):
results = []
# TODO could this be handled better? (removing the need for 'searcher.get_media_searcher_id')
searcher_id = fireEvent('searcher.get_media_searcher_id', media['type'], single = True)
for search_protocol in protocols:
protocol_results = fireEvent('provider.search.%s.%s' % (search_protocol, searcher_id), media, quality, merge = True)
protocol_results = fireEvent('provider.search.%s.%s' % (search_protocol, media['type']), media, quality, merge = True)
if protocol_results:
results += protocol_results

View File

@@ -31,7 +31,6 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
addEvent('movie.searcher.could_be_released', self.couldBeReleased)
addEvent('searcher.correct_release', self.correctRelease)
addEvent('searcher.get_search_title', self.getSearchTitle)
addEvent('searcher.get_media_searcher_id', self.getMediaSearcherId)
addApiView('movie.searcher.try_next', self.tryNextReleaseView, docs = {
'desc': 'Marks the snatched results as ignored and try the next best release',
@@ -348,9 +347,5 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
if media['type'] == 'movie':
return getTitle(media['library'])
def getMediaSearcherId(self, media_type):
if media_type == 'movie':
return 'movie'
class SearchSetupError(Exception):
pass

View File

@@ -37,7 +37,6 @@ class ShowSearcher(Plugin):
addEvent('searcher.get_media_identifier', self.getMediaIdentifier)
addEvent('searcher.get_media_root', self.getMediaRoot)
addEvent('searcher.get_media_searcher_id', self.getMediaSearcherId)
def single(self, media, search_protocols = None, manual = False):
if media['type'] == 'show':
@@ -109,7 +108,7 @@ class ShowSearcher(Plugin):
found_releases += fireEvent('release.create_from_search', results, media, quality_type, single = True)
# Try find a valid result and download it
if fireEvent('searcher.try_download_result', results, media, quality_type, manual, single = True):
if fireEvent('release.try_download_result', results, media, quality_type, manual, single = True):
ret = True
# Remove releases that aren't found anymore
@@ -209,6 +208,7 @@ class ShowSearcher(Plugin):
def correctMatch(self, chain, release, media, quality):
log.info("Checking if '%s' is valid", release['name'])
log.info2('Release parsed as: %s', chain.info)
if not fireEvent('matcher.correct_quality', chain, quality, self.quality_map, single = True):
log.info('Wrong: %s, quality does not match', release['name'])
@@ -224,6 +224,7 @@ class ShowSearcher(Plugin):
return True
# TODO move this somewhere else
def getMediaIdentifier(self, media_library):
if media_library['type'] not in ['show', 'season', 'episode']:
return None
@@ -253,6 +254,7 @@ class ShowSearcher(Plugin):
return identifier
# TODO move this somewhere else
def getMediaRoot(self, media):
if media['type'] not in ['show', 'season', 'episode']:
return None
@@ -264,10 +266,7 @@ class ShowSearcher(Plugin):
return show.to_dict()
def getMediaSearcherId(self, media_type):
if media_type in ['show', 'season', 'episode']:
return 'show'
# TODO move this somewhere else
def getMedia(self, media):
db = get_session()

View File

@@ -23,13 +23,13 @@ class Matcher(Plugin):
return self.caper.parse(release['name'])
def best(self, release, media, quality):
rel_info = fireEvent('matcher.parse', release, single = True)
match = fireEvent('matcher.parse', release, single = True)
if len(rel_info.chains) < 1:
if len(match.chains) < 1:
log.info2('Wrong: %s, unable to parse release name (no chains)', release['name'])
return False
for chain in rel_info.chains:
for chain in match.chains:
if fireEvent('searcher.correct_match', chain, release, media, quality, single = True):
return chain

View File

@@ -100,14 +100,14 @@ class Release(Plugin):
done_status, snatched_status = fireEvent('status.get', ['done', 'snatched'], single = True)
# Add movie
movie = db.query(Media).filter_by(library_id = group['library'].get('id')).first()
if not movie:
movie = Media(
media = db.query(Media).filter_by(library_id = group['library'].get('id')).first()
if not media:
media = Media(
library_id = group['library'].get('id'),
profile_id = 0,
status_id = done_status.get('id')
)
db.add(movie)
db.add(media)
db.commit()
# Add Release
@@ -120,7 +120,7 @@ class Release(Plugin):
if not rel:
rel = Relea(
identifier = identifier,
movie = movie,
media = media,
quality_id = group['meta_data']['quality'].get('id'),
status_id = done_status.get('id')
)
@@ -142,7 +142,7 @@ class Release(Plugin):
except:
log.debug('Failed to attach "%s" to release: %s', (added_files, traceback.format_exc()))
fireEvent('movie.restatus', movie.id)
fireEvent('movie.restatus', media.id)
return True
@@ -228,7 +228,7 @@ class Release(Plugin):
if item.get('protocol') != 'torrent_magnet':
item['download'] = provider.loginDownload if provider.urls.get('login') else provider.download
success = self.download(data = item, media = rel.movie.to_dict({
success = self.download(data = item, media = rel.media.to_dict({
'profile': {'types': {'quality': {}}},
'releases': {'status': {}, 'quality': {}},
'library': {'titles': {}, 'files':{}},
@@ -365,8 +365,7 @@ class Release(Plugin):
if not rls:
rls = Relea(
identifier = rel_identifier,
movie_id = media.get('id'),
#media_id = media.get('id'),
media_id = media.get('id'),
quality_id = quality_type.get('quality_id'),
status_id = available_status.get('id')
)

View File

@@ -118,7 +118,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():

View File

@@ -6,4 +6,4 @@ class MovieProvider(Provider):
class ShowProvider(Provider):
type = 'show'
type = ['season', 'episode']

View File

@@ -76,7 +76,8 @@ PATTERN_GROUPS = [
'HDTV',
'PDTV',
'DSR',
'DVDRiP'
'DVDRiP',
'WEBDL' # TODO support 'WEB.DL' tag
]),
(r'(?P<codec>%s)', [

View File

@@ -135,6 +135,9 @@ class MergeTransformer(Transformer):
def _merge(self, nodes, depth = 0):
Logr.debug(str('\t' * depth) + str(nodes))
if not len(nodes):
return []
top = nodes[0]
# Merge into top