示例#1
0
    def saveAddShowDefaults(default_status,
                            allowed_qualities,
                            preferred_qualities,
                            default_season_folders,
                            subtitles=False,
                            anime=False,
                            scene=False,
                            default_status_after=WANTED):

        allowed_qualities = [_.strip() for _ in allowed_qualities.split(',')
                             ] if allowed_qualities else []
        preferred_qualities = [
            _.strip() for _ in preferred_qualities.split(',')
        ] if preferred_qualities else []

        new_quality = Quality.combine_qualities(
            [int(quality) for quality in allowed_qualities],
            [int(quality) for quality in preferred_qualities])

        app.STATUS_DEFAULT = int(default_status)
        app.STATUS_DEFAULT_AFTER = int(default_status_after)
        app.QUALITY_DEFAULT = int(new_quality)

        app.SEASON_FOLDERS_DEFAULT = config.checkbox_to_value(
            default_season_folders)
        app.SUBTITLES_DEFAULT = config.checkbox_to_value(subtitles)

        app.ANIME_DEFAULT = config.checkbox_to_value(anime)

        app.SCENE_DEFAULT = config.checkbox_to_value(scene)
        app.instance.save_config()
示例#2
0
    def saveAddShowDefaults(default_status, allowed_qualities, preferred_qualities, default_season_folders,
                            subtitles=False, anime=False, scene=False, default_status_after=WANTED):

        allowed_qualities = [_.strip() for _ in allowed_qualities.split(',')] if allowed_qualities else []
        preferred_qualities = [_.strip() for _ in preferred_qualities.split(',')] if preferred_qualities else []

        new_quality = Quality.combine_qualities([int(quality) for quality in allowed_qualities],
                                                [int(quality) for quality in preferred_qualities])

        app.STATUS_DEFAULT = int(default_status)
        app.STATUS_DEFAULT_AFTER = int(default_status_after)
        app.QUALITY_DEFAULT = int(new_quality)

        app.SEASON_FOLDERS_DEFAULT = config.checkbox_to_value(default_season_folders)
        app.SUBTITLES_DEFAULT = config.checkbox_to_value(subtitles)

        app.ANIME_DEFAULT = config.checkbox_to_value(anime)

        app.SCENE_DEFAULT = config.checkbox_to_value(scene)
        app.instance.save_config()
