def playing_now(self, channel):
        """Return the EPG information for what is playing now"""
        now = datetime.now(dateutil.tz.tzlocal())
        epg = now
        # Daily EPG information shows information from 6AM until 6AM
        if epg.hour < 6:
            epg += timedelta(days=-1)

        entry = find_entry(CHANNELS, 'name', channel)
        if not entry:
            return ''

        epg_url = epg.strftime(self.VRT_TVGUIDE)
        schedule = get_cached_url_json(url=epg_url,
                                       cache='schedule.today.json',
                                       ttl=ttl('indirect'),
                                       fail={})
        episodes = iter(schedule.get(entry.get('id'), []))

        while True:
            try:
                episode = next(episodes)
            except StopIteration:
                break
            start_date = dateutil.parser.parse(episode.get('startTime'))
            end_date = dateutil.parser.parse(episode.get('endTime'))
            if start_date <= now <= end_date:  # Now playing
                return episode.get('title')
        return ''
Example #2
0
    def get_tvshows(self, category=None, channel=None, feature=None):
        """Get all TV shows for a given category, channel or feature, optionally filtered by favorites"""
        params = {}

        if category:
            params['facets[categories]'] = category
            cache_file = 'category.{category}.json'.format(category=category)

        if channel:
            params['facets[programBrands]'] = channel
            cache_file = 'channel.{channel}.json'.format(channel=channel)

        if feature:
            params['facets[programTags.title]'] = feature
            cache_file = 'featured.{feature}.json'.format(feature=feature)

        # If no facet-selection is done, we return the 'All programs' listing
        if not category and not channel and not feature:
            params[
                'facets[transcodingStatus]'] = 'AVAILABLE'  # Required for getting results in Suggests API
            cache_file = 'programs.json'

        querystring = '&'.join('{}={}'.format(key, value)
                               for key, value in list(params.items()))
        suggest_url = self._VRTNU_SUGGEST_URL + '?' + querystring
        return get_cached_url_json(url=suggest_url,
                                   cache=cache_file,
                                   ttl=ttl('indirect'),
                                   fail=[])
Example #3
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 live_description(self, channel):
        """Return the EPG information for current and next live program"""
        now = datetime.now(dateutil.tz.tzlocal())
        epg = now
        # Daily EPG information shows information from 6AM until 6AM
        if epg.hour < 6:
            epg += timedelta(days=-1)

        entry = find_entry(CHANNELS, 'name', channel)
        if not entry:
            return ''

        epg_url = epg.strftime(self.VRT_TVGUIDE)
        schedule = get_cached_url_json(url=epg_url,
                                       cache='schedule.today.json',
                                       ttl=ttl('indirect'),
                                       fail={})
        episodes = iter(schedule.get(entry.get('id'), []))

        description = ''
        episode = None
        while True:
            try:
                episode = next(episodes)
            except StopIteration:
                break
            start_date = dateutil.parser.parse(episode.get('startTime'))
            end_date = dateutil.parser.parse(episode.get('endTime'))
            if start_date <= now <= end_date:  # Now playing
                description = '[COLOR={highlighted}][B]%s[/B] %s[/COLOR]\n' % (
                    localize(30421), self.episode_description(episode))
                try:
                    description += '[B]%s[/B] %s' % (localize(30422),
                                                     self.episode_description(
                                                         next(episodes)))
                except StopIteration:
                    break
                break
            if now < start_date:  # Nothing playing now, but this may be next
                description = '[B]%s[/B] %s\n' % (
                    localize(30422), self.episode_description(episode))
                try:
                    description += '[B]%s[/B] %s' % (localize(30422),
                                                     self.episode_description(
                                                         next(episodes)))
                except StopIteration:
                    break
                break
        if episode and not description:
            # Add a final 'No transmission' program
            description = '[COLOR={highlighted}][B]%s[/B] %s - 06:00\n» %s[/COLOR]' % (
                localize(30421), episode.get('end'), localize(30423))
        return colour(description)
    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
