예제 #1
0
    def setUpClass(cls):
        cls.shows = []

        show = Series(1, 121361)
        show.name = "Italian Works"
        show.episodes = []
        episode = Episode(show, 5, 10)
        episode.name = "Pines of Rome"
        episode.scene_season = 5
        episode.scene_episode = 10
        show.episodes.append(episode)
        cls.shows.append(show)
예제 #2
0
파일: naming.py 프로젝트: pymedusa/SickRage
def generate_sample_ep(multi=None, abd=False, sports=False, anime_type=None):
    series = Series(indexer=1, indexerid=12345, lang='en')
    series.name = 'Show Name'
    series.genre = 'Comedy'
    if anime_type:
        series.anime = 1

    # make a fake episode object
    ep = Episode(series=series, season=2, episode=3)

    ep.status = DOWNLOADED
    ep.quality = Quality.HDTV
    ep.airdate = datetime.date(2011, 3, 9)
    ep.name = 'Ep Name'
    ep.absolute_number = 13
    ep.release_name = 'Show.Name.S02E03.HDTV.x264-RLSGROUP'
    ep.is_proper = True

    if abd:
        ep.release_name = 'Show.Name.2011.03.09.HDTV.x264-RLSGROUP'
        ep.series.air_by_date = 1
    elif sports:
        ep.release_name = 'Show.Name.2011.03.09.HDTV.x264-RLSGROUP'
        ep.series.sports = 1
    elif anime_type:
        ep.release_name = 'Show.Name.013.HDTV.x264-RLSGROUP'

    if multi is not None:
        ep.name = 'Ep Name (1)'
        ep.release_name = 'Show.Name.S02E03E04E05.HDTV.x264-RLSGROUP'
        if anime_type:
            ep.release_name = 'Show.Name.013-015.HDTV.x264-RLSGROUP'

        second_ep = Episode(series, 2, 4)
        second_ep.name = 'Ep Name (2)'
        second_ep.status = DOWNLOADED
        second_ep.quality = Quality.HDTV
        second_ep.absolute_number = 14
        second_ep.release_name = ep.release_name

        third_ep = Episode(series, 2, 5)
        third_ep.name = 'Ep Name (3)'
        third_ep.status = DOWNLOADED
        third_ep.quality = Quality.HDTV
        third_ep.absolute_number = 15
        third_ep.release_name = ep.release_name

        ep.related_episodes.append(second_ep)
        ep.related_episodes.append(third_ep)

    return ep
예제 #3
0
def generate_sample_ep(multi=None, abd=False, sports=False, anime_type=None):
    series = Series(indexer=1, indexerid=12345, lang='en')
    series.name = 'Show Name'
    series.genre = 'Comedy'
    if anime_type:
        series.anime = 1

    # make a fake episode object
    ep = Episode(series=series, season=2, episode=3)

    ep._status = DOWNLOADED
    ep.quality = Quality.HDTV
    ep.airdate = datetime.date(2011, 3, 9)
    ep.name = 'Ep Name'
    ep.absolute_number = 13
    ep.release_name = 'Show.Name.S02E03.HDTV.x264-RLSGROUP'
    ep.is_proper = True

    if abd:
        ep.release_name = 'Show.Name.2011.03.09.HDTV.x264-RLSGROUP'
        ep.series.air_by_date = 1
    elif sports:
        ep.release_name = 'Show.Name.2011.03.09.HDTV.x264-RLSGROUP'
        ep.series.sports = 1
    elif anime_type:
        ep.release_name = 'Show.Name.013.HDTV.x264-RLSGROUP'

    if multi is not None:
        ep.name = 'Ep Name (1)'
        ep.release_name = 'Show.Name.S02E03E04E05.HDTV.x264-RLSGROUP'
        if anime_type:
            ep.release_name = 'Show.Name.013-015.HDTV.x264-RLSGROUP'

        second_ep = Episode(series, 2, 4)
        second_ep.name = 'Ep Name (2)'
        second_ep._status = DOWNLOADED
        second_ep.quality = Quality.HDTV
        second_ep.absolute_number = 14
        second_ep.release_name = ep.release_name

        third_ep = Episode(series, 2, 5)
        third_ep.name = 'Ep Name (3)'
        third_ep._status = DOWNLOADED
        third_ep.quality = Quality.HDTV
        third_ep.absolute_number = 15
        third_ep.release_name = ep.release_name

        ep.related_episodes.append(second_ep)
        ep.related_episodes.append(third_ep)

    return ep
예제 #4
0
    def _test_all_possible_show_names(self, name, indexerid=0, expected=None):
        """Test all possible show names.

        :param name:
        :param indexerid:
        :param expected:
        :return:
        """
        expected = [] if expected is None else expected
        show = Series(1, indexerid)
        show.name = name

        result = show.get_all_possible_names(show)
        self.assertTrue(len(set(expected).intersection(set(result))) == len(expected))
예제 #5
0
    def _test_all_possible_show_names(self, name, indexerid=0, expected=None):
        """Test all possible show names.

        :param name:
        :param indexerid:
        :param expected:
        :return:
        """
        expected = [] if expected is None else expected
        show = Series(1, indexerid)
        show.name = name

        result = show.get_all_possible_names(show)
        self.assertTrue(
            len(set(expected).intersection(set(result))) == len(expected))
예제 #6
0
 def test_init_empty_db(self):
     show = Series(1, 1, "en")
     episode = Episode(show, 1, 1)
     episode.name = "asdasdasdajkaj"
     episode.save_to_db()
     episode.load_from_db(1, 1)
     self.assertEqual(episode.name, "asdasdasdajkaj")
예제 #7
0
    def backlogShow(self, showslug):
        identifier = SeriesIdentifier.from_slug(showslug)
        series_obj = Series.find_by_identifier(identifier)

        if series_obj:
            app.backlog_search_scheduler.action.search_backlog([series_obj])

        return self.redirect('/manage/backlogOverview/')
예제 #8
0
    def load_from_db():
        """Populate the showList with shows from the database."""
        test_main_db_con = test.db.DBConnection()
        sql_results = test_main_db_con.select("SELECT * FROM tv_shows")

        for sql_show in sql_results:
            try:
                cur_show = Series(int(sql_show["indexer"]),
                                  int(sql_show["indexer_id"]))
                app.showList.append(cur_show)
            except Exception as error:  # pylint: disable=broad-except
                print("There was an error creating the show {}".format(error))
예제 #9
0
    def setUpClass(cls):
        """Set up class for tests."""
        num_legacy_shows = 3
        num_shows = 3
        num_episodes_per_show = 5
        cls.mydb = db.DBConnection()
        cls.legacy_shows = []
        cls.shows = []

        # Per-show-notifications were originally added for email notifications only.  To add
        # this feature to other notifiers, it was necessary to alter the way text is stored in
        # one of the DB columns.  Therefore, to test properly, we must create some shows that
        # store emails in the old method (legacy method) and then other shows that will use
        # the new method.
        for show_counter in list(range(100, 100 + num_legacy_shows)):
            show = Series(1, show_counter)
            show.name = "Show " + text_type(show_counter)
            show.episodes = []
            for episode_counter in list(range(0, num_episodes_per_show)):
                episode = Episode(show, test.SEASON, episode_counter)
                episode.name = "Episode " + text_type(episode_counter + 1)
                episode.quality = "SDTV"
                show.episodes.append(episode)
            show.save_to_db()
            cls.legacy_shows.append(show)

        for show_counter in list(range(200, 200 + num_shows)):
            show = Series(1, show_counter)
            show.name = "Show " + text_type(show_counter)
            show.episodes = []
            for episode_counter in list(range(0, num_episodes_per_show)):
                episode = Episode(show, test.SEASON, episode_counter)
                episode.name = "Episode " + text_type(episode_counter + 1)
                episode.quality = "SDTV"
                show.episodes.append(episode)
            show.save_to_db()
            cls.shows.append(show)