示例#3
0
    def addNewShow(self,
                   whichSeries=None,
                   indexer_lang=None,
                   rootDir=None,
                   defaultStatus=None,
                   quality_preset=None,
                   allowed_qualities=None,
                   preferred_qualities=None,
                   season_folders=None,
                   subtitles=None,
                   fullShowPath=None,
                   other_shows=None,
                   skipShow=None,
                   providedIndexer=None,
                   anime=None,
                   scene=None,
                   blacklist=None,
                   whitelist=None,
                   defaultStatusAfter=None):
        """
        Receive tvdb id, dir, and other options and create a show from them. If extra show dirs are
        provided then it forwards back to newShow, if not it goes to /home.
        """
        provided_indexer = providedIndexer

        indexer_lang = app.INDEXER_DEFAULT_LANGUAGE if not indexer_lang else indexer_lang

        # grab our list of other dirs if given
        if not other_shows:
            other_shows = []
        elif not isinstance(other_shows, list):
            other_shows = [other_shows]

        def finishAddShow():
            # if there are no extra shows then go home
            if not other_shows:
                return json_redirect('/home/')

            # go to add the next show
            return json_redirect(
                '/addShows/newShow/',
                [('show_to_add' if not i else 'other_shows', cur_dir)
                 for i, cur_dir in enumerate(other_shows)])

        # if we're skipping then behave accordingly
        if skipShow:
            return finishAddShow()

        # sanity check on our inputs
        if (not rootDir and not fullShowPath) or not whichSeries:
            return 'Missing params, no Indexer ID or folder:{series!r} and {root!r}/{path!r}'.format(
                series=whichSeries, root=rootDir, path=fullShowPath)

        # figure out what show we're adding and where
        series_pieces = whichSeries.split('|')
        if (whichSeries and rootDir) or (whichSeries and fullShowPath
                                         and len(series_pieces) > 1):
            if len(series_pieces) < 6:
                logger.log(
                    u'Unable to add show due to show selection. Not enough arguments: %s'
                    % (repr(series_pieces)), logger.ERROR)
                ui.notifications.error(
                    'Unknown error. Unable to add show due to problem with show selection.'
                )
                return json_redirect('/addShows/existingShows/')

            indexer = int(series_pieces[1])
            indexer_id = int(series_pieces[3])
            show_name = series_pieces[4]
        else:
            # if no indexer was provided use the default indexer set in General settings
            if not provided_indexer:
                provided_indexer = app.INDEXER_DEFAULT

            indexer = int(provided_indexer)
            indexer_id = int(whichSeries)
            show_name = os.path.basename(os.path.normpath(fullShowPath))

        # use the whole path if it's given, or else append the show name to the root dir to get the full show path
        if fullShowPath:
            show_dir = os.path.normpath(fullShowPath)
        else:
            show_dir = os.path.join(rootDir, sanitize_filename(show_name))

        # blanket policy - if the dir exists you should have used 'add existing show' numbnuts
        if os.path.isdir(show_dir) and not fullShowPath:
            ui.notifications.error(
                'Unable to add show',
                'Folder {path} exists already'.format(path=show_dir))
            return json_redirect('/addShows/existingShows/')

        # don't create show dir if config says not to
        if app.ADD_SHOWS_WO_DIR:
            logger.log(
                u'Skipping initial creation of {path} due to config.ini setting'
                .format(path=show_dir))
        else:
            dir_exists = helpers.make_dir(show_dir)
            if not dir_exists:
                logger.log(
                    u'Unable to create the folder {path}, can\'t add the show'.
                    format(path=show_dir), logger.ERROR)
                ui.notifications.error(
                    'Unable to add show',
                    'Unable to create the folder {path}, can\'t add the show'.
                    format(path=show_dir))
                # Don't redirect to default page because user wants to see the new show
                return json_redirect('/home/')
            else:
                helpers.chmod_as_parent(show_dir)

        # prepare the inputs for passing along
        scene = config.checkbox_to_value(scene)
        anime = config.checkbox_to_value(anime)
        season_folders = config.checkbox_to_value(season_folders)
        subtitles = config.checkbox_to_value(subtitles)

        if whitelist:
            whitelist = short_group_names(whitelist)
        if blacklist:
            blacklist = short_group_names(blacklist)

        if not allowed_qualities:
            allowed_qualities = []
        if not preferred_qualities or try_int(quality_preset, None):
            preferred_qualities = []
        if not isinstance(allowed_qualities, list):
            allowed_qualities = [allowed_qualities]
        if not isinstance(preferred_qualities, list):
            preferred_qualities = [preferred_qualities]
        new_quality = Quality.combine_qualities(
            [int(q) for q in allowed_qualities],
            [int(q) for q in preferred_qualities])

        # add the show
        app.show_queue_scheduler.action.addShow(indexer, indexer_id, show_dir,
                                                int(defaultStatus),
                                                new_quality, season_folders,
                                                indexer_lang, subtitles, anime,
                                                scene, None, blacklist,
                                                whitelist,
                                                int(defaultStatusAfter))
        ui.notifications.message(
            'Show added',
            'Adding the specified show into {path}'.format(path=show_dir))

        return finishAddShow()
