def mylist_removed(video_type, content_id):
        """ Something has been removed from My List. We want to de-index this. """
        if video_type == CONTENT_TYPE_MOVIE:
            if kodiutils.get_setting_int('library_movies') != LIBRARY_ONLY_MYLIST:
                return
            Library().clean('plugin://plugin.video.streamz/library/movies/?movie=%s' % content_id)

        elif video_type == CONTENT_TYPE_PROGRAM:
            if kodiutils.get_setting_int('library_tvshows') != LIBRARY_ONLY_MYLIST:
                return
            Library().clean('plugin://plugin.video.streamz/library/tvshows/?program=%s' % content_id)
    def mylist_added(video_type, content_id):
        """ Something has been added to My List. We want to index this. """
        if video_type == CONTENT_TYPE_MOVIE:
            if kodiutils.get_setting_int('library_movies') != LIBRARY_ONLY_MYLIST:
                return
            # This unfortunately adds the movie to the database with the wrong parent path:
            # Library().update('plugin://plugin.video.streamz/library/movies/?movie=%s&kodi_action=refresh_info' % content_id)
            Library().update('plugin://plugin.video.streamz/library/movies/')

        elif video_type == CONTENT_TYPE_PROGRAM:
            if kodiutils.get_setting_int('library_tvshows') != LIBRARY_ONLY_MYLIST:
                return
            Library().update('plugin://plugin.video.streamz/library/tvshows/?program=%s&kodi_action=refresh_info' % content_id)
Exemplo n.º 3
0
    def show_library_tvshows(self, program=None):
        """ Return a list of the series that should be exported. """
        if program is None:
            if kodiutils.get_setting_int(
                    'library_tvshows') == LIBRARY_FULL_CATALOG:
                # Full catalog
                # Use cache if available, fetch from api otherwise so we get rich metadata for new content
                # NOTE: We should probably use CACHE_PREVENT here, so we can pick up new episodes, but we can't since that would
                #       require a massive amount of API calls for each update. We do this only for programs in 'My list'.
                items = self._api.get_items(content_filter=Program,
                                            cache=CACHE_AUTO)
            else:
                # Only favourites, don't use cache, fetch from api
                # If we use CACHE_AUTO, we will miss updates until the user manually opens the program in the Add-on
                items = self._api.get_mylist(content_filter=Program,
                                             cache=CACHE_PREVENT)
        else:
            # Fetch only a single program
            items = [self._api.get_program(program, cache=CACHE_PREVENT)]

        listing = []
        for item in items:
            title_item = Menu.generate_titleitem(item)
            # title_item.path = kodiutils.url_for('library_tvshows', program=item.program_id)  # We need a trailing /
            title_item.path = 'plugin://plugin.video.vtm.go/library/tvshows/?program={program_id}'.format(
                program_id=item.program_id)
            listing.append(title_item)

        kodiutils.show_listing(listing,
                               30003,
                               content='tvshows',
                               sort=['label', 'year', 'duration'])
Exemplo n.º 4
0
    def show_library_movies(self, movie=None):
        """ Return a list of the movies that should be exported. """
        if movie is None:
            if kodiutils.get_setting_int(
                    'library_movies') == LIBRARY_FULL_CATALOG:
                # Full catalog
                # Use cache if available, fetch from api otherwise so we get rich metadata for new content
                items = self._api.get_items(content_filter=Movie,
                                            cache=CACHE_AUTO)
            else:
                # Only favourites, use cache if available, fetch from api otherwise
                items = self._api.get_mylist(content_filter=Movie)
        else:
            items = [self._api.get_movie(movie)]

        listing = []
        for item in items:
            title_item = Menu.generate_titleitem(item)
            # title_item.path = kodiutils.url_for('library_movies', movie=item.movie_id)  # We need a trailing /
            title_item.path = 'plugin://plugin.video.vtm.go/library/movies/?movie=%s' % item.movie_id
            listing.append(title_item)

        kodiutils.show_listing(listing,
                               30003,
                               content='movies',
                               sort=['label', 'year', 'duration'])
Exemplo n.º 5
0
    def show_channels(self):
        """ Shows TV channels. """
        channels = self._channel_api.get_channels(
            filter_pin=kodiutils.get_setting_int(
                'interface_adult') == SETTINGS_ADULT_HIDE)

        # Load EPG details for the next 6 hours
        date_now = datetime.now(dateutil.tz.UTC)
        date_from = date_now.replace(minute=0, second=0, microsecond=0)
        date_to = (date_from + timedelta(hours=6))
        epg = self._epg_api.get_guide([channel.uid for channel in channels],
                                      date_from, date_to)
        for channel in channels:
            shows = [
                show for show in epg.get(channel.uid, {})
                if show.end > date_now
            ]
            try:
                channel.epg_now = shows[0]
            except (IndexError, KeyError):
                pass
            try:
                channel.epg_next = shows[1]
            except (IndexError, KeyError):
                pass

        listing = []
        for item in channels:
            title_item = Menu.generate_titleitem_channel(item)
            title_item.path = kodiutils.url_for('show_channel',
                                                channel_id=item.get_combi_id())
            title_item.is_playable = False
            listing.append(title_item)

        kodiutils.show_listing(listing, 30007)
