def manage(self): """Allow the user to unselect favorites to be removed from the listing""" from utils import url_to_program self.refresh(ttl=0) if not self._data: ok_dialog(heading=localize(30418), message=localize(30419)) # No favorites found return def by_title(item): """Sort by title""" return item.get('value').get('title') items = [ dict(program=url_to_program(value.get('value').get('programUrl')), title=unquote(value.get('value').get('title')), enabled=value.get('value').get('isFavorite')) for value in list(sorted(list(self._data.values()), key=by_title)) ] titles = [item['title'] for item in items] preselect = [ idx for idx in range(0, len(items) - 1) if items[idx]['enabled'] ] selected = multiselect( localize(30420), options=titles, preselect=preselect) # Please select/unselect to follow/unfollow if selected is not None: for idx in set(preselect).difference(set(selected)): self.unfollow(program=items[idx]['program'], title=items[idx]['title']) for idx in set(selected).difference(set(preselect)): self.follow(program=items[idx]['program'], title=items[idx]['title'])
def manage(self): """Allow the user to unselect favorites to be removed from the listing""" self.refresh(ttl=0) if not self._favorites: ok_dialog(heading=localize(30418), message=localize(30419)) # No favorites found return def by_title(tup): """Sort by title""" _, value = tup return value.get('title') items = [ dict(program_id=value.get('program_id'), program_name=key, title=unquote(value.get('title'))) for key, value in sorted(self._favorites.items(), key=by_title) ] titles = [item['title'] for item in items] preselect = list(range(0, len(items))) selected = multiselect( localize(30420), options=titles, preselect=preselect) # Please select/unselect to follow/unfollow if selected is not None: for idx in set(preselect).difference(set(selected)): self.unfollow(program_name=items[idx]['program_name'], title=items[idx]['title'], program_id=items[idx]['program_id']) for idx in set(selected).difference(set(preselect)): self.follow(program_name=items[idx]['program_name'], title=items[idx]['title'], program_id=items[idx]['program_id'])
def login(self, refresh=False, token_variant=None): """Kodi GUI login flow""" # If no credentials, ask user for credentials if not has_credentials(): if refresh: return open_settings() open_settings() if not self._credentials_changed(): return None # Check credentials login_json = self._get_login_json() # Bad credentials while login_json.get('errorCode') != 0: # Show localized login error messages in Kodi GUI message = login_json.get('errorDetails') log_error('Login failed: {msg}', msg=message) if message == 'invalid loginID or password': message = localize(30953) # Invalid login! elif message == 'loginID must be provided': message = localize(30955) # Please fill in username elif message == 'Missing required parameter: password': message = localize(30956) # Please fill in password ok_dialog(heading=localize(30951), message=message) # Login failed! if refresh: return open_settings() open_settings() if not self._credentials_changed(): return None login_json = self._get_login_json() # Get token return self._get_new_xvrttoken(login_json, token_variant)
def show_tvguide(self, date=None, channel=None): """Offer a menu depending on the information provided""" if not date and not channel: date_items = self.get_date_items() show_listing(date_items, category=30026, content='files') # TV guide elif not channel: channel_items = self.get_channel_items(date=date) entry = find_entry(RELATIVE_DATES, 'id', date) date_name = localize(entry.get('msgctxt')) if entry else date show_listing(channel_items, category=date_name) elif not date: date_items = self.get_date_items(channel=channel) channel_name = find_entry(CHANNELS, 'name', channel).get('label') show_listing(date_items, category=channel_name, content='files', selected=7) else: episode_items = self.get_episode_items(date, channel) channel_name = find_entry(CHANNELS, 'name', channel).get('label') entry = find_entry(RELATIVE_DATES, 'id', date) date_name = localize(entry.get('msgctxt')) if entry else date show_listing(episode_items, category='%s / %s' % (channel_name, date_name), content='episodes', cache=False)
def test_localize(self): xbmc.settings['locale.language'] = 'resource.language.nl_nl' msg = localize(30958) #self.assertEqual(msg, "There is a problem with this VRT NU {protocol} stream. Try again with {component} {state} or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/") # noqa self.assertEqual( msg, "Er is een probleem met deze VRT NU {protocol}-stream. Probeer het opnieuw met {component} {state} of probeer dit programma af te spelen vanaf de VRT NU-website. Meld dit probleem op https://www.vrt.be/vrtnu/help/" ) # noqa msg = localize(30958, component='Widevine DRM', state='enabled') #self.assertEqual(msg, "There is a problem with this VRT NU {protocol} stream. Try again with Widevine DRM enabled or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/") # noqa self.assertEqual( msg, "Er is een probleem met deze VRT NU {protocol}-stream. Probeer het opnieuw met Widevine DRM enabled of probeer dit programma af te spelen vanaf de VRT NU-website. Meld dit probleem op https://www.vrt.be/vrtnu/help/" ) # noqa msg = localize(30958, protocol='MPEG-DASH', component='Widevine DRM', state='enabled') #self.assertEqual(msg, "There is a problem with this VRT NU MPEG-DASH stream. Try again with Widevine DRM enabled or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/") # noqa self.assertEqual( msg, "Er is een probleem met deze VRT NU MPEG-DASH-stream. Probeer het opnieuw met Widevine DRM enabled of probeer dit programma af te spelen vanaf de VRT NU-website. Meld dit probleem op https://www.vrt.be/vrtnu/help/" ) # noqa
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 update_repos(): """Force an update of the repositories""" if get_global_setting( 'general.addonupdates') == 0: # Automatic updates is enabled execute_builtin('UpdateAddonRepos') ok_dialog(heading=localize(30450), message=localize(30451)) # Repositories are being updated else: ok_dialog(heading=localize(30452), message=localize(30453)) # Automatic updates is disabled show_settings_addons()
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
def _get_fresh_token(self, refresh_token, name): """Refresh an expired X-VRT-Token, vrtlogin-at or vrtlogin-rt token""" refresh_url = self._TOKEN_GATEWAY_URL + '/refreshtoken?legacy=true' cookie_value = 'vrtlogin-rt=' + refresh_token headers = {'Cookie': cookie_value} cookiejar = cookielib.CookieJar() try: open_url(refresh_url, headers=headers, cookiejar=cookiejar, raise_errors=[401]) except HTTPError: ok_dialog(heading=localize(30970), message=localize(30971)) return TokenResolver._create_token_dictionary(cookiejar, name)
def show_end_result_sp(self): self.rec_speed = ControlTextBox(325, 475, 600, 300, textColor='0xFFFFFFFF') self.addControl(self.rec_speed) self.rec_speed.setVisible(False) self.rec_speed.setEnabled(False) self.rec_speed.setText('\n'.join([localize(30980), localize(30981), localize(30982), localize(30983), localize(30984), localize(30985)])) self.rec_speed.setAnimations([( 'conditional', 'effect=fade start=0 end=100 time=1000 delay=100 condition=Control.IsVisible(%d)' % self.rec_speed.getId() )]) self.rec_speed.setVisible(True) self.rec_speed.setEnabled(True)
def play_episode_by_air_date(self, channel, start_date, end_date): """Play an episode of a program given the channel and the air date in iso format (2019-07-06T19:35:00)""" video = self._apihelper.get_episode_by_air_date(channel, start_date, end_date) if video and video.get('errorlabel'): ok_dialog(message=localize(30986, title=video.get('errorlabel'))) end_of_directory() return if not video: log_error('Play episode by air date failed, channel {channel}, start_date {start}', channel=channel, start=start_date) ok_dialog(message=localize(30954)) end_of_directory() return self.play(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 _version_check(self): first_run, settings_version, addon_version = self._first_run() if first_run: # 2.0.0 version: changed plugin:// url interface: show warning that Kodi favourites and what-was-watched will break if settings_version == '' and has_credentials(): ok_dialog(localize(30978), localize(30979)) if addon_version == '2.2.1': # 2.2.1 version: changed artwork: delete old cached artwork delete_cached_thumbnail( get_addon_info('fanart').replace('.png', '.jpg')) delete_cached_thumbnail(get_addon_info('icon')) # 2.2.1 version: moved tokens: delete old tokens from tokenresolver import TokenResolver TokenResolver().delete_tokens()
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) # Try the cache if it is fresh schedule = get_cache('schedule.today.json', ttl=60 * 60) if not schedule: from json import load epg_url = epg.strftime(self.VRT_TVGUIDE) log(2, 'URL get: {url}', url=epg_url) schedule = load(urlopen(epg_url)) update_cache('schedule.today.json', schedule) entry = find_entry(CHANNELS, 'name', channel) if not entry: return '' episodes = iter(schedule.get(entry.get('id'), [])) description = '' 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 yellow][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 not description: # Add a final 'No transmission' program description = '[COLOR yellow][B]%s[/B] %s - 06:00\n» %s[/COLOR]' % (localize(30421), episode.get('end'), localize(30423)) return description
def update(self, program, title, value=True): """Set a program as favorite, and update local copy""" # Survive any recent updates self.refresh(ttl=5) if value is self.is_favorite(program): # Already followed/unfollowed, nothing to do return True from tokenresolver import TokenResolver xvrttoken = TokenResolver().get_xvrttoken(token_variant='user') if xvrttoken is None: log_error('Failed to get favorites token from VRT NU') notification(message=localize(30975)) return False headers = { 'authorization': 'Bearer ' + xvrttoken, 'content-type': 'application/json', 'Referer': 'https://www.vrt.be/vrtnu', } from json import dumps from utils import program_to_url payload = dict(isFavorite=value, programUrl=program_to_url(program, 'short'), title=title) data = dumps(payload).encode('utf-8') program_id = program_to_id(program) try: get_url_json( 'https://video-user-data.vrt.be/favorites/{program_id}'.format( program_id=program_id), headers=headers, data=data) except HTTPError as exc: log_error( "Failed to (un)follow program '{program}' at VRT NU ({error})", program=program, error=exc) notification(message=localize(30976, program=program)) return False # NOTE: Updates to favorites take a longer time to take effect, so we keep our own cache and use it self._data[program_id] = dict(value=payload) update_cache('favorites.json', dumps(self._data)) invalidate_caches('my-offline-*.json', 'my-recent-*.json') return True
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)
def _get_new_xvrttoken(self, login_json, token_variant=None): """Get new X-VRT-Token from VRT NU website""" if token_variant == 'roaming': xvrttoken = self._get_roaming_xvrttoken() else: login_token = login_json.get('sessionInfo', {}).get('login_token') if not login_token: return None from json import dumps login_cookie = 'glt_{api_key}={token}'.format(api_key=self._API_KEY, token=login_token) payload = dict( uid=login_json.get('UID'), uidsig=login_json.get('UIDSignature'), ts=login_json.get('signatureTimestamp'), email=from_unicode(get_setting('username')), ) data = dumps(payload).encode() headers = {'Content-Type': 'application/json', 'Cookie': login_cookie} log(2, 'URL post: {url}', url=unquote(self._TOKEN_GATEWAY_URL)) req = Request(self._TOKEN_GATEWAY_URL, data=data, headers=headers) try: # Python 3 setcookie_header = urlopen(req).info().get('Set-Cookie') except AttributeError: # Python 2 setcookie_header = urlopen(req).info().getheader('Set-Cookie') xvrttoken = TokenResolver._create_token_dictionary(setcookie_header) if xvrttoken is None: return None self._set_cached_token(xvrttoken, token_variant) notification(message=localize(30952)) # Login succeeded. return xvrttoken.get('X-VRT-Token')
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)
def _get_xvrttoken(self, login_json=None): """Get a one year valid X-VRT-Token""" from json import dumps if not login_json: login_json = self._get_login_json() login_token = login_json.get('sessionInfo', {}).get('login_token') if not login_token: return None login_cookie = 'glt_{api_key}={token}'.format(api_key=self._API_KEY, token=login_token) payload = dict(uid=login_json.get('UID'), uidsig=login_json.get('UIDSignature'), ts=login_json.get('signatureTimestamp'), email=from_unicode(get_setting('username'))) data = dumps(payload).encode() headers = {'Content-Type': 'application/json', 'Cookie': login_cookie} response = open_url(self._TOKEN_GATEWAY_URL, data=data, headers=headers) if response is None: return None setcookie_header = response.info().get('Set-Cookie') xvrttoken = TokenResolver._create_token_dictionary(setcookie_header) if xvrttoken is None: return None notification(message=localize(30952)) # Login succeeded. return xvrttoken
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 display_button_close(self, function='true'): if function == 'true': self.button_close_glow = ControlImage(880, 418, 300, 122, '', aspectRatio=0) self.addControl(self.button_close_glow) self.button_close_glow.setVisible(False) self.button_close_glow.setImage(self.image_button_run_glow) self.button_close_glow.setAnimations([( 'conditional', 'effect=fade start=0 time=1000 delay=2000 pulse=true condition=Control.IsVisible(%d)' % self.button_close_glow.getId() )]) self.button_close = ControlButton(99999, 99999, 300, 122, localize(30951), focusTexture=self.image_button_run, noFocusTexture=self.image_button_run, alignment=2 | 4, textColor='0xFF000000', focusedColor='0xFF000000', shadowColor='0xFFCCCCCC', disabledColor='0xFF000000') self.addControl(self.button_close) self.button_close.setVisible(False) self.button_close.setPosition(880, 418) self.button_close_id = self.button_close.getId() self.button_close.setAnimations([( 'conditional', 'effect=fade start=0 end=100 delay=1000 time=1000 condition=Control.IsVisible(%d)' % self.button_close.getId() )]) elif function == 'visible': self.button_close.setVisible(True) self.button_close_glow.setVisible(True) self.setFocus(self.button_close) else: self.button_close.setVisible(False) self.button_close_glow.setVisible(False)
def generate_list_item(element, element_type): from xbmcgui import ListItem list_item = ListItem(element.get('label') or element.get('title')) info_labels = dict(title=element.get('title')) uid = element.get('id') resources = element.get('resources') if element.get('playable') or element.get('action') == 'play': list_item.setPath(plugin.url_for(play_uid, uid=uid)) list_item.setProperty('IsPlayable', 'true') if element.get('duration'): info_labels['duration'] = element.get('duration') / 1000 elif element.get('type') == 'video' and element.get('status').get( 'label') == 'Upcoming': info_labels['premiered'] = element.get('status').get('start_time') from time import timezone list_item.setPath( '/notify/' + localize(30024), localize(30025), element.get('event_date') + ' (GMT+' + str(timezone / 3600 * -1)) elif element_type == COLLECTION: list_item.setPath(plugin.url_for(browse_collection, uid=uid)) elif element_type == PRODUCT: list_item.setPath(plugin.url_for(browse_product, uid=uid)) info_labels['title'] = element.get('label') or element.get('title') info_labels['genre'] = element.get('subheading') info_labels['plot'] = element.get('long_description') if element.get( 'long_description') else element.get('short_description') if resources: list_item.setArt( dict(fanart=redbull.get_image_url(uid, resources, 'landscape'))) list_item.setArt( dict(landscape=redbull.get_image_url(uid, resources, 'landscape'))) list_item.setArt( dict(banner=redbull.get_image_url(uid, resources, 'banner'))) list_item.setArt( dict(poster=redbull.get_image_url(uid, resources, 'poster'))) list_item.setArt( dict(thumb=redbull.get_image_url(uid, resources, 'thumb'))) if list_item.getArt('thumb') is None: list_item.setArt(dict(thumb=addon_icon())) list_item.setInfo(type='Video', infoLabels=info_labels) return list_item
def _get_usertoken(self, name=None, login_json=None, roaming=False): """Get a user X-VRT-Token, vrtlogin-at, vrtlogin-expiry, vrtlogin-rt, SESSION, OIDCXSRF or state token""" if not login_json: login_json = self._get_login_json() cookiejar = cookielib.CookieJar() open_url(self._USER_TOKEN_GATEWAY_URL, cookiejar=cookiejar) xsrf = next( (cookie for cookie in cookiejar if cookie.name == 'OIDCXSRF'), None) if xsrf is None: return None payload = dict(UID=login_json.get('UID'), UIDSignature=login_json.get('UIDSignature'), signatureTimestamp=login_json.get('signatureTimestamp'), client_id='vrtnu-site', _csrf=xsrf.value) data = urlencode(payload).encode() response = open_url(self._VRT_LOGIN_URL, data=data, cookiejar=cookiejar) if response is None: return None destination = response.geturl() usertoken = TokenResolver._create_token_dictionary(cookiejar, name) if not usertoken and not destination.startswith( 'https://www.vrt.be/vrtnu'): if roaming is False: ok_dialog(heading=localize(30970), message=localize(30972)) return None # Cache additional tokens for later use refreshtoken = TokenResolver._create_token_dictionary( cookiejar, cookie_name='vrtlogin-rt') accesstoken = TokenResolver._create_token_dictionary( cookiejar, cookie_name='vrtlogin-at') if refreshtoken is not None: from json import dumps cache_file = self._get_token_filename('vrtlogin-rt') update_cache(cache_file, dumps(refreshtoken), self._TOKEN_CACHE_DIR) if accesstoken is not None: from json import dumps cache_file = self._get_token_filename('vrtlogin-at') update_cache(cache_file, dumps(accesstoken), self._TOKEN_CACHE_DIR) return usertoken
def watchlater(self, episode_id, title): """Watch an episode later""" succeeded = self.update_watchlater(episode_id=episode_id, title=title, watch_later=True) if succeeded: notification(message=localize(30403, title=title)) container_refresh()
def watchlater(self, uuid, title, url): ''' Watch an episode later ''' succeeded = self.update(uuid=uuid, title=title, url=url, watch_later=True) if succeeded: notification(message=localize(30403, title=title)) container_refresh()
def watchlater(self, asset_id, title, url): """Watch an episode later""" succeeded = self.update(asset_id=asset_id, title=title, url=url, watch_later=True) if succeeded: notification(message=localize(30403, title=title)) container_refresh()
def _version_check(self): first_run, settings_version, addon_version = self._first_run() if first_run: # 2.0.0 version: changed plugin:// url interface: show warning that Kodi favourites and what-was-watched will break if settings_version == '' and has_credentials(): ok_dialog(localize(30978), localize(30979)) if addon_version == '2.2.1': # 2.2.1 version: changed artwork: delete old cached artwork delete_cached_thumbnail(get_addon_info('fanart').replace('.png', '.jpg')) delete_cached_thumbnail(get_addon_info('icon')) # 2.2.1 version: moved tokens: delete old tokens from tokenresolver import TokenResolver TokenResolver().delete_tokens() # Make user aware that timeshift functionality will not work without ISA when user starts up the first time if settings_version == '' and kodi_version_major() > 17 and not has_inputstream_adaptive(): ok_dialog(message=localize(30988))
def play_upnext(self, video_id): """Play the next episode of a program by video_id""" video = self._apihelper.get_single_episode(video_id=video_id) if not video: log_error('Play Up Next with video_id {video_id} failed', video_id=video_id) ok_dialog(message=localize(30954)) end_of_directory() return self.play(video)
def play_episode_by_whatson_id(self, whatson_id): """Play an episode of a program given the whatson_id""" video = self._apihelper.get_single_episode(whatson_id=whatson_id) if not video: log_error('Play episode by whatson_id failed, whatson_id {whatson_id}', whatson_id=whatson_id) ok_dialog(message=localize(30954)) end_of_directory() return self.play(video)
def play_latest_episode(self, program): """A hidden feature in the VRT NU add-on to play the latest episode of a program""" video = self._apihelper.get_latest_episode(program) if not video: log_error('Play latest episode failed, program {program}', program=program) ok_dialog(message=localize(30954)) end_of_directory() return self.play(video)