示例#4
0
    def addShowByID(self,
                    indexername=None,
                    seriesid=None,
                    show_name=None,
                    which_series=None,
                    indexer_lang=None,
                    root_dir=None,
                    default_status=None,
                    quality_preset=None,
                    any_qualities=None,
                    best_qualities=None,
                    season_folders=None,
                    subtitles=None,
                    full_show_path=None,
                    other_shows=None,
                    skip_show=None,
                    provided_indexer=None,
                    anime=None,
                    scene=None,
                    blacklist=None,
                    whitelist=None,
                    default_status_after=None,
                    configure_show_options=False):
        """
        Add's a new show with provided show options by indexer_id.
        Currently only TVDB and IMDB id's supported.
        """
        series_id = seriesid
        if indexername != 'tvdb':
            series_id = helpers.get_tvdb_from_id(seriesid, indexername.upper())
            if not series_id:
                logger.log(u'Unable to to find tvdb ID to add %s' % show_name)
                ui.notifications.error(
                    'Unable to add %s' % show_name,
                    'Could not add %s.  We were unable to locate the tvdb id at this time.'
                    % show_name)
                return

        if Show.find_by_id(app.showList, INDEXER_TVDBV2, series_id):
            return

        # Sanitize the parameter allowed_qualities and preferred_qualities. As these would normally be passed as lists
        if any_qualities:
            any_qualities = any_qualities.split(',')
        else:
            any_qualities = []

        if best_qualities:
            best_qualities = best_qualities.split(',')
        else:
            best_qualities = []

        # If configure_show_options is enabled let's use the provided settings
        configure_show_options = config.checkbox_to_value(
            configure_show_options)

        if configure_show_options:
            # prepare the inputs for passing along
            scene = config.checkbox_to_value(scene)
            anime = config.checkbox_to_value(anime)
            season_folders = config.checkbox_to_value(season_folders)
            subtitles = config.checkbox_to_value(subtitles)

            if whitelist:
                whitelist = short_group_names(whitelist)
            if blacklist:
                blacklist = short_group_names(blacklist)

            if not any_qualities:
                any_qualities = []

            if not best_qualities or try_int(quality_preset, None):
                best_qualities = []

            if not isinstance(any_qualities, list):
                any_qualities = [any_qualities]

            if not isinstance(best_qualities, list):
                best_qualities = [best_qualities]

            quality = Quality.combine_qualities(
                [int(q) for q in any_qualities],
                [int(q) for q in best_qualities])

            location = root_dir

        else:
            default_status = app.STATUS_DEFAULT
            quality = app.QUALITY_DEFAULT
            season_folders = app.SEASON_FOLDERS_DEFAULT
            subtitles = app.SUBTITLES_DEFAULT
            anime = app.ANIME_DEFAULT
            scene = app.SCENE_DEFAULT
            default_status_after = app.STATUS_DEFAULT_AFTER

            if app.ROOT_DIRS:
                root_dirs = app.ROOT_DIRS
                location = root_dirs[int(root_dirs[0]) + 1]
            else:
                location = None

        if not location:
            logger.log(
                u'There was an error creating the show, '
                u'no root directory setting found', logger.WARNING)
            return 'No root directories setup, please go back and add one.'

        show_name = get_showname_from_indexer(INDEXER_TVDBV2, series_id)
        show_dir = None

        # add the show
        app.show_queue_scheduler.action.addShow(INDEXER_TVDBV2,
                                                int(series_id),
                                                show_dir,
                                                int(default_status),
                                                quality,
                                                season_folders,
                                                indexer_lang,
                                                subtitles,
                                                anime,
                                                scene,
                                                None,
                                                blacklist,
                                                whitelist,
                                                int(default_status_after),
                                                root_dir=location)

        ui.notifications.message(
            'Show added', 'Adding the specified show {0}'.format(show_name))

        # done adding show
        return self.redirect('/home/')
