def show_livestream_items(self): livestream_items = [ helperobjects.TitleItem( title=self._kodi_wrapper.get_localized_string(32101), url_dict=dict(action=actions.PLAY, video_url=self._EEN_LIVESTREAM), is_playable=True, art_dict=dict(thumb=self.__get_media('een.png'), icon='DefaultAddonPVRClient.png', fanart=self._api_helper.get_live_screenshot('een')), video_dict=dict(plot=self._kodi_wrapper.get_localized_string(32201) + '\n' + self._kodi_wrapper.get_localized_string(32102)), ), helperobjects.TitleItem( title=self._kodi_wrapper.get_localized_string(32111), url_dict=dict(action=actions.PLAY, video_url=self._CANVAS_LIVESTREAM), is_playable=True, art_dict=dict(thumb=self.__get_media('canvas.png'), icon='DefaultAddonPVRClient.png', fanart=self._api_helper.get_live_screenshot('canvas')), video_dict=dict(plot=self._kodi_wrapper.get_localized_string(32201) + '\n' + self._kodi_wrapper.get_localized_string(32112)), ), helperobjects.TitleItem( title=self._kodi_wrapper.get_localized_string(32121), url_dict=dict(action=actions.PLAY, video_url=self._KETNET_LIVESTREAM), is_playable=True, art_dict=dict(thumb=self.__get_media('ketnet.png'), icon='DefaultAddonPVRClient.png', fanart=self._api_helper.get_live_screenshot('ketnet')), video_dict=dict(plot=self._kodi_wrapper.get_localized_string(32201) + '\n' + self._kodi_wrapper.get_localized_string(32122)), ), ] self._kodi_wrapper.show_listing(livestream_items, content_type='videos')
def show_main_menu_items(self): main_items = [ helperobjects.TitleItem(title=self._kodi_wrapper.get_localized_string(32080), url_dict=dict(action=actions.LISTING_AZ_TVSHOWS), is_playable=False, art_dict=dict(thumb='DefaultMovieTitle.png', icon='DefaultMovieTitle.png', fanart='DefaultMovieTitle.png'), video_dict=dict(plot=self._kodi_wrapper.get_localized_string(32081))), helperobjects.TitleItem(title=self._kodi_wrapper.get_localized_string(32082), url_dict=dict(action=actions.LISTING_CATEGORIES), is_playable=False, art_dict=dict(thumb='DefaultGenre.png', icon='DefaultGenre.png', fanart='DefaultGenre.png'), video_dict=dict(plot=self._kodi_wrapper.get_localized_string(32083))), helperobjects.TitleItem(title=self._kodi_wrapper.get_localized_string(32084), url_dict=dict(action=actions.LISTING_LIVE), is_playable=False, art_dict=dict(thumb='DefaultAddonPVRClient.png', icon='DefaultAddonPVRClient.png', fanart='DefaultAddonPVRClient.png'), video_dict=dict(plot=self._kodi_wrapper.get_localized_string(32085))), helperobjects.TitleItem(title=self._kodi_wrapper.get_localized_string(32086), url_dict=dict(action=actions.LISTING_EPISODES, video_url='recent'), is_playable=False, art_dict=dict(thumb='DefaultYear.png', icon='DefaultYear.png', fanart='DefaultYear.png'), video_dict=dict(plot=self._kodi_wrapper.get_localized_string(32087))), helperobjects.TitleItem(title=self._kodi_wrapper.get_localized_string(32088), url_dict=dict(action=actions.LISTING_TVGUIDE), is_playable=False, art_dict=dict(thumb='DefaultAddonTvInfo.png', icon='DefaultAddonTvInfo.png', fanart='DefaultAddonTvInfo.png'), video_dict=dict(plot=self._kodi_wrapper.get_localized_string(32089))), ] self._kodi_wrapper.show_listing(main_items, sort='unsorted', content_type='files')
def show_main_menu_items(self): menu_items = { helperobjects.TitleItem( self._kodi_wrapper.get_localized_string(32091), {'action': actions.LISTING_AZ}, False, None), helperobjects.TitleItem( self._kodi_wrapper.get_localized_string(32092), {'action': actions.LISTING_CATEGORIES}, False, None), helperobjects.TitleItem( self._kodi_wrapper.get_localized_string(32100), {'action': actions.LISTING_LIVE}, False, None) } self._kodi_wrapper.show_listing(menu_items, sortmethod.ALPHABET)
def show_video_category_episodes(self, path): category = path.split('/')[-2] joined_url = self._VRTNU_SEARCH_URL + category response = requests.get(joined_url) programs = response.json() menu_items = [] for program in programs: title = program['title'] plot = BeautifulSoup(program['description'], 'html.parser').text thumbnail = statichelper.replace_double_slashes_with_https( program['thumbnail']) metadata_creator = metadatacreator.MetadataCreator() metadata_creator.plot = plot video_dictionary = metadata_creator.get_video_dictionary() #cut vrtbase url off since it will be added again when searching for episodes (with a-z we dont have the # full url) link_to_video = statichelper.replace_double_slashes_with_https( program['targetUrl']).replace(self._VRT_BASE, '') item = helperobjects.TitleItem(title, { 'action': actions.LISTING_VIDEOS, 'video': link_to_video }, False, thumbnail, video_dictionary) menu_items.append(item) self._kodi_wrapper.show_listing(menu_items, sortmethod.ALPHABET)
def _map_to_season_items(self, api_url, seasons, episode): season_items = [] sort = 'label' ascending = True fanart = statichelper.add_https_method(episode.get('programImageUrl', 'DefaultSets.png')) program_type = episode.get('programType') metadata = metadatacreator.MetadataCreator() metadata.mediatype = 'season' metadata.brands = episode.get('programBrands') or episode.get('brands') # Reverse sort seasons if program_type is 'reeksaflopend' or 'daily' if program_type in ('daily', 'reeksaflopend'): ascending = False # NOTE: Sort the episodes ourselves, because Kodi does not allow to set to 'ascending' seasons = sorted(seasons, key=lambda k: k['key'], reverse=not ascending) for season in seasons: season_key = season.get('key') title = '%s %s' % (self._kodi_wrapper.get_localized_string(32094), season_key) season_facet = '&facets[seasonTitle]=' path = api_url + season_facet + season_key season_items.append(helperobjects.TitleItem( title=title, url_dict=dict(action=actions.LISTING_EPISODES, video_url=path), is_playable=False, art_dict=dict(thumb=fanart, icon='DefaultSets.png', fanart=fanart), video_dict=metadata.get_video_dict(), )) return season_items, sort, ascending
def __get_multiple_videos(self, tiles): title_items = [] episode_list = tiles.find("div", {"id": "episodelist__slider"}) for tile in episode_list.find_all(class_="tile"): thumbnail = VRTPlayer.__format_image_url(tile) found_element = tile.find(class_="tile__title") if found_element is not None: title = statichelper.replace_newlines_and_strip( found_element.contents[0]) broadcast_date_tag = tile.find( class_="tile__broadcastdate--mobile") if broadcast_date_tag is not None: title = broadcast_date_tag.text + " " + title path = tile["href"] video_dictionary = self.metadata_collector.get_multiple_layout_episode_metadata( tile) title_items.append( helperobjects.TitleItem(title, { "action": actions.PLAY, "video": path }, True, thumbnail, video_dictionary)) return title_items
def get_tvshow_items(self, path=None): if path: api_url = self._VRTNU_SUGGEST_URL + '?facets[categories]=' + path else: # If no path is provided, we return the A-Z listing api_url = self._VRTNU_SUGGEST_URL + '?facets[transcodingStatus]=AVAILABLE' tvshows = requests.get(api_url, proxies=self._proxies).json() tvshow_items = [] for tvshow in tvshows: metadata = metadatacreator.MetadataCreator() metadata.mediatype = 'tvshow' metadata.tvshowtitle = tvshow.get('title', '???') metadata.plot = statichelper.unescape(tvshow.get('description', '???')) metadata.brands = tvshow.get('brands') metadata.permalink = statichelper.shorten_link(tvshow.get('targetUrl')) # NOTE: This adds episode_count to title, would be better as metadata # title = '%s [LIGHT][COLOR yellow]%s[/COLOR][/LIGHT]' % (tvshow.get('title', '???'), tvshow.get('episode_count', '?')) title = tvshow.get('title', '???') thumbnail = statichelper.add_https_method(tvshow.get('thumbnail', 'DefaultAddonVideo.png')) # Cut vrtbase url off since it will be added again when searching for episodes # (with a-z we dont have the full url) video_url = statichelper.add_https_method(tvshow.get('targetUrl')).replace(self._VRT_BASE, '') tvshow_items.append(helperobjects.TitleItem(title=title, url_dict=dict(action=actions.LISTING_EPISODES, video_url=video_url), is_playable=False, art_dict=dict(thumb=thumbnail, icon='DefaultAddonVideo.png', fanart=thumbnail), video_dict=metadata.get_video_dict())) return tvshow_items
def __get_multiple_videos_episodes_list_id(self, soup): title_items = [] #some episodes have a different episodelist using class episodelist instead of id episode-list :/ episode_list_css = soup.find('div', {'class': 'episodeslist'}) episode_list = soup.find('div', {'id': 'episodes-list'}) if episode_list_css is not None: episode_list = episode_list_css.find( 'div', {'id': 'episodes-list-wrapper'}) for tile in episode_list.find_all('li'): thumbnail = VRTPlayer.__format_image_url(tile) found_element = tile.find(class_='vrtnu-list--item-meta') if found_element is not None: h_tag = found_element.find('h3') title = statichelper.replace_newlines_and_strip(h_tag.text) broadcast_date_tag = found_element.find( class_='vrtnu-list--item-meta__mobile') if broadcast_date_tag is not None: clean_date = VRTPlayer.__strip_date_from_unessecary_caracters( broadcast_date_tag.text) title = clean_date + ' ' + title path = tile.find('a')['href'] video_dictionary = self.metadata_collector.get_multiple_layout_episode_metadata( tile) title_items.append( helperobjects.TitleItem(title, { 'action': actions.PLAY, 'video': path }, True, thumbnail, video_dictionary)) return title_items
def show_livestream_items(self): livestream_items = { helperobjects.TitleItem( self._kodi_wrapper.get_localized_string(32101), { 'action': actions.PLAY, 'video': self._EEN_LIVESTREAM }, True, self.__get_media('een.png')), helperobjects.TitleItem( self._kodi_wrapper.get_localized_string(32102), { 'action': actions.PLAY, 'video': self._CANVAS_LIVESTREAM_ }, True, self.__get_media('canvas.png')), helperobjects.TitleItem( self._kodi_wrapper.get_localized_string(32103), { 'action': actions.PLAY, 'video': self._KETNET_LIVESTREAM }, True, self.__get_media('ketnet.png')) } self._kodi_wrapper.show_listing(livestream_items, sortmethod.ALPHABET)
def __get_episodes(self, option_tags): """ This method gets all the episodes = seasons from the dropdownmenus on the vrt.nu website :param option_tags: :return: """ title_items = [] for option_tag in option_tags: title = statichelper.replace_newlines_and_strip(option_tag.text) if option_tag.has_attr('data-href'): path = option_tag['data-href'] title_items.append( helperobjects.TitleItem(title, { "action": actions.LISTING_VIDEOS, 'video': path }, False)) return title_items
def __get_category_menu_items(self, url, soupstrainer_parser_selector, routing_action, video_dict_action=None): response = requests.get(url, proxies=self._proxies) tiles = SoupStrainer('a', soupstrainer_parser_selector) soup = BeautifulSoup(response.content, 'html.parser', parse_only=tiles) listing = [] for tile in soup.find_all(class_='nui-tile'): category = tile.get('href').split('/')[-2] thumbnail, title = self.__get_category_thumbnail_and_title(tile) video_dict = None if video_dict_action is not None: video_dict = video_dict_action(tile) listing.append(helperobjects.TitleItem(title=title, url_dict=dict(action=routing_action, video_url=category), is_playable=False, art_dict=dict(thumb=thumbnail, icon='DefaultGenre.png', fanart=thumbnail), video_dict=video_dict)) return listing
def __get_single_video(self, path, soup): title_items = [] video_dictionary = self.metadata_collector.get_single_layout_episode_metadata( soup) list_item_title = soup.find(class_="content__title").text if "shortdate" in video_dictionary: list_item_title = video_dictionary[ "shortdate"] + " " + list_item_title vrt_video = soup.find(class_="vrtvideo") thumbnail = VRTPlayer.__format_image_url(vrt_video) title_items.append( helperobjects.TitleItem(list_item_title, { "action": actions.PLAY, "video": path }, True, thumbnail, video_dictionary)) return title_items
def __get_single_video(self, path, soup): title_items = [] video_dictionary = self.metadata_collector.get_single_layout_episode_metadata( soup) content = soup.find(class_='content2') list_item_title = content.find('h1').text if 'shortdate' in video_dictionary: list_item_title = video_dictionary[ 'shortdate'] + ' ' + list_item_title vrt_video = soup.find(class_='vrtvideo') thumbnail = VRTPlayer.__format_image_url(vrt_video) title_items.append( helperobjects.TitleItem(list_item_title, { 'action': actions.PLAY, 'video': path }, True, thumbnail, video_dictionary)) return title_items
def __get_episodes(self, li_tags, original_path): ''' This method gets all the episodes = seasons from the tabmenus on the vrt.nu website :param option_tags: :return: ''' title_items = [] for li_tag in li_tags: a_tag = li_tag.find('a') if a_tag is not None and a_tag.has_attr('href'): title = a_tag.text path = a_tag['href'] stripped_title = statichelper.replace_newlines_and_strip(title) title_items.append( helperobjects.TitleItem(stripped_title, { 'action': actions.LISTING_VIDEOS, 'video': path }, False)) return title_items
def __get_az_menu_items(self, url, soupstrainer_parser_selector, routing_action, video_dictionary_action=None): response = requests.get(url) tiles = SoupStrainer('a', soupstrainer_parser_selector) soup = BeautifulSoup(response.content, 'html.parser', parse_only=tiles) listing = [] for tile in soup.find_all(class_='nui-tile'): link_to_video = tile['href'] thumbnail, title = self.__get_az_thumbnail_and_title(tile) video_dictionary = None if video_dictionary_action is not None: video_dictionary = video_dictionary_action(tile) item = helperobjects.TitleItem(title, { 'action': routing_action, 'video': link_to_video }, False, thumbnail, video_dictionary) listing.append(item) return listing
def _map_to_episode_items(self, episodes, titletype=None, season_key=None): episode_items = [] sort = 'episode' ascending = True for episode in episodes: # VRT API workaround: seasonTitle facet behaves as a partial match regex, # so we have to filter out the episodes from seasons that don't exactly match. if season_key and episode.get('seasonTitle') != season_key: continue display_options = episode.get('displayOptions', dict()) # NOTE: Hard-code showing seasons because it is unreliable (i.e; Thuis or Down the Road have it disabled) display_options['showSeason'] = True if titletype is None: titletype = episode.get('programType') metadata = metadatacreator.MetadataCreator() metadata.tvshowtitle = episode.get('program') if episode.get('broadcastDate') != -1: metadata.datetime = datetime.fromtimestamp(episode.get('broadcastDate', 0) / 1000) metadata.duration = (episode.get('duration', 0) * 60) # Minutes to seconds metadata.plot = statichelper.convert_html_to_kodilabel(episode.get('description')) metadata.brands = episode.get('programBrands') or episode.get('brands') metadata.geolocked = episode.get('allowedRegion') == 'BE' if display_options.get('showShortDescription'): short_description = statichelper.convert_html_to_kodilabel(episode.get('shortDescription')) metadata.plotoutline = short_description metadata.subtitle = short_description else: metadata.plotoutline = episode.get('subtitle') metadata.subtitle = episode.get('subtitle') metadata.season = episode.get('seasonName') metadata.episode = episode.get('episodeNumber') metadata.mediatype = episode.get('type', 'episode') metadata.permalink = statichelper.shorten_link(episode.get('permalink')) or episode.get('externalPermalink') if episode.get('assetOnTime'): metadata.ontime = statichelper.strptime(episode.get('assetOnTime'), '%Y-%m-%dT%H:%M:%S+0000') if episode.get('assetOffTime'): metadata.offtime = statichelper.strptime(episode.get('assetOffTime'), '%Y-%m-%dT%H:%M:%S+0000') # Add additional metadata to plot plot_meta = '' if metadata.geolocked: # Show Geo-locked plot_meta += self._kodi_wrapper.get_localized_string(32201) # Only display when a video disappears if it is within the next 3 months if metadata.offtime is not None and (metadata.offtime - datetime.utcnow()).days < 93: # Show date when episode is removed plot_meta += self._kodi_wrapper.get_localized_string(32202) % metadata.offtime.strftime(self._kodi_wrapper.get_localized_dateshort()) # Show the remaining days/hours the episode is still available if (metadata.offtime - datetime.utcnow()).days > 0: plot_meta += self._kodi_wrapper.get_localized_string(32203) % (metadata.offtime - datetime.utcnow()).days else: plot_meta += self._kodi_wrapper.get_localized_string(32204) % int((metadata.offtime - datetime.utcnow()).seconds / 3600) if plot_meta: metadata.plot = '%s\n%s' % (plot_meta, metadata.plot) if self._showpermalink and metadata.permalink: metadata.plot = '%s\n\n[COLOR yellow]%s[/COLOR]' % (metadata.plot, metadata.permalink) thumb = statichelper.add_https_method(episode.get('videoThumbnailUrl', 'DefaultAddonVideo.png')) fanart = statichelper.add_https_method(episode.get('programImageUrl', thumb)) video_url = statichelper.add_https_method(episode.get('url')) title, sort, ascending = self._make_title(episode, titletype, options=display_options) metadata.title = title episode_items.append(helperobjects.TitleItem( title=title, url_dict=dict(action=actions.PLAY, video_url=video_url, video_id=episode.get('videoId'), publication_id=episode.get('publicationId')), is_playable=True, art_dict=dict(thumb=thumb, icon='DefaultAddonVideo.png', fanart=fanart), video_dict=metadata.get_video_dict(), )) return episode_items, sort, ascending
def show_tvguide(self, params): date = params.get('date') channel = params.get('channel') if not date: today = datetime.today() date_items = [] for i in range(7, -31, -1): day = today + timedelta(days=i) title = day.strftime( self._kodi_wrapper.get_localized_datelong()) if str(i) in DATE_STRINGS: if i == 0: title = '[COLOR yellow][B]%s[/B], %s[/COLOR]' % ( self._kodi_wrapper.get_localized_string( DATE_STRINGS[str(i)]), title) else: title = '[B]%s[/B], %s' % ( self._kodi_wrapper.get_localized_string( DATE_STRINGS[str(i)]), title) date_items.append( helperobjects.TitleItem( title=title, url_dict=dict(action=actions.LISTING_TVGUIDE, date=day.strftime('%Y-%m-%d')), is_playable=False, art_dict=dict(thumb='DefaultYear.png', icon='DefaultYear.png', fanart='DefaultYear.png'), video_dict=dict(plot=day.strftime( self._kodi_wrapper.get_localized_datelong()))), ) self._kodi_wrapper.show_listing(date_items, sort='unsorted', content_type='files') elif not channel: dateobj = statichelper.strptime(date, '%Y-%m-%d') datelong = dateobj.strftime( self._kodi_wrapper.get_localized_datelong()) channel_items = [] for channel in ('een', 'canvas', 'ketnet'): plot = self._kodi_wrapper.get_localized_string( 32301) % CHANNELS[channel]['name'] + '\n' + datelong channel_items.append( helperobjects.TitleItem( title=CHANNELS[channel]['name'], url_dict=dict(action=actions.LISTING_TVGUIDE, date=date, channel=channel), is_playable=False, art_dict=dict(thumb=self.__get_media(channel + '.png'), icon='DefaultAddonPVRClient.png', fanart='DefaultAddonPVRClient.png'), video_dict=dict(plot=plot), ), ) self._kodi_wrapper.show_listing(channel_items, content_type='files') else: dateobj = statichelper.strptime(date, '%Y-%m-%d') datelong = dateobj.strftime( self._kodi_wrapper.get_localized_datelong()) api_url = dateobj.strftime(self.VRT_TVGUIDE) schedule = requests.get(api_url, proxies=self._proxies).json() episodes = schedule[CHANNELS[channel]['id']] episode_items = [] for episode in episodes: metadata = metadatacreator.MetadataCreator() title = episode.get('title') start = episode.get('start') end = episode.get('end') url = episode.get('url') metadata.title = '%s - %s' % (start, title) metadata.tvshowtitle = title metadata.datetime = dateobj metadata.duration = ( statichelper.strptime(end, '%H:%M') - statichelper.strptime(start, '%H:%M')).total_seconds() metadata.plot = '[B]%s[/B]\n%s\n%s - %s\n[I]%s[/I]' % ( title, datelong, start, end, CHANNELS[channel]['name']) metadata.brands = [channel] metadata.mediatype = 'episode' thumb = episode.get('image', 'DefaultAddonVideo.png') metadata.icon = thumb if url: video_url = statichelper.add_https_method(url) url_dict = dict(action=actions.PLAY, video_url=video_url) else: # FIXME: Find a better solution for non-actionable items url_dict = dict(action=actions.LISTING_TVGUIDE, date=date, channel=channel) metadata.title = '[COLOR gray]%s[/COLOR]' % metadata.title title = '[COLOR gray]%s[/COLOR]' % metadata.title episode_items.append( helperobjects.TitleItem( title=title, url_dict=url_dict, is_playable=bool(url), art_dict=dict(thumb=thumb, icon='DefaultAddonVideo.png', fanart=thumb), video_dict=metadata.get_video_dict(), )) self._kodi_wrapper.show_listing(episode_items, sort='unsorted', content_type='episodes')