def createFromSearch(self, search_results, media, quality_type): available_status = fireEvent('status.get', ['available'], single=True) try: db = get_session() found_releases = [] for rel in search_results: rel_identifier = md5(rel['url']) found_releases.append(rel_identifier) rls = db.query(Relea).filter_by( identifier=rel_identifier).first() if not rls: rls = Relea( identifier=rel_identifier, movie_id=media.get('id'), #media_id = media.get('id'), quality_id=quality_type.get('quality_id'), status_id=available_status.get('id')) db.add(rls) else: [db.delete(old_info) for old_info in rls.info] rls.last_edit = int(time.time()) db.commit() for info in rel: try: if not isinstance(rel[info], (str, unicode, int, long, float)): continue rls_info = ReleaseInfo(identifier=info, value=toUnicode(rel[info])) rls.info.append(rls_info) except InterfaceError: log.debug('Couldn\'t add %s to ReleaseInfo: %s', (info, traceback.format_exc())) db.commit() rel['status_id'] = rls.status_id return found_releases except: log.error('Failed: %s', traceback.format_exc()) db.rollback() finally: db.close() return []
def single(self, movie): done_status = fireEvent('status.get', 'done', single=True) if not movie['profile'] or movie['status_id'] == done_status.get('id'): log.debug( 'Movie doesn\'t have a profile or already done, assuming in manage tab.' ) return db = get_session() pre_releases = fireEvent('quality.pre_releases', single=True) release_dates = fireEvent('library.update_release_date', identifier=movie['library']['identifier'], merge=True) available_status = fireEvent('status.get', 'available', single=True) ignored_status = fireEvent('status.get', 'ignored', single=True) default_title = getTitle(movie['library']) if not default_title: log.error( 'No proper info found for movie, removing it from library to cause it from having more issues.' ) fireEvent('movie.delete', movie['id'], single=True) return fireEvent('notify.frontend', type='searcher.started.%s' % movie['id'], data=True, message='Searching for "%s"' % default_title) ret = False for quality_type in movie['profile']['types']: if not self.couldBeReleased(quality_type['quality']['identifier'], release_dates, pre_releases): log.info( 'Too early to search for %s, %s', (quality_type['quality']['identifier'], default_title)) continue has_better_quality = 0 # See if better quality is available for release in movie['releases']: if release['quality']['order'] <= quality_type['quality'][ 'order'] and release['status_id'] not in [ available_status.get('id'), ignored_status.get('id') ]: has_better_quality += 1 # Don't search for quality lower then already available. if has_better_quality is 0: log.info('Search for %s in %s', (default_title, quality_type['quality']['label'])) quality = fireEvent( 'quality.single', identifier=quality_type['quality']['identifier'], single=True) results = fireEvent('yarr.search', movie, quality, merge=True) sorted_results = sorted(results, key=lambda k: k['score'], reverse=True) if len(sorted_results) == 0: log.debug( 'Nothing found for %s in %s', (default_title, quality_type['quality']['label'])) download_preference = self.conf('preferred_method') if download_preference != 'both': sorted_results = sorted( sorted_results, key=lambda k: k['type'], reverse=(download_preference == 'torrent')) # Check if movie isn't deleted while searching if not db.query(Movie).filter_by(id=movie.get('id')).first(): break # Add them to this movie releases list for nzb in sorted_results: rls = db.query(Release).filter_by( identifier=md5(nzb['url'])).first() if not rls: rls = Release( identifier=md5(nzb['url']), movie_id=movie.get('id'), quality_id=quality_type.get('quality_id'), status_id=available_status.get('id')) db.add(rls) db.commit() else: [db.delete(info) for info in rls.info] db.commit() for info in nzb: try: if not isinstance( nzb[info], (str, unicode, int, long, float)): continue rls_info = ReleaseInfo(identifier=info, value=toUnicode(nzb[info])) rls.info.append(rls_info) db.commit() except InterfaceError: log.debug('Couldn\'t add %s to ReleaseInfo: %s', (info, traceback.format_exc())) nzb['status_id'] = rls.status_id for nzb in sorted_results: if nzb['status_id'] == ignored_status.get('id'): log.info('Ignored: %s', nzb['name']) continue if nzb['score'] <= 0: log.info('Ignored, score to low: %s', nzb['name']) continue downloaded = self.download(data=nzb, movie=movie) if downloaded is True: ret = True break elif downloaded != 'try_next': break else: log.info( 'Better quality (%s) already available or snatched for %s', (quality_type['quality']['label'], default_title)) fireEvent('movie.restatus', movie['id']) break # Break if CP wants to shut down if self.shuttingDown() or ret: break fireEvent('notify.frontend', type='searcher.ended.%s' % movie['id'], data=True) #db.close() return ret
def download(self, data, media, manual=False): 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, done_status, active_status = fireEvent( 'status.get', ['snatched', 'done', 'active'], 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(Relea).filter_by( identifier=md5(data['url'])).first() if rls: renamer_enabled = Env.setting('enabled', 'renamer') # 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 self.updateStatus( rls.id, status=done_status) # 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()) else: self.updateStatus(rls.id, status=snatched_status) 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 single(self, movie): available_status = fireEvent('status.get', 'available', single=True) for type in movie['profile']['types']: has_better_quality = 0 default_title = movie['library']['titles'][0]['title'] # See if beter quality is available for release in movie['releases']: if release['quality']['order'] <= type['quality'][ 'order'] and release[ 'status_id'] is not available_status.get('id'): has_better_quality += 1 # Don't search for quality lower then already available. if has_better_quality is 0: log.info('Search for %s in %s' % (default_title, type['quality']['label'])) results = fireEvent('provider.yarr.search', movie, type['quality'], merge=True) sorted_results = sorted(results, key=lambda k: k['score'], reverse=True) # Add them to this movie releases list for nzb in sorted_results: db = get_session() rls = db.query(Release).filter_by( identifier=md5(nzb['url'])).first() if not rls: rls = Release(identifier=md5(nzb['url']), movie_id=movie.get('id'), quality_id=type.get('quality_id'), status_id=available_status.get('id')) db.add(rls) db.commit() for info in nzb: try: if not isinstance(nzb[info], (str, unicode, int, long)): continue rls_info = ReleaseInfo(identifier=info, value=nzb[info]) rls.info.append(rls_info) db.commit() except InterfaceError: log.debug( 'Couldn\'t add %s to ReleaseInfo: %s' % (info, traceback.format_exc())) for nzb in sorted_results: return self.download(data=nzb, movie=movie) else: log.info( 'Better quality (%s) already available or snatched for %s' % (type['quality']['label'], default_title)) break # Break if CP wants to shut down if self.shuttingDown(): break return False
def single(self, movie, search_protocols=None, manual=False): # Find out search type try: if not search_protocols: search_protocols = fireEvent('searcher.protocols', single=True) except SearchSetupError: return done_status = fireEvent('status.get', 'done', single=True) if not movie['profile'] or (movie['status_id'] == done_status.get('id') and not manual): log.debug( 'Movie doesn\'t have a profile or already done, assuming in manage tab.' ) return db = get_session() pre_releases = fireEvent('quality.pre_releases', single=True) release_dates = fireEvent('library.update.movie.release_date', identifier=movie['library']['identifier'], merge=True) available_status, ignored_status, failed_status = fireEvent( 'status.get', ['available', 'ignored', 'failed'], single=True) found_releases = [] too_early_to_search = [] default_title = getTitle(movie['library']) if not default_title: log.error( 'No proper info found for movie, removing it from library to cause it from having more issues.' ) fireEvent('movie.delete', movie['id'], single=True) return fireEvent('notify.frontend', type='movie.searcher.started.%s' % movie['id'], data=True, message='Searching for "%s"' % default_title) ret = False for quality_type in movie['profile']['types']: if not self.conf('always_search') and not self.couldBeReleased( quality_type['quality']['identifier'] in pre_releases, release_dates, movie['library']['year']): too_early_to_search.append( quality_type['quality']['identifier']) continue has_better_quality = 0 # See if better quality is available for release in movie['releases']: if release['quality']['order'] <= quality_type['quality'][ 'order'] and release['status_id'] not in [ available_status.get('id'), ignored_status.get('id'), failed_status.get('id') ]: has_better_quality += 1 # Don't search for quality lower then already available. if has_better_quality is 0: log.info('Search for %s in %s', (default_title, quality_type['quality']['label'])) quality = fireEvent( 'quality.single', identifier=quality_type['quality']['identifier'], single=True) results = [] for search_protocol in search_protocols: protocol_results = fireEvent('provider.search.%s.movie' % search_protocol, movie, quality, merge=True) if protocol_results: results += protocol_results sorted_results = sorted(results, key=lambda k: k['score'], reverse=True) if len(sorted_results) == 0: log.debug( 'Nothing found for %s in %s', (default_title, quality_type['quality']['label'])) download_preference = self.conf('preferred_method', section='searcher') if download_preference != 'both': sorted_results = sorted( sorted_results, key=lambda k: k['protocol'][:3], reverse=(download_preference == 'torrent')) # Check if movie isn't deleted while searching if not db.query(Media).filter_by(id=movie.get('id')).first(): break # Add them to this movie releases list for nzb in sorted_results: nzb_identifier = md5(nzb['url']) found_releases.append(nzb_identifier) rls = db.query(Release).filter_by( identifier=nzb_identifier).first() if not rls: rls = Release( identifier=nzb_identifier, movie_id=movie.get('id'), quality_id=quality_type.get('quality_id'), status_id=available_status.get('id')) db.add(rls) else: [db.delete(old_info) for old_info in rls.info] rls.last_edit = int(time.time()) db.commit() for info in nzb: try: if not isinstance( nzb[info], (str, unicode, int, long, float)): continue rls_info = ReleaseInfo(identifier=info, value=toUnicode(nzb[info])) rls.info.append(rls_info) except InterfaceError: log.debug('Couldn\'t add %s to ReleaseInfo: %s', (info, traceback.format_exc())) db.commit() nzb['status_id'] = rls.status_id for nzb in sorted_results: if not quality_type.get( 'finish', False) and quality_type.get( 'wait_for', 0) > 0 and nzb.get('age') <= quality_type.get( 'wait_for', 0): log.info('Ignored, waiting %s days: %s', (quality_type.get('wait_for'), nzb['name'])) continue if nzb['status_id'] in [ ignored_status.get('id'), failed_status.get('id') ]: log.info('Ignored: %s', nzb['name']) continue if nzb['score'] <= 0: log.info('Ignored, score to low: %s', nzb['name']) continue downloaded = fireEvent('searcher.download', data=nzb, movie=movie, manual=manual, single=True) if downloaded is True: ret = True break elif downloaded != 'try_next': break # Remove releases that aren't found anymore for release in movie.get('releases', []): if release.get('status_id') == available_status.get( 'id') and release.get( 'identifier') not in found_releases: fireEvent('release.delete', release.get('id'), single=True) else: log.info( 'Better quality (%s) already available or snatched for %s', (quality_type['quality']['label'], default_title)) fireEvent('movie.restatus', movie['id']) break # Break if CP wants to shut down if self.shuttingDown() or ret: break if len(too_early_to_search) > 0: log.info2('Too early to search for %s, %s', (too_early_to_search, default_title)) fireEvent('notify.frontend', type='movie.searcher.ended.%s' % movie['id'], data=True) return ret