def show_main_menu(self):
        """The VRT NU add-on main menu"""
        # self._favorites.refresh(ttl=ttl('indirect'))
        main_items = []

        # Only add 'My favorites' when it has been activated
        if self._favorites.is_activated():
            main_items.append(TitleItem(
                label=localize(30010),  # My favorites
                path=url_for('favorites_menu'),
                art_dict=dict(thumb='DefaultFavourites.png'),
                info_dict=dict(plot=localize(30011)),
            ))

        main_items.extend([
            TitleItem(label=localize(30012),  # All programs
                      path=url_for('programs'),
                      art_dict=dict(thumb='DefaultMovieTitle.png'),
                      info_dict=dict(plot=localize(30013))),
            TitleItem(label=localize(30014),  # Categories
                      path=url_for('categories'),
                      art_dict=dict(thumb='DefaultGenre.png'),
                      info_dict=dict(plot=localize(30015))),
            TitleItem(label=localize(30016),  # Channels
                      path=url_for('channels'),
                      art_dict=dict(thumb='DefaultTags.png'),
                      info_dict=dict(plot=localize(30017))),
            TitleItem(label=localize(30018),  # Live TV
                      path=url_for('livetv'),
                      art_dict=dict(thumb='DefaultTVShows.png'),
                      info_dict=dict(plot=localize(30019))),
            TitleItem(label=localize(30020),  # Recent items
                      path=url_for('recent'),
                      art_dict=dict(thumb='DefaultRecentlyAddedEpisodes.png'),
                      info_dict=dict(plot=localize(30021))),
            TitleItem(label=localize(30022),  # Soon offline
                      path=url_for('offline'),
                      art_dict=dict(thumb='DefaultYear.png'),
                      info_dict=dict(plot=localize(30023))),
            TitleItem(label=localize(30024),  # Featured content
                      path=url_for('featured'),
                      art_dict=dict(thumb='DefaultCountry.png'),
                      info_dict=dict(plot=localize(30025))),
            TitleItem(label=localize(30026),  # TV guide
                      path=url_for('tvguide'),
                      art_dict=dict(thumb='DefaultAddonTvInfo.png'),
                      info_dict=dict(plot=localize(30027))),
            TitleItem(label=localize(30028),  # Search
                      path=url_for('search'),
                      art_dict=dict(thumb='DefaultAddonsSearch.png'),
                      info_dict=dict(plot=localize(30029))),
        ])
        show_listing(main_items, cache=False)  # No category
        self._version_check()
    def show_recent_menu(self, page=0, use_favorites=False):
        """The VRT NU add-on 'Most recent' and 'My most recent' listing menu"""

        # My favorites menus may need more up-to-date favorites
        self._favorites.refresh(
            ttl=ttl('direct' if use_favorites else 'indirect'))
        self._resumepoints.refresh(
            ttl=ttl('direct' if use_favorites else 'indirect'))
        page = realpage(page)
        episode_items, sort, ascending, content = self._apihelper.list_episodes(
            page=page, use_favorites=use_favorites, variety='recent')

        # Add 'More...' entry at the end
        if len(episode_items) == get_setting_int('itemsperpage', default=50):
            recent = 'favorites_recent' if use_favorites else 'recent'
            episode_items.append(
                TitleItem(
                    label=colour(localize(30300)),
                    path=url_for(recent, page=page + 1),
                    art_dict=dict(thumb='DefaultRecentlyAddedEpisodes.png'),
                    info_dict=dict(),
                ))

        show_listing(episode_items,
                     category=30020,
                     sort=sort,
                     ascending=ascending,
                     content=content,
                     cache=False)
    def show_offline_menu(self, page=0, use_favorites=False):
        ''' The VRT NU add-on 'Soon offline' and 'My soon offline' listing menu '''
        from statichelper import realpage

        # My favorites menus may need more up-to-date favorites
        self._favorites.refresh(ttl=5 * 60 if use_favorites else 60 * 60)
        self._resumepoints.refresh(ttl=5 * 60 if use_favorites else 60 * 60)
        page = realpage(page)
        episode_items, sort, ascending, content = self._apihelper.list_episodes(
            page=page, use_favorites=use_favorites, variety='offline')

        # Add 'More...' entry at the end
        if len(episode_items) == 50:
            if use_favorites:
                offline = 'favorites_offline'
            else:
                offline = 'offline'
            episode_items.append(
                TitleItem(
                    title=localize(30300),
                    path=url_for(offline, page=page + 1),
                    art_dict=dict(thumb='DefaultYear.png'),
                    info_dict=dict(),
                ))

        show_listing(episode_items,
                     category=30022,
                     sort=sort,
                     ascending=ascending,
                     content=content,
                     cache=False)
Example #4
0
    def episode_to_listitem(self, episode, program, cache_file, titletype):
        """Return a ListItem based on a Search API result"""

        label, sort, ascending = self._metadata.get_label(episode,
                                                          titletype,
                                                          return_sort=True)

        if program:
            context_menu, favorite_marker, watchlater_marker = self._metadata.get_context_menu(
                episode, program, cache_file)
            label += favorite_marker + watchlater_marker

        info_labels = self._metadata.get_info_labels(episode)
        # FIXME: Due to a bug in Kodi, ListItem.Title is used when Sort methods are used, not ListItem.Label
        info_labels['title'] = label

        return TitleItem(
            label=label,
            path=url_for('play_id',
                         video_id=episode.get('videoId'),
                         publication_id=episode.get('publicationId')),
            art_dict=self._metadata.get_art(episode),
            info_dict=info_labels,
            prop_dict=self._metadata.get_properties(episode),
            context_menu=context_menu,
            is_playable=True,
        ), sort, ascending
