def play(self, video_id): params = { 'encoding': 'mpd_widevine_modular', 'subscription_status': 'full', 'lang': 'eng', } data = self._session.get('playback/play/{0}'.format(video_id), params=params).json() url = data['url'] task_id = data['packaging_task_id'] session_id = data['session_id'] data = { 'user_id': userdata.get('user_id'), 'video_id': video_id, 'hw_code': userdata.get('device_id'), 'packaging_task_id': task_id, 'session_id': session_id, } params = {'showmax_rating': 'adults', 'lang': 'eng'} data = self._session.post('playback/verify', params=params, data=data).json() license_request = data['license_request'] license_url = API_URL.format( 'drm/widevine_modular?license_request={0}'.format(license_request)) return url, license_url
def _refresh_token(self): if userdata.get('expires', 0) > time(): return payload = { "refresh_token": userdata.get('refresh_token'), "grant_type": "refresh_token", "client_id": CLIENTID, } self._oauth_token(payload)
def panel(self, id): params = { #'evaluate': 3, 'profile': userdata.get('profile'), } return self._session.get('https://vccapi.kayosports.com.au/content/types/carousel/keys/{}'.format(id), params=params).json()[0]
def landing(self, name): params = { 'evaluate': 99, 'profile': userdata.get('profile'), } return self._session.get('https://vccapi.kayosports.com.au/content/types/landing/names/{}'.format(name), params=params).json()
def _set_authentication(self): access_token = userdata.get('access_token') if not access_token: return self._session.headers.update({'authorization': 'Bearer {}'.format(access_token)}) self.logged_in = True
def show(show_id, title, **kwargs): data = api.show(show_id=show_id, profile=userdata.get('profile')) folder = plugin.Folder(title=title) for row in data: if row['title'] == 'Seasons': for row2 in row.get('contents', []): asset = row2['data']['asset'] folder.add_item( label=asset['title'], art={ 'thumb': _get_image(asset, 'show', 'thumb'), 'fanart': _get_image(asset, 'show', 'fanart'), }, info={ 'plot': asset.get('description-short'), }, path=plugin.url_for(season, show_id=show_id, season_id=asset['id'], title=asset['title']), ) return folder
def _set_authentication(self): token = userdata.get('access_token') if not token: return self._session.headers.update({'sky-x-access-token': token}) self.logged_in = True
def service(): alerts = userdata.get('alerts', []) if not alerts: return now = arrow.now() notify = [] _alerts = [] for id in alerts: asset = api.event(id) start = arrow.get(asset.get('preCheckTime', asset['transmissionTime'])) #If we are streaming and started less than 10 minutes ago if asset.get('isStreaming', False) and (now - start).total_seconds() <= 60*10: notify.append(asset) elif start > now: _alerts.append(id) userdata.set('alerts', _alerts) for asset in notify: if not gui.yes_no(_(_.EVENT_STARTED, event=asset['title']), yeslabel=_.WATCH, nolabel=_.CLOSE): continue with signals.throwable(): start_from = 1 start = arrow.get(asset['transmissionTime']) if start < now and 'preCheckTime' in asset: precheck = arrow.get(asset['preCheckTime']) if precheck < start: start_from = (start - precheck).seconds play(id=asset['id'], start_from=start_from, play_type=settings.getEnum('live_play_type', LIVE_PLAY_TYPES, default=FROM_CHOOSE))
def _set_authentication(self): access_token = userdata.get('token') if not access_token: return self._session.headers.update({'X-Auth-Token': access_token}) self.logged_in = True
def search(query=None, page=1, **kwargs): page = int(page) if not query: query = gui.input(_.SEARCH, default=userdata.get('search', '')).strip() if not query: return userdata.set('search', query) data = api.filter_media('keyword', query, page=page) total_pages = int(data['paginator']['total_pages']) folder = plugin.Folder(title=_(_.SEARCH_FOR, query=query, page=page, total_pages=total_pages)) for row in data['data']: item = _process_media(row) folder.add_items([item]) if total_pages > page: folder.add_item( label = _(_.NEXT_PAGE, next_page=page+1), path = plugin.url_for(search, query=query, page=page+1), ) return folder
def event(self, id): params = { 'evaluate': 1, 'profile': userdata.get('profile'), 'event': id, } return self._session.get('https://vccapi.kayosports.com.au/content/types/landing/names/event', params=params).json()[0]['contents'][0]['data']['asset']
def show(self, id): params = { 'evaluate': 99, 'profile': userdata.get('profile'), 'showCategory': id, } return self._session.get('https://vccapi.kayosports.com.au/content/types/landing/names/show', params=params).json()
def sport(self, sport=None): params = { 'evaluate': 99, 'profile': userdata.get('profile'), 'sport': sport, } return self._session.get('https://vccapi.kayosports.com.au/content/types/landing/names/sport', params=params).json()
def _get_play_token(self): self._renew_token() params = { 'profileId': userdata.get('device_id'), 'deviceId': userdata.get('device_id'), 'partnerId': 'skygo', 'description': 'ANDROID', } resp = self._session.get(TOKEN_URL, params=params) data = resp.json() if resp.status_code != 200 or 'token' not in data: raise APIError(_(_.TOKEN_ERROR, message=data.get('message'))) return data['token']
def season(show_id, season_id, title, **kwargs): data = api.show(show_id=show_id, season_id=season_id, profile=userdata.get('profile')) folder = plugin.Folder(title=title) for row in data: if row['title'] == 'Episodes': folder.add_items(_parse_contents(row.get('contents', []))) return folder
def alert(asset, title, **kwargs): alerts = userdata.get('alerts', []) if asset not in alerts: alerts.append(asset) gui.notification(title, heading=_.REMINDER_SET) else: alerts.remove(asset) gui.notification(title, heading=_.REMINDER_REMOVED) userdata.set('alerts', alerts) gui.refresh()
def alert(asset, title, image): alerts = userdata.get('alerts', []) if asset not in alerts: alerts.append(asset) gui.notification(_.REMINDER_SET, heading=title, icon=image) else: alerts.remove(asset) gui.notification(_.REMINDER_REMOVED, heading=title, icon=image) userdata.set('alerts', alerts) gui.refresh()
def _renew_token(self): password = userdata.get('pswd') if password: self.login(userdata.get('username'), password) return data = { "deviceID": userdata.get('device_id'), "deviceIP": DEVICE_IP, "sessionToken": userdata.get('access_token'), } resp = self._session.post(RENEW_URL, json=data) data = resp.json() if resp.status_code != 200 or 'sessiontoken' not in data: raise APIError(_(_.RENEW_TOKEN_ERROR, message=data.get('message'))) userdata.set('access_token', data['sessiontoken']) self._set_authentication()
def login(**kwargs): username = gui.input(_.ASK_USERNAME, default=userdata.get('username', '')).strip() if not username: return userdata.set('username', username) password = gui.input(_.ASK_PASSWORD, hide_input=True).strip() if not password: return api.login(username=username, password=password) gui.refresh()
def _landing(name, sport=None): items = [] for row in api.landing(name, sport=sport, profile=userdata.get('profile')): if row['panelType'] == 'hero-carousel' and row.get('contents') and settings.getBool('show_hero_contents', True): items.extend(_parse_contents(row['contents'])) elif row['panelType'] != 'hero-carousel' and 'id' in row: items.append(plugin.Item( label = row['title'], path = plugin.url_for(panel, id=row['id'], sport=sport), )) return items
def start(): restart_queued = False while not monitor.waitForAbort(2): forced = ADDON_DEV or xbmc.getInfoLabel( 'Skin.String({})'.format(ADDON_ID)) == FORCE_RUN_FLAG if forced or (settings.getBool('auto_merge', True) and time.time() - userdata.get('last_run', 0) > settings.getInt('reload_time_mins', 10) * 60): xbmc.executebuiltin('Skin.SetString({},{})'.format( ADDON_ID, FORCE_RUN_FLAG)) try: run_merge([Source.PLAYLIST, Source.EPG]) except Exception as e: result = False log.exception(e) else: result = True userdata.set('last_run', int(time.time())) xbmc.executebuiltin('Skin.SetString({},)'.format(ADDON_ID)) if result: restart_queued = True if forced: gui.notification(_.MERGE_COMPLETE) elif forced: gui.exception() if restart_queued and ( forced or (settings.getBool('restart_pvr', False) and not xbmc.getCondVisibility('Pvr.IsPlayingTv') and not xbmc.getCondVisibility('Pvr.IsPlayingRadio'))): restart_queued = False xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":false}}}}' .format(IPTV_SIMPLE_ID)) monitor.waitForAbort(2) xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":true}}}}' .format(IPTV_SIMPLE_ID)) if ADDON_DEV: break
def login(): username = gui.input(_.ASK_USERNAME, default=userdata.get('username', '')).strip() if not username: return userdata.set('username', username) password = gui.input(_.ASK_PASSWORD).strip() if not password: return api.login(username=username, password=password) _select_profile() gui.refresh()
def start(): monitor = xbmc.Monitor() restart_required = False while not monitor.waitForAbort(5): forced = xbmc.getInfoLabel( 'Skin.String({})'.format(ADDON_ID)) == FORCE_RUN_FLAG xbmc.executebuiltin('Skin.SetString({},)'.format(ADDON_ID)) if forced or time.time() - userdata.get( 'last_run', 0) > settings.getInt('reload_time_mins') * 60: try: run_merge() except Exception as e: result = False log.exception(e) else: result = True userdata.set('last_run', int(time.time())) if result: restart_required = settings.getBool('restart_pvr', False) if forced: gui.notification(_.MERGE_COMPLETE) elif forced: gui.exception() if restart_required and not xbmc.getCondVisibility( 'Pvr.IsPlayingTv') and not xbmc.getCondVisibility( 'Pvr.IsPlayingRadio'): restart_required = False addon_id = PVR_ADDON_IDS[settings.getInt('unused_pvr_id')] xbmc.executebuiltin('InstallAddon({})'.format(addon_id), True) xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":true}}}}' .format(addon_id)) xbmc.executeJSONRPC( '{{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{{"addonid":"{}","enabled":false}}}}' .format(addon_id))
def login(): while not api.logged_in: username = gui.input(_(L_ASK_USERNAME), default=userdata.get('username', '')).strip() if not username: break userdata.set('username', username) password = gui.input(_(L_ASK_PASSWORD), default=cache.get('password', '')).strip() if not password: break cache.set('password', password, expires=60) if api.login(username=username, password=password): gui.refresh() else: gui.ok(_(L_LOGIN_ERROR)) cache.delete('password')
def service(): alerts = userdata.get('alerts', []) if not alerts: return now = arrow.now() _alerts = [] for id in alerts: asset = api.event(id) start = arrow.get(asset.get('preCheckTime', asset['transmissionTime'])) if asset.get('isStreaming', False): if gui.yes_no(_(_.EVENT_STARTED, event=asset['title']), yeslabel=_.WATCH, nolabel=_.CLOSE): play(id).play() elif start > now or (now - start).seconds < SERVICE_TIME: _alerts.append(id) userdata.set('alerts', _alerts)
def _get_channels(): subscriptions = userdata.get('subscriptions', []) channels = [] rows = api.channels() def _get_play_url(content): for row in content: if 'SkyGoStream' in row['plfile$assetTypes']: return row['plfile$streamingUrl'] return None for row in sorted(rows, key=lambda r: float(r.get('sky$liveChannelOrder', 'inf'))): if 'Live' not in row.get('sky$channelType', []): continue channel_id = row['plmedia$publicUrl'].rsplit('/')[-1] label = row['title'] subscribed = _is_subscribed(subscriptions, row.get('media$categories')) play_url = _get_play_url(row.get('media$content')) if not subscribed: label = _(_.LOCKED, label=label) elif 'faxs' in play_url: label = _(_.ADOBE_DRM, label=label) if settings.getBool('hide_unplayable', False) and (not subscribed or 'faxs' in play_url): continue channels.append({ 'label': label, 'channel': row.get('sky$skyGOChannelID', ''), 'description': row.get('description'), 'image': _get_image(row), 'path': plugin.url_for(play_channel, id=channel_id, _is_live=True), }) return channels
def home(**kwargs): folder = plugin.Folder(cacheToDisc=False) if not userdata.get('dns4me_key'): folder.add_item( label='dns4me Login', path=plugin.url_for(dns4me_login), ) else: folder.add_item( label='dns4me Logout', path=plugin.url_for(dns4me_logout), ) folder.add_item( label='Install Widevine CDM', path=plugin.url_for(ia_install), ) #folder.add_item(label=_.SETTINGS, path=plugin.url_for(plugin.ROUTE_SETTINGS)) return folder
def search(): query = gui.input(_(L_SEARCH), default=userdata.get('search', '')).strip() if not query: return userdata.set('search', query) @cache.cached(LIST_EXPIRY) def get_results(query): folder = plugin.Folder(title=_(L_SEARCH_FOR, query=query)) rows = api.search(query) folder.add_items(_parse_rows(rows)) if not folder.items: folder.add_item( label = _(L_NO_RESULTS, label=True), is_folder = False, ) return folder return get_results(query)
def search(query=None, start=0, **kwargs): start = int(start) if not query: query = gui.input(_.SEARCH, default=userdata.get('search', '')).strip() if not query: return userdata.set('search', query) folder = plugin.Folder(title=_(_.SEARCH_FOR, query=query)) data = api.content(text=query, start=start) items = _process_content(data['data']) folder.add_items(items) if items and data['index'] < data['available']: folder.add_item( label = _(_.NEXT_PAGE, _bold=True), path = plugin.url_for(search, query=query, start=data['index']), ) return folder
def _process_content(rows): items = [] subscriptions = userdata.get('subscriptions', []) for row in rows: if row['suspended']: continue label = row['title'] if 'subCode' in row and subscriptions and row['subCode'] not in subscriptions: label = _(_.LOCKED, label=label) if settings.getBool('hide_unplayable', False): continue if row['type'] == 'movie': items.append(plugin.Item( label = label, info = { 'plot': row.get('synopsis'), 'duration': int(row.get('duration', '0 mins').strip(' mins')) * 60, 'mediatype': 'movie', }, art = {'thumb': IMAGE_URL.format(row['images'].get('MP',''))}, path = plugin.url_for(play, id=row['mediaId']), playable = True, )) elif row['type'] == 'season': items.append(plugin.Item( label = label, art = {'thumb': IMAGE_URL.format(row['images'].get('MP',''))}, path = plugin.url_for(series, id=row['id']), )) return items