Exemplo n.º 6
0
    def check_library_movie(self, movie):
        """ Check if the given movie is still available. """
        _LOGGER.debug('Checking if movie %s is still available', movie)

        # Our parent path always exists
        if movie is None:
            kodiutils.library_return_status(True)
            return

        if kodiutils.get_setting_int('library_movies') == LIBRARY_FULL_CATALOG:
            id_list = self._api.get_catalog_ids()
        else:
            id_list = self._api.get_mylist_ids()

        kodiutils.library_return_status(movie in id_list)
    def check_library_tvshow(self, program):
        """ Check if the given program is still available. """
        _LOGGER.debug('Checking if program %s is still available', program)

        # Our parent path always exists
        if program is None:
            kodiutils.library_return_status(True)
            return

        if kodiutils.get_setting_int('library_tvshows') == LIBRARY_FULL_CATALOG:
            id_list = self._api.get_catalog_ids()
        else:
            id_list = self._api.get_mylist_ids()

        kodiutils.library_return_status(program in id_list)
    def send_channels(self):
        """ Return JSON-STREAMS formatted information to IPTV Manager. """
        channel_api = ChannelApi(self._auth)

        streams = []

        channels = channel_api.get_channels(
            filter_pin=kodiutils.get_setting_int(
                'interface_adult') == SETTINGS_ADULT_HIDE)
        for channel in channels:
            streams.append(
                dict(
                    name=channel.title,
                    stream=kodiutils.url_for('play_asset',
                                             asset_id=channel.uid),
                    id=channel.station_id,
                    logo=channel.icon,
                    preset=channel.number,
                ))

        return dict(version=1, streams=streams)
Exemplo n.º 9
0
 def _is_refresh_required():
     """Returns if we should trigger an update based on the settings."""
     refresh_interval = kodiutils.get_setting_int('refresh_interval',
                                                  24) * 3600
     last_refreshed = kodiutils.get_setting_int('last_refreshed', 0)
     return (last_refreshed + refresh_interval) <= time.time()
Exemplo n.º 10
0
    def play(self, category, item):
        """ Play the requested item.
        :type category: string
        :type item: string
        """
        if not self._check_credentials():
            kodiutils.end_of_directory()
            return

        # Check if inputstreamhelper is correctly installed
        if not self._check_inputstream():
            kodiutils.end_of_directory()
            return

        try:
            # Get stream information
            resolved_stream = self._vtm_go_stream.get_stream(category, item)

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

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

        info_dict = {
            'tvshowtitle': resolved_stream.program,
            'title': resolved_stream.title,
            'duration': resolved_stream.duration,
        }

        prop_dict = {}

        stream_dict = {
            'duration': resolved_stream.duration,
        }

        upnext_data = None

        # Lookup metadata
        try:
            if category in ['movies', 'oneoffs']:
                info_dict.update({'mediatype': 'movie'})

                # Get details
                movie_details = self._vtm_go.get_movie(item)
                if movie_details:
                    info_dict.update({
                        'plot': movie_details.description,
                        'year': movie_details.year,
                        'aired': movie_details.aired,
                    })

            elif category == 'episodes':
                info_dict.update({'mediatype': 'episode'})

                # There is no direct API to get episode details, so we go trough the cached program details
                program = self._vtm_go.get_program(resolved_stream.program_id)
                if program:
                    episode_details = self._vtm_go.get_episode_from_program(program, item)
                    if episode_details:
                        info_dict.update({
                            'plot': episode_details.description,
                            'season': episode_details.season,
                            'episode': episode_details.number,
                        })

                        # Lookup the next episode
                        next_episode_details = self._vtm_go.get_next_episode_from_program(program, episode_details.season, episode_details.number)

                        # Create the data for Up Next
                        if next_episode_details:
                            upnext_data = self.generate_upnext(episode_details, next_episode_details)

            elif category == 'channels':
                info_dict.update({'mediatype': 'episode'})

                # For live channels, we need to keep on updating the manifest
                # This might not be needed, and could be done with the Location-tag updates if inputstream.adaptive supports it
                # See https://github.com/peak3d/inputstream.adaptive/pull/298#issuecomment-524206935
                prop_dict.update({
                    'inputstream.adaptive.manifest_update_parameter': 'full',
                })

            else:
                _LOGGER.warning('Unknown category %s', category)

        except UnavailableException:
            # We continue without details.
            # This allows to play some programs that don't have metadata (yet).
            pass

        # If we have enabled the Manifest proxy, route the call trough that.
        if category in ['movies', 'oneoffs', 'episodes'] and kodiutils.get_setting_bool('manifest_proxy'):
            try:  # Python 3
                from urllib.parse import urlencode
            except ImportError:  # Python 2
                from urllib import urlencode

            port = kodiutils.get_setting_int('manifest_proxy_port')
            if not port:
                kodiutils.notification(message=kodiutils.localize(30718), icon='error')
                kodiutils.end_of_directory()
                return

            url = 'http://127.0.0.1:{port}/manifest?{path}'.format(port=port,
                                                                   path=urlencode({'path': resolved_stream.url}))
        else:
            url = resolved_stream.url

        license_key = self._vtm_go_stream.create_license_key(resolved_stream.license_url)

        # Play this item
        kodiutils.play(url, license_key, resolved_stream.title, {}, info_dict, prop_dict, stream_dict)

        # Wait for playback to start
        kodi_player = KodiPlayer()
        if not kodi_player.waitForPlayBack(url=url):
            # Playback didn't start
            kodiutils.end_of_directory()
            return

        # Send Up Next data
        if upnext_data and kodiutils.get_setting_bool('useupnext'):
            _LOGGER.debug("Sending Up Next data: %s", upnext_data)
            self.send_upnext(upnext_data)