Example #5
0
    def list_featured(self, online=False):
        """Construct a list of featured Listitems"""
        featured = []
        if online:
            featured = self.get_featured_from_api()
        else:
            from data import FEATURED

            # Add VRT NU website featured items
            featured.extend(self.get_featured_from_web())

            # Add hardcoded VRT Search API featured items
            for feature in self.localize_features(FEATURED):
                featured.append(feature)

        featured_items = []
        for feature in featured:
            featured_name = feature.get('name')
            featured_items.append(
                TitleItem(
                    label=featured_name,
                    path=url_for('featured', feature=feature.get('id')),
                    art_dict=dict(thumb='DefaultCountry.png'),
                    info_dict=dict(plot='[B]%s[/B]' % feature.get('name'),
                                   studio='VRT'),
                ))
        return featured_items
    def show_offline_menu(self, page=0, use_favorites=False):
        """The VRT NU add-on 'Soon offline' and 'My soon offline' listing menu"""

        # My favorites menus may need more up-to-date favorites
        self._favorites.refresh(
            ttl=ttl('direct' if use_favorites else 'indirect'))
        self._resumepoints.refresh(
            ttl=ttl('direct' if use_favorites else 'indirect'))
        page = realpage(page)
        items_per_page = get_setting_int('itemsperpage', default=50)
        sort_key = 'assetOffTime'
        episode_items, sort, ascending, content = self._apihelper.list_episodes(
            page=page,
            items_per_page=items_per_page,
            use_favorites=use_favorites,
            variety='offline',
            sort_key=sort_key)

        # Add 'More...' entry at the end
        if len(episode_items) == items_per_page:
            offline = 'favorites_offline' if use_favorites else 'offline'
            episode_items.append(
                TitleItem(
                    label=localize(30300),
                    path=url_for(offline, page=page + 1),
                    art_dict=dict(thumb='DefaultYear.png'),
                    info_dict=dict(),
                ))

        show_listing(episode_items,
                     category=30022,
                     sort=sort,
                     ascending=ascending,
                     content=content,
                     cache=False)
Example #7
0
    def get_episode_items(self, date, channel):
        """Show episodes for a given date and channel"""
        now = datetime.now(dateutil.tz.tzlocal())
        epg = self.parse(date, now)
        epg_url = epg.strftime(self.VRT_TVGUIDE)

        self._favorites.refresh(ttl=ttl('indirect'))
        self._resumepoints.refresh(ttl=ttl('indirect'))

        cache_file = 'schedule.{date}.json'.format(date=date)
        if date in ('today', 'yesterday', 'tomorrow'):
            schedule = get_cached_url_json(url=epg_url,
                                           cache=cache_file,
                                           ttl=ttl('indirect'),
                                           fail={})
        else:
            schedule = get_url_json(url=epg_url, fail={})

        entry = find_entry(CHANNELS, 'name', channel)
        if entry:
            episodes = schedule.get(entry.get('id'), [])
        else:
            episodes = []
        episode_items = []
        for episode in episodes:
            program = url_to_program(episode.get('url', ''))
            if episode.get('url'):
                video_url = add_https_proto(episode.get('url'))
                path = url_for('play_url', video_url=video_url)
                context_menu, favorite_marker, watchlater_marker = self._metadata.get_context_menu(
                    episode, program, cache_file)
                label = self._metadata.get_label(
                    episode) + favorite_marker + watchlater_marker
                is_playable = True
            else:
                label = '[COLOR={greyedout}]%s[/COLOR]' % self._metadata.get_label(
                    episode)
                path = url_for('noop')
                context_menu, _, _ = self._metadata.get_context_menu(
                    episode, program, cache_file)
                is_playable = False

            info_labels = self._metadata.get_info_labels(episode,
                                                         date=date,
                                                         channel=entry)
            # FIXME: Due to a bug in Kodi, ListItem.Title is used when Sort methods are used, not ListItem.Label
            info_labels['title'] = colour(label)

            episode_items.append(
                TitleItem(
                    label=colour(label),
                    path=path,
                    art_dict=self._metadata.get_art(episode),
                    info_dict=info_labels,
                    context_menu=context_menu,
                    is_playable=is_playable,
                ))
        return episode_items
    def show_favorites_menu(self):
        ''' The VRT NU addon 'My programs' menu '''
        self._favorites.refresh(ttl=60 * 60)
        favorites_items = [
            TitleItem(
                title=localize(30040),  # My programs
                path=url_for('favorites_programs'),
                art_dict=dict(thumb='DefaultMovieTitle.png'),
                info_dict=dict(plot=localize(30041))),
            TitleItem(
                title=localize(30046),  # My recent items
                path=url_for('favorites_recent'),
                art_dict=dict(thumb='DefaultRecentlyAddedEpisodes.png'),
                info_dict=dict(plot=localize(30047))),
            TitleItem(
                title=localize(30048),  # My soon offline
                path=url_for('favorites_offline'),
                art_dict=dict(thumb='DefaultYear.png'),
                info_dict=dict(plot=localize(30049))),
        ]

        # Only add 'My watch later' and 'Continue watching' when it has been activated
        if self._resumepoints.is_activated():
            favorites_items.append(
                TitleItem(
                    title=localize(30050),  # My watch later
                    path=url_for('resumepoints_watchlater'),
                    art_dict=dict(thumb='DefaultVideoPlaylists.png'),
                    info_dict=dict(plot=localize(30051)),
                ))
            favorites_items.append(
                TitleItem(
                    title=localize(30052),  # Continue Watching
                    path=url_for('resumepoints_continue'),
                    art_dict=dict(thumb='DefaultInProgressShows.png'),
                    info_dict=dict(plot=localize(30053)),
                ))

        if get_setting('addmymovies', 'true') == 'true':
            favorites_items.append(
                TitleItem(
                    title=localize(30042),  # My movies
                    path=url_for('categories', category='films'),
                    art_dict=dict(thumb='DefaultAddonVideo.png'),
                    info_dict=dict(plot=localize(30043))), )

        if get_setting('addmydocu', 'true') == 'true':
            favorites_items.append(
                TitleItem(
                    title=localize(30044),  # My documentaries
                    path=url_for('favorites_docu'),
                    art_dict=dict(thumb='DefaultMovies.png'),
                    info_dict=dict(plot=localize(30045))), )

        show_listing(favorites_items, category=30010,
                     cache=False)  # My favorites

        # Show dialog when no favorites were found
        if not self._favorites.titles():
            ok_dialog(heading=localize(30415), message=localize(30416))
    def __map_seasons(self, program, seasons, episodes):
        import random
        season_items = []
        sort = 'label'
        ascending = True
        content = 'seasons'

        episode = random.choice(episodes)
        info_labels = self._metadata.get_info_labels(episode, season=True)
        program_type = episode.get('programType')

        # Reverse sort seasons if program_type is 'reeksaflopend' or 'daily'
        if program_type in ('daily', 'reeksaflopend'):
            ascending = False

        # Add an "* All seasons" list item
        if get_global_setting('videolibrary.showallitems') is True:
            season_items.append(TitleItem(
                title=localize(30133),
                path=url_for('programs', program=program, season='allseasons'),
                art_dict=self._metadata.get_art(episode, season='allseasons'),
                info_dict=info_labels,
            ))

        # 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', '')
            try:
                # If more than 300 episodes exist, we may end up with an empty season (Winteruur)
                episode = random.choice([e for e in episodes if e.get('seasonName') == season_key])
            except IndexError:
                episode = episodes[0]

            label = '%s %s' % (localize(30131), season_key)
            season_items.append(TitleItem(
                title=label,
                path=url_for('programs', program=program, season=season_key),
                art_dict=self._metadata.get_art(episode, season=True),
                info_dict=info_labels,
                prop_dict=self._metadata.get_properties(episode),
            ))
        return season_items, sort, ascending, content
