Beispiel #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)
Beispiel #2
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())
Beispiel #3
0
 def create(series, season, episode, filepath='', **kwargs):
     monkeypatch.setattr(Episode, '_specify_episode',
                         lambda method, season, episode: None)
     target = Episode(series=series,
                      season=season,
                      episode=episode,
                      filepath=filepath)
     return _patch_object(monkeypatch, target, **kwargs)
Beispiel #4
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")
Beispiel #5
0
    def subtitleMissedPP(self):
        t = PageTemplate(rh=self, filename='manage_subtitleMissedPP.mako')
        app.RELEASES_IN_PP = []
        for root, _, files in os.walk(app.TV_DOWNLOAD_DIR, topdown=False):
            # Skip folders that are being used for unpacking
            if u'_UNPACK' in root.upper():
                continue
            for filename in sorted(files):
                if not is_media_file(filename):
                    continue

                video_path = os.path.join(root, filename)
                video_date = datetime.datetime.fromtimestamp(os.stat(video_path).st_ctime)
                video_age = datetime.datetime.today() - video_date

                tv_episode = Episode.from_filepath(video_path)

                if not tv_episode:
                    logger.log(u"Filename '{0}' cannot be parsed to an episode".format(filename), logger.DEBUG)
                    continue

                ep_status = tv_episode.status
                if ep_status in (SNATCHED, SNATCHED_PROPER, SNATCHED_BEST):
                    status = 'snatched'
                elif ep_status == DOWNLOADED:
                    status = 'downloaded'
                else:
                    continue

                if not tv_episode.series.subtitles:
                    continue

                related_files = PostProcessor(video_path).list_associated_files(video_path, subtitles_only=True)
                if related_files:
                    continue

                age_hours = divmod(video_age.seconds, 3600)[0]
                age_minutes = divmod(video_age.seconds, 60)[0]
                if video_age.days > 0:
                    age_unit = 'd'
                    age_value = video_age.days
                elif age_hours > 0:
                    age_unit = 'h'
                    age_value = age_hours
                else:
                    age_unit = 'm'
                    age_value = age_minutes

                app.RELEASES_IN_PP.append({'release': video_path, 'seriesid': tv_episode.series.indexerid,
                                           'show_name': tv_episode.series.name, 'season': tv_episode.season,
                                           'episode': tv_episode.episode, 'status': status, 'age': age_value,
                                           'age_unit': age_unit, 'date': video_date,
                                           'indexername': tv_episode.series.indexer_name})

        return t.render(releases_in_pp=app.RELEASES_IN_PP,
                        controller='manage', action='subtitleMissedPP')
Beispiel #6
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
Beispiel #7
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")
Beispiel #8
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)
Beispiel #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)
Beispiel #10
0
    def subtitles_download_in_pp():  # pylint: disable=too-many-locals, too-many-branches, too-many-statements
        """Check for needed subtitles in the post process folder."""
        from medusa import process_tv
        from medusa.tv import Episode

        logger.info(u'Checking for needed subtitles in Post-Process folder')

        # Check if PP folder is set
        if not app.TV_DOWNLOAD_DIR or not os.path.isdir(app.TV_DOWNLOAD_DIR):
            logger.warning(
                u'You must set a valid post-process folder in "Post Processing" settings'
            )
            return

        # Search for all wanted languages
        if not wanted_languages():
            return

        SubtitlesFinder.unpack_rar_files(app.TV_DOWNLOAD_DIR)

        run_post_process = False
        for root, _, files in os.walk(app.TV_DOWNLOAD_DIR, topdown=False):
            # Skip folders that are being used for unpacking
            if u'_UNPACK' in root.upper():
                continue
            for filename in sorted(files):
                # Delete unwanted subtitles before downloading new ones
                delete_unwanted_subtitles(root, filename)

                if not is_media_file(filename):
                    continue

                video_path = os.path.join(root, filename)
                tv_episode = Episode.from_filepath(video_path)

                if not tv_episode:
                    logger.debug(u'%s cannot be parsed to an episode',
                                 filename)
                    continue

                if tv_episode.status not in (SNATCHED, SNATCHED_PROPER,
                                             SNATCHED_BEST):
                    continue

                if not tv_episode.series.subtitles:
                    logger.debug(
                        u'Subtitle disabled for show: %s. Running post-process to PP it',
                        filename)
                    run_post_process = True
                    continue

                # Should not consider existing subtitles from db if it's a replacement
                new_release_name = remove_extension(filename)
                if tv_episode.release_name and new_release_name != tv_episode.release_name:
                    logger.debug(
                        u"As this is a release replacement I'm not going to consider existing "
                        u'subtitles or release name from database to refine the new release'
                    )
                    logger.debug(
                        u"Replacing old release name '%s' with new release name '%s'",
                        tv_episode.release_name, new_release_name)
                    tv_episode.subtitles = []
                    tv_episode.release_name = new_release_name
                embedded_subtitles = bool(not app.IGNORE_EMBEDDED_SUBS
                                          and video_path.endswith('.mkv'))
                downloaded_languages = download_subtitles(
                    tv_episode,
                    video_path=video_path,
                    subtitles=False,
                    embedded_subtitles=embedded_subtitles)

                # Don't run post processor unless at least one file has all of the needed subtitles OR
                # if user don't want to ignore embedded subtitles and wants to consider 'unknown' as wanted sub,
                # and .mkv has one.
                if not app.PROCESS_AUTOMATICALLY and not run_post_process:
                    if not needs_subtitles(downloaded_languages):
                        run_post_process = True
                    elif not app.IGNORE_EMBEDDED_SUBS:
                        embedded_subs = get_embedded_subtitles(video_path)
                        run_post_process = accept_unknown(
                            embedded_subs) or accept_any(embedded_subs)

        if run_post_process:
            logger.info(
                u'Starting post-process with default settings now that we found subtitles'
            )
            process_tv.ProcessResult(app.TV_DOWNLOAD_DIR,
                                     app.PROCESS_METHOD).process()