示例#5
0
@pytest.mark.parametrize(
    'p',
    [
        {  # p0: Downloaded a quality not in quality system : yes
            'status':
            DOWNLOADED,
            'quality':
            Quality.SDTV,
            'show_obj':
            TestTVShow(
                indexer=1,
                indexer_id=1,
                lang='',
                quality=Quality.combine_qualities(
                    [Quality.HDTV],  # Allowed Qualities
                    [Quality.HDWEBDL])),  # Preferred Qualities
            'manually_searched':
            False,
            'expected':
            True
        },
        {  # p1: Current status is SKIPPED: no
            'status':
            SKIPPED,
            'quality':
            Quality.NA,
            'show_obj':
            TestTVShow(
                indexer=1,
                indexer_id=1,
示例#6
0
    def addNewShow(self, whichSeries=None, indexer_lang=None, rootDir=None, defaultStatus=None, quality_preset=None,
                   allowed_qualities=None, preferred_qualities=None, season_folders=None, subtitles=None,
                   fullShowPath=None, other_shows=None, skipShow=None, providedIndexer=None, anime=None,
                   scene=None, blacklist=None, whitelist=None, defaultStatusAfter=None):
        """
        Receive tvdb id, dir, and other options and create a show from them. If extra show dirs are
        provided then it forwards back to newShow, if not it goes to /home.
        """
        provided_indexer = providedIndexer

        indexer_lang = app.INDEXER_DEFAULT_LANGUAGE if not indexer_lang else indexer_lang

        # grab our list of other dirs if given
        if not other_shows:
            other_shows = []
        elif not isinstance(other_shows, list):
            other_shows = [other_shows]

        other_shows = decode_shows(other_shows)

        def finishAddShow():
            # if there are no extra shows then go home
            if not other_shows:
                return json_response(redirect='/home/')

            # go to add the next show
            return json_response(
                redirect='/addShows/newShow/',
                params=[
                    ('show_to_add' if not i else 'other_shows', cur_dir)
                    for i, cur_dir in enumerate(other_shows)
                ]
            )

        # if we're skipping then behave accordingly
        if skipShow:
            return finishAddShow()

        # sanity check on our inputs
        if (not rootDir and not fullShowPath) or not whichSeries:
            error_msg = 'Missing params, no Indexer ID or folder: {series!r} and {root!r}/{path!r}'.format(
                series=whichSeries, root=rootDir, path=fullShowPath)
            log.error(error_msg)
            return json_response(
                result=False,
                message=error_msg,
                redirect='/home/'
            )

        # figure out what show we're adding and where
        series_pieces = whichSeries.split('|')
        if (whichSeries and rootDir) or (whichSeries and fullShowPath and len(series_pieces) > 1):
            if len(series_pieces) < 6:
                log.error('Unable to add show due to show selection. Not enough arguments: {pieces!r}',
                          {'pieces': series_pieces})
                ui.notifications.error('Unknown error. Unable to add show due to problem with show selection.')
                return json_response(
                    result=False,
                    message='Unable to add show due to show selection. Not enough arguments: {0!r}'.format(series_pieces),
                    redirect='/addShows/existingShows/'
                )

            indexer = int(series_pieces[1])
            indexer_id = int(series_pieces[3])
            show_name = series_pieces[4]
        else:
            # if no indexer was provided use the default indexer set in General settings
            if not provided_indexer:
                provided_indexer = app.INDEXER_DEFAULT

            indexer = int(provided_indexer)
            indexer_id = int(whichSeries)
            show_name = os.path.basename(os.path.normpath(fullShowPath))

        # use the whole path if it's given, or else append the show name to the root dir to get the full show path
        if fullShowPath:
            show_dir = os.path.normpath(fullShowPath)
        else:
            show_dir = os.path.join(rootDir, sanitize_filename(show_name))

        # blanket policy - if the dir exists you should have used 'add existing show' numbnuts
        if os.path.isdir(show_dir) and not fullShowPath:
            ui.notifications.error('Unable to add show', 'Folder {path} exists already'.format(path=show_dir))
            return json_response(
                result=False,
                message='Unable to add show: Folder {path} exists already'.format(path=show_dir),
                redirect='/addShows/existingShows/'
            )

        # don't create show dir if config says not to
        if app.ADD_SHOWS_WO_DIR:
            log.info('Skipping initial creation of {path} due to config.ini setting',
                     {'path': show_dir})
        else:
            dir_exists = helpers.make_dir(show_dir)
            if not dir_exists:
                log.error("Unable to create the folder {path}, can't add the show",
                          {'path': show_dir})
                ui.notifications.error('Unable to add show',
                                       'Unable to create the folder {path}, can\'t add the show'.format(path=show_dir))
                # Don't redirect to default page because user wants to see the new show
                return json_response(
                    result=False,
                    message='Unable to add show: Unable to create the folder {path}'.format(path=show_dir),
                    redirect='/home/'
                )
            else:
                helpers.chmod_as_parent(show_dir)

        # prepare the inputs for passing along
        scene = config.checkbox_to_value(scene)
        anime = config.checkbox_to_value(anime)
        season_folders = config.checkbox_to_value(season_folders)
        subtitles = config.checkbox_to_value(subtitles)

        if whitelist:
            if not isinstance(whitelist, list):
                whitelist = [whitelist]
            whitelist = short_group_names(whitelist)
        if blacklist:
            if not isinstance(blacklist, list):
                blacklist = [blacklist]
            blacklist = short_group_names(blacklist)

        if not allowed_qualities:
            allowed_qualities = []
        if not preferred_qualities or try_int(quality_preset, None):
            preferred_qualities = []
        if not isinstance(allowed_qualities, list):
            allowed_qualities = [allowed_qualities]
        if not isinstance(preferred_qualities, list):
            preferred_qualities = [preferred_qualities]
        new_quality = Quality.combine_qualities([int(q) for q in allowed_qualities], [int(q) for q in preferred_qualities])

        # add the show
        app.show_queue_scheduler.action.addShow(indexer, indexer_id, show_dir, int(defaultStatus), new_quality,
                                                season_folders, indexer_lang, subtitles, anime,
                                                scene, None, blacklist, whitelist, int(defaultStatusAfter))
        ui.notifications.message('Show added', 'Adding the specified show into {path}'.format(path=show_dir))

        return finishAddShow()
示例#7
0
    def addShowByID(self, indexername=None, seriesid=None, show_name=None, which_series=None,
                    indexer_lang=None, root_dir=None, default_status=None,
                    quality_preset=None, any_qualities=None, best_qualities=None,
                    season_folders=None, subtitles=None, full_show_path=None,
                    other_shows=None, skip_show=None, provided_indexer=None,
                    anime=None, scene=None, blacklist=None, whitelist=None,
                    default_status_after=None, configure_show_options=False):
        """
        Add's a new show with provided show options by indexer_id.
        Currently only TVDB and IMDB id's supported.
        """
        series_id = seriesid
        if indexername != 'tvdb':
            series_id = helpers.get_tvdb_from_id(seriesid, indexername.upper())
            if not series_id:
                log.info('Unable to find tvdb ID to add {name}', {'name': show_name})
                ui.notifications.error(
                    'Unable to add {0}'.format(show_name),
                    'Could not add {0}. We were unable to locate the tvdb id at this time.'.format(show_name)
                )
                return json_response(
                    result=False,
                    message='Unable to find tvdb ID to add {show}'.format(show=show_name)
                )

        if Show.find_by_id(app.showList, INDEXER_TVDBV2, series_id):
            return json_response(
                result=False,
                message='Show already exists'
            )

        # Sanitize the parameter allowed_qualities and preferred_qualities. As these would normally be passed as lists
        if any_qualities:
            any_qualities = any_qualities.split(',')
        else:
            any_qualities = []

        if best_qualities:
            best_qualities = best_qualities.split(',')
        else:
            best_qualities = []

        # If configure_show_options is enabled let's use the provided settings
        configure_show_options = config.checkbox_to_value(configure_show_options)

        if configure_show_options:
            # prepare the inputs for passing along
            scene = config.checkbox_to_value(scene)
            anime = config.checkbox_to_value(anime)
            season_folders = config.checkbox_to_value(season_folders)
            subtitles = config.checkbox_to_value(subtitles)

            if whitelist:
                whitelist = short_group_names(whitelist)
            if blacklist:
                blacklist = short_group_names(blacklist)

            if not any_qualities:
                any_qualities = []

            if not best_qualities or try_int(quality_preset, None):
                best_qualities = []

            if not isinstance(any_qualities, list):
                any_qualities = [any_qualities]

            if not isinstance(best_qualities, list):
                best_qualities = [best_qualities]

            quality = Quality.combine_qualities([int(q) for q in any_qualities], [int(q) for q in best_qualities])

            location = root_dir

        else:
            default_status = app.STATUS_DEFAULT
            quality = app.QUALITY_DEFAULT
            season_folders = app.SEASON_FOLDERS_DEFAULT
            subtitles = app.SUBTITLES_DEFAULT
            anime = app.ANIME_DEFAULT
            scene = app.SCENE_DEFAULT
            default_status_after = app.STATUS_DEFAULT_AFTER

            if app.ROOT_DIRS:
                root_dirs = app.ROOT_DIRS
                location = root_dirs[int(root_dirs[0]) + 1]
            else:
                location = None

        if not location:
            log.warning('There was an error creating the show, no root directory setting found')
            return json_response(
                result=False,
                message='No root directories set up, please go back and add one.'
            )

        show_name = get_showname_from_indexer(INDEXER_TVDBV2, series_id)
        show_dir = None

        # add the show
        app.show_queue_scheduler.action.addShow(INDEXER_TVDBV2, int(series_id), show_dir, int(default_status), quality,
                                                season_folders, indexer_lang, subtitles, anime, scene, None, blacklist,
                                                whitelist, int(default_status_after), root_dir=location)

        ui.notifications.message('Show added', 'Adding the specified show {0}'.format(show_name))

        # done adding show
        return json_response(
            message='Adding the specified show {0}'.format(show_name),
            redirect='home'
        )
示例#8
0
             'quality': Quality.FULLHDTV
         },
         {  # 2
             'name': 'Show.Name.S03E04.iNTERNAL.1080p.WEB-DL.x264-RlsGrp',
             'quality': Quality.FULLHDWEBDL
         },
     ]
 },
 {  # p4 - preferred lower quality
     'config': {
         'PREFERRED_WORDS': [],
         'UNDESIRED_WORDS': [],
     },
     'series': {
         'quality': Quality.combine_qualities(
             [Quality.FULLHDTV, Quality.FULLHDWEBDL, Quality.FULLHDBLURAY],
             [Quality.HDTV]
         ),
     },
     'expected': 1,  # Index of the expected result
     'results': [
         {  # 0
             'name': 'Show.Name.S03E04.1080p.WEB-DL.x264-RlsGrp',
             'quality': Quality.FULLHDWEBDL
         },
         {  # 1
             'name': 'Show.Name.S03E04.720p.HDTV.x264-RlsGrp',
             'quality': Quality.HDTV
         },
         {  # 2
             'name': 'Show.Name.S03E04.1080p.HDTV.x264-RlsGrp',
             'quality': Quality.FULLHDTV
示例#9
0
             'quality': Quality.FULLHDTV
         },
         {  # 2
             'name': 'Show.Name.S03E04.iNTERNAL.1080p.WEB-DL.x264-RlsGrp',
             'quality': Quality.FULLHDWEBDL
         },
     ]
 },
 {  # p4 - preferred lower quality
     'config': {
         'PREFERRED_WORDS': [],
         'UNDESIRED_WORDS': [],
     },
     'series': {
         'quality': Quality.combine_qualities(
             [Quality.FULLHDTV, Quality.FULLHDWEBDL, Quality.FULLHDBLURAY],
             [Quality.HDTV]
         ),
     },
     'expected': 1,  # Index of the expected result
     'results': [
         {  # 0
             'name': 'Show.Name.S03E04.1080p.WEB-DL.x264-RlsGrp',
             'quality': Quality.FULLHDWEBDL
         },
         {  # 1
             'name': 'Show.Name.S03E04.720p.HDTV.x264-RlsGrp',
             'quality': Quality.HDTV
         },
         {  # 2
             'name': 'Show.Name.S03E04.1080p.HDTV.x264-RlsGrp',
             'quality': Quality.FULLHDTV
示例#10
0
    def post(self):
        """Perform a mass update action."""
        required_options = (
            'paused', 'defaultEpisodeStatus', 'anime', 'sports', 'scene',
            'airByDate', 'seasonFolders', 'subtitles', 'qualities'
        )
        data = json_decode(self.request.body)
        shows = data.get('shows', [])
        options = data.get('options')
        errors = 0

        if not options:
            return self._bad_request('Options missing')

        missing_options = []
        for req_option in required_options:
            if req_option not in options:
                missing_options.append(req_option)

        if missing_options:
            return self._bad_request(f"Missing options: {', '.join(missing_options)}")

        paused = options.get('paused')
        default_ep_status = options.get('defaultEpisodeStatus')
        if isinstance(default_ep_status, str):
            default_ep_status = {v: k for k, v in statusStrings.items()}.get(default_ep_status)
        anime = options.get('anime')
        sports = options.get('sports')
        scene = options.get('scene')
        air_by_date = options.get('airByDate')
        dvd_order = options.get('dvdOrder')
        season_folders = options.get('seasonFolders')
        subtitles = options.get('subtitles')
        qualities = options.get('qualities')

        for show_slug in shows:
            identifier = SeriesIdentifier.from_slug(show_slug)
            show_obj = Series.find_by_identifier(identifier)

            if not show_obj:
                continue

            cur_root_dir = path.dirname(show_obj._location)
            cur_show_dir = path.basename(show_obj._location)
            for root_dir in options.get('rootDirs'):
                if cur_root_dir != root_dir['old']:
                    continue

                if root_dir['old'] != root_dir['new']:
                    new_show_dir = path.join(root_dir['new'], cur_show_dir)
                    log.info('For show {show_name} changing dir from {old_location} to {new_location}', {
                             'show_name': show_obj.name, 'old_location': show_obj._location, 'new_location': new_show_dir})
                else:
                    new_show_dir = show_obj._location

            new_paused = show_obj.paused if paused is None else paused
            new_default_ep_status = show_obj.default_ep_status if default_ep_status is None else default_ep_status
            new_anime = show_obj.anime if anime is None else anime
            new_sports = show_obj.sports if sports is None else sports
            new_scene = show_obj.scene if scene is None else scene
            new_air_by_date = show_obj.air_by_date if air_by_date is None else air_by_date
            new_dvd_order = show_obj.dvd_order if dvd_order is None else dvd_order
            new_season_folders = show_obj.season_folders if season_folders is None else season_folders
            new_subtitles = show_obj.subtitles if subtitles is None else subtitles

            # If both are false (two empty arrays), use the shows current value.
            if not qualities['allowed'] and not qualities['preferred']:
                new_quality_allowed, new_quality_preferred = show_obj.current_qualities
            else:
                new_quality_allowed, new_quality_preferred = qualities['allowed'], qualities['preferred']

            # If user set quality_preset remove all preferred_qualities
            if Quality.combine_qualities(new_quality_allowed, new_quality_preferred) in qualityPresets:
                new_quality_preferred = []

            errors += self.mass_edit_show(
                show_obj, location=new_show_dir,
                allowed_qualities=new_quality_allowed, preferred_qualities=new_quality_preferred,
                season_folders=new_season_folders, paused=new_paused, air_by_date=new_air_by_date, sports=new_sports,
                dvd_order=new_dvd_order, subtitles=new_subtitles, anime=new_anime, scene=new_scene,
                default_ep_status=new_default_ep_status,
            )

        return self._created(data={'errors': errors})
示例#11
0
    def mass_edit_show(
        self, show_obj, location=None, allowed_qualities=None, preferred_qualities=None,
        season_folders=None, paused=None, air_by_date=None, sports=None, dvd_order=None, subtitles=None,
        anime=None, scene=None, default_ep_status=None
    ):
        """A variation of the original `editShow`, where `directCall` is always true."""
        allowed_qualities = allowed_qualities or []
        preferred_qualities = preferred_qualities or []

        errors = 0

        do_update_scene_numbering = not (scene == show_obj.scene and anime == show_obj.anime)

        if not isinstance(allowed_qualities, list):
            allowed_qualities = [allowed_qualities]

        if not isinstance(preferred_qualities, list):
            preferred_qualities = [preferred_qualities]

        with show_obj.lock:
            new_quality = Quality.combine_qualities([int(q) for q in allowed_qualities],
                                                    [int(q) for q in preferred_qualities])
            show_obj.quality = new_quality

            # reversed for now
            if bool(show_obj.season_folders) != bool(season_folders):
                show_obj.season_folders = season_folders
                try:
                    app.show_queue_scheduler.action.refreshShow(show_obj)
                except CantRefreshShowException as error:
                    errors += 1
                    log.warning("Unable to refresh show '{show}': {error}", {
                        'show': show_obj.name, 'error': error
                    })

            # Check if we should erase parsed cached results for that show
            do_erase_parsed_cache = False
            for item in [('scene', scene), ('anime', anime), ('sports', sports),
                         ('air_by_date', air_by_date), ('dvd_order', dvd_order)]:
                if getattr(show_obj, item[0]) != item[1]:
                    do_erase_parsed_cache = True
                    # Break if at least one setting was changed
                    break

            show_obj.paused = paused
            show_obj.scene = scene
            show_obj.anime = anime
            show_obj.sports = sports
            show_obj.subtitles = subtitles
            show_obj.air_by_date = air_by_date
            show_obj.default_ep_status = int(default_ep_status)
            show_obj.dvd_order = dvd_order

            # if we change location clear the db of episodes, change it, write to db, and rescan
            old_location = path.normpath(show_obj._location)
            new_location = path.normpath(location)
            if old_location != new_location:
                changed_location = True
                log.info('Changing show location to: {new}', {'new': new_location})
                if not path.isdir(new_location):
                    if app.CREATE_MISSING_SHOW_DIRS:
                        log.info("Show directory doesn't exist, creating it")
                        try:
                            mkdir(new_location)
                        except OSError as error:
                            errors += 1
                            changed_location = False
                            log.warning("Unable to create the show directory '{location}'. Error: {msg}", {
                                        'location': new_location, 'msg': error})
                        else:
                            log.info('New show directory created')
                            helpers.chmod_as_parent(new_location)
                    else:
                        changed_location = False
                        log.warning("New location '{location}' does not exist. "
                                    "Enable setting 'Create missing show dirs'", {'location': location})

                # Save new location to DB only if we changed it
                if changed_location:
                    show_obj.location = new_location

                if changed_location and path.isdir(new_location):
                    try:
                        app.show_queue_scheduler.action.refreshShow(show_obj)
                    except CantRefreshShowException as error:
                        errors += 1
                        log.warning("Unable to refresh show '{show}'. Error: {error}", {
                                    'show': show_obj.name, 'error': error})

            # Save all settings changed while in show_obj.lock
            show_obj.save_to_db()

        if do_update_scene_numbering or do_erase_parsed_cache:
            try:
                xem_refresh(show_obj)
            except CantUpdateShowException as error:
                errors += 1
                log.warning("Unable to update scene numbering for show '{show}': {error}",
                            {'show': show_obj.name, 'error': error})

            # Must erase cached DB results when toggling scene numbering
            show_obj.erase_provider_cache()

            # Erase parsed cached names as we are changing scene numbering
            show_obj.flush_episodes()
            show_obj.erase_cached_parse()

            # Need to refresh show as we updated scene numbering or changed show format
            try:
                app.show_queue_scheduler.action.refreshShow(show_obj)
            except CantRefreshShowException as error:
                errors += 1
                log.warning(
                    "Unable to refresh show '{show}'. Please manually trigger a full show refresh. "
                    'Error: {error!r}'.format(show=show_obj.name, error=error),
                    {'show': show_obj.name, 'error': error}
                )

        return errors
示例#12
0
    # Then
    assert actual is True


@pytest.mark.parametrize('p', [
    {  # p0 - Invalid combined quality
        'quality': -4,
        'expected': False
    },
    {  # p1 - Valid 'allowed' quality
        'quality': Quality.HDTV,
        'expected': True
    },
    {  # p2 - Valid 'allowed' quality + valid 'preferred' quality
        'quality': Quality.combine_qualities([Quality.HDTV], [Quality.HDWEBDL]),
        'expected': True
    },
    {  # p3 - Valid 'allowed' quality + **invalid** 'preferred' quality
        'quality': Quality.combine_qualities([Quality.HDTV], [-4]),
        'expected': False
    },
])
def test_is_valid_combined_quality(p):
    # Given
    quality = p['quality']
    expected = p['expected']

    # When
    actual = Quality.is_valid_combined_quality(quality)
示例#13
0
    def __init__(self, indexer, indexer_id, lang, quality):
        """Initialize the object."""
        super(TestTVShow, self).__init__(indexer, indexer_id, lang, quality)

    def _load_from_db(self):
        """Override Series._load_from_db to avoid DB access during testing."""
        pass


@pytest.mark.parametrize('p', [
    {  # p0: Downloaded a quality not in quality system : yes
        'status': DOWNLOADED,
        'quality': Quality.SDTV,
        'show_obj': TestTVShow(indexer=1, indexer_id=1, lang='',
                               quality=Quality.combine_qualities([Quality.HDTV],  # Allowed Qualities
                                                                 [Quality.HDWEBDL])),  # Preferred Qualities
        'manually_searched': False,
        'expected': True
    },
    {  # p1: Current status is SKIPPED: no
        'status': SKIPPED,
        'quality': Quality.NA,
        'show_obj': TestTVShow(indexer=1, indexer_id=1, lang='',
                               quality=Quality.combine_qualities([Quality.HDTV],  # Allowed Qualities
                                                                 [Quality.HDWEBDL])),  # Preferred Qualities
        'manually_searched': False,
        'expected': False
    },
    {  # p2: Current status is IGNORED: no
        'status': IGNORED,
        'quality': Quality.NA,