Example #10
0
    def list_youtube(channels=None):
        """Construct a list of youtube ListItems, either for Live TV or the TV Guide listing"""

        youtube_items = []

        if not has_addon('plugin.video.youtube') or not get_setting_bool(
                'showyoutube', default=True):
            return youtube_items

        for channel in CHANNELS:
            if channels and channel.get('name') not in channels:
                continue

            art_dict = {}

            # Try to use the white icons for thumbnails (used for icons as well)
            if has_addon('resource.images.studios.white'):
                art_dict[
                    'thumb'] = 'resource://resource.images.studios.white/{studio}.png'.format(
                        **channel)
            else:
                art_dict['thumb'] = 'DefaultTags.png'

            for youtube in channel.get('youtube', []):
                path = youtube_to_plugin_url(youtube['url'])
                label = localize(30143, **youtube)  # Channel on YouTube
                # A single Live channel means it is the entry for channel's TV Show listing, so make it stand out
                if channels and len(channels) == 1:
                    label = '[B]%s[/B]' % label
                plot = localize(30144, **youtube)  # Watch on YouTube
                # NOTE: Playcount is required to not have live streams as "Watched"
                info_dict = dict(title=label,
                                 plot=plot,
                                 studio=channel.get('studio'),
                                 mediatype='video',
                                 playcount=0)

                context_menu = [(
                    localize(30413),  # Refresh menu
                    'RunPlugin(%s)' %
                    url_for('delete_cache',
                            cache_file='channel.{channel}.json'.format(
                                channel=channel)),
                )]

                youtube_items.append(
                    TitleItem(
                        label=label,
                        path=path,
                        art_dict=art_dict,
                        info_dict=info_dict,
                        context_menu=context_menu,
                        is_playable=False,
                    ))

        return youtube_items
    def get_channel_items(self, date=None, channel=None):
        """Offer a menu to select the channel"""
        if date:
            now = datetime.now(dateutil.tz.tzlocal())
            epg = self.parse(date, now)
            datelong = localize_datelong(epg)

        channel_items = []
        for chan in CHANNELS:
            # Only some channels are supported
            if not chan.get('has_tvguide'):
                continue

            # If a channel is requested, stop processing if it is no match
            if channel and channel != chan.get('name'):
                continue

            art_dict = {}

            # Try to use the white icons for thumbnails (used for icons as well)
            if has_addon('resource.images.studios.white'):
                art_dict[
                    'thumb'] = 'resource://resource.images.studios.white/{studio}.png'.format(
                        **chan)
            else:
                art_dict['thumb'] = 'DefaultTags.png'

            if date:
                label = chan.get('label')
                path = url_for('tvguide', date=date, channel=chan.get('name'))
                plot = '[B]%s[/B]\n%s' % (datelong, localize(30302, **chan))
            else:
                label = '[B]%s[/B]' % localize(30303, **chan)
                path = url_for('tvguide_channel', channel=chan.get('name'))
                plot = '%s\n\n%s' % (localize(
                    30302, **chan), self.live_description(chan.get('name')))

            context_menu = [(
                localize(30413),  # Refresh menu
                'RunPlugin(%s)' %
                url_for('delete_cache',
                        cache_file='channel.{channel}.json'.format(
                            channel=chan.get('name'))),
            )]

            channel_items.append(
                TitleItem(
                    label=label,
                    path=path,
                    art_dict=art_dict,
                    context_menu=context_menu,
                    info_dict=dict(plot=plot, studio=chan.get('studio')),
                ))
        return channel_items