Beispiel #11
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
Beispiel #12
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
Beispiel #13
0
    def subtitles_download_in_pp():  # pylint: disable=too-many-locals, too-many-branches, too-many-statements
        """Check for needed subtitles in the post process folder."""
        from medusa import process_tv
        from medusa.tv import Episode

        logger.info(u'Checking for needed subtitles in Post-Process folder')

        # Check if PP folder is set
        if not app.TV_DOWNLOAD_DIR or not os.path.isdir(app.TV_DOWNLOAD_DIR):
            logger.warning(u'You must set a valid post-process folder in "Post Processing" settings')
            return

        # Search for all wanted languages
        if not wanted_languages():
            return

        SubtitlesFinder.unpack_rar_files(app.TV_DOWNLOAD_DIR)

        run_post_process = False
        for root, _, files in os.walk(app.TV_DOWNLOAD_DIR, topdown=False):
            # Skip folders that are being used for unpacking
            if u'_UNPACK' in root.upper():
                continue
            for filename in sorted(files):
                # Delete unwanted subtitles before downloading new ones
                delete_unwanted_subtitles(root, filename)

                if not is_media_file(filename):
                    continue

                video_path = os.path.join(root, filename)
                tv_episode = Episode.from_filepath(video_path)

                if not tv_episode:
                    logger.debug(u'%s cannot be parsed to an episode', filename)
                    continue

                if tv_episode.status not in (SNATCHED, SNATCHED_PROPER, SNATCHED_BEST):
                    continue

                if not tv_episode.series.subtitles:
                    logger.debug(u'Subtitle disabled for show: %s. Running post-process to PP it', filename)
                    run_post_process = True
                    continue

                # Should not consider existing subtitles from db if it's a replacement
                new_release_name = remove_extension(filename)
                if tv_episode.release_name and new_release_name != tv_episode.release_name:
                    logger.debug(u"As this is a release replacement I'm not going to consider existing "
                                 u'subtitles or release name from database to refine the new release')
                    logger.debug(u"Replacing old release name '%s' with new release name '%s'",
                                 tv_episode.release_name, new_release_name)
                    tv_episode.subtitles = []
                    tv_episode.release_name = new_release_name
                embedded_subtitles = bool(not app.IGNORE_EMBEDDED_SUBS and video_path.endswith('.mkv'))
                downloaded_languages = download_subtitles(tv_episode, video_path=video_path,
                                                          subtitles=False, embedded_subtitles=embedded_subtitles)

                # Don't run post processor unless at least one file has all of the needed subtitles OR
                # if user don't want to ignore embedded subtitles and wants to consider 'unknown' as wanted sub,
                # and .mkv has one.
                if not app.PROCESS_AUTOMATICALLY and not run_post_process:
                    if not needs_subtitles(downloaded_languages):
                        run_post_process = True
                    elif not app.IGNORE_EMBEDDED_SUBS:
                        embedded_subs = get_embedded_subtitles(video_path)
                        run_post_process = accept_unknown(embedded_subs) or accept_any(embedded_subs)

        if run_post_process:
            logger.info(u'Starting post-process with default settings now that we found subtitles')
            process_tv.ProcessResult(app.TV_DOWNLOAD_DIR, app.PROCESS_METHOD).process()
Beispiel #14
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
Beispiel #15
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