예제 #10
0
 def create(indexer=INDEXER_TVDBV2,
            indexerid=0,
            lang='',
            quality=SD,
            season_folders=1,
            enabled_subtitles=0,
            **kwargs):
     monkeypatch.setattr(Series, '_load_from_db', lambda method: None)
     target = Series(indexer=indexer,
                     indexerid=indexerid,
                     lang=lang,
                     quality=quality,
                     season_folders=season_folders,
                     enabled_subtitles=enabled_subtitles)
     return _patch_object(monkeypatch, target, **kwargs)
예제 #11
0
def test_should_refresh(p):
    """Run the test."""
    # Given
    cur_status = p['cur_status']
    same_file = p['same_file']
    check_quality_again = p['check_quality_again']
    anime = p['anime']
    filepath = p['filepath']
    expected = p['expected']

    # When
    replace, msg = Series.should_refresh_file(cur_status, same_file,
                                              check_quality_again, anime,
                                              filepath)
    actual = replace

    # Then
    if expected != actual:
        print msg
    assert expected == actual
예제 #12
0
    def test_process(self):
        show = Series(1, 3)
        show.name = test.SHOW_NAME
        show.location = test.SHOW_DIR
        show.save_to_db()

        app.showList = [show]
        episode = Episode(show, test.SEASON, test.EPISODE)
        episode.name = "some episode name"
        episode.save_to_db()

        addNameToCache('show name', 3)
        app.PROCESS_METHOD = 'move'

        post_processor = PostProcessor(test.FILE_PATH)
        self.assertTrue(post_processor.process())
예제 #13
0
    def do_test():
        """Test to perform."""
        global search_items  # pylint: disable=global-statement
        search_items = cur_data["i"]
        show = Series(1, tvdb_id)
        show.name = show_name
        show.quality = cur_data["q"]
        show.save_to_db()
        app.showList.append(show)
        episode = None

        for epNumber in cur_data["e"]:
            episode = Episode(show, cur_data["s"], epNumber)
            episode.status = common.WANTED
            episode.save_to_db()

        best_result = search_providers(show, episode.episode, force_search)
        if not best_result:
            assert cur_data["b"] == best_result
        # pylint: disable=no-member
        assert cur_data["b"] == best_result.name  # first is expected, second is chosen one
예제 #14
0
 def test_get_episode():
     show = Series(1, 1, "en")
     show.name = "show name"
     show.network = "cbs"
     show.genre = "crime"
     show.runtime = 40
     show.status = "Ended"
     show.default_ep_status = "5"
     show.airs = "monday"
     show.start_year = 1987
     show.save_to_db()
     app.showList = [show]
예제 #15
0
 def test_set_name(self):
     show = Series(1, 1, "en")
     show.name = "newName"
     show.save_to_db()
     show._load_from_db()
     self.assertEqual(show.name, "newName")
예제 #16
0
    def test_change_indexerid(self):
        show = Series(1, 1, "en")
        show.name = "show name"
        show.network = "cbs"
        show.genre = "crime"
        show.runtime = 40
        show.status = "Ended"
        show.default_ep_status = "5"
        show.airs = "monday"
        show.start_year = 1987

        show.save_to_db()
        show._load_from_db()

        show.indexerid = 2
        show.save_to_db()
        show._load_from_db()

        self.assertEqual(show.indexerid, 2)
예제 #17
0
    def do_test(self):
        """Test to perform."""
        series = Series(1, int(cur_data["tvdbid"]))
        series.name = cur_name
        series.quality = common.ANY | common.Quality.UNKNOWN | common.Quality.RAWHDTV
        # series.save_to_db()
        # app.showList.append(series)

        for ep_number in cur_data["e"]:
            episode = Episode(series, cur_data["s"], ep_number)
            episode.status = common.WANTED

            # We aren't updating scene numbers, so fake it here
            episode.scene_season = cur_data["s"]
            episode.scene_episode = ep_number

            # episode.save_to_db()

            cur_provider.series = series
            season_strings = cur_provider._get_season_search_strings(episode)  # pylint: disable=protected-access
            episode_strings = cur_provider._get_episode_search_strings(episode)  # pylint: disable=protected-access

            fail = False
            cur_string = ''
            for cur_string in season_strings, episode_strings:
                if not all([isinstance(cur_string, list), isinstance(cur_string[0], dict)]):
                    print(" %s is using a wrong string format!" % cur_provider.name)
                    print(cur_string)
                    fail = True
                    continue

            if fail:
                continue

            try:
                assert season_strings == cur_data["s_strings"]
                assert episode_strings == cur_data["e_strings"]
            except AssertionError:
                print (" %s is using a wrong string format!" % cur_provider.name)
                print (cur_string)
                continue

            search_strings = episode_strings[0]
            # search_strings.update(season_strings[0])
            # search_strings.update({"RSS":['']})

            # print(search_strings)

            if not cur_provider.public:
                continue

            items = cur_provider.search(search_strings)  # pylint: disable=protected-access
            if not items:
                print("No results from cur_provider?")
                continue

            title, url = cur_provider._get_title_and_url(items[0])  # pylint: disable=protected-access
            for word in series.name.split(" "):
                if not word.lower() in title.lower():
                    print("Show cur_name not in title: %s. URL: %s" % (title, url))
                    continue

            if not url:
                print("url is empty")
                continue

            quality = cur_provider.get_quality(items[0])
            size = cur_provider._get_size(items[0])  # pylint: disable=protected-access

            if not series.quality & quality:
                print("Quality not in common.ANY, %r %s" % (quality, size))
                continue