Example #12
0
    def get_episode_items(self, date, channel):
        ''' Show episodes for a given date and channel '''
        now = datetime.now(dateutil.tz.tzlocal())
        epg = self.parse(date, now)
        epg_url = epg.strftime(self.VRT_TVGUIDE)

        self._favorites.refresh(ttl=60 * 60)

        cache_file = 'schedule.%s.json' % date
        if date in ('today', 'yesterday', 'tomorrow'):
            # Try the cache if it is fresh
            schedule = get_cache(cache_file, ttl=60 * 60)
            if not schedule:
                from json import load
                log(2, 'URL get: {url}', url=epg_url)
                schedule = load(urlopen(epg_url))
                update_cache(cache_file, schedule)
        else:
            from json import load
            log(2, 'URL get: {url}', url=epg_url)
            schedule = load(urlopen(epg_url))

        entry = find_entry(CHANNELS, 'name', channel)
        if entry:
            episodes = schedule.get(entry.get('id'), [])
        else:
            episodes = []
        episode_items = []
        for episode in episodes:

            label = self._metadata.get_label(episode)

            context_menu = []
            path = None
            if episode.get('url'):
                from statichelper import add_https_method, url_to_program
                video_url = add_https_method(episode.get('url'))
                path = url_for('play_url', video_url=video_url)
                program = url_to_program(episode.get('url'))
                context_menu, favorite_marker, watchlater_marker = self._metadata.get_context_menu(episode, program, cache_file)
                label += favorite_marker + watchlater_marker

            info_labels = self._metadata.get_info_labels(episode, date=date, channel=entry)
            info_labels['title'] = label

            episode_items.append(TitleItem(
                title=label,
                path=path,
                art_dict=self._metadata.get_art(episode),
                info_dict=info_labels,
                is_playable=True,
                context_menu=context_menu,
            ))
        return episode_items
