def _t_search_grab(movie): ''' Run verify/search/snatch chain movie (dict): movie to run search for Meant to be executed *IN ITS OWN THREAD* after adding a movie from user-input (ie api, search) so the main thread is not tied up. Does not return ''' logging.info('Executing automatic search/grab for {}.'.format( movie['title'])) imdbid = movie['imdbid'] title = movie['title'] year = movie['year'] quality = movie['quality'] if core.CONFIG['Search']['verifyreleases'] == 'predb': movie = predb.backlog_search(movie) if not Manage.verify(movie): return if core.CONFIG['Search']['searchafteradd'] and search( imdbid, title, year, quality) and core.CONFIG['Search']['autograb']: best_release = snatcher.get_best_release(movie) if best_release: snatcher.download(best_release)
def check_torrents(): for client, config in core.CONFIG['Downloader']['Torrent'].items(): if config['enabled']: progress = {} now = int(datetime.datetime.timestamp(datetime.datetime.now())) if config.get('removestalledfor'): progress = core.sql.get_download_progress(client) downloader = getattr(downloaders, client) for torrent in downloader.get_torrents_status(stalled_for=config.get('removestalledfor'), progress=progress): progress_update = None if torrent['status'] == 'finished' and config.get('removetorrents'): logging.info('Check if we know finished torrent {} and is postprocessed ({})'.format(torrent['hash'], torrent['name'])) if core.sql.row_exists('MARKEDRESULTS', guid=str(torrent['hash']), status='Finished'): logging.info('Yes, now we remove the torrent') downloader.cancel_download(torrent['hash']) else: logging.info('No, did not find the torrent as finished') if torrent['status'] == 'stalled': logging.info('Check if we know torrent {} and is snatched ({})'.format(torrent['hash'], torrent['name'])) if torrent['hash'] in progress: result = core.sql.get_single_search_result('downloadid', str(torrent['hash'])) movie = core.sql.get_movie_details('imdbid', result['imdbid']) best_release = snatcher.get_best_release(movie, ignore_guid=result['guid']) # if top score is already downloading returns {}, stalled torrent will be deleted and nothing will be snatched if best_release is not None: logging.info('Torrent {} is stalled, download will be cancelled and marked as Bad'.format(torrent['hash'])) Manage.searchresults(result['guid'], 'Bad') Manage.markedresults(result['guid'], 'Bad', imdbid=result['imdbid']) downloader.cancel_download(torrent['hash']) if best_release: logging.info("Snatch {} {}".format(best_release['guid'], best_release['title'])) snatcher.download(best_release) elif config.get('removestalledfor') and 'progress' in torrent and torrent['hash'] in progress: if torrent['status'] == 'downloading': if progress[torrent['hash']]['progress'] is None or torrent['progress'] != progress[torrent['hash']]['progress']: progress_update = {'download_progress': torrent['progress'], 'download_time': now} elif progress[torrent['hash']]['progress']: progress_update = {'download_progress': None, 'download_time': None} if progress_update and core.sql.row_exists('SEARCHRESULTS', downloadid=str(torrent['hash']), status='Snatched'): core.sql.update_multiple_values('SEARCHRESULTS', progress_update, 'downloadid', torrent['hash']) return
def manual_download(self, params): ''' Sends search result to downloader params(dict): params passed in request url, must include guid and kind (torrent, magnet, nzb) Returns dict ajax-style response ''' guid = params.get('guid') kind = params.get('kind') if not guid: return {'response': False, 'error': 'no guid supplied'} if kind not in ('torrent', 'magnet', 'nzb'): return {'response': False, 'error': 'no guid supplied'} torrent_enabled = core.CONFIG['Downloader']['Sources'][ 'torrentenabled'] usenet_enabled = core.CONFIG['Downloader']['Sources']['usenetenabled'] if kind == 'nzb' and not usenet_enabled: return { 'response': False, 'error': 'Link is NZB but no Usent client is enabled.' } elif kind in ('torrent', 'magnet') and not torrent_enabled: return { 'response': False, 'error': 'Link is {} but no Torrent client is enabled.'.format(kind) } data = dict(core.sql.get_single_search_result('guid', guid)) if data: data['year'] = core.sql.get_movie_details('imdbid', data['imdbid'])['year'] return snatcher.download(data) else: return { 'response': False, 'error': 'Unable to read {} details from database'.format(kind) }
def failed(self, data): ''' Post-process a failed download data (dict): of gathered data from downloader and localdb/tmdb In SEARCHRESULTS marks guid as Bad In MARKEDRESULTS: Creates or updates entry for guid and optional guid2 with status=Bad Updates MOVIES status If Clean Up is enabled will delete path and contents. If Auto Grab is enabled will grab next best release. Returns dict of post-processing results ''' config = core.CONFIG['Postprocessing'] # dict we will json.dump and send back to downloader result = {} result['status'] = 'finished' result['data'] = data result['tasks'] = {} # mark guid in both results tables logging.info('Marking guid as Bad.') guid_result = {'url': data['guid']} if data['guid']: # guid can be empty string if Manage.searchresults(data['guid'], 'Bad'): guid_result['update_SEARCHRESULTS'] = True else: guid_result['update_SEARCHRESULTS'] = False if Manage.markedresults(data['guid'], 'Bad', imdbid=data['imdbid']): guid_result['update_MARKEDRESULTS'] = True else: guid_result['update_MARKEDRESULTS'] = False # create result entry for guid result['tasks']['guid'] = guid_result # if we have a guid2, do it all again if 'guid2' in data.keys(): logging.info('Marking guid2 as Bad.') guid2_result = {'url': data['guid2']} if Manage.searchresults(data['guid2'], 'Bad'): guid2_result['update SEARCHRESULTS'] = True else: guid2_result['update SEARCHRESULTS'] = False if Manage.markedresults( data['guid2'], 'Bad', imdbid=data['imdbid'], ): guid2_result['update_MARKEDRESULTS'] = True else: guid2_result['update_MARKEDRESULTS'] = False # create result entry for guid2 result['tasks']['guid2'] = guid2_result # set movie status if data['imdbid']: logging.info('Setting MOVIE status.') r = Manage.movie_status(data['imdbid']) else: logging.info( 'Imdbid not supplied or found, unable to update Movie status.') r = '' result['tasks']['update_movie_status'] = r # delete failed files if config['cleanupfailed']: result['tasks']['cleanup'] = { 'enabled': True, 'path': data['path'] } logging.info('Deleting leftover files from failed download.') if self.cleanup(data['path']) is True: result['tasks']['cleanup']['response'] = True else: result['tasks']['cleanup']['response'] = False else: result['tasks']['cleanup'] = {'enabled': False} # grab the next best release if core.CONFIG['Search']['autograb']: result['tasks']['autograb'] = {'enabled': True} logging.info('Grabbing the next best release.') if data.get('imdbid') and data.get('quality'): best_release = snatcher.get_best_release(data) if best_release and snatcher.download(best_release): r = True else: r = False else: r = False result['tasks']['autograb']['response'] = r else: result['tasks']['autograb'] = {'enabled': False} # all done! result['status'] = 'finished' return result