Exemplo n.º 11
0
    def show_channel(self, channel_id):
        """ Shows TV channel details.

        :param str channel_id:          The channel we want to display.
        """
        channel = self._channel_api.get_asset(channel_id.split(':')[0])

        # Verify PIN
        if channel.pin and kodiutils.get_setting_int(
                'interface_adult') != SETTINGS_ADULT_ALLOW:
            pin = kodiutils.get_numeric_input(
                kodiutils.localize(30204))  # Enter PIN
            if not pin:
                # Cancelled
                kodiutils.end_of_directory()
                return

            if not self._channel_api.verify_pin(pin):
                kodiutils.ok_dialog(message=kodiutils.localize(
                    30205))  # The PIN you have entered is invalid!
                kodiutils.end_of_directory()
                return

        listing = []

        # Play live
        live_titleitem = Menu.generate_titleitem_channel(channel)
        live_titleitem.info_dict['title'] = kodiutils.localize(
            30051, channel=channel.title)  # Watch live [B]{channel}[/B]
        listing.append(live_titleitem)

        # Restart currently airing program
        if channel.epg_now and channel.epg_now.restart:
            restart_titleitem = Menu.generate_titleitem_program(
                channel.epg_now)
            restart_titleitem.info_dict['title'] = kodiutils.localize(
                30052,
                program=channel.epg_now.title)  # Restart [B]{program}[/B]
            restart_titleitem.art_dict['thumb'] = 'DefaultInProgressShows.png'
            listing.append(restart_titleitem)

        # TV Guide
        listing.append(
            TitleItem(
                title=kodiutils.localize(
                    30053, channel=channel.title),  # TV Guide for {channel}
                path=kodiutils.url_for('show_channel_guide',
                                       channel_id=channel_id),
                art_dict=dict(icon='DefaultAddonTvInfo.png', ),
                info_dict=dict(
                    plot=kodiutils.localize(
                        30054, channel=channel.title
                    ),  # Browse the TV Guide for {channel}
                ),
            ))

        if channel.replay:
            listing.append(
                TitleItem(
                    title=kodiutils.localize(
                        30055, channel=channel.title),  # Catalog for {channel}
                    path=kodiutils.url_for('show_channel_replay',
                                           channel_id=channel_id),
                    art_dict=dict(icon='DefaultMovieTitle.png', ),
                    info_dict=dict(
                        plot=kodiutils.localize(
                            30056, channel=channel.title
                        ),  # Browse the Catalog for {channel}
                    ),
                ))

        kodiutils.show_listing(listing, 30007)
    def send_epg(self):
        """ Return JSON-EPG formatted information to IPTV Manager. """
        channel_api = ChannelApi(self._auth)
        epg_api = EpgApi(self._auth)

        epg = defaultdict(list)

        # Load EPG data
        channels = channel_api.get_channels(
            filter_pin=kodiutils.get_setting_int(
                'interface_adult') == SETTINGS_ADULT_HIDE)
        for date in ['yesterday', 'today', 'tomorrow']:
            for channel, programs in epg_api.get_guide_with_capi(
                [channel.station_id for channel in channels], date).items():
                for program in programs:
                    # Hide these items
                    if program.title == EpgApi.EPG_NO_BROADCAST:
                        continue

                    # Construct mapping for credits
                    program_credits = []
                    for credit in program.credit:
                        if credit.role == Credit.ROLE_ACTOR:
                            program_credits.append({
                                'type': 'actor',
                                'name': credit.person,
                                'role': credit.character
                            })
                        elif credit.role == Credit.ROLE_DIRECTOR:
                            program_credits.append({
                                'type': 'director',
                                'name': credit.person
                            })
                        elif credit.role == Credit.ROLE_PRODUCER:
                            program_credits.append({
                                'type': 'producer',
                                'name': credit.person
                            })
                        elif credit.role == Credit.ROLE_COMPOSER:
                            program_credits.append({
                                'type': 'composer',
                                'name': credit.person
                            })
                        elif credit.role == Credit.ROLE_PRESENTER:
                            program_credits.append({
                                'type': 'presenter',
                                'name': credit.person
                            })
                        elif credit.role == Credit.ROLE_GUEST:
                            program_credits.append({
                                'type': 'guest',
                                'name': credit.person
                            })

                    epg[channel].append(
                        dict(start=program.start.isoformat(),
                             stop=program.end.isoformat(),
                             title=program.title,
                             description=program.description,
                             subtitle=None,
                             episode='S%dE%d' %
                             (program.season, program.episode)
                             if program.season and program.episode else None,
                             genre=program.genres,
                             image=program.cover,
                             date=None,
                             credits=program_credits,
                             stream=kodiutils.url_for('play_asset',
                                                      asset_id=program.uid)
                             if program.replay else None))

        return dict(version=1, epg=epg)