Example #13
0
 def get_single_episode(self, video_id=None, whatson_id=None, video_url=None):
     """Get single episode by videoId, whatsonId or url"""
     video = None
     episode = self.get_single_episode_data(video_id=video_id, whatson_id=whatson_id, video_url=video_url)
     if episode:
         video_item = TitleItem(
             label=self._metadata.get_label(episode),
             art_dict=self._metadata.get_art(episode),
             info_dict=self._metadata.get_info_labels(episode),
             prop_dict=self._metadata.get_properties(episode),
         )
         video = dict(listitem=video_item, video_id=episode.get('videoId'), publication_id=episode.get('publicationId'))
     return video
    def search_menu(self):
        """Main search menu"""
        from helperobjects import TitleItem
        menu_items = [
            TitleItem(
                label=localize(30424),  # New search...
                path=url_for('search_query'),
                art_dict=dict(thumb='DefaultAddonsSearch.png'),
                info_dict=dict(plot=localize(30425)),
                is_playable=False,
            )
        ]

        history = self.read_history()
        for keywords in history:
            menu_items.append(TitleItem(
                label=keywords,
                path=url_for('search_query', keywords=keywords),
                is_playable=False,
                context_menu=[(
                    localize(30033),  # Edit
                    'RunPlugin(%s)' % url_for('edit_search', keywords=keywords),
                ), (
                    localize(30030),  # Remove
                    'RunPlugin(%s)' % url_for('remove_search', keywords=keywords),
                )],
            ))

        if history:
            menu_items.append(TitleItem(
                label=localize(30426),  # Clear search history
                path=url_for('clear_search'),
                info_dict=dict(plot=localize(30427)),
                art_dict=dict(thumb='icons/infodialogs/uninstall.png'),
                is_playable=False,
            ))

        show_listing(menu_items, category=30031, cache=False)
    def list_featured(self):
        ''' Construct a list of featured Listitems '''
        from data import FEATURED

        featured_items = []
        for feature in self.localize_features(FEATURED):
            featured_name = feature.get('name')
            featured_items.append(TitleItem(
                title=featured_name,
                path=url_for('featured', feature=feature.get('id')),
                art_dict=dict(thumb='DefaultCountry.png'),
                info_dict=dict(plot='[B]%s[/B]' % feature.get('name'), studio='VRT'),
            ))
        return featured_items
 def get_single_episode(self, whatson_id):
     ''' Get single episode by whatsonId '''
     video = None
     api_data = self.get_episodes(whatson_id=whatson_id, variety='single')
     if len(api_data) == 1:
         episode = api_data[0]
         video_item = TitleItem(
             title=self._metadata.get_label(episode),
             art_dict=self._metadata.get_art(episode),
             info_dict=self._metadata.get_info_labels(episode),
             prop_dict=self._metadata.get_properties(episode),
         )
         video = dict(listitem=video_item, video_id=episode.get('videoId'), publication_id=episode.get('publicationId'))
     return video
    def get_date_items(channel=None):
        """Offer a menu to select the TV-guide date"""

        epg = datetime.now(dateutil.tz.tzlocal())
        # Daily EPG information shows information from 6AM until 6AM
        if epg.hour < 6:
            epg += timedelta(days=-1)
        date_items = []
        for offset in range(14, -19, -1):
            day = epg + timedelta(days=offset)
            label = localize_datelong(day)
            date = day.strftime('%Y-%m-%d')

            # Highlight today with context of 2 days
            entry = find_entry(RELATIVE_DATES, 'offset', offset)
            if entry:
                date_name = localize(entry.get('msgctxt'))
                if entry.get('permalink'):
                    date = entry.get('id')
                if offset == 0:
                    label = '[COLOR={highlighted}][B]{name}[/B], {date}[/COLOR]'.format(
                        highlighted=themecolour('highlighted'),
                        name=date_name,
                        date=label)
                else:
                    label = '[B]{name}[/B], {date}'.format(name=date_name,
                                                           date=label)

            plot = '[B]{datelong}[/B]'.format(datelong=localize_datelong(day))

            # Show channel list or channel episodes
            if channel:
                path = url_for('tvguide', date=date, channel=channel)
            else:
                path = url_for('tvguide', date=date)

            cache_file = 'schedule.{date}.json'.format(date=date)
            date_items.append(
                TitleItem(
                    label=label,
                    path=path,
                    art_dict=dict(thumb='DefaultYear.png'),
                    info_dict=dict(plot=plot),
                    context_menu=[(
                        localize(30413),  # Refresh menu
                        'RunPlugin(%s)' %
                        url_for('delete_cache', cache_file=cache_file))],
                ))
        return date_items
 def get_latest_episode(self, program):
     ''' Get the latest episode of a program '''
     api_data = self.get_episodes(program=program, variety='single')
     if len(api_data) != 1:
         return None
     episode = api_data[0]
     log(2, str(episode))
     video_item = TitleItem(
         title=self._metadata.get_label(episode),
         art_dict=self._metadata.get_art(episode),
         info_dict=self._metadata.get_info_labels(episode),
         prop_dict=self._metadata.get_properties(episode),
     )
     video = dict(listitem=video_item, video_id=episode.get('videoId'), publication_id=episode.get('publicationId'))
     return video
    def tvshow_to_listitem(self, tvshow, program, cache_file):
        ''' Return a ListItem based on a Suggests API result '''

        label = self._metadata.get_label(tvshow)

        if program:
            context_menu, favorite_marker, _ = self._metadata.get_context_menu(tvshow, program, cache_file)
            label += favorite_marker

        return TitleItem(
            title=label,
            path=url_for('programs', program=program),
            art_dict=self._metadata.get_art(tvshow),
            info_dict=self._metadata.get_info_labels(tvshow),
            context_menu=context_menu,
        )
Example #20
0
 def list_categories(self):
     """Construct a list of category ListItems"""
     from webscraper import get_categories
     categories = get_categories()
     category_items = []
     from data import CATEGORIES
     for category in self.localize_categories(categories, CATEGORIES):
         if get_setting_bool('showfanart', default=True):
             thumbnail = category.get('thumbnail', 'DefaultGenre.png')
         else:
             thumbnail = 'DefaultGenre.png'
         category_items.append(TitleItem(
             label=category.get('name'),
             path=url_for('categories', category=category.get('id')),
             art_dict=dict(thumb=thumbnail, icon='DefaultGenre.png'),
             info_dict=dict(plot='[B]%s[/B]' % category.get('name'), studio='VRT'),
         ))
     return category_items