Example #6
0
    def get_episodes(self,
                     program=None,
                     season=None,
                     episodes=None,
                     category=None,
                     feature=None,
                     programtype=None,
                     keywords=None,
                     whatson_id=None,
                     video_id=None,
                     video_url=None,
                     page=None,
                     use_favorites=False,
                     variety=None,
                     cache_file=None):
        """Get episodes or season data from VRT NU Search API"""

        # Contruct params
        if page:
            page = realpage(page)
            all_items = False
            items_per_page = get_setting_int('itemsperpage', default=50)
            params = {
                'from': ((page - 1) * items_per_page) + 1,
                'i': 'video',
                'size': items_per_page,
            }
        elif variety == 'single':
            all_items = False
            params = {
                'i': 'video',
                'size': '1',
            }
        else:
            all_items = True
            params = {
                'i': 'video',
                'size': '300',
            }

        if variety:
            season = 'allseasons'

            if variety == 'offline':
                from datetime import datetime, timedelta
                import dateutil.tz
                now = datetime.now(dateutil.tz.gettz('Europe/Brussels'))
                off_dates = [(now + timedelta(days=day)).strftime('%Y-%m-%d')
                             for day in range(0, 7)]
                params['facets[assetOffTime]'] = '[%s]' % (','.join(off_dates))

            if variety == 'oneoff':
                params[
                    'facets[episodeNumber]'] = '[0,1]'  # This to avoid VRT NU metadata errors (see #670)
                params['facets[programType]'] = 'oneoff'

            if variety == 'watchlater':
                self._resumepoints.refresh(ttl=ttl('direct'))
                episode_urls = self._resumepoints.watchlater_urls()
                params['facets[url]'] = '[%s]' % (','.join(episode_urls))

            if variety == 'continue':
                self._resumepoints.refresh(ttl=ttl('direct'))
                episode_urls = self._resumepoints.resumepoints_urls()
                params['facets[url]'] = '[%s]' % (','.join(episode_urls))

            if use_favorites:
                program_urls = [
                    program_to_url(p, 'medium')
                    for p in self._favorites.programs()
                ]
                params['facets[programUrl]'] = '[%s]' % (
                    ','.join(program_urls))
            elif variety in ('offline', 'recent'):
                channel_filter = []
                for channel in CHANNELS:
                    if channel.get('vod') is True and get_setting_bool(
                            channel.get('name'), default=True):
                        channel_filter.append(channel.get('name'))
                params['facets[programBrands]'] = '[%s]' % (
                    ','.join(channel_filter))

        if program:
            params['facets[programUrl]'] = program_to_url(program, 'medium')

        if season and season != 'allseasons':
            params['facets[seasonTitle]'] = season

        if episodes:
            params['facets[episodeNumber]'] = '[%s]' % (','.join(
                str(episode) for episode in episodes))

        if category:
            params['facets[categories]'] = category

        if feature:
            params['facets[programTags.title]'] = feature

        if programtype:
            params['facets[programType]'] = programtype

        if keywords:
            if not season:
                season = 'allseasons'
            params['q'] = quote_plus(from_unicode(keywords))
            params['highlight'] = 'true'

        if whatson_id:
            params['facets[whatsonId]'] = whatson_id

        if video_id:
            params['facets[videoId]'] = video_id

        if video_url:
            params['facets[url]'] = video_url

        # Construct VRT NU Search API Url and get api data
        querystring = '&'.join('{}={}'.format(key, value)
                               for key, value in list(params.items()))
        search_url = self._VRTNU_SEARCH_URL + '?' + querystring.replace(
            ' ', '%20')  # Only encode spaces to minimize url length
        if cache_file:
            search_json = get_cached_url_json(url=search_url,
                                              cache=cache_file,
                                              ttl=ttl('indirect'),
                                              fail={})
        else:
            search_json = get_url_json(url=search_url, fail={})

        # Check for multiple seasons
        seasons = []
        if 'facets[seasonTitle]' not in unquote(search_url):
            facets = search_json.get('facets', {}).get('facets')
            if facets:
                seasons = next((f.get('buckets', [])
                                for f in facets if f.get('name') == 'seasons'
                                and len(f.get('buckets', [])) > 1), None)
            # Experimental: VRT Search API only returns a maximum of 10 seasons, to get all seasons we need to use the "model.json" API
            if seasons and program and len(seasons) == 10:
                season_json = get_url_json(
                    'https://www.vrt.be/vrtnu/a-z/%s.model.json' % program)
                season_items = None
                try:
                    season_items = season_json.get(':items').get('parsys').get(':items').get('container') \
                                              .get(':items').get('banner').get(':items').get('navigation').get(':items')
                except AttributeError:
                    pass
                if season_items:
                    seasons = []
                    for item in season_items:
                        seasons.append(dict(key=item.lstrip('0')))

        episodes = search_json.get('results', [{}])
        show_seasons = bool(season != 'allseasons')

        # Return seasons
        if show_seasons and seasons:
            return (seasons, episodes)

        api_pages = search_json.get('meta').get('pages').get('total')
        api_page_size = search_json.get('meta').get('pages').get('size')
        total_results = search_json.get('meta').get('total_results')

        if all_items and total_results > api_page_size:
            for api_page in range(1, api_pages):
                api_page_url = search_url + '&from=' + str(api_page *
                                                           api_page_size + 1)
                api_page_json = get_url_json(api_page_url)
                if api_page_json is not None:
                    episodes += api_page_json.get('results', [{}])

        # Return episodes
        return episodes