def show_program(self, program): """ Show a program from the catalog :type program: str """ try: program_obj = self._vtm_go.get_program(program, cache=CACHE_PREVENT) # Use CACHE_PREVENT since we want fresh data except UnavailableException: self._kodi.show_ok_dialog(message=self._kodi.localize(30717)) # This program is not available in the VTM GO catalogue. self._kodi.end_of_directory() return # Go directly to the season when we have only one season if len(program_obj.seasons) == 1: self.show_program_season(program, list(program_obj.seasons.values())[0].number) return studio = CHANNELS.get(program_obj.channel, {}).get('studio_icon') listing = [] # Add an '* All seasons' entry when configured in Kodi if self._kodi.get_global_setting('videolibrary.showallitems') is True: listing.append(TitleItem( title='* %s' % self._kodi.localize(30204), # * All seasons path=self._kodi.url_for('show_catalog_program_season', program=program, season=-1), art_dict=dict( thumb=program_obj.cover, fanart=program_obj.cover, ), info_dict=dict( tvshowtitle=program_obj.name, title=self._kodi.localize(30204), # All seasons tagline=program_obj.description, set=program_obj.name, studio=studio, mpaa=', '.join(program_obj.legal) if hasattr(program_obj, 'legal') and program_obj.legal else self._kodi.localize(30216), # All ages ), )) # Add the seasons for season in list(program_obj.seasons.values()): listing.append(TitleItem( title=self._kodi.localize(30205, season=season.number), # Season {season} path=self._kodi.url_for('show_catalog_program_season', program=program, season=season.number), art_dict=dict( thumb=season.cover, fanart=program_obj.cover, ), info_dict=dict( tvshowtitle=program_obj.name, title=self._kodi.localize(30205, season=season.number), # Season {season} tagline=program_obj.description, set=program_obj.name, studio=studio, mpaa=', '.join(program_obj.legal) if hasattr(program_obj, 'legal') and program_obj.legal else self._kodi.localize(30216), # All ages ), )) # Sort by label. Some programs return seasons unordered. self._kodi.show_listing(listing, 30003, content='tvshows', sort=['label'])
def show_tvguide(): """ Shows the TV guide """ kids = kodi.kids_mode() from . import CHANNELS listing = [] for entry in CHANNELS: # Skip non-kids channels when we are in kids mode. if kids and entry.get('kids') is False: continue # Lookup the high resolution logo based on the channel name icon = '{path}/resources/logos/{logo}-white.png'.format( path=kodi.get_addon_path(), logo=entry.get('logo')) fanart = '{path}/resources/logos/{logo}.png'.format( path=kodi.get_addon_path(), logo=entry.get('logo')) listing.append( TitleItem(title=entry.get('label'), path=routing.url_for(show_tvguide_channel, channel=entry.get('key')), art_dict={ 'icon': icon, 'thumb': icon, 'fanart': fanart, }, info_dict={ 'plot': kodi.localize(30215, channel=entry.get('label')), })) kodi.show_listing(listing, 30013)
def show_youtube(): """ Shows the Youtube channel overview """ kids = kodi.kids_mode() listing = [] from resources.lib import YOUTUBE for entry in YOUTUBE: # Skip non-kids channels when we are in kids mode. if kids and entry.get('kids') is False: continue # Lookup the high resolution logo based on the channel name icon = '{path}/resources/logos/{logo}-white.png'.format( path=kodi.get_addon_path(), logo=entry.get('logo')) fanart = '{path}/resources/logos/{logo}.png'.format( path=kodi.get_addon_path(), logo=entry.get('logo')) listing.append( TitleItem(title=entry.get('label'), path=entry.get('path'), art_dict={ 'icon': icon, 'thumb': icon, 'fanart': fanart, }, info_dict={ 'plot': kodi.localize(30206, label=entry.get('label')), 'studio': entry.get('studio'), })) # Sort by default like in our dict. kodi.show_listing(listing, 30007)
def show_tvguide_channel(self, channel): """ Shows the dates in the tv guide :type channel: str """ listing = [] for day in self._vtm_go_epg.get_dates('%A %d %B %Y'): if day.get('highlight'): title = '[B]{title}[/B]'.format(title=day.get('title')) else: title = day.get('title') listing.append( TitleItem(title=title, path=self._kodi.url_for('show_tvguide_detail', channel=channel, date=day.get('key')), art_dict={ 'icon': 'DefaultYear.png', 'thumb': 'DefaultYear.png', }, info_dict={ 'plot': None, 'date': day.get('date'), })) self._kodi.show_listing(listing, 30013, content='files', sort=['date'])
def show_tvguide_detail(self, channel=None, date=None): """ Shows the programs of a specific date in the tv guide :type channel: str :type date: str """ try: epg = self._vtm_go_epg.get_epg(channel=channel, date=date) except UnavailableException as ex: self._kodi.show_notification(message=str(ex)) self._kodi.end_of_directory() return listing = [] for broadcast in epg.broadcasts: if broadcast.playable_type == 'episodes': context_menu = [( self._kodi.localize(30102), # Go to Program 'XBMC.Container.Update(%s)' % self._kodi.url_for('show_program_from_epg', channel=channel, program=broadcast.uuid) )] else: context_menu = None title = '{time} - {title}{live}'.format( time=broadcast.time.strftime('%H:%M'), title=broadcast.title, live=' [I](LIVE)[/I]' if broadcast.live else '' ) if broadcast.airing: title = '[B]{title}[/B]'.format(title=title) if broadcast.title == self.EPG_NO_BROADCAST: title = '[COLOR gray]' + title + '[/COLOR]' listing.append( TitleItem(title=title, path=self._kodi.url_for('play_epg_program', channel=channel, program_type=broadcast.playable_type, epg_id=broadcast.uuid, airing=epg.uuid if broadcast.airing else None), art_dict={ 'icon': broadcast.image, 'thumb': broadcast.image, }, info_dict={ 'title': title, 'plot': broadcast.description, 'duration': broadcast.duration, 'mediatype': 'video', }, stream_dict={ 'duration': broadcast.duration, 'codec': 'h264', 'height': 1080, 'width': 1920, }, context_menu=context_menu, is_playable=True) ) self._kodi.show_listing(listing, 30013, content='episodes', sort=['unsorted'])
def show_catalog(self): """ Show the catalog """ try: categories = self._vtm_go.get_categories() except ApiUpdateRequired: self._kodi.show_ok_dialog(message=self._kodi.localize(30705)) # The VTM GO Service has been updated... return except Exception as ex: # pylint: disable=broad-except _LOGGER.error("%s", ex) self._kodi.show_ok_dialog(message="%s" % ex) return listing = [] for cat in categories: listing.append(TitleItem( title=cat.title, path=self._kodi.url_for('show_catalog_category', category=cat.category_id), info_dict=dict( plot='[B]{category}[/B]'.format(category=cat.title), ), )) # Sort categories by default like in VTM GO. self._kodi.show_listing(listing, 30003, content='files')
def show_livetv(): """ Shows Live TV channels """ try: channels = vtm_go.get_live_channels() except Exception as ex: kodi.show_notification(message=str(ex)) raise from . import CHANNEL_MAPPING listing = [] for channel in channels: if CHANNEL_MAPPING.get(channel.name): # Lookup the high resolution logo based on the channel name icon = '{path}/resources/logos/{logo}-white.png'.format( path=kodi.get_addon_path(), logo=CHANNEL_MAPPING.get(channel.name)) fanart = '{path}/resources/logos/{logo}.png'.format( path=kodi.get_addon_path(), logo=CHANNEL_MAPPING.get(channel.name)) else: # Fallback to the default (lower resolution) logo icon = channel.logo fanart = channel.logo title = channel.name if channel.epg: title += '[COLOR gray] | {title}[/COLOR]'.format( title=channel.epg[0].title) listing.append( TitleItem(title=title, path=routing.url_for( play, category='channels', item=channel.channel_id) + '?.pvr', art_dict={ 'icon': icon, 'thumb': icon, 'fanart': fanart, }, info_dict={ 'plot': _format_plot(channel), 'playcount': 0, 'mediatype': 'video', }, stream_dict={ 'codec': 'h264', 'height': 1080, 'width': 1920, }, is_playable=True), ) kodi.show_listing(listing, 30005)
def select_profile(self, key=None): """ Show your profiles :type key: str """ try: profiles = self._vtm_go.get_profiles() except InvalidLoginException: self._kodi.show_ok_dialog(message=self._kodi.localize(30203)) # Your credentials are not valid! self._kodi.open_settings() return except LoginErrorException as e: self._kodi.show_ok_dialog(message=self._kodi.localize(30702, code=e.code)) # Unknown error while logging in: {code} self._kodi.open_settings() return # Show warning when you have no profiles if not profiles: self._kodi.show_ok_dialog(message=self._kodi.localize(30703)) # Your account has no profiles defined. Please login on vtm.be/vtmgo and create a Profile. self._kodi.end_of_directory() return # Select the first profile when you only have one if len(profiles) == 1: key = profiles[0].key # Save the selected profile if key: profile = [x for x in profiles if x.key == key][0] self._kodi.log('Setting profile to %s' % profile) self._kodi.set_setting('profile', '%s:%s' % (profile.key, profile.product)) self._kodi.set_setting('profile_name', profile.name) self._kodi.redirect(self._kodi.url_for('show_main_menu')) return # Show profile selection when you have multiple profiles listing = [ TitleItem(title=self._get_profile_name(profile), path=self._kodi.url_for('select_profile', key=profile.key), art_dict=dict( icon='DefaultUser.png' ), info_dict=dict( plot=profile.name, )) for profile in profiles ] self._kodi.show_listing(listing, sort=['unsorted'], category=30057) # Select Profile return
def show_tvguide_detail(channel=None, date=None): """ Shows the programs of a specific date in the tv guide """ try: _vtmGoEpg = VtmGoEpg(kodi) epg = _vtmGoEpg.get_epg(channel=channel, date=date) except Exception as ex: kodi.show_notification(message=str(ex)) raise listing = [] for broadcast in epg.broadcasts: title = '{time} - {title}{live}'.format( time=broadcast.time.strftime('%H:%M'), title=broadcast.title, live=' [I](LIVE)[/I]' if broadcast.live else '') if broadcast.airing: title = '[B]{title}[/B]'.format(title=title) listing.append( TitleItem(title=title, path=routing.url_for( play_epg, channel=channel, program_type=broadcast.playable_type, epg_id=broadcast.uuid), art_dict={ 'icon': broadcast.image, 'thumb': broadcast.image, }, info_dict={ 'title': title, 'plot': broadcast.description, 'duration': broadcast.duration, 'mediatype': 'video', }, stream_dict={ 'duration': broadcast.duration, 'codec': 'h264', 'height': 1080, 'width': 1920, }, is_playable=True)) kodi.show_listing(listing, 30013, content='tvshows')
def show_catalog(self): """ Show the catalog """ try: categories = self._vtm_go.get_categories() except Exception as ex: self._kodi.show_notification(message=str(ex)) raise listing = [] for cat in categories: listing.append( TitleItem(title=cat.title, path=self._kodi.url_for('show_catalog_category', category=cat.category_id), info_dict={ 'plot': '[B]{category}[/B]'.format(category=cat.title), })) # Sort categories by default like in VTM GO. self._kodi.show_listing(listing, 30003, content='files')
def show_recommendations(self): """ Show the recommendations """ try: recommendations = self._vtm_go.get_recommendations() except Exception as ex: self._kodi.show_notification(message=str(ex)) raise listing = [] for cat in recommendations: listing.append( TitleItem(title=cat.title, path=self._kodi.url_for( 'show_recommendations_category', kids=self._kodi.kids_mode(), category=cat.category_id), info_dict={ 'plot': '[B]{category}[/B]'.format(category=cat.title), })) # Sort categories by default like in VTM GO. self._kodi.show_listing(listing, 30015, content='files')
def show_tvguide_channel(channel): """ Shows the dates in the tv guide """ listing = [] for day in VtmGoEpg(kodi).get_dates('%A %d %B %Y'): if day.get('highlight'): title = '[B]{title}[/B]'.format(title=day.get('title')) else: title = day.get('title') listing.append( TitleItem(title=title, path=routing.url_for(show_tvguide_detail, channel=channel, date=day.get('date')), art_dict={ 'icon': 'DefaultYear.png', 'thumb': 'DefaultYear.png', }, info_dict={ 'plot': None, })) kodi.show_listing(listing, 30013, content='files')
def show_catalog(): """ Show the catalog """ kids = kodi.kids_mode() try: categories = vtm_go.get_categories() except Exception as ex: kodi.show_notification(message=str(ex)) raise listing = [] for cat in categories: listing.append( TitleItem(title=cat.title, path=routing.url_for(show_kids_catalog_category if kids else show_catalog_category, category=cat.category_id), info_dict={ 'plot': '[B]{category}[/B]'.format(category=cat.title), })) # Sort categories by default like in VTM GO. kodi.show_listing(listing, 30003, content='files')
def show_channel_menu(self, key): """ Shows a TV channel :type key: str """ channel = CHANNELS[key] # Fetch EPG from API channel_info = self._vtm_go.get_live_channel(key) title = self._kodi.localize( 30052, channel=channel.get('label')) # Watch live {channel} if channel_info.epg: title += '[COLOR gray] | {title} ({start} - {end})[/COLOR]'.format( title=channel_info.epg[0].title, start=channel_info.epg[0].start.strftime('%H:%M'), end=channel_info.epg[0].end.strftime('%H:%M')) # Lookup the high resolution logo based on the channel name icon = '{path}/resources/logos/{logo}-white.png'.format( path=self._kodi.get_addon_path(), logo=channel.get('logo')) fanart = '{path}/resources/logos/{logo}.png'.format( path=self._kodi.get_addon_path(), logo=channel.get('logo')) listing = [ TitleItem(title=title, path=self._kodi.url_for('play', category='channels', item=channel_info.channel_id) + '?.pvr', art_dict={ 'icon': icon, 'thumb': icon, 'fanart': fanart, }, info_dict={ 'plot': self._menu.format_plot(channel_info), 'playcount': 0, 'mediatype': 'video', }, stream_dict={ 'codec': 'h264', 'height': 1080, 'width': 1920, }, is_playable=True), TitleItem( title=self._kodi.localize( 30053, channel=channel.get('label')), # TV Guide for {channel} path=self._kodi.url_for('show_tvguide_channel', channel=channel.get('epg')), art_dict={'icon': 'DefaultAddonTvInfo.png'}, info_dict={ 'plot': self._kodi.localize(30054, channel=channel.get( 'label')), # Browse the TV Guide for {channel} }), ] if self._kodi.get_setting_as_bool('metadata_update'): listing.append( TitleItem( title=self._kodi.localize( 30055, channel=channel.get('label')), # Catalog for {channel} path=self._kodi.url_for('show_catalog_channel', channel=key), art_dict={'icon': 'DefaultMovieTitle.png'}, info_dict={ 'plot': self._kodi.localize(30056, channel=channel.get('label')), })) # Add YouTube channels if self._kodi.get_cond_visibility( 'System.HasAddon(plugin.video.youtube)') != 0: for youtube in channel.get('youtube', []): listing.append( TitleItem( title=self._kodi.localize( 30206, label=youtube.get( 'label')), # Watch {label} on YouTube path=youtube.get('path'), info_dict={ 'plot': self._kodi.localize( 30206, label=youtube.get( 'label')), # Watch {label} on YouTube })) self._kodi.show_listing(listing, 30007, sort=['unsorted'])
def play(self, category, item): """ Play the requested item. :type category: string :type item: string """ # Check if inputstreamhelper is correctly installed try: from inputstreamhelper import Helper is_helper = Helper('mpd', drm='com.widevine.alpha') if not is_helper.check_inputstream(): # inputstreamhelper has already shown an error return except ImportError: self._kodi.show_ok_dialog(message=self._kodi.localize(30708)) # Please reboot Kodi return try: # Get stream information resolved_stream = self._vtm_go_stream.get_stream(category, item) except StreamGeoblockedException: self._kodi.show_ok_dialog(heading=self._kodi.localize(30709), message=self._kodi.localize(30710)) # This video is geo-blocked... self._kodi.end_of_directory() return except StreamUnavailableException: self._kodi.show_ok_dialog(heading=self._kodi.localize(30711), message=self._kodi.localize(30712)) # The video is unavailable... self._kodi.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, } # Lookup metadata try: if category in ['movies', 'oneoffs']: info_dict.update({'mediatype': 'movie'}) # Get details details = VtmGo(self._kodi).get_movie(item) info_dict.update({ 'plot': details.description, 'year': details.year, 'aired': details.aired, }) elif category == 'episodes': info_dict.update({'mediatype': 'episode'}) # Get details details = VtmGo(self._kodi).get_episode(item) info_dict.update({ 'plot': details.description, 'season': details.season, 'episode': details.number, }) 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: raise Exception('Unknown category %s' % category) except UnavailableException: # We continue without details. # This seems to make it possible to play some programs what don't have metadata. pass # Play this item self._kodi.play( TitleItem( title=resolved_stream.title, path=resolved_stream.url, subtitles_path=resolved_stream.subtitles, art_dict={}, info_dict=info_dict, prop_dict=prop_dict, stream_dict=stream_dict, is_playable=True, ), license_key=self._vtm_go_stream.create_license_key(resolved_stream.license_url))
def show_program(self, program): """ Show a program from the catalog :type program: str """ try: program_obj = self._vtm_go.get_program(program) except UnavailableException: self._kodi.show_ok_dialog( message=self._kodi.localize(30717) ) # This program is not available in the VTM GO catalogue. self._kodi.end_of_directory() return studio = CHANNELS.get(program_obj.channel, {}).get('studio_icon') listing = [] # Add an '* All seasons' entry when configured in Kodi if self._kodi.get_global_setting('videolibrary.showallitems') is True: listing.append( TitleItem( title='* %s' % self._kodi.localize(30204), # * All seasons path=self._kodi.url_for('show_catalog_program_season', program=program, season=-1), art_dict={ 'thumb': program_obj.cover, 'fanart': program_obj.cover, }, info_dict={ 'tvshowtitle': program_obj.name, 'title': self._kodi.localize(30204), # All seasons 'tagline': program_obj.description, 'set': program_obj.name, 'studio': studio, 'mpaa': ', '.join(program_obj.legal) if hasattr(program_obj, 'legal') and program_obj.legal else self._kodi.localize(30216), })) # Add the seasons for s in program_obj.seasons.values(): listing.append( TitleItem( title=self._kodi.localize(30205, season=s.number), # Season X path=self._kodi.url_for('show_catalog_program_season', program=program, season=s.number), art_dict={ 'thumb': s.cover, 'fanart': program_obj.cover, }, info_dict={ 'tvshowtitle': program_obj.name, 'title': self._kodi.localize(30205, season=s.number), 'tagline': program_obj.description, 'set': program_obj.name, 'studio': studio, 'mpaa': ', '.join(program_obj.legal) if hasattr(program_obj, 'legal') and program_obj.legal else self._kodi.localize(30216), })) # Sort by label. Some programs return seasons unordered. self._kodi.show_listing(listing, 30003, content='tvshows', sort='label')
def show_channels(self): """ Shows TV channels """ product = self._vtm_go.get_product() kids = (product == 'VTM_GO_KIDS') # Fetch EPG from API channel_infos = self._vtm_go.get_live_channels() listing = [] for i, key in enumerate(CHANNELS): # pylint: disable=unused-variable channel = CHANNELS[key] if kids and channel.get('kids') is False: continue # Find this channel in the list channel_info = next(c for c in channel_infos if c.key == key) # Lookup the high resolution logo based on the channel name icon = '{path}/resources/logos/{logo}-white.png'.format( path=self._kodi.get_addon_path(), logo=channel.get('logo')) fanart = '{path}/resources/logos/{logo}.png'.format( path=self._kodi.get_addon_path(), logo=channel.get('logo')) context_menu = [ ( self._kodi.localize( 30052, channel=channel.get('label')), # Watch live {channel} 'XBMC.PlayMedia(%s)' % self._kodi.url_for('play', category='channels', item=channel_info.channel_id)), ( self._kodi.localize(30053, channel=channel.get( 'label')), # TV Guide for {channel} 'XBMC.Container.Update(%s)' % self._kodi.url_for( 'show_tvguide_channel', channel=channel.get('epg'))) ] if self._kodi.get_setting_as_bool('metadata_update'): context_menu.append(( self._kodi.localize( 30055, channel=channel.get('label')), # Catalog for {channel} 'XBMC.Container.Update(%s)' % self._kodi.url_for('show_catalog_channel', channel=key))) title = channel.get('label') if channel_info and channel_info.epg: title += '[COLOR gray] | {title} ({start} - {end})[/COLOR]'.format( title=channel_info.epg[0].title, start=channel_info.epg[0].start.strftime('%H:%M'), end=channel_info.epg[0].end.strftime('%H:%M')) listing.append( TitleItem(title=title, path=self._kodi.url_for('show_channel_menu', channel=key), art_dict={ 'icon': icon, 'thumb': icon, 'fanart': fanart, }, info_dict={ 'plot': self._menu.format_plot(channel), 'playcount': 0, 'mediatype': 'video', 'studio': channel.get('studio_icon'), }, stream_dict={ 'codec': 'h264', 'height': 1080, 'width': 1920, }, context_menu=context_menu), ) self._kodi.show_listing(listing, 30007)
def play(self, category, item): """ Play the requested item. :type category: string :type item: string """ if not self._check_credentials(): self._kodi.end_of_directory() return # Check if inputstreamhelper is correctly installed if not self._check_inputstream(): self._kodi.end_of_directory() return try: # Get stream information resolved_stream = self._vtm_go_stream.get_stream(category, item) except StreamGeoblockedException: self._kodi.show_ok_dialog( heading=self._kodi.localize(30709), message=self._kodi.localize( 30710)) # This video is geo-blocked... self._kodi.end_of_directory() return except StreamUnavailableException: self._kodi.show_ok_dialog( heading=self._kodi.localize(30711), message=self._kodi.localize( 30712)) # The video is unavailable... self._kodi.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 # Play this item self._kodi.play(TitleItem( title=resolved_stream.title, path=resolved_stream.url, subtitles_path=resolved_stream.subtitles, art_dict={}, info_dict=info_dict, prop_dict=prop_dict, stream_dict=stream_dict, is_playable=True, ), license_key=self._vtm_go_stream.create_license_key( resolved_stream.license_url)) # Wait for playback to start kodi_player = KodiPlayer(kodi=self._kodi) if not kodi_player.waitForPlayBack(url=resolved_stream.url): # Playback didn't start return # Add subtitles if resolved_stream.subtitles: _LOGGER.debug('Setting subtitles') kodi_player.setSubtitles(resolved_stream.subtitles[0]) # Turn on subtitles if needed if self._kodi.get_setting_as_bool('showsubtitles'): _LOGGER.debug('Enabling subtitles') kodi_player.showSubtitles(True) # Send Up Next data if upnext_data: _LOGGER.debug("Sending Up Next data: %s", upnext_data) self.send_upnext(upnext_data)
def show_channels(self): """ Shows TV channels """ # Fetch EPG from API channels = self._vtm_go.get_live_channels() listing = [] for channel in channels: channel_data = CHANNELS.get(channel.key) icon = channel.logo fanart = channel.background title = channel.name if channel_data: icon = '{path}/resources/logos/{logo}-white.png'.format( path=self._kodi.get_addon_path(), logo=channel.key) title = channel_data.get('label') context_menu = [( self._kodi.localize(30052, channel=title), # Watch live {channel} 'PlayMedia(%s)' % self._kodi.url_for( 'play', category='channels', item=channel.channel_id), )] if channel_data and channel_data.get('epg'): context_menu.append(( self._kodi.localize( 30053, channel=title), # TV Guide for {channel} 'Container.Update(%s)' % self._kodi.url_for('show_tvguide_channel', channel=channel_data.get('epg')))) context_menu.append(( self._kodi.localize(30055, channel=title), # Catalog for {channel} 'Container.Update(%s)' % self._kodi.url_for( 'show_catalog_channel', channel=channel.key))) if channel.epg: label = title + '[COLOR gray] | {title} ({start} - {end})[/COLOR]'.format( title=channel.epg[0].title, start=channel.epg[0].start.strftime('%H:%M'), end=channel.epg[0].end.strftime('%H:%M')) else: label = title listing.append( TitleItem( title=label, path=self._kodi.url_for('show_channel_menu', channel=channel.key), art_dict=dict( icon=icon, thumb=icon, fanart=fanart, ), info_dict=dict( plot=self._menu.format_plot(channel), playcount=0, mediatype='video', studio=channel_data.get('studio_icon') if channel_data else None, ), stream_dict=dict( codec='h264', height=1080, width=1920, ), context_menu=context_menu, )) self._kodi.show_listing(listing, 30007)
def show_mainmenu(self): """ Show the main menu """ kids = self._kodi.kids_mode() listing = [] listing.append( TitleItem( title=self._kodi.localize(30001), # A-Z path=self._kodi.url_for('show_catalog_all', kids=kids), art_dict=dict(icon='DefaultMovieTitle.png'), info_dict=dict(plot=self._kodi.localize(30002), ))) listing.append( TitleItem( title=self._kodi.localize(30003), # Catalogue path=self._kodi.url_for('show_catalog', kids=kids), art_dict=dict(icon='DefaultGenre.png'), info_dict=dict(plot=self._kodi.localize(30004), ))) listing.append( TitleItem( title=self._kodi.localize(30007), # TV Channels path=self._kodi.url_for('show_channels', kids=kids), art_dict=dict(icon='DefaultAddonPVRClient.png'), info_dict=dict(plot=self._kodi.localize(30008), ))) if self._kodi.get_setting_as_bool('interface_show_recommendations'): listing.append( TitleItem( title=self._kodi.localize(30015), # Recommendations path=self._kodi.url_for('show_recommendations', kids=kids), art_dict={'icon': 'DefaultFavourites.png'}, info_dict={ 'plot': self._kodi.localize(30016), })) if self._kodi.get_setting_as_bool('interface_show_mylist'): listing.append( TitleItem( title=self._kodi.localize(30017), # My List path=self._kodi.url_for('show_mylist', kids=kids), art_dict={'icon': 'DefaultPlaylist.png'}, info_dict={ 'plot': self._kodi.localize(30018), })) if self._kodi.get_setting_as_bool('interface_show_continuewatching'): listing.append( TitleItem( title=self._kodi.localize(30019), # Continue watching path=self._kodi.url_for('show_continuewatching', kids=kids), art_dict={'icon': 'DefaultInProgressShows.png'}, info_dict={ 'plot': self._kodi.localize(30020), })) listing.append( TitleItem( title=self._kodi.localize(30009), # Search path=self._kodi.url_for('show_search', kids=kids), art_dict=dict(icon='DefaultAddonsSearch.png'), info_dict=dict(plot=self._kodi.localize(30010), ))) if self._kodi.get_setting_as_bool( 'interface_show_kids_zone') and not kids: listing.append( TitleItem( title=self._kodi.localize(30011), # Kids Zone path=self._kodi.url_for('show_main_menu', kids=True), art_dict=dict(icon='DefaultUser.png'), info_dict=dict(plot=self._kodi.localize(30012), ))) self._kodi.show_listing(listing)
def show_channel_menu(self, key): """ Shows a TV channel :type key: str """ # Fetch EPG from API channel = self._vtm_go.get_live_channel(key) channel_data = CHANNELS.get(channel.key) icon = channel.logo fanart = channel.background title = channel.name if channel_data: icon = '{path}/resources/logos/{logo}-white.png'.format( path=self._kodi.get_addon_path(), logo=channel.key) title = channel_data.get('label') title = self._kodi.localize(30052, channel=title) # Watch live {channel} if channel.epg: label = title + '[COLOR gray] | {title} ({start} - {end})[/COLOR]'.format( title=channel.epg[0].title, start=channel.epg[0].start.strftime('%H:%M'), end=channel.epg[0].end.strftime('%H:%M')) else: label = title # The .pvr suffix triggers some code paths in Kodi to mark this as a live channel listing = [ TitleItem( title=label, path=self._kodi.url_for( 'play', category='channels', item=channel.channel_id) + '?.pvr', art_dict=dict( icon=icon, thumb=icon, fanart=fanart, ), info_dict=dict( plot=self._menu.format_plot(channel), playcount=0, mediatype='video', ), stream_dict=dict( codec='h264', height=1080, width=1920, ), is_playable=True, ) ] if channel_data and channel_data.get('epg'): listing.append( TitleItem( title=self._kodi.localize( 30053, channel=channel.name), # TV Guide for {channel} path=self._kodi.url_for('show_tvguide_channel', channel=channel_data.get('epg')), art_dict=dict(icon='DefaultAddonTvInfo.png', ), info_dict=dict( plot=self._kodi.localize( 30054, channel=channel.name ), # Browse the TV Guide for {channel} ), )) listing.append( TitleItem( title=self._kodi.localize( 30055, channel=channel.name), # Catalog for {channel} path=self._kodi.url_for('show_catalog_channel', channel=key), art_dict=dict(icon='DefaultMovieTitle.png'), info_dict=dict(plot=self._kodi.localize( 30056, channel=channel.name), ), )) # Add YouTube channels if channel_data and self._kodi.get_cond_visibility( 'System.HasAddon(plugin.video.youtube)') != 0: for youtube in channel_data.get('youtube', []): listing.append( TitleItem( title=self._kodi.localize( 30206, label=youtube.get( 'label')), # Watch {label} on YouTube path=youtube.get('path'), info_dict=dict( plot=self._kodi.localize( 30206, label=youtube.get( 'label')), # Watch {label} on YouTube ))) self._kodi.show_listing(listing, 30007, sort=['unsorted'])
def _generate_titleitem(item, my_list=False): """ Generate a TitleItem based on a Content. :type item: Content :rtype TitleItem """ kids = kodi.kids_mode() art_dict = { 'thumb': item.cover, } info_dict = { 'title': item.title, 'plot': item.description, } if my_list: context_menu = [( kodi.localize(30051), # Remove from My List 'XBMC.Container.Update(%s)' % routing.url_for(mylist_del if not kids else kids_mylist_del, video_type=item.video_type, content_id=item.content_id))] else: context_menu = [( kodi.localize(30050), # Add to My List 'XBMC.Container.Update(%s)' % routing.url_for(mylist_add if not kids else kids_mylist_add, video_type=item.video_type, content_id=item.content_id))] if item.video_type == Content.CONTENT_TYPE_MOVIE: # Get movie details from cache movie = vtm_go.get_movie(item.content_id, only_cache=True) if movie: art_dict.update({ 'fanart': movie.cover, }) info_dict.update({ 'plot': _format_plot(movie), 'duration': movie.duration, 'year': movie.year, 'aired': movie.aired, 'mpaa': ', '.join(movie.legal) if hasattr(movie, 'legal') and movie.legal else kodi.localize(30216), }) info_dict.update({ 'mediatype': 'movie', }) return TitleItem(title=item.title, path=routing.url_for(play, category='movies', item=item.content_id), art_dict=art_dict, info_dict=info_dict, stream_dict={ 'codec': 'h264', 'height': 1080, 'width': 1920, }, context_menu=context_menu, is_playable=True) if item.video_type == Content.CONTENT_TYPE_PROGRAM: # Get program details from cache program = vtm_go.get_program(item.content_id, only_cache=True) if program: art_dict.update({ 'fanart': program.cover, 'banner': item.cover, }) info_dict.update({ 'title': program.name, 'plot': _format_plot(program), 'mpaa': ', '.join(program.legal) if hasattr(program, 'legal') and program.legal else kodi.localize(30216), 'season': len(program.seasons), }) info_dict.update({ 'mediatype': None, }) return TitleItem(title=item.title, path=routing.url_for(show_program, program=item.content_id), art_dict=art_dict, info_dict=info_dict, context_menu=context_menu) return None
def generate_titleitem(self, item, progress=False): """ Generate a TitleItem based on a Movie, Program or Episode. :type item: Union[Movie, Program, Episode] :type progress: bool :rtype TitleItem """ art_dict = { 'thumb': item.cover, 'cover': item.cover, } info_dict = { 'title': item.name, 'plot': self.format_plot(item), 'studio': CHANNELS.get(item.channel, {}).get('studio_icon'), 'mpaa': ', '.join(item.legal) if hasattr(item, 'legal') and item.legal else self._kodi.localize(30216), # All ages } prop_dict = {} # # Movie # if isinstance(item, Movie): if item.my_list: context_menu = [( self._kodi.localize(30101), # Remove from My List 'Container.Update(%s)' % self._kodi.url_for( 'mylist_del', video_type=self._vtm_go.CONTENT_TYPE_MOVIE, content_id=item.movie_id))] else: context_menu = [( self._kodi.localize(30100), # Add to My List 'Container.Update(%s)' % self._kodi.url_for( 'mylist_add', video_type=self._vtm_go.CONTENT_TYPE_MOVIE, content_id=item.movie_id))] art_dict.update({ 'fanart': item.image, }) info_dict.update({ 'mediatype': 'movie', 'duration': item.duration, 'year': item.year, 'aired': item.aired, }) stream_dict = { 'codec': 'h264', 'duration': item.duration, 'height': 1080, 'width': 1920, } return TitleItem( title=item.name, path=self._kodi.url_for('play', category='movies', item=item.movie_id), art_dict=art_dict, info_dict=info_dict, stream_dict=stream_dict, context_menu=context_menu, is_playable=True, ) # # Program # if isinstance(item, Program): if item.my_list: context_menu = [( self._kodi.localize(30101), # Remove from My List 'Container.Update(%s)' % self._kodi.url_for( 'mylist_del', video_type=self._vtm_go.CONTENT_TYPE_PROGRAM, content_id=item.program_id))] else: context_menu = [( self._kodi.localize(30100), # Add to My List 'Container.Update(%s)' % self._kodi.url_for( 'mylist_add', video_type=self._vtm_go.CONTENT_TYPE_PROGRAM, content_id=item.program_id))] art_dict.update({ 'fanart': item.image, }) info_dict.update({ 'mediatype': None, 'season': len(item.seasons), }) return TitleItem( title=item.name, path=self._kodi.url_for('show_catalog_program', program=item.program_id), art_dict=art_dict, info_dict=info_dict, context_menu=context_menu, ) # # Episode # if isinstance(item, Episode): context_menu = [] if item.program_id: context_menu = [( self._kodi.localize(30102), # Go to Program 'Container.Update(%s)' % self._kodi.url_for( 'show_catalog_program', program=item.program_id))] art_dict.update({ 'fanart': item.cover, }) info_dict.update({ 'mediatype': 'episode', 'tvshowtitle': item.program_name, 'duration': item.duration, 'season': item.season, 'episode': item.number, 'set': item.program_name, 'aired': item.aired, }) if progress and item.watched: info_dict.update({ 'playcount': 1, }) stream_dict = { 'codec': 'h264', 'duration': item.duration, 'height': 1080, 'width': 1920, } # Add progress info if progress and not item.watched and item.progress: prop_dict.update({ 'ResumeTime': item.progress, 'TotalTime': item.progress + 1, }) return TitleItem( title=info_dict['title'], path=self._kodi.url_for('play', category='episodes', item=item.episode_id), art_dict=art_dict, info_dict=info_dict, stream_dict=stream_dict, prop_dict=prop_dict, context_menu=context_menu, is_playable=True, ) raise Exception('Unknown video_type')
def show_mainmenu(self): """ Show the main menu """ listing = [] listing.append( TitleItem( title=self._kodi.localize(30001), # A-Z path=self._kodi.url_for('show_catalog_all'), art_dict=dict( icon='DefaultMovieTitle.png', fanart=self._kodi.get_addon_info('fanart'), ), info_dict=dict(plot=self._kodi.localize(30002), ), )) listing.append( TitleItem( title=self._kodi.localize(30003), # Catalogue path=self._kodi.url_for('show_catalog'), art_dict=dict( icon='DefaultGenre.png', fanart=self._kodi.get_addon_info('fanart'), ), info_dict=dict(plot=self._kodi.localize(30004), ), )) listing.append( TitleItem( title=self._kodi.localize(30007), # TV Channels path=self._kodi.url_for('show_channels'), art_dict=dict( icon='DefaultAddonPVRClient.png', fanart=self._kodi.get_addon_info('fanart'), ), info_dict=dict(plot=self._kodi.localize(30008), ), )) if self._kodi.get_setting_as_bool('interface_show_recommendations'): listing.append( TitleItem( title=self._kodi.localize(30015), # Recommendations path=self._kodi.url_for('show_recommendations'), art_dict=dict( icon='DefaultFavourites.png', fanart=self._kodi.get_addon_info('fanart'), ), info_dict=dict(plot=self._kodi.localize(30016), ), )) if self._kodi.get_setting_as_bool( 'interface_show_mylist') and self._kodi.has_credentials(): listing.append( TitleItem( title=self._kodi.localize(30017), # My List path=self._kodi.url_for('show_mylist'), art_dict=dict( icon='DefaultPlaylist.png', fanart=self._kodi.get_addon_info('fanart'), ), info_dict=dict(plot=self._kodi.localize(30018), ), )) if self._kodi.get_setting_as_bool('interface_show_continuewatching' ) and self._kodi.has_credentials(): listing.append( TitleItem( title=self._kodi.localize(30019), # Continue watching path=self._kodi.url_for('show_continuewatching'), art_dict=dict( icon='DefaultInProgressShows.png', fanart=self._kodi.get_addon_info('fanart'), ), info_dict=dict(plot=self._kodi.localize(30020), ), )) listing.append( TitleItem( title=self._kodi.localize(30009), # Search path=self._kodi.url_for('show_search'), art_dict=dict( icon='DefaultAddonsSearch.png', fanart=self._kodi.get_addon_info('fanart'), ), info_dict=dict(plot=self._kodi.localize(30010), ), )) self._kodi.show_listing(listing, sort=['unsorted'])
def show_program_season(program, season): """ Show a program from the catalog """ try: program_obj = vtm_go.get_program(program) except Exception as ex: kodi.show_notification(message=str(ex)) raise if season == 'all': # Show all seasons seasons = program_obj.seasons.values() else: # Show the season that was selected seasons = [program_obj.seasons[int(season)]] listing = [] for s in seasons: for episode in s.episodes.values(): listing.append( TitleItem( title=episode.name, path=routing.url_for(play, category='episodes', item=episode.episode_id), art_dict={ 'banner': program_obj.cover, 'fanart': program_obj.cover, 'thumb': episode.cover, }, info_dict={ 'tvshowtitle': program_obj.name, 'title': episode.name, 'tagline': program_obj.description, 'plot': _format_plot(episode), 'duration': episode.duration, 'season': episode.season, 'episode': episode.number, 'mediatype': 'episode', 'set': program_obj.name, 'studio': episode.channel, 'aired': episode.aired, 'mpaa': ', '.join(episode.legal) if hasattr(episode, 'legal') and episode.legal else kodi.localize(30216), }, stream_dict={ 'duration': episode.duration, 'codec': 'h264', 'height': 1080, 'width': 1920, }, is_playable=True)) # Sort by episode number by default. Takes seasons into account. kodi.show_listing(listing, 30003, content='episodes', sort='episode')
def show_program(program): """ Show a program from the catalog """ try: program_obj = vtm_go.get_program(program) except Exception as ex: kodi.show_notification(message=str(ex)) raise listing = [] # Add an '* All seasons' entry when configured in Kodi if kodi.get_global_setting('videolibrary.showallitems') is True: listing.append( TitleItem( title='* %s' % kodi.localize(30204), # * All seasons path=routing.url_for(show_program_season, program=program, season='all'), art_dict={ 'thumb': program_obj.cover, 'fanart': program_obj.cover, }, info_dict={ 'tvshowtitle': program_obj.name, 'title': kodi.localize(30204), # All seasons 'tagline': program_obj.description, 'set': program_obj.name, 'mpaa': ', '.join(program_obj.legal) if hasattr(program_obj, 'legal') and program_obj.legal else kodi.localize(30216), })) # Add the seasons for s in program_obj.seasons.values(): listing.append( TitleItem( title=kodi.localize(30205, season=s.number), # Season X path=routing.url_for(show_program_season, program=program, season=s.number), art_dict={ 'thumb': s.cover, 'fanart': program_obj.cover, }, info_dict={ 'tvshowtitle': program_obj.name, 'title': kodi.localize(30205, season=s.number), 'tagline': program_obj.description, 'set': program_obj.name, 'mpaa': ', '.join(program_obj.legal) if hasattr(program_obj, 'legal') and program_obj.legal else kodi.localize(30216), })) # Sort by label. Some programs return seasons unordered. kodi.show_listing(listing, 30003, content='tvshows', sort='label')
def show_tvguide_detail(self, channel=None, date=None): """ Shows the programs of a specific date in the tv guide :type channel: str :type date: str """ try: epg = self._vtm_go_epg.get_epg(channel=channel, date=date) except UnavailableException as ex: self._kodi.show_notification(message=str(ex)) self._kodi.end_of_directory() return listing = [] for broadcast in epg.broadcasts: if broadcast.playable_type == 'episodes': context_menu = [( self._kodi.localize(30102), # Go to Program 'Container.Update(%s)' % self._kodi.url_for('show_catalog_program', channel=channel, program=broadcast.program_uuid))] else: context_menu = None title = '{time} - {title}{live}'.format( time=broadcast.time.strftime('%H:%M'), title=broadcast.title, live=' [I](LIVE)[/I]' if broadcast.live else '') if broadcast.airing: title = '[B]{title}[/B]'.format(title=title) path = self._kodi.url_for('play_or_live', channel=broadcast.channel_uuid, category=broadcast.playable_type, item=broadcast.playable_uuid) else: path = self._kodi.url_for('play', category=broadcast.playable_type, item=broadcast.playable_uuid) listing.append( TitleItem( title=title, path=path, art_dict=dict( icon=broadcast.image, thumb=broadcast.image, ), info_dict=dict( title=title, plot=broadcast.description, duration=broadcast.duration, mediatype='video', ), stream_dict=dict( duration=broadcast.duration, codec='h264', height=1080, width=1920, ), context_menu=context_menu, is_playable=True, )) self._kodi.show_listing(listing, 30013, content='episodes', sort=['unsorted'])
def show_index(): """ Show the main menu """ kids = kodi.kids_mode() listing = [] listing.extend([ TitleItem( title=kodi.localize(30001), # A-Z path=routing.url_for(show_catalog_category if not kids else show_kids_catalog_category, category='all'), art_dict=dict(icon='DefaultMovieTitle.png'), info_dict=dict(plot=kodi.localize(30002), )), TitleItem( title=kodi.localize(30003), # Catalogue path=routing.url_for( show_catalog if not kids else show_kids_catalog), art_dict=dict(icon='DefaultGenre.png'), info_dict=dict(plot=kodi.localize(30004), )), TitleItem( title=kodi.localize(30005), # Live TV path=routing.url_for( show_livetv if not kids else show_kids_livetv), art_dict=dict(icon='DefaultAddonPVRClient.png'), info_dict=dict(plot=kodi.localize(30006), )), TitleItem( title=kodi.localize(30013), # TV Guide path=routing.url_for( show_tvguide if not kids else show_kids_tvguide), art_dict={'icon': 'DefaultAddonTvInfo.png'}, info_dict={ 'plot': kodi.localize(30014), }), TitleItem( title=kodi.localize(30015), # Recommendations path=routing.url_for(show_recommendations if not kids else show_kids_recommendations), art_dict={'icon': 'DefaultFavourites.png'}, info_dict={ 'plot': kodi.localize(30016), }), TitleItem( title=kodi.localize(30017), # My List path=routing.url_for( show_mylist if not kids else show_kids_mylist), art_dict={'icon': 'DefaultPlaylist.png'}, info_dict={ 'plot': kodi.localize(30018), }), ]) # Only provide YouTube option when plugin.video.youtube is available if kodi.get_cond_visibility('System.HasAddon(plugin.video.youtube)') != 0: listing.append( TitleItem( title=kodi.localize(30007), # YouTube path=routing.url_for( show_youtube if not kids else show_kids_youtube), art_dict=dict(icon='DefaultTags.png'), info_dict=dict(plot=kodi.localize(30008), ))) listing.extend([ TitleItem( title=kodi.localize(30009), # Search path=routing.url_for( show_search if not kids else show_kids_search), art_dict=dict(icon='DefaultAddonsSearch.png'), info_dict=dict(plot=kodi.localize(30010), )), ]) if not kids: listing.append( TitleItem( title=kodi.localize(30011), # Kids Zone path=routing.url_for(show_kids_index), art_dict=dict(icon='DefaultUser.png'), info_dict=dict(plot=kodi.localize(30012), ))) kodi.show_listing(listing)