Example #21
0
    def search(self, keywords=None, page=None):
        ''' The VRT NU add-on Search functionality and results '''
        if keywords is None:
            keywords = get_search_string()

        if not keywords:
            end_of_directory()
            return

        from statichelper import realpage
        page = realpage(page)

        self.add(keywords)

        from apihelper import ApiHelper
        search_items, sort, ascending, content = ApiHelper(
            self._favorites, self._resumepoints).list_search(keywords,
                                                             page=page)
        if not search_items:
            ok_dialog(heading=localize(30135),
                      message=localize(30136, keywords=keywords))
            end_of_directory()
            return

        # Add 'More...' entry at the end
        from helperobjects import TitleItem
        if len(search_items) == 50:
            search_items.append(
                TitleItem(
                    title=localize(30300),
                    path=url_for('search_query',
                                 keywords=keywords,
                                 page=page + 1),
                    art_dict=dict(thumb='DefaultAddonSearch.png'),
                    info_dict=dict(),
                ))

        self._favorites.refresh(ttl=60 * 60)
        show_listing(search_items,
                     category=30032,
                     sort=sort,
                     ascending=ascending,
                     content=content,
                     cache=False)
    def episode_to_listitem(self, episode, program, cache_file, titletype):
        ''' Return a ListItem based on a Search API result '''

        label, sort, ascending = self._metadata.get_label(episode, titletype, return_sort=True)

        if program:
            context_menu, favorite_marker, watchlater_marker = self._metadata.get_context_menu(episode, program, cache_file)
            label += favorite_marker + watchlater_marker

        info_labels = self._metadata.get_info_labels(episode)
        info_labels['title'] = label

        return TitleItem(
            title=label,
            path=url_for('play_id', video_id=episode.get('videoId'), publication_id=episode.get('publicationId')),
            art_dict=self._metadata.get_art(episode),
            info_dict=info_labels,
            prop_dict=self._metadata.get_properties(episode),
            context_menu=context_menu,
            is_playable=True,
        ), sort, ascending
    def list_categories(self):
        ''' Construct a list of category ListItems '''
        categories = []

        # Try the cache if it is fresh
        categories = get_cache('categories.json', ttl=7 * 24 * 60 * 60)

        # Try to scrape from the web
        if not categories:
            try:
                categories = self.get_categories()
            except Exception:  # pylint: disable=broad-except
                categories = []
            else:
                update_cache('categories.json', categories)

        # Use the cache anyway (better than hard-coded)
        if not categories:
            categories = get_cache('categories.json', ttl=None)

        # Fall back to internal hard-coded categories if all else fails
        from data import CATEGORIES
        if not categories:
            categories = CATEGORIES

        category_items = []
        for category in self.localize_categories(categories, CATEGORIES):
            if get_setting('showfanart', 'true') == 'true':
                thumbnail = category.get('thumbnail', 'DefaultGenre.png')
            else:
                thumbnail = 'DefaultGenre.png'
            category_items.append(TitleItem(
                title=category.get('name'),
                path=url_for('categories', category=category.get('id')),
                art_dict=dict(thumb=thumbnail, icon='DefaultGenre.png'),
                info_dict=dict(plot='[B]%s[/B]' % category.get('name'), studio='VRT'),
            ))
        return category_items
    def search(self, keywords=None, page=0, edit=False):
        """The VRT NU add-on Search functionality and results"""
        if keywords is None or edit is True:
            keywords = get_search_string(keywords)

        if not keywords:
            end_of_directory()
            return
        if edit is True:
            container_update(url_for('search_query', keywords=keywords))
            return

        from apihelper import ApiHelper
        from utils import realpage
        page = realpage(page)

        self.add(keywords)

        search_items, sort, ascending, content = ApiHelper(self._favorites, self._resumepoints).list_search(keywords, page=page)
        if not search_items:
            ok_dialog(heading=localize(30135), message=localize(30136, keywords=keywords))
            end_of_directory()
            return

        # Add 'More…' entry at the end
        from helperobjects import TitleItem
        if len(search_items) == get_setting_int('itemsperpage', default=50):
            search_items.append(TitleItem(
                label=colour(localize(30300)),  # More…
                path=url_for('search_query', keywords=keywords, page=page + 1),
                art_dict=dict(thumb='DefaultAddonSearch.png'),
                info_dict={},
            ))

        self._favorites.refresh(ttl=ttl('indirect'))
        show_listing(search_items, category=30032, sort=sort, ascending=ascending, content=content, cache=False)
    def list_channels(self, channels=None, live=True):
        ''' Construct a list of channel ListItems, either for Live TV or the TV Guide listing '''
        from tvguide import TVGuide
        _tvguide = TVGuide()

        channel_items = []
        for channel in CHANNELS:
            if channels and channel.get('name') not in channels:
                continue

            context_menu = []
            art_dict = dict()

            # Try to use the white icons for thumbnails (used for icons as well)
            if has_addon('resource.images.studios.white'):
                art_dict['thumb'] = 'resource://resource.images.studios.white/{studio}.png'.format(**channel)
            else:
                art_dict['thumb'] = 'DefaultTags.png'

            if not live:
                path = url_for('channels', channel=channel.get('name'))
                label = channel.get('label')
                plot = '[B]%s[/B]' % channel.get('label')
                is_playable = False
                info_dict = dict(title=label, plot=plot, studio=channel.get('studio'), mediatype='video')
                stream_dict = []
            elif channel.get('live_stream') or channel.get('live_stream_id'):
                if channel.get('live_stream_id'):
                    path = url_for('play_id', video_id=channel.get('live_stream_id'))
                elif channel.get('live_stream'):
                    path = url_for('play_url', video_url=channel.get('live_stream'))
                label = localize(30141, **channel)  # Channel live
                playing_now = _tvguide.playing_now(channel.get('name'))
                if playing_now:
                    label += ' [COLOR yellow]| %s[/COLOR]' % playing_now
                # A single Live channel means it is the entry for channel's TV Show listing, so make it stand out
                if channels and len(channels) == 1:
                    label = '[B]%s[/B]' % label
                is_playable = True
                if channel.get('name') in ['een', 'canvas', 'ketnet']:
                    if get_setting('showfanart', 'true') == 'true':
                        art_dict['fanart'] = self.get_live_screenshot(channel.get('name', art_dict.get('fanart')))
                    plot = '%s\n\n%s' % (localize(30142, **channel), _tvguide.live_description(channel.get('name')))
                else:
                    plot = localize(30142, **channel)  # Watch live
                # NOTE: Playcount is required to not have live streams as "Watched"
                info_dict = dict(title=label, plot=plot, studio=channel.get('studio'), mediatype='video', playcount=0, duration=0)
                stream_dict = dict(duration=0)
                context_menu.append((
                    localize(30413),
                    'RunPlugin(%s)' % url_for('delete_cache', cache_file='channel.%s.json' % channel)
                ))
            else:
                # Not a playable channel
                continue

            channel_items.append(TitleItem(
                title=label,
                path=path,
                art_dict=art_dict,
                info_dict=info_dict,
                stream_dict=stream_dict,
                context_menu=context_menu,
                is_playable=is_playable,
            ))

        return channel_items
    def get_episode_by_air_date(self, channel_name, start_date, end_date=None):
        ''' Get an episode of a program given the channel and the air date in iso format (2019-07-06T19:35:00) '''
        channel = statichelper.find_entry(CHANNELS, 'name', channel_name)
        if not channel:
            return None

        from datetime import datetime, timedelta
        import dateutil.parser
        import dateutil.tz
        offairdate = None
        try:
            onairdate = dateutil.parser.parse(start_date, default=datetime.now(dateutil.tz.gettz('Europe/Brussels')))
        except ValueError:
            return None

        if end_date:
            try:
                offairdate = dateutil.parser.parse(end_date, default=datetime.now(dateutil.tz.gettz('Europe/Brussels')))
            except ValueError:
                return None
        video = None
        episode_guess_off = None
        now = datetime.now(dateutil.tz.gettz('Europe/Brussels'))
        if onairdate.hour < 6:
            schedule_date = onairdate - timedelta(days=1)
        else:
            schedule_date = onairdate
        schedule_datestr = schedule_date.isoformat().split('T')[0]
        url = 'https://www.vrt.be/bin/epg/schedule.%s.json' % schedule_datestr
        from json import load
        schedule_json = load(urlopen(url))
        episodes = schedule_json.get(channel.get('id'), [])
        if not episodes:
            return None
        if offairdate:
            mindate = min(abs(offairdate - dateutil.parser.parse(episode.get('endTime'))) for episode in episodes)
            episode_guess_off = next((episode for episode in episodes if abs(offairdate - dateutil.parser.parse(episode.get('endTime'))) == mindate), None)

        mindate = min(abs(onairdate - dateutil.parser.parse(episode.get('startTime'))) for episode in episodes)
        episode_guess_on = next((episode for episode in episodes if abs(onairdate - dateutil.parser.parse(episode.get('startTime'))) == mindate), None)
        offairdate_guess = dateutil.parser.parse(episode_guess_on.get('endTime'))
        if (episode_guess_off and episode_guess_on.get('vrt.whatson-id') == episode_guess_off.get('vrt.whatson-id')
                or (not episode_guess_off and episode_guess_on)):
            video = self.get_single_episode(episode_guess_on.get('vrt.whatson-id'))
            if video:
                return video

            # Airdate live2vod feature: use livestream cache of last 24 hours if no video was found

            if now - timedelta(hours=24) <= dateutil.parser.parse(episode_guess_on.get('endTime')) <= now:
                start_date = onairdate.astimezone(dateutil.tz.UTC).isoformat()[0:19]
                end_date = offairdate_guess.astimezone(dateutil.tz.UTC).isoformat()[0:19]

            # Offairdate defined
            if offairdate and now - timedelta(hours=24) <= offairdate <= now:
                start_date = onairdate.astimezone(dateutil.tz.UTC).isoformat()[0:19]
                end_date = offairdate.astimezone(dateutil.tz.UTC).isoformat()[0:19]

            if start_date and end_date:
                video_item = TitleItem(
                    title=self._metadata.get_label(episode_guess_on),
                    art_dict=self._metadata.get_art(episode_guess_on),
                    info_dict=self._metadata.get_info_labels(episode_guess_on, channel=channel, date=start_date),
                    prop_dict=self._metadata.get_properties(episode_guess_on),
                )
                video = dict(
                    listitem=video_item,
                    video_id=channel.get('live_stream_id'),
                    start_date=start_date,
                    end_date=end_date,
                )
                return video

            video = dict(
                errorlabel=episode_guess_on.get('title')
            )
        return video