Exemplo n.º 13
0
    def play(self, category, item):
        """ Play the requested item.

        :type category: string
        :type item: string
        """
        # Check if inputstreamhelper is correctly installed
        if not self._check_inputstream():
            kodiutils.end_of_directory()
            return

        try:
            # Get stream information
            resolved_stream = self._stream.get_stream(category, item)

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

        except LimitReachedException:
            kodiutils.ok_dialog(
                message=kodiutils.localize(30713)
            )  # You have reached the maximum amount of concurrent streams...
            kodiutils.end_of_directory()
            return

        info_dict = {
            'tvshowtitle': resolved_stream.program,
            'title': resolved_stream.title,
            'duration': resolved_stream.duration,
        }

        prop_dict = {}

        stream_dict = {
            'duration': resolved_stream.duration,
        }

        upnext_data = None

        # Lookup metadata
        try:
            if category in ['movies', 'oneoffs']:
                info_dict.update({'mediatype': 'movie'})

                # Get details
                movie_details = self._api.get_movie(item)
                if movie_details:
                    info_dict.update({
                        'plot': movie_details.description,
                        'year': movie_details.year,
                        'aired': movie_details.aired,
                    })

            elif category == 'episodes':
                info_dict.update({'mediatype': 'episode'})

                # There is no direct API to get episode details, so we go trough the cached program details
                program = self._api.get_program(resolved_stream.program_id)
                if program:
                    episode_details = self._api.get_episode_from_program(
                        program, item)
                    if episode_details:
                        info_dict.update({
                            'plot': episode_details.description,
                            'season': episode_details.season,
                            'episode': episode_details.number,
                        })

                        # Lookup the next episode
                        next_episode_details = self._api.get_next_episode_from_program(
                            program, episode_details.season,
                            episode_details.number)

                        # Create the data for Up Next
                        if next_episode_details:
                            upnext_data = self.generate_upnext(
                                episode_details, next_episode_details)

            else:
                _LOGGER.warning('Unknown category %s', category)

        except UnavailableException:
            # We continue without details.
            # This allows to play some programs that don't have metadata (yet).
            pass

        # If we have enabled the Manifest proxy, route the call trough that.
        if kodiutils.get_setting_bool('manifest_proxy'):
            try:  # Python 3
                from urllib.parse import urlencode
            except ImportError:  # Python 2
                from urllib import urlencode

            port = kodiutils.get_setting_int('manifest_proxy_port')
            if not port:
                kodiutils.notification(message=kodiutils.localize(30718),
                                       icon='error')
                kodiutils.end_of_directory()
                return

            url = 'http://127.0.0.1:{port}/manifest?{path}'.format(
                port=port, path=urlencode({'path': resolved_stream.url}))
        else:
            url = resolved_stream.url

        license_key = self._stream.create_license_key(
            resolved_stream.license_url)

        # Play this item
        kodiutils.play(url,
                       license_key,
                       resolved_stream.title, {},
                       info_dict,
                       prop_dict,
                       stream_dict,
                       subtitles=resolved_stream.subtitles)

        # Wait for playback to start
        kodi_player = KodiPlayer()
        if not kodi_player.waitForPlayBack(url=url):
            # Playback didn't start
            return

        # Send Up Next data
        if upnext_data and kodiutils.get_setting_bool('useupnext'):
            _LOGGER.debug("Sending Up Next data: %s", upnext_data)
            self.send_upnext(upnext_data)