Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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)
            }
Ejemplo n.º 4
0
    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