예제 #18
0
파일: show_queue.py 프로젝트: akang6/Medusa
    def run(self):

        ShowQueueItem.run(self)

        logger.log(u"Starting to add show {0}".format(
            "by ShowDir: {0}".format(self.showDir) if self.
            showDir else u"by Indexer Id: {0}".format(self.indexer_id)))

        # make sure the Indexer IDs are valid
        try:
            l_indexer_api_params = indexerApi(self.indexer).api_params.copy()
            if self.lang:
                l_indexer_api_params['language'] = self.lang

            logger.log(u"" + str(indexerApi(self.indexer).name) + ": " +
                       repr(l_indexer_api_params))

            indexer_api = indexerApi(
                self.indexer).indexer(**l_indexer_api_params)
            s = indexer_api[self.indexer_id]

            # Let's try to create the show Dir if it's not provided. This way we force the show dir
            # to build build using the Indexers provided series name
            if not self.showDir and self.root_dir:
                show_name = get_showname_from_indexer(self.indexer,
                                                      self.indexer_id,
                                                      self.lang)
                if show_name:
                    self.showDir = os.path.join(self.root_dir,
                                                sanitize_filename(show_name))
                    dir_exists = make_dir(self.showDir)
                    if not dir_exists:
                        logger.log(
                            u"Unable to create the folder {0}, can't add the show"
                            .format(self.showDir))
                        return

                    chmod_as_parent(self.showDir)
                else:
                    logger.log(
                        u"Unable to get a show {0}, can't add the show".format(
                            self.showDir))
                    return

            # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that
            # has no proper english version of the show
            if getattr(s, 'seriesname', None) is None:
                logger.log(
                    u"Show in {0} has no name on {1}, probably searched with the wrong language."
                    .format(self.showDir,
                            indexerApi(self.indexer).name), logger.ERROR)

                ui.notifications.error(
                    'Unable to add show',
                    'Show in {0} has no name on {1}, probably the wrong language. \
                                       Delete .nfo and manually add the correct language.'
                    .format(self.showDir,
                            indexerApi(self.indexer).name))
                self._finishEarly()
                return
            # if the show has no episodes/seasons
            if not s:
                logger.log(u"Show " + str(s['seriesname']) + u" is on " +
                           str(indexerApi(self.indexer).name) +
                           u" but contains no season/episode data.")
                ui.notifications.error(
                    "Unable to add show",
                    "Show {0} is on {1} but contains no season/episode data.".
                    format(s['seriesname'],
                           indexerApi(self.indexer).name))
                self._finishEarly()

                return

            # Check if we can already find this show in our current showList.
            try:
                check_existing_shows(s, self.indexer)
            except IndexerShowAllreadyInLibrary as e:
                logger.log(
                    u"Could not add the show %s, as it already is in your library."
                    u" Error: %s" % (s['seriesname'], e.message),
                    logger.WARNING)
                ui.notifications.error('Unable to add show',
                                       'reason: {0}'.format(e.message))
                self._finishEarly()

                # Clean up leftover if the newly created directory is empty.
                delete_empty_folders(self.showDir)
                return

        # TODO: Add more specific indexer exceptions, that should provide the user with some accurate feedback.
        except IndexerShowIncomplete as e:
            logger.log(
                u"%s Error while loading information from indexer %s. "
                u"Error: %s" %
                (self.indexer_id, indexerApi(self.indexer).name, e.message),
                logger.WARNING)
            ui.notifications.error(
                "Unable to add show",
                "Unable to look up the show in {0} on {1} using ID {2} "
                "Reason: {3}".format(self.showDir,
                                     indexerApi(self.indexer).name,
                                     self.indexer_id, e.message))
            self._finishEarly()
            return
        except IndexerShowNotFoundInLanguage as e:
            logger.log(
                u'{id}: Data retrieved from {indexer} was incomplete. The indexer does not provide '
                u'show information in the searched language {language}. Aborting: {error_msg}'
                .format(id=self.indexer_id,
                        indexer=indexerApi(self.indexer).name,
                        language=e.language,
                        error_msg=e.message), logger.WARNING)
            ui.notifications.error(
                'Error adding show!',
                'Unable to add show {indexer_id} on {indexer} with this language: {language}'
                .format(indexer_id=self.indexer_id,
                        indexer=indexerApi(self.indexer).name,
                        language=e.language))
            self._finishEarly()
            return
        except Exception as e:
            logger.log(
                u"%s Error while loading information from indexer %s. "
                u"Error: %r" %
                (self.indexer_id, indexerApi(self.indexer).name, e.message),
                logger.ERROR)
            ui.notifications.error(
                "Unable to add show",
                "Unable to look up the show in {0} on {1} using ID {2}, not using the NFO. "
                "Delete .nfo and try adding manually again.".format(
                    self.showDir,
                    indexerApi(self.indexer).name, self.indexer_id))
            self._finishEarly()
            return

        try:
            newShow = Series(self.indexer, self.indexer_id, self.lang)
            newShow.load_from_indexer(indexer_api)

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles if self.subtitles is not None else app.SUBTITLES_DEFAULT
            self.show.quality = self.quality if self.quality else app.QUALITY_DEFAULT
            self.show.flatten_folders = self.flatten_folders if self.flatten_folders is not None \
                else app.FLATTEN_FOLDERS_DEFAULT
            self.show.anime = self.anime if self.anime is not None else app.ANIME_DEFAULT
            self.show.scene = self.scene if self.scene is not None else app.SCENE_DEFAULT
            self.show.paused = self.paused if self.paused is not None else False

            # set up default new/missing episode status
            logger.log(
                u"Setting all previously aired episodes to the specified status: {status}"
                .format(status=statusStrings[self.default_status]))
            self.show.default_ep_status = self.default_status

            if self.show.anime:
                self.show.release_groups = BlackAndWhiteList(
                    self.show.indexerid)
                if self.blacklist:
                    self.show.release_groups.set_black_keywords(self.blacklist)
                if self.whitelist:
                    self.show.release_groups.set_white_keywords(self.whitelist)

            # # be smartish about this
            # if self.show.genre and "talk show" in self.show.genre.lower():
            #     self.show.air_by_date = 1
            # if self.show.genre and "documentary" in self.show.genre.lower():
            #     self.show.air_by_date = 0
            # if self.show.classification and "sports" in self.show.classification.lower():
            #     self.show.sports = 1

        except IndexerException as e:
            logger.log(
                u"Unable to add show due to an error with " +
                indexerApi(self.indexer).name + ": " + e.message, logger.ERROR)
            if self.show:
                ui.notifications.error("Unable to add " + str(self.show.name) +
                                       " due to an error with " +
                                       indexerApi(self.indexer).name + "")
            else:
                ui.notifications.error(
                    "Unable to add show due to an error with " +
                    indexerApi(self.indexer).name + "")
            self._finishEarly()
            return

        except MultipleShowObjectsException:
            logger.log(
                u"The show in " + self.showDir +
                " is already in your show list, skipping", logger.WARNING)
            ui.notifications.error(
                'Show skipped', "The show in " + self.showDir +
                " is already in your show list")
            self._finishEarly()
            return

        except Exception as e:
            logger.log(u"Error trying to add show: " + e.message, logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finishEarly()
            raise

        logger.log(u"Retrieving show info from IMDb", logger.DEBUG)
        try:
            self.show.load_imdb_info()
        except ImdbAPIError as e:
            logger.log(u"Something wrong on IMDb api: " + e.message,
                       logger.INFO)
        except Exception as e:
            logger.log(u"Error loading IMDb info: " + e.message, logger.ERROR)

        try:
            self.show.save_to_db()
        except Exception as e:
            logger.log(u"Error saving the show to the database: " + e.message,
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finishEarly()
            raise

        # add it to the show list
        app.showList.append(self.show)

        try:
            self.show.load_episodes_from_indexer(tvapi=indexer_api)
        except Exception as e:
            logger.log(
                u"Error with " + indexerApi(self.show.indexer).name +
                ", not creating episode list: " + e.message, logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # update internal name cache
        name_cache.build_name_cache(self.show)

        try:
            self.show.load_episodes_from_dir()
        except Exception as e:
            logger.log(u"Error searching dir for episodes: " + e.message,
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # if they set default ep status to WANTED then run the backlog to search for episodes
        # FIXME: This needs to be a backlog queue item!!!
        if self.show.default_ep_status == WANTED:
            logger.log(
                u"Launching backlog for this show since its episodes are WANTED"
            )
            app.backlog_search_scheduler.action.search_backlog([self.show])

        self.show.write_metadata()
        self.show.update_metadata()
        self.show.populate_cache()

        self.show.flush_episodes()

        if app.USE_TRAKT:
            # if there are specific episodes that need to be added by trakt
            app.trakt_checker_scheduler.action.manage_new_show(self.show)

            # add show to trakt.tv library
            if app.TRAKT_SYNC:
                app.trakt_checker_scheduler.action.add_show_trakt_library(
                    self.show)

            if app.TRAKT_SYNC_WATCHLIST:
                logger.log(u"update watchlist")
                notifiers.trakt_notifier.update_watchlist(show_obj=self.show)

        # Load XEM data to DB for show
        scene_numbering.xem_refresh(self.show.indexerid,
                                    self.show.indexer,
                                    force=True)

        # check if show has XEM mapping so we can determine if searches
        # should go by scene numbering or indexer numbering.
        if not self.scene and scene_numbering.get_xem_numbering_for_show(
                self.show.indexerid, self.show.indexer):
            self.show.scene = 1

        # After initial add, set to default_status_after.
        self.show.default_ep_status = self.default_status_after

        self.finish()
예제 #19
0
    def run(self):

        ShowQueueItem.run(self)

        log.info('Starting to add show by {0}',
                 ('show_dir: {0}'.format(self.show_dir) if self.show_dir else
                  'Indexer Id: {0}'.format(self.indexer_id)))

        # make sure the Indexer IDs are valid
        try:
            l_indexer_api_params = indexerApi(self.indexer).api_params.copy()
            if self.lang:
                l_indexer_api_params['language'] = self.lang

            log.info(
                '{indexer_name}: {indexer_params!r}', {
                    'indexer_name': indexerApi(self.indexer).name,
                    'indexer_params': l_indexer_api_params
                })

            indexer_api = indexerApi(
                self.indexer).indexer(**l_indexer_api_params)
            s = indexer_api[self.indexer_id]

            # Let's try to create the show Dir if it's not provided. This way we force the show dir
            # to build build using the Indexers provided series name
            if not self.show_dir and self.root_dir:
                show_name = get_showname_from_indexer(self.indexer,
                                                      self.indexer_id,
                                                      self.lang)
                if show_name:
                    self.show_dir = os.path.join(self.root_dir,
                                                 sanitize_filename(show_name))
                    dir_exists = make_dir(self.show_dir)
                    if not dir_exists:
                        log.info(
                            "Unable to create the folder {0}, can't add the show",
                            self.show_dir)
                        return

                    chmod_as_parent(self.show_dir)
                else:
                    log.info("Unable to get a show {0}, can't add the show",
                             self.show_dir)
                    return

            # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that
            # has no proper english version of the show
            if getattr(s, 'seriesname', None) is None:
                log.error(
                    'Show in {path} has no name on {indexer}, probably searched with the wrong language.',
                    {
                        'path': self.show_dir,
                        'indexer': indexerApi(self.indexer).name
                    })

                ui.notifications.error(
                    'Unable to add show',
                    'Show in {path} has no name on {indexer}, probably the wrong language.'
                    ' Delete .nfo and manually add the correct language.'.
                    format(path=self.show_dir,
                           indexer=indexerApi(self.indexer).name))
                self._finishEarly()
                return

            # Check if we can already find this show in our current showList.
            try:
                check_existing_shows(s, self.indexer)
            except IndexerShowAlreadyInLibrary as error:
                log.warning(
                    'Could not add the show {series}, as it already is in your library.'
                    ' Error: {error}', {
                        'series': s['seriesname'],
                        'error': error
                    })
                ui.notifications.error('Unable to add show',
                                       'reason: {0}'.format(error))
                self._finishEarly()

                # Clean up leftover if the newly created directory is empty.
                delete_empty_folders(self.show_dir)
                return

        # TODO: Add more specific indexer exceptions, that should provide the user with some accurate feedback.
        except IndexerShowNotFound as error:
            log.warning(
                '{id}: Unable to look up the show in {path} using id {id} on {indexer}.'
                ' Delete metadata files from the folder and try adding it again.\n'
                'With error: {error}', {
                    'id': self.indexer_id,
                    'path': self.show_dir,
                    'indexer': indexerApi(self.indexer).name,
                    'error': error
                })
            ui.notifications.error(
                'Unable to add show',
                'Unable to look up the show in {path} using id {id} on {indexer}.'
                ' Delete metadata files from the folder and try adding it again.'
                .format(path=self.show_dir,
                        id=self.indexer_id,
                        indexer=indexerApi(self.indexer).name))
            self._finishEarly()
            return
        except IndexerShowNotFoundInLanguage as error:
            log.warning(
                '{id}: Data retrieved from {indexer} was incomplete. The indexer does not provide'
                ' show information in the searched language {language}. Aborting: {error_msg}',
                {
                    'id': self.indexer_id,
                    'indexer': indexerApi(self.indexer).name,
                    'language': error.language,
                    'error_msg': error
                })
            ui.notifications.error(
                'Error adding show!',
                'Unable to add show {indexer_id} on {indexer} with this language: {language}'
                .format(indexer_id=self.indexer_id,
                        indexer=indexerApi(self.indexer).name,
                        language=error.language))
            self._finishEarly()
            return
        except Exception as error:
            log.error(
                '{id}: Error while loading information from indexer {indexer}. Error: {error!r}',
                {
                    'id': self.indexer_id,
                    'indexer': indexerApi(self.indexer).name,
                    'error': error
                })
            ui.notifications.error(
                'Unable to add show',
                'Unable to look up the show in {path} on {indexer} using ID {id}.'
                .format(path=self.show_dir,
                        indexer=indexerApi(self.indexer).name,
                        id=self.indexer_id))
            self._finishEarly()
            return

        try:
            newShow = Series(self.indexer, self.indexer_id, self.lang)
            newShow.load_from_indexer(indexer_api)

            self.show = newShow

            # set up initial values
            self.show.location = self.show_dir
            self.show.subtitles = self.subtitles if self.subtitles is not None else app.SUBTITLES_DEFAULT
            self.show.quality = self.quality if self.quality else app.QUALITY_DEFAULT
            self.show.season_folders = self.season_folders if self.season_folders is not None \
                else app.SEASON_FOLDERS_DEFAULT
            self.show.anime = self.anime if self.anime is not None else app.ANIME_DEFAULT
            self.show.scene = self.scene if self.scene is not None else app.SCENE_DEFAULT
            self.show.paused = self.paused if self.paused is not None else False

            # set up default new/missing episode status
            log.info(
                'Setting all previously aired episodes to the specified status: {status}',
                {'status': statusStrings[self.default_status]})
            self.show.default_ep_status = self.default_status

            if self.show.anime:
                self.show.release_groups = BlackAndWhiteList(self.show)
                if self.blacklist:
                    self.show.release_groups.set_black_keywords(self.blacklist)
                if self.whitelist:
                    self.show.release_groups.set_white_keywords(self.whitelist)

        except IndexerException as error:
            log.error(
                'Unable to add show due to an error with {indexer}: {error}', {
                    'indexer': indexerApi(self.indexer).name,
                    'error': error
                })
            ui.notifications.error(
                'Unable to add {series_name} due to an error with {indexer_name}'
                .format(series_name=self.show.name if self.show else 'show',
                        indexer_name=indexerApi(self.indexer).name))
            self._finishEarly()
            return

        except MultipleShowObjectsException:
            log.warning(
                'The show in {show_dir} is already in your show list, skipping',
                {'show_dir': self.show_dir})
            ui.notifications.error(
                'Show skipped',
                'The show in {show_dir} is already in your show list'.format(
                    show_dir=self.show_dir))
            self._finishEarly()
            return

        except Exception as error:
            log.error('Error trying to add show: {0}', error)
            log.debug(traceback.format_exc())
            self._finishEarly()
            raise

        log.debug('Retrieving show info from IMDb')
        try:
            self.show.load_imdb_info()
        except ImdbAPIError as error:
            log.info('Something wrong on IMDb api: {0}', error)
        except RequestException as error:
            log.warning('Error loading IMDb info: {0}', error)

        try:
            log.debug('{id}: Saving new show to database',
                      {'id': self.show.series_id})
            self.show.save_to_db()
        except Exception as error:
            log.error('Error saving the show to the database: {0}', error)
            log.debug(traceback.format_exc())
            self._finishEarly()
            raise

        # add it to the show list
        app.showList.append(self.show)

        try:
            self.show.load_episodes_from_indexer(tvapi=indexer_api)
        except Exception as error:
            log.error(
                'Error with {indexer}, not creating episode list: {error}', {
                    'indexer': indexerApi(self.show.indexer).name,
                    'error': error
                })
            log.debug(traceback.format_exc())

        # update internal name cache
        name_cache.build_name_cache(self.show)

        try:
            self.show.load_episodes_from_dir()
        except Exception as error:
            log.error('Error searching dir for episodes: {0}', error)
            log.debug(traceback.format_exc())

        # if they set default ep status to WANTED then run the backlog to search for episodes
        if self.show.default_ep_status == WANTED:
            log.info(
                'Launching backlog for this show since its episodes are WANTED'
            )
            wanted_segments = self.show.get_wanted_segments()
            for season, segment in viewitems(wanted_segments):
                cur_backlog_queue_item = BacklogQueueItem(self.show, segment)
                app.forced_search_queue_scheduler.action.add_item(
                    cur_backlog_queue_item)

                log.info('Sending forced backlog for {show} season {season}'
                         ' because some episodes were set to wanted'.format(
                             show=self.show.name, season=season))

        self.show.write_metadata()
        self.show.update_metadata()
        self.show.populate_cache()

        self.show.flush_episodes()

        if app.USE_TRAKT:
            # if there are specific episodes that need to be added by trakt
            app.trakt_checker_scheduler.action.manage_new_show(self.show)

            # add show to trakt.tv library
            if app.TRAKT_SYNC:
                app.trakt_checker_scheduler.action.add_show_trakt_library(
                    self.show)

            if app.TRAKT_SYNC_WATCHLIST:
                log.info('update watchlist')
                notifiers.trakt_notifier.update_watchlist(show_obj=self.show)

        # Load XEM data to DB for show
        scene_numbering.xem_refresh(self.show, force=True)

        # check if show has XEM mapping so we can determine if searches
        # should go by scene numbering or indexer numbering. Warn the user.
        if not self.scene and scene_numbering.get_xem_numbering_for_show(
                self.show):
            log.warning(
                '{id}: while adding the show {title} we noticed thexem.de has an episode mapping available'
                '\nyou might want to consider enabling the scene option for this show.',
                {
                    'id': self.show.series_id,
                    'title': self.show.name
                })
            ui.notifications.message(
                'consider enabling scene for this show',
                'for show {title} you might want to consider enabling the scene option'
                .format(title=self.show.name))

        # After initial add, set to default_status_after.
        self.show.default_ep_status = self.default_status_after

        try:
            log.debug('{id}: Saving new show info to database',
                      {'id': self.show.series_id})
            self.show.save_to_db()
        except Exception as error:
            log.warning(
                '{id}: Error saving new show info to database: {error_msg}', {
                    'id': self.show.series_id,
                    'error_msg': error
                })
            log.error(traceback.format_exc())

        # Send ws update to client
        ws.Message('showAdded', self.show.to_json(detailed=False)).push()

        self.finish()
예제 #20
0
    def massEditSubmit(self,
                       paused=None,
                       default_ep_status=None,
                       dvd_order=None,
                       anime=None,
                       sports=None,
                       scene=None,
                       season_folders=None,
                       quality_preset=None,
                       subtitles=None,
                       air_by_date=None,
                       allowed_qualities=None,
                       preferred_qualities=None,
                       toEdit=None,
                       *args,
                       **kwargs):
        allowed_qualities = allowed_qualities or []
        preferred_qualities = preferred_qualities or []

        dir_map = {}
        for cur_arg in kwargs:
            if not cur_arg.startswith('orig_root_dir_'):
                continue
            which_index = cur_arg.replace('orig_root_dir_', '')
            end_dir = kwargs['new_root_dir_{index}'.format(index=which_index)]
            dir_map[kwargs[cur_arg]] = end_dir

        series_slugs = toEdit.split('|') if toEdit else []
        errors = 0
        for series_slug in series_slugs:
            identifier = SeriesIdentifier.from_slug(series_slug)
            series_obj = Series.find_by_identifier(identifier)

            if not series_obj:
                continue

            cur_root_dir = os.path.dirname(series_obj._location)
            cur_show_dir = os.path.basename(series_obj._location)
            if cur_root_dir in dir_map and cur_root_dir != dir_map[
                    cur_root_dir]:
                new_show_dir = os.path.join(dir_map[cur_root_dir],
                                            cur_show_dir)
                logger.log(
                    u'For show {show.name} changing dir from {show._location} to {location}'
                    .format(show=series_obj, location=new_show_dir))
            else:
                new_show_dir = series_obj._location

            if paused == 'keep':
                new_paused = series_obj.paused
            else:
                new_paused = True if paused == 'enable' else False
            new_paused = 'on' if new_paused else 'off'

            if default_ep_status == 'keep':
                new_default_ep_status = series_obj.default_ep_status
            else:
                new_default_ep_status = default_ep_status

            if anime == 'keep':
                new_anime = series_obj.anime
            else:
                new_anime = True if anime == 'enable' else False
            new_anime = 'on' if new_anime else 'off'

            if sports == 'keep':
                new_sports = series_obj.sports
            else:
                new_sports = True if sports == 'enable' else False
            new_sports = 'on' if new_sports else 'off'

            if scene == 'keep':
                new_scene = series_obj.is_scene
            else:
                new_scene = True if scene == 'enable' else False
            new_scene = 'on' if new_scene else 'off'

            if air_by_date == 'keep':
                new_air_by_date = series_obj.air_by_date
            else:
                new_air_by_date = True if air_by_date == 'enable' else False
            new_air_by_date = 'on' if new_air_by_date else 'off'

            if dvd_order == 'keep':
                new_dvd_order = series_obj.dvd_order
            else:
                new_dvd_order = True if dvd_order == 'enable' else False
            new_dvd_order = 'on' if new_dvd_order else 'off'

            if season_folders == 'keep':
                new_season_folders = series_obj.season_folders
            else:
                new_season_folders = True if season_folders == 'enable' else False
            new_season_folders = 'on' if new_season_folders else 'off'

            if subtitles == 'keep':
                new_subtitles = series_obj.subtitles
            else:
                new_subtitles = True if subtitles == 'enable' else False

            new_subtitles = 'on' if new_subtitles else 'off'

            if quality_preset == 'keep':
                allowed_qualities, preferred_qualities = series_obj.current_qualities
            elif try_int(quality_preset, None):
                preferred_qualities = []

            exceptions_list = []

            errors += self.editShow(identifier.indexer.slug,
                                    identifier.id,
                                    new_show_dir,
                                    allowed_qualities,
                                    preferred_qualities,
                                    exceptions_list,
                                    defaultEpStatus=new_default_ep_status,
                                    season_folders=new_season_folders,
                                    paused=new_paused,
                                    sports=new_sports,
                                    dvd_order=new_dvd_order,
                                    subtitles=new_subtitles,
                                    anime=new_anime,
                                    scene=new_scene,
                                    air_by_date=new_air_by_date,
                                    directCall=True)

        if errors:
            ui.notifications.error(
                'Errors',
                '{num} error{s} while saving changes. Please check logs'.
                format(num=errors, s='s' if errors > 1 else ''))

        return self.redirect('/manage/')
예제 #21
0
    def do_test(self):
        """Test to perform."""
        series = Series(1, int(cur_data["tvdbid"]))
        series.name = cur_name
        series.quality = common.ANY | common.Quality.UNKNOWN | common.Quality.RAWHDTV
        # series.save_to_db()
        # app.showList.append(series)

        for ep_number in cur_data["e"]:
            episode = Episode(series, cur_data["s"], ep_number)
            episode.status = common.WANTED

            # We aren't updating scene numbers, so fake it here
            episode.scene_season = cur_data["s"]
            episode.scene_episode = ep_number

            # episode.save_to_db()

            cur_provider.series = series
            season_strings = cur_provider._get_season_search_strings(episode)  # pylint: disable=protected-access
            episode_strings = cur_provider._get_episode_search_strings(episode)  # pylint: disable=protected-access

            fail = False
            cur_string = ''
            for cur_string in season_strings, episode_strings:
                if not all([isinstance(cur_string, list), isinstance(cur_string[0], dict)]):
                    print("%s is using a wrong string format!" % cur_provider.name)
                    print(cur_string)
                    fail = True
                    continue

            if fail:
                continue

            try:
                assert season_strings == cur_data["s_strings"]
                assert episode_strings == cur_data["e_strings"]
            except AssertionError:
                print("%s is using a wrong string format!" % cur_provider.name)
                print(cur_string)
                continue

            search_strings = episode_strings[0]
            # search_strings.update(season_strings[0])
            # search_strings.update({"RSS":['']})

            # print(search_strings)

            if not cur_provider.public:
                continue

            items = cur_provider.search(search_strings)  # pylint: disable=protected-access
            if not items:
                print("No results from cur_provider?")
                continue

            title, url = cur_provider._get_title_and_url(items[0])  # pylint: disable=protected-access
            for word in series.name.split(" "):
                if not word.lower() in title.lower():
                    print("Show cur_name not in title: %s. URL: %s" % (title, url))
                    continue

            if not url:
                print("url is empty")
                continue

            quality = cur_provider.get_quality(items[0])
            size = cur_provider._get_size(items[0])  # pylint: disable=protected-access

            if not series.quality & quality:
                print("Quality not in common.ANY, %r %s" % (quality, size))
                continue
예제 #22
0
 def test_scene_ex_babylon_5(self):
     series_obj = Series(1, 70726)
     self.assertEqual(
         sorted(scene_exceptions.get_scene_exceptions(series_obj, 1)),
         sorted({'Babylon 5', 'Babylon5'}))
예제 #23
0
 def test_set_name(self):
     show = Series(1, 1, "en")
     show.name = "newName"
     show.save_to_db()
     show._load_from_db()
     self.assertEqual(show.name, "newName")
예제 #24
0
    def test_change_indexerid(self):
        show = Series(1, 1, "en")
        show.name = "show name"
        show.network = "cbs"
        show.genre = "crime"
        show.runtime = 40
        show.status = "Ended"
        show.default_ep_status = "5"
        show.airs = "monday"
        show.start_year = 1987

        show.save_to_db()
        show._load_from_db()

        show.indexerid = 2
        show.save_to_db()
        show._load_from_db()

        self.assertEqual(show.indexerid, 2)
예제 #25
0
 def test_init_indexerid(self):
     show = Series(1, 1, "en")
     self.assertEqual(show.indexerid, 1)
예제 #26
0
    def setUpClass(cls):
        """Set up class for tests."""
        num_legacy_shows = 3
        num_shows = 3
        num_episodes_per_show = 5
        cls.mydb = db.DBConnection()
        cls.legacy_shows = []
        cls.shows = []

        # Per-show-notifications were originally added for email notifications only.  To add
        # this feature to other notifiers, it was necessary to alter the way text is stored in
        # one of the DB columns.  Therefore, to test properly, we must create some shows that
        # store emails in the old method (legacy method) and then other shows that will use
        # the new method.
        for show_counter in range(100, 100 + num_legacy_shows):
            show = Series(1, show_counter)
            show.name = "Show " + str(show_counter)
            show.episodes = []
            for episode_counter in range(0, num_episodes_per_show):
                episode = Episode(show, test.SEASON, episode_counter)
                episode.name = "Episode " + str(episode_counter + 1)
                episode.quality = "SDTV"
                show.episodes.append(episode)
            show.save_to_db()
            cls.legacy_shows.append(show)

        for show_counter in range(200, 200 + num_shows):
            show = Series(1, show_counter)
            show.name = "Show " + str(show_counter)
            show.episodes = []
            for episode_counter in range(0, num_episodes_per_show):
                episode = Episode(show, test.SEASON, episode_counter)
                episode.name = "Episode " + str(episode_counter + 1)
                episode.quality = "SDTV"
                show.episodes.append(episode)
            show.save_to_db()
            cls.shows.append(show)
예제 #27
0
 def test_default_media_name(self):
     series_obj = Series(1, 70726)
     self.assertEqual(ShowNetworkLogo(series_obj, '').default_media_name, os.path.join('network', 'nonetwork.png'))
예제 #28
0
    def massEdit(self, toEdit=None):
        t = PageTemplate(rh=self, filename='manage_massEdit.mako')

        if not toEdit:
            return self.redirect('/manage/')

        series_slugs = toEdit.split('|')
        show_list = []
        show_names = []
        for slug in series_slugs:
            identifier = SeriesIdentifier.from_slug(slug)
            series_obj = Series.find_by_identifier(identifier)

            if series_obj:
                show_list.append(series_obj)
                show_names.append(series_obj.name)

        season_folders_all_same = True
        last_season_folders = None

        paused_all_same = True
        last_paused = None

        default_ep_status_all_same = True
        last_default_ep_status = None

        anime_all_same = True
        last_anime = None

        sports_all_same = True
        last_sports = None

        quality_all_same = True
        last_quality = None

        subtitles_all_same = True
        last_subtitles = None

        scene_all_same = True
        last_scene = None

        air_by_date_all_same = True
        last_air_by_date = None

        dvd_order_all_same = True
        last_dvd_order = None

        root_dir_list = []

        for cur_show in show_list:

            cur_root_dir = os.path.dirname(cur_show._location)  # pylint: disable=protected-access
            if cur_root_dir not in root_dir_list:
                root_dir_list.append(cur_root_dir)

            # if we know they're not all the same then no point even bothering
            if paused_all_same:
                # if we had a value already and this value is different then they're not all the same
                if last_paused not in (None, cur_show.paused):
                    paused_all_same = False
                else:
                    last_paused = cur_show.paused

            if default_ep_status_all_same:
                if last_default_ep_status not in (None,
                                                  cur_show.default_ep_status):
                    default_ep_status_all_same = False
                else:
                    last_default_ep_status = cur_show.default_ep_status

            if anime_all_same:
                # if we had a value already and this value is different then they're not all the same
                if last_anime not in (None, cur_show.is_anime):
                    anime_all_same = False
                else:
                    last_anime = cur_show.anime

            if season_folders_all_same:
                if last_season_folders not in (None, cur_show.season_folders):
                    season_folders_all_same = False
                else:
                    last_season_folders = cur_show.season_folders

            if quality_all_same:
                if last_quality not in (None, cur_show.quality):
                    quality_all_same = False
                else:
                    last_quality = cur_show.quality

            if subtitles_all_same:
                if last_subtitles not in (None, cur_show.subtitles):
                    subtitles_all_same = False
                else:
                    last_subtitles = cur_show.subtitles

            if scene_all_same:
                if last_scene not in (None, cur_show.scene):
                    scene_all_same = False
                else:
                    last_scene = cur_show.scene

            if sports_all_same:
                if last_sports not in (None, cur_show.sports):
                    sports_all_same = False
                else:
                    last_sports = cur_show.sports

            if air_by_date_all_same:
                if last_air_by_date not in (None, cur_show.air_by_date):
                    air_by_date_all_same = False
                else:
                    last_air_by_date = cur_show.air_by_date

            if dvd_order_all_same:
                if last_dvd_order not in (None, cur_show.dvd_order):
                    dvd_order_all_same = False
                else:
                    last_dvd_order = cur_show.dvd_order

        default_ep_status_value = last_default_ep_status if default_ep_status_all_same else None
        paused_value = last_paused if paused_all_same else None
        anime_value = last_anime if anime_all_same else None
        season_folders_value = last_season_folders if season_folders_all_same else None
        quality_value = last_quality if quality_all_same else None
        subtitles_value = last_subtitles if subtitles_all_same else None
        scene_value = last_scene if scene_all_same else None
        sports_value = last_sports if sports_all_same else None
        air_by_date_value = last_air_by_date if air_by_date_all_same else None
        dvd_order_value = last_dvd_order if dvd_order_all_same else None
        root_dir_list = root_dir_list

        return t.render(showList=toEdit,
                        showNames=show_names,
                        default_ep_status_value=default_ep_status_value,
                        dvd_order_value=dvd_order_value,
                        paused_value=paused_value,
                        anime_value=anime_value,
                        season_folders_value=season_folders_value,
                        quality_value=quality_value,
                        subtitles_value=subtitles_value,
                        scene_value=scene_value,
                        sports_value=sports_value,
                        air_by_date_value=air_by_date_value,
                        root_dir_list=root_dir_list)
예제 #29
0
    def massEdit(self, toEdit=None):
        t = PageTemplate(rh=self, filename='manage_massEdit.mako')

        if not toEdit:
            return self.redirect('/manage/')

        series_slugs = toEdit.split('|')
        show_list = []
        show_names = []
        for slug in series_slugs:
            identifier = SeriesIdentifier.from_slug(slug)
            series_obj = Series.find_by_identifier(identifier)

            if series_obj:
                show_list.append(series_obj)
                show_names.append(series_obj.name)

        season_folders_all_same = True
        last_season_folders = None

        paused_all_same = True
        last_paused = None

        default_ep_status_all_same = True
        last_default_ep_status = None

        anime_all_same = True
        last_anime = None

        sports_all_same = True
        last_sports = None

        quality_all_same = True
        last_quality = None

        subtitles_all_same = True
        last_subtitles = None

        scene_all_same = True
        last_scene = None

        air_by_date_all_same = True
        last_air_by_date = None

        dvd_order_all_same = True
        last_dvd_order = None

        root_dir_list = []

        for cur_show in show_list:

            cur_root_dir = os.path.dirname(cur_show._location)  # pylint: disable=protected-access
            if cur_root_dir not in root_dir_list:
                root_dir_list.append(cur_root_dir)

            # if we know they're not all the same then no point even bothering
            if paused_all_same:
                # if we had a value already and this value is different then they're not all the same
                if last_paused not in (None, cur_show.paused):
                    paused_all_same = False
                else:
                    last_paused = cur_show.paused

            if default_ep_status_all_same:
                if last_default_ep_status not in (None, cur_show.default_ep_status):
                    default_ep_status_all_same = False
                else:
                    last_default_ep_status = cur_show.default_ep_status

            if anime_all_same:
                # if we had a value already and this value is different then they're not all the same
                if last_anime not in (None, cur_show.is_anime):
                    anime_all_same = False
                else:
                    last_anime = cur_show.anime

            if season_folders_all_same:
                if last_season_folders not in (None, cur_show.season_folders):
                    season_folders_all_same = False
                else:
                    last_season_folders = cur_show.season_folders

            if quality_all_same:
                if last_quality not in (None, cur_show.quality):
                    quality_all_same = False
                else:
                    last_quality = cur_show.quality

            if subtitles_all_same:
                if last_subtitles not in (None, cur_show.subtitles):
                    subtitles_all_same = False
                else:
                    last_subtitles = cur_show.subtitles

            if scene_all_same:
                if last_scene not in (None, cur_show.scene):
                    scene_all_same = False
                else:
                    last_scene = cur_show.scene

            if sports_all_same:
                if last_sports not in (None, cur_show.sports):
                    sports_all_same = False
                else:
                    last_sports = cur_show.sports

            if air_by_date_all_same:
                if last_air_by_date not in (None, cur_show.air_by_date):
                    air_by_date_all_same = False
                else:
                    last_air_by_date = cur_show.air_by_date

            if dvd_order_all_same:
                if last_dvd_order not in (None, cur_show.dvd_order):
                    dvd_order_all_same = False
                else:
                    last_dvd_order = cur_show.dvd_order

        default_ep_status_value = last_default_ep_status if default_ep_status_all_same else None
        paused_value = last_paused if paused_all_same else None
        anime_value = last_anime if anime_all_same else None
        season_folders_value = last_season_folders if season_folders_all_same else None
        quality_value = last_quality if quality_all_same else None
        subtitles_value = last_subtitles if subtitles_all_same else None
        scene_value = last_scene if scene_all_same else None
        sports_value = last_sports if sports_all_same else None
        air_by_date_value = last_air_by_date if air_by_date_all_same else None
        dvd_order_value = last_dvd_order if dvd_order_all_same else None
        root_dir_list = root_dir_list

        return t.render(showList=toEdit, showNames=show_names, default_ep_status_value=default_ep_status_value, dvd_order_value=dvd_order_value,
                        paused_value=paused_value, anime_value=anime_value, season_folders_value=season_folders_value,
                        quality_value=quality_value, subtitles_value=subtitles_value, scene_value=scene_value, sports_value=sports_value,
                        air_by_date_value=air_by_date_value, root_dir_list=root_dir_list)
예제 #30
0
    def massUpdate(self,
                   toUpdate=None,
                   toRefresh=None,
                   toRename=None,
                   toDelete=None,
                   toRemove=None,
                   toMetadata=None,
                   toSubtitle=None,
                   toImageUpdate=None):
        to_update = toUpdate.split('|') if toUpdate else []
        to_refresh = toRefresh.split('|') if toRefresh else []
        to_rename = toRename.split('|') if toRename else []
        to_subtitle = toSubtitle.split('|') if toSubtitle else []
        to_delete = toDelete.split('|') if toDelete else []
        to_remove = toRemove.split('|') if toRemove else []
        to_metadata = toMetadata.split('|') if toMetadata else []
        to_image_update = toImageUpdate.split('|') if toImageUpdate else []

        errors = []
        refreshes = []
        updates = []
        renames = []
        subtitles = []
        image_update = []

        for slug in set(to_update + to_refresh + to_rename + to_subtitle +
                        to_delete + to_remove + to_metadata + to_image_update):
            identifier = SeriesIdentifier.from_slug(slug)
            series_obj = Series.find_by_identifier(identifier)

            if not series_obj:
                continue

            if slug in to_delete + to_remove:
                app.show_queue_scheduler.action.removeShow(
                    series_obj, slug in to_delete)
                continue  # don't do anything else if it's being deleted or removed

            if slug in to_update:
                try:
                    app.show_queue_scheduler.action.updateShow(series_obj)
                    updates.append(series_obj.name)
                except CantUpdateShowException as msg:
                    errors.append(
                        'Unable to update show: {error}'.format(error=msg))

            elif slug in to_refresh:  # don't bother refreshing shows that were updated
                try:
                    app.show_queue_scheduler.action.refreshShow(series_obj)
                    refreshes.append(series_obj.name)
                except CantRefreshShowException as msg:
                    errors.append(
                        'Unable to refresh show {show.name}: {error}'.format(
                            show=series_obj, error=msg))

            if slug in to_rename:
                app.show_queue_scheduler.action.renameShowEpisodes(series_obj)
                renames.append(series_obj.name)

            if slug in to_subtitle:
                app.show_queue_scheduler.action.download_subtitles(series_obj)
                subtitles.append(series_obj.name)

            if slug in to_image_update:
                image_cache.replace_images(series_obj)

        if errors:
            ui.notifications.error('Errors encountered',
                                   '<br />\n'.join(errors))

        message = ''
        if updates:
            message += '\nUpdates: {0}'.format(len(updates))
        if refreshes:
            message += '\nRefreshes: {0}'.format(len(refreshes))
        if renames:
            message += '\nRenames: {0}'.format(len(renames))
        if subtitles:
            message += '\nSubtitles: {0}'.format(len(subtitles))
        if image_update:
            message += '\nImage updates: {0}'.format(len(image_update))

        if message:
            ui.notifications.message('Queued actions:', message)

        return self.redirect('/manage/')
예제 #31
0
    def massEditSubmit(self, paused=None, default_ep_status=None, dvd_order=None,
                       anime=None, sports=None, scene=None, season_folders=None, quality_preset=None,
                       subtitles=None, air_by_date=None, allowed_qualities=None, preferred_qualities=None, toEdit=None, *args,
                       **kwargs):
        allowed_qualities = allowed_qualities or []
        preferred_qualities = preferred_qualities or []

        dir_map = {}
        for cur_arg in kwargs:
            if not cur_arg.startswith('orig_root_dir_'):
                continue
            which_index = cur_arg.replace('orig_root_dir_', '')
            end_dir = kwargs['new_root_dir_{index}'.format(index=which_index)]
            dir_map[kwargs[cur_arg]] = end_dir

        series_slugs = toEdit.split('|') if toEdit else []
        errors = 0
        for series_slug in series_slugs:
            identifier = SeriesIdentifier.from_slug(series_slug)
            series_obj = Series.find_by_identifier(identifier)

            if not series_obj:
                continue

            cur_root_dir = os.path.dirname(series_obj._location)
            cur_show_dir = os.path.basename(series_obj._location)
            if cur_root_dir in dir_map and cur_root_dir != dir_map[cur_root_dir]:
                new_show_dir = os.path.join(dir_map[cur_root_dir], cur_show_dir)
                logger.log(u'For show {show.name} changing dir from {show._location} to {location}'.format
                           (show=series_obj, location=new_show_dir))
            else:
                new_show_dir = series_obj._location

            if paused == 'keep':
                new_paused = series_obj.paused
            else:
                new_paused = True if paused == 'enable' else False
            new_paused = 'on' if new_paused else 'off'

            if default_ep_status == 'keep':
                new_default_ep_status = series_obj.default_ep_status
            else:
                new_default_ep_status = default_ep_status

            if anime == 'keep':
                new_anime = series_obj.anime
            else:
                new_anime = True if anime == 'enable' else False
            new_anime = 'on' if new_anime else 'off'

            if sports == 'keep':
                new_sports = series_obj.sports
            else:
                new_sports = True if sports == 'enable' else False
            new_sports = 'on' if new_sports else 'off'

            if scene == 'keep':
                new_scene = series_obj.is_scene
            else:
                new_scene = True if scene == 'enable' else False
            new_scene = 'on' if new_scene else 'off'

            if air_by_date == 'keep':
                new_air_by_date = series_obj.air_by_date
            else:
                new_air_by_date = True if air_by_date == 'enable' else False
            new_air_by_date = 'on' if new_air_by_date else 'off'

            if dvd_order == 'keep':
                new_dvd_order = series_obj.dvd_order
            else:
                new_dvd_order = True if dvd_order == 'enable' else False
            new_dvd_order = 'on' if new_dvd_order else 'off'

            if season_folders == 'keep':
                new_season_folders = series_obj.season_folders
            else:
                new_season_folders = True if season_folders == 'enable' else False
            new_season_folders = 'on' if new_season_folders else 'off'

            if subtitles == 'keep':
                new_subtitles = series_obj.subtitles
            else:
                new_subtitles = True if subtitles == 'enable' else False

            new_subtitles = 'on' if new_subtitles else 'off'

            if quality_preset == 'keep':
                allowed_qualities, preferred_qualities = series_obj.current_qualities
            elif try_int(quality_preset, None):
                preferred_qualities = []

            exceptions_list = []

            errors += self.editShow(identifier.indexer.slug, identifier.id, new_show_dir, allowed_qualities,
                                    preferred_qualities, exceptions_list,
                                    defaultEpStatus=new_default_ep_status,
                                    season_folders=new_season_folders,
                                    paused=new_paused, sports=new_sports, dvd_order=new_dvd_order,
                                    subtitles=new_subtitles, anime=new_anime,
                                    scene=new_scene, air_by_date=new_air_by_date,
                                    directCall=True)

        if errors:
            ui.notifications.error('Errors', '{num} error{s} while saving changes. Please check logs'.format
                                   (num=errors, s='s' if errors > 1 else ''))

        return self.redirect('/manage/')
예제 #32
0
 def test_default_media_name(self):
     series_obj = Series(1, 70726)
     self.assertEqual(GenericMedia(series_obj, '').default_media_name, '')
예제 #33
0
    def massUpdate(self, toUpdate=None, toRefresh=None, toRename=None, toDelete=None, toRemove=None, toMetadata=None,
                   toSubtitle=None, toImageUpdate=None):
        to_update = toUpdate.split('|') if toUpdate else []
        to_refresh = toRefresh.split('|') if toRefresh else []
        to_rename = toRename.split('|') if toRename else []
        to_subtitle = toSubtitle.split('|') if toSubtitle else []
        to_delete = toDelete.split('|') if toDelete else []
        to_remove = toRemove.split('|') if toRemove else []
        to_metadata = toMetadata.split('|') if toMetadata else []
        to_image_update = toImageUpdate.split('|') if toImageUpdate else []

        errors = []
        refreshes = []
        updates = []
        renames = []
        subtitles = []
        image_update = []

        for slug in set(to_update + to_refresh + to_rename + to_subtitle + to_delete + to_remove + to_metadata + to_image_update):
            identifier = SeriesIdentifier.from_slug(slug)
            series_obj = Series.find_by_identifier(identifier)

            if not series_obj:
                continue

            if slug in to_delete + to_remove:
                app.show_queue_scheduler.action.removeShow(series_obj, slug in to_delete)
                continue  # don't do anything else if it's being deleted or removed

            if slug in to_update:
                try:
                    app.show_queue_scheduler.action.updateShow(series_obj)
                    updates.append(series_obj.name)
                except CantUpdateShowException as msg:
                    errors.append('Unable to update show: {error}'.format(error=msg))

            elif slug in to_refresh:  # don't bother refreshing shows that were updated
                try:
                    app.show_queue_scheduler.action.refreshShow(series_obj)
                    refreshes.append(series_obj.name)
                except CantRefreshShowException as msg:
                    errors.append('Unable to refresh show {show.name}: {error}'.format
                                  (show=series_obj, error=msg))

            if slug in to_rename:
                app.show_queue_scheduler.action.renameShowEpisodes(series_obj)
                renames.append(series_obj.name)

            if slug in to_subtitle:
                app.show_queue_scheduler.action.download_subtitles(series_obj)
                subtitles.append(series_obj.name)

            if slug in to_image_update:
                image_cache.replace_images(series_obj)

        if errors:
            ui.notifications.error('Errors encountered',
                                   '<br />\n'.join(errors))

        message = ''
        if updates:
            message += '\nUpdates: {0}'.format(len(updates))
        if refreshes:
            message += '\nRefreshes: {0}'.format(len(refreshes))
        if renames:
            message += '\nRenames: {0}'.format(len(renames))
        if subtitles:
            message += '\nSubtitles: {0}'.format(len(subtitles))
        if image_update:
            message += '\nImage updates: {0}'.format(len(image_update))

        if message:
            ui.notifications.message('Queued actions:', message)

        return self.redirect('/manage/')
예제 #34
0
 def test_scene_ex_empty(self):
     series_obj = Series(1, 70725)
     self.assertEqual(scene_exceptions.get_scene_exceptions(series_obj, 0),
                      set())
예제 #35
0
 def test_get_episode():
     show = Series(1, 1, "en")
     show.name = "show name"
     show.network = "cbs"
     show.genre = "crime"
     show.runtime = 40
     show.status = "Ended"
     show.default_ep_status = "5"
     show.airs = "monday"
     show.start_year = 1987
     show.save_to_db()
     app.showList = [show]
예제 #36
0
 def test_default_media_name(self):
     series_obj = Series(1, 70726)
     self.assertEqual(ShowBanner(series_obj, '').default_media_name, 'banner.png')
예제 #37
0
 def test_default_media_name(self):
     series_obj = Series(1, 70726)
     self.assertEqual(ShowFanArt(series_obj, '').default_media_name, 'fanart.png')