示例#1
0
class TestAuth(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(TestAuth, self).__init__(*args, **kwargs)
        self._auth = AuthApi(kodiutils.get_setting('username'),
                             kodiutils.get_setting('password'),
                             kodiutils.get_tokens_path())

    def test_login(self):
        # Clear any cache we have
        self._auth.clear_cache()

        # We should get a token by logging in
        token = self._auth.get_token()
        self.assertTrue(token)

        # Test it a second time, it should go from memory now
        token = self._auth.get_token()
        self.assertTrue(token)
示例#2
0
class TestApi(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(TestApi, self).__init__(*args, **kwargs)
        self._auth = AuthApi(kodiutils.get_setting('username'),
                             kodiutils.get_setting('password'),
                             kodiutils.get_tokens_path())

    def test_notifications(self):
        api = ContentApi(self._auth.get_token())
        notifications = api.get_notifications()
        self.assertIsInstance(notifications, list)

    def test_programs(self):
        api = ContentApi(self._auth.get_token())

        for channel in ['vier', 'vijf', 'zes']:
            channels = api.get_programs(channel)
            self.assertIsInstance(channels, list)

    def test_episodes(self):
        api = ContentApi(self._auth.get_token())

        for channel, program in [('vier', 'auwch'),
                                 ('vijf', 'zo-man-zo-vrouw')]:
            program = api.get_program(channel, program)
            self.assertIsInstance(program, Program)
            self.assertIsInstance(program.seasons, dict)
            # self.assertIsInstance(program.seasons[0], Season)
            self.assertIsInstance(program.episodes, list)
            self.assertIsInstance(program.episodes[0], Episode)
            _LOGGER.info('Got program: %s', program)

    def test_get_stream(self):
        api = ContentApi(self._auth.get_token())
        program = api.get_program('vier', 'auwch')
        episode = program.episodes[0]
        video = api.get_stream(episode.channel, episode.uuid)
        self.assertTrue(video)

        _LOGGER.info('Got video URL: %s', video)
class TestEpg(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(TestEpg, self).__init__(*args, **kwargs)
        self._auth = AuthApi(kodiutils.get_setting('username'), kodiutils.get_setting('password'), kodiutils.get_tokens_path())

    def test_vier_today(self):
        epg = EpgApi()
        programs = epg.get_epg('vier', date.today().strftime('%Y-%m-%d'))
        self.assertIsInstance(programs, list)
        self.assertIsInstance(programs[0], EpgProgram)

    def test_vijf_today(self):
        epg = EpgApi()
        programs = epg.get_epg('vijf', date.today().strftime('%Y-%m-%d'))
        self.assertIsInstance(programs, list)
        self.assertIsInstance(programs[0], EpgProgram)

    def test_zes_today(self):
        epg = EpgApi()
        programs = epg.get_epg('zes', date.today().strftime('%Y-%m-%d'))
        self.assertIsInstance(programs, list)
        self.assertIsInstance(programs[0], EpgProgram)

    def test_unknown_today(self):
        epg = EpgApi()
        with self.assertRaises(Exception):
            epg.get_epg('vtm', date.today().strftime('%Y-%m-%d'))

    def test_vier_out_of_range(self):
        epg = EpgApi()
        programs = epg.get_epg('vier', '2020-01-01')
        self.assertEqual(programs, [])

    def test_play_video_from_epg(self):
        epg = EpgApi()
        epg_programs = epg.get_epg('vier', date.today().strftime('%Y-%m-%d'))
        epg_program = [program for program in epg_programs if program.video_url][0]

        # Lookup the Episode data since we don't have an UUID
        api = ContentApi(self._auth.get_token())
        episode = api.get_episode(epg_program.channel, epg_program.video_url)
        self.assertIsInstance(episode, Episode)

        # Get stream based on the Episode's UUID
        video = api.get_stream(episode.channel, episode.uuid)
        self.assertTrue(video)
class Player:
    """ Code responsible for playing media """

    def __init__(self):
        """ Initialise object """
        self._auth = AuthApi(kodiutils.get_setting('username'), kodiutils.get_setting('password'), kodiutils.get_tokens_path())
        self._api = ContentApi(self._auth.get_token())

    def play_from_page(self, channel, path):
        """ Play the requested item.
        :type channel: string
        :type path: string
        """
        # Get episode information
        episode = self._api.get_episode(channel, path)

        # Play this now we have the uuid
        self.play(channel, episode.uuid)

    def play(self, channel, item):
        """ Play the requested item.
        :type channel: string
        :type item: string
        """
        try:
            # Get stream information
            resolved_stream = self._api.get_stream(channel, item)

        except GeoblockedException:
            kodiutils.ok_dialog(heading=kodiutils.localize(30709), message=kodiutils.localize(30710))  # This video is geo-blocked...
            return

        except UnavailableException:
            kodiutils.ok_dialog(heading=kodiutils.localize(30711), message=kodiutils.localize(30712))  # The video is unavailable...
            return

        # Play this item
        kodiutils.play(resolved_stream)
示例#5
0
class Catalog:
    """ Menu code related to the catalog """
    def __init__(self):
        """ Initialise object """
        self._auth = AuthApi(kodiutils.get_setting('username'),
                             kodiutils.get_setting('password'),
                             kodiutils.get_tokens_path())
        self._api = ContentApi(self._auth.get_token())
        self._menu = Menu()

    def show_catalog(self):
        """ Show all the programs of all channels """
        try:
            items = []
            for channel in list(CHANNELS):
                items.extend(self._api.get_programs(channel))
        except Exception as ex:
            kodiutils.notification(message=str(ex))
            raise

        listing = [self._menu.generate_titleitem(item) for item in items]

        # Sort items by label, but don't put folders at the top.
        # Used for A-Z listing or when movies and episodes are mixed.
        kodiutils.show_listing(listing, 30003, content='tvshows', sort='label')

    def show_catalog_channel(self, channel):
        """ Show the programs of a specific channel
        :type channel: str
        """
        try:
            items = self._api.get_programs(channel)
        except Exception as ex:
            kodiutils.notification(message=str(ex))
            raise

        listing = []
        for item in items:
            listing.append(self._menu.generate_titleitem(item))

        # Sort items by label, but don't put folders at the top.
        # Used for A-Z listing or when movies and episodes are mixed.
        kodiutils.show_listing(listing, 30003, content='tvshows', sort='label')

    def show_program(self, channel, program_id):
        """ Show a program from the catalog
        :type channel: str
        :type program_id: str
         """
        try:
            program = self._api.get_program(channel, program_id)
        except UnavailableException:
            kodiutils.ok_dialog(
                message=kodiutils.localize(30717)
            )  # This program is not available in the Vier/Vijf/Zes catalogue.
            kodiutils.end_of_directory()
            return

        if not program.episodes:
            kodiutils.ok_dialog(
                message=kodiutils.localize(30717)
            )  # This program is not available in the Vier/Vijf/Zes catalogue.
            kodiutils.end_of_directory()
            return

        # Go directly to the season when we have only one season
        if len(program.seasons) == 1:
            self.show_program_season(channel, program_id,
                                     program.seasons.values()[0].number)
            return

        studio = CHANNELS.get(program.channel, {}).get('studio_icon')

        listing = []

        # Add an '* All seasons' entry when configured in Kodi
        if kodiutils.get_global_setting('videolibrary.showallitems') is True:
            listing.append(
                TitleItem(
                    title='* %s' % kodiutils.localize(30204),  # * All seasons
                    path=kodiutils.url_for('show_catalog_program_season',
                                           channel=channel,
                                           program=program_id,
                                           season=-1),
                    art_dict={
                        'thumb': program.cover,
                        'fanart': program.background,
                    },
                    info_dict={
                        'tvshowtitle': program.title,
                        'title': kodiutils.localize(30204),  # All seasons
                        'plot': program.description,
                        'set': program.title,
                        'studio': studio,
                    }))

        # Add the seasons
        for s in list(program.seasons.values()):
            listing.append(
                TitleItem(
                    title=s.
                    title,  # kodiutils.localize(30205, season=s.number),  # Season {season}
                    path=kodiutils.url_for('show_catalog_program_season',
                                           channel=channel,
                                           program=program_id,
                                           season=s.number),
                    art_dict={
                        'thumb': s.cover,
                        'fanart': program.background,
                    },
                    info_dict={
                        'tvshowtitle': program.title,
                        'title':
                        kodiutils.localize(30205,
                                           season=s.number),  # Season {season}
                        'plot': s.description,
                        'set': program.title,
                        'studio': studio,
                    }))

        # Sort by label. Some programs return seasons unordered.
        kodiutils.show_listing(listing,
                               30003,
                               content='tvshows',
                               sort=['label'])

    def show_program_season(self, channel, program_id, season):
        """ Show the episodes of a program from the catalog
        :type channel: str
        :type program_id: str
        :type season: int
        """
        try:
            program = self._api.get_program(channel, program_id)
        except UnavailableException:
            kodiutils.ok_dialog(
                message=kodiutils.localize(30717)
            )  # This program is not available in the Vier/Vijf/Zes catalogue.
            kodiutils.end_of_directory()
            return

        if season == -1:
            # Show all episodes
            episodes = program.episodes
        else:
            # Show the episodes of the season that was selected
            episodes = [e for e in program.episodes if e.season == season]

        listing = [
            self._menu.generate_titleitem(episode) for episode in episodes
        ]

        # Sort by episode number by default. Takes seasons into account.
        kodiutils.show_listing(listing,
                               30003,
                               content='episodes',
                               sort=['episode', 'duration'])