Example #27
0
    def get_episode_by_air_date(self, channel_name, start_date, end_date=None):
        """Get an episode of a program given the channel and the air date in iso format (2019-07-06T19:35:00)"""
        channel = find_entry(CHANNELS, 'name', channel_name)
        if not channel:
            return None

        from datetime import datetime, timedelta
        import dateutil.parser
        import dateutil.tz
        offairdate = None
        try:
            onairdate = dateutil.parser.parse(
                start_date,
                default=datetime.now(dateutil.tz.gettz('Europe/Brussels')))
        except ValueError:
            return None

        if end_date:
            try:
                offairdate = dateutil.parser.parse(
                    end_date,
                    default=datetime.now(dateutil.tz.gettz('Europe/Brussels')))
            except ValueError:
                return None
        video = None
        now = datetime.now(dateutil.tz.gettz('Europe/Brussels'))
        if onairdate.hour < 6:
            schedule_date = onairdate - timedelta(days=1)
        else:
            schedule_date = onairdate
        schedule_datestr = schedule_date.isoformat().split('T')[0]
        url = 'https://www.vrt.be/bin/epg/schedule.{date}.json'.format(
            date=schedule_datestr)
        schedule_json = get_url_json(url, fail={})
        episodes = schedule_json.get(channel.get('id'), [])
        if not episodes:
            return None

        # Guess the episode
        episode_guess = None
        if not offairdate:
            mindate = min(
                abs(onairdate -
                    dateutil.parser.parse(episode.get('startTime')))
                for episode in episodes)
            episode_guess = next((episode for episode in episodes if abs(
                onairdate -
                dateutil.parser.parse(episode.get('startTime'))) == mindate),
                                 None)
        else:
            duration = offairdate - onairdate
            midairdate = onairdate + timedelta(
                seconds=duration.total_seconds() / 2)
            mindate = min(
                abs(midairdate -
                    (dateutil.parser.parse(episode.get('startTime')) +
                     timedelta(seconds=(dateutil.parser.parse(
                         episode.get('endTime')) - dateutil.parser.parse(
                             episode.get('startTime'))).total_seconds() / 2)))
                for episode in episodes)
            episode_guess = next((episode for episode in episodes if abs(
                midairdate -
                (dateutil.parser.parse(episode.get('startTime')) + timedelta(
                    seconds=(dateutil.parser.parse(episode.get('endTime')) -
                             dateutil.parser.parse(episode.get('startTime'))
                             ).total_seconds() / 2))) == mindate), None)

        if episode_guess and episode_guess.get('vrt.whatson-id', None):
            offairdate_guess = dateutil.parser.parse(
                episode_guess.get('endTime'))
            video = self.get_single_episode(
                whatson_id=episode_guess.get('vrt.whatson-id'))
            if video:
                return video

            # Airdate live2vod feature: use livestream cache of last 24 hours if no video was found

            if now - timedelta(hours=24) <= dateutil.parser.parse(
                    episode_guess.get('endTime')) <= now:
                start_date = onairdate.astimezone(
                    dateutil.tz.UTC).isoformat()[0:19]
                end_date = offairdate_guess.astimezone(
                    dateutil.tz.UTC).isoformat()[0:19]

            # Offairdate defined
            if offairdate and now - timedelta(hours=24) <= offairdate <= now:
                start_date = onairdate.astimezone(
                    dateutil.tz.UTC).isoformat()[:19]
                end_date = offairdate.astimezone(
                    dateutil.tz.UTC).isoformat()[:19]

            if start_date and end_date:
                info = self._metadata.get_info_labels(episode_guess,
                                                      channel=channel,
                                                      date=start_date)
                live2vod_title = '{} ({})'.format(
                    info.get('tvshowtitle'),
                    localize(30454))  # from livestream cache
                info.update(tvshowtitle=live2vod_title)
                video_item = TitleItem(
                    label=self._metadata.get_label(episode_guess),
                    art_dict=self._metadata.get_art(episode_guess),
                    info_dict=info,
                    prop_dict=self._metadata.get_properties(episode_guess),
                )
                video = dict(
                    listitem=video_item,
                    video_id=channel.get('live_stream_id'),
                    start_date=start_date,
                    end_date=end_date,
                )
                return video

            video = dict(errorlabel=episode_guess.get('title'))
        return video
    def get_episode_items(self, date, channel):
        """Show episodes for a given date and channel"""
        now = datetime.now(dateutil.tz.tzlocal())
        epg = self.parse(date, now)
        epg_url = epg.strftime(self.VRT_TVGUIDE)

        self._favorites.refresh(ttl=ttl('indirect'))
        self._resumepoints.refresh(ttl=ttl('indirect'))

        cache_file = 'schedule.{date}.json'.format(date=date)
        if date in ('today', 'yesterday', 'tomorrow'):
            schedule = get_cached_url_json(url=epg_url,
                                           cache=cache_file,
                                           ttl=ttl('indirect'),
                                           fail={})
        else:
            schedule = get_url_json(url=epg_url, fail={})

        entry = find_entry(CHANNELS, 'name', channel)
        if entry:
            episodes = schedule.get(entry.get('id'), [])
        else:
            episodes = []
        episode_items = []
        for episode in episodes:
            program = url_to_program(episode.get('url', ''))
            context_menu, favorite_marker, watchlater_marker = self._metadata.get_context_menu(
                episode, program, cache_file)
            label = self._metadata.get_label(episode)
            path = self.get_episode_path(episode, channel)
            # Playable item
            if '/play/' in path:
                is_playable = True
                label += favorite_marker + watchlater_marker
            # Non-actionable item
            else:
                is_playable = False
                label = '[COLOR={greyedout}]%s[/COLOR]' % label

            # Now playing
            start_date = dateutil.parser.parse(episode.get('startTime'))
            end_date = dateutil.parser.parse(episode.get('endTime'))
            if start_date <= now <= end_date:
                if is_playable:
                    label = '[COLOR={highlighted}]%s[/COLOR] %s' % (
                        label, localize(30301))
                else:
                    label += localize(30301)

            info_labels = self._metadata.get_info_labels(episode,
                                                         date=date,
                                                         channel=entry)
            # FIXME: Due to a bug in Kodi, ListItem.Title is used when Sort methods are used, not ListItem.Label
            info_labels['title'] = colour(label)

            episode_items.append(
                TitleItem(
                    label=colour(label),
                    path=path,
                    art_dict=self._metadata.get_art(episode),
                    info_dict=info_labels,
                    context_menu=context_menu,
                    is_playable=is_playable,
                ))
        return episode_items