Merge pull request #2523 from fuzeman/tv_searcher
[TV] Merge fixes, removed get_media_searcher_id event
This commit is contained in:
@@ -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]
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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')
|
||||
)
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -6,4 +6,4 @@ class MovieProvider(Provider):
|
||||
|
||||
|
||||
class ShowProvider(Provider):
|
||||
type = 'show'
|
||||
type = ['season', 'episode']
|
||||
|
||||
@@ -76,7 +76,8 @@ PATTERN_GROUPS = [
|
||||
'HDTV',
|
||||
'PDTV',
|
||||
'DSR',
|
||||
'DVDRiP'
|
||||
'DVDRiP',
|
||||
'WEBDL' # TODO support 'WEB.DL' tag
|
||||
]),
|
||||
|
||||
(r'(?P<codec>%s)', [
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user