def _check_token(self): if userdata.get('expires') > time.time(): return headers = { 'X-Amz-Target': 'AWSCognitoIdentityProviderService.InitiateAuth', 'X-Amz-User-Agent': 'aws-amplify/0.1.x js', 'Content-Type': 'application/x-amz-json-1.1', } payload = { 'AuthFlow': 'REFRESH_TOKEN_AUTH', 'AuthParameters': { 'DEVICE_KEY': None, 'REFRESH_TOKEN': userdata.get('refresh_token'), }, 'ClientId': AWS_CLIENT_ID, } r = self._session.post(AWS_URL, json=payload, headers=headers) data = r.json() if 'message' in data: raise APIError(_(_.LOGIN_ERROR, msg=data['message'])) self._parse_token(data['AuthenticationResult'])
def _sync_token(self, site_id, catalog_name): self._refresh_token() params = { 'serviceID': 'PLAY', } payload = { 'loginToken': userdata.get('token'), 'deviceId': userdata.get('deviceid'), 'format': 'json', } vod_token = None live_token = None data = self._session.post( '/userCatalog.class.api.php/getSyncTokens/{site_id}'.format( site_id=VOD_SITEID), params=params, data=payload).json() for token in data.get('tokens', []): if token['siteId'] == site_id and token[ 'catalogName'] == catalog_name: return token['token'] return None
def _set_ob_token(self): password = userdata.get('pswd') if password: ticket = self.login(userdata.get('username'), password) else: resp = self._session.post( 'https://auth.tab.co.nz/identity-service/api/v1/assertion/by-token', cookies={'OB-TGT': userdata.get('ob_tgt')}) if resp.status_code == 403: raise APIError(_.GEO_ERROR) elif resp.status_code != 201: raise APIError(_.AUTH_ERROR) else: ticket = resp.json()['data']['ticket'] resp = self._session.get( 'https://api.tab.co.nz/account-service/api/v1/account/header', headers={'Authentication': ticket}) if 'OB-TOKEN' not in self._session.cookies: raise APIError(_.AUTH_ERROR) userdata.set('ob_session', self._session.cookies['OB-SESSION'])
def _refresh_token(self, force=False): if not force and userdata.get('expires', 0) > time() or not self.logged_in: return log.debug('Refreshing token') self._set_profile(userdata.get('profile_id'))
def play(self, media_id, media_type, start=None, duration=None): payload = { 'id': media_id, 'nt': 1, 'type': media_type, 'format': 'json', 'drmtoken': True, 'deviceid': self.deviceid(), } if start: payload['st'] = '{}000'.format(start) if duration: payload['dur'] = '{}000'.format(duration) login_cookies = { 'nllinktoken': userdata.get('nllinktoken'), 'UserName': userdata.get('username') } data = self._session.post('/service/publishpoint', data=payload, cookies=login_cookies).json() if 'path' not in data: code = data.get('code') or _.UNKNOWN_ERROR if code == 'failedgeo': raise APIError(_.GEO_ERROR) else: raise APIError(_(_.PLAYBACK_ERROR, code=code)) return data
def index(**kwargs): folder = plugin.Folder(cacheToDisc=False) if not api.logged_in: folder.add_item(label=_(_.LOGIN, _bold=True), path=plugin.url_for(login), bookmark=False) else: folder.add_item(label=_(_.FEATURED, _bold=True), path=plugin.url_for(page, slug='urn:hbo:page:home', label=_.FEATURED)) folder.add_item(label=_(_.SERIES, _bold=True), path=plugin.url_for(page, slug='urn:hbo:page:series', label=_.SERIES)) folder.add_item(label=_(_.MOVIES, _bold=True), path=plugin.url_for(page, slug='urn:hbo:page:movies', label=_.MOVIES)) folder.add_item(label=_(_.ORIGINALS, _bold=True), path=plugin.url_for(page, slug='urn:hbo:page:originals', label=_.ORIGINALS)) folder.add_item(label=_(_.JUST_ADDED, _bold=True), path=plugin.url_for(page, slug='urn:hbo:page:just-added', label=_.JUST_ADDED)) folder.add_item(label=_(_.LAST_CHANCE, _bold=True), path=plugin.url_for(page, slug='urn:hbo:page:last-chance', label=_.LAST_CHANCE)) folder.add_item(label=_(_.COMING_SOON, _bold=True), path=plugin.url_for(page, slug='urn:hbo:page:coming-soon', label=_.COMING_SOON)) folder.add_item(label=_(_.TRENDING_NOW, _bold=True), path=plugin.url_for(page, slug='urn:hbo:page:trending', label=_.TRENDING_NOW)) folder.add_item(label=_(_.SEARCH, _bold=True), path=plugin.url_for(search)) if settings.getBool('bookmarks', True): folder.add_item(label=_(_.BOOKMARKS, _bold=True), path=plugin.url_for(plugin.ROUTE_BOOKMARKS), bookmark=False) if not userdata.get('kid_lockdown', False): profile = userdata.get('profile', {}) folder.add_item(label=_.SELECT_PROFILE, path=plugin.url_for(select_profile), art={'thumb': profile.get('avatar')}, info={'plot': profile.get('name')}, _kiosk=False, bookmark=False) folder.add_item(label=_.LOGOUT, path=plugin.url_for(logout), _kiosk=False, bookmark=False) folder.add_item(label=_.SETTINGS, path=plugin.url_for(plugin.ROUTE_SETTINGS), _kiosk=False, bookmark=False) return folder
def _device_id(self): device_id = userdata.get('device_id') if device_id: return device_id device_id = settings.get('device_id') try: mac_address = uuid.getnode() if mac_address != uuid.getnode(): mac_address = '' except: mac_address = '' system, arch = get_system_arch() device_id = device_id.format(username=userdata.get('username'), mac_address=mac_address, system=system).strip() if not device_id: device_id = uuid.uuid4() log.debug('Raw device id: {}'.format(device_id)) device_id = hash_6(device_id, length=16) log.debug('Hashed device id: {}'.format(device_id)) userdata.set('device_id', device_id) return device_id
def play(self, entity_id): entity = self.entitiy(entity_id) if not entity or not entity.get('assetIDs'): raise APIError(_.NO_ASSET_ERROR) with self.api_call(): assets = self._session.get('/ocm/v2/assets/{}'.format( entity['assetIDs'][0])).json()['assets'] mpd_url = None for asset in assets: try: urls = asset['liveURLs'] or asset['vodURLs'] mpd_url = urls['dash']['primary'] backup = urls['dash'].get('backup') if 'dai.google.com' in mpd_url and backup and 'dai.google.com' not in backup: mpd_url = backup except (TypeError, KeyError): continue else: break if not mpd_url: raise APIError(_.NO_MPD_ERROR) # Hack until Spark fix their bad second base-url # if '/startover/' in mpd_url: # mpd_url = mpd_url.split('/') # mpd_url = "/".join(mpd_url[:-3]) + '/master.mpd' # payload = { 'assetID': entity_id, 'playbackUrl': mpd_url, 'deviceID': userdata.get('deviceid'), } data = self._session.post('/oem/v2/entitlement?tokentype=isp-atlas', json=payload).json() token = data.get('entitlementToken') if not token: raise APIError(_(_.NO_ENTITLEMENT, error=data.get('errorMessage'))) params = { 'progress': 0, 'device': userdata.get('deviceid'), } self._session.put('/oxm/v1/streams/{}/stopped'.format(entity_id), params=params) headers = {'X-ISP-TOKEN': token} from_start = True if entity.get('customAttributes', {}).get('isLinearChannelInLiveEvent') == 'true': from_start = False return mpd_url, WV_LICENSE_URL, headers, from_start
def play(self, channel_id, call_letter): payload = { 'deviceType': APP_DEVICE, 'deviceId': userdata.get('device_id'), 'identityType': APP_ID_TYPE, 'identityId': userdata.get('identification_no'), 'iptvNo': userdata.get('singtel_tv_no'), 'callLetter': call_letter, 'channelID': channel_id, 'appId': APP_ID, 'appKey': APP_KEY, 'mode': APP_MODE, 'ver': APP_VER, } data = self._session.get('/WatchOTTStreaming.aspx', data={ 'JSONtext': json.dumps(payload) }).json()['item'][0] if data.get('StatusCode'): raise APIError(_(_.PLAYBACK_ERROR, error=data.get('StatusDesc'))) self._stop_stream(channel_id, data['UserToken']) return data
def _refresh_token(self, force=False): refresh_token = userdata.get('refresh_token') if not refresh_token or (not force and userdata.get('expires', 0) > time()): return params = { 'key': GOOGLE_KEY, } payload = { 'grantType': 'refresh_token', 'refreshToken': refresh_token, } data = self._session.post(TOKEN_URL, params=params, json=payload).json() if 'error' in data: self.logout() raise APIError(data['error']['message']) userdata.set('access_token', data['access_token']) userdata.set('refresh_token', data['refresh_token']) userdata.set('expires', int(time()) + int(data['expires_in']) - 30) self._set_authentication()
def _select_profile(): profiles = api.user()['accountProfiles'] values = [] options = [] default = -1 for index, profile in enumerate(profiles): values.append(profile['id']) options.append( plugin.Item(label=profile['name'], art={'thumb': config.image(profile['profilePicPath'])})) if profile['id'] == userdata.get('profile_id'): default = index index = gui.select(_.SELECT_PROFILE, options=options, preselect=default, useDetails=True) if index < 0: return api.set_profile(values[index]) gui.notification(_.PROFILE_ACTIVATED, heading=userdata.get('profile_name'), icon=config.image(userdata.get('profile_img')))
def index(**kwargs): folder = plugin.Folder(cacheToDisc=False) if not api.logged_in: folder.add_item(label=_(_.LOGIN, _bold=True), path=plugin.url_for(login), bookmark=False) else: if not userdata.get('profile_kids', False): folder.add_item(label=_(_.FEATURED, _bold=True), path=plugin.url_for(featured, key='sitemap', title=_.FEATURED)) folder.add_item(label=_(_.TV, _bold=True), path=plugin.url_for(nav, key='tv', title=_.TV)) folder.add_item(label=_(_.MOVIES, _bold=True), path=plugin.url_for(nav, key='movies', title=_.MOVIES)) if not settings.getBool('hide_sport', False): folder.add_item(label=_(_.SPORT, _bold=True), path=plugin.url_for(nav, key='sport', title=_.SPORT)) folder.add_item(label=_(_.KIDS, _bold=True), path=plugin.url_for(nav, key='kids', title=_.KIDS)) folder.add_item(label=_(_.MY_LIST, _bold=True), path=plugin.url_for(my_list)) folder.add_item(label=_(_.CONTINUE_WATCHING, _bold=True), path=plugin.url_for(continue_watching)) folder.add_item(label=_(_.SEARCH, _bold=True), path=plugin.url_for(search)) if settings.getBool('bookmarks', True): folder.add_item(label=_(_.BOOKMARKS, _bold=True), path=plugin.url_for(plugin.ROUTE_BOOKMARKS), bookmark=False) if not userdata.get('kid_lockdown', False): folder.add_item(label=_.SELECT_PROFILE, path=plugin.url_for(select_profile), art={'thumb': userdata.get('profile_icon')}, info={'plot': userdata.get('profile_name')}, _kiosk=False, bookmark=False) folder.add_item(label=_.LOGOUT, path=plugin.url_for(logout), _kiosk=False, bookmark=False) folder.add_item(label=_.SETTINGS, path=plugin.url_for(plugin.ROUTE_SETTINGS), _kiosk=False, bookmark=False) return folder
def _refresh_token(self, force=False): if not force and userdata.get('expires', 0) > time() or not self.logged_in: return log.debug('Refreshing token') data = self._session.get(API_URL+'identity/refresh/{}'.format(userdata.get('refresh_token'))).json() self._process_token(data)
def play(self, media_type, id): self._refresh_token() payload = { 'deviceId': userdata.get('deviceid'), 'loginToken': userdata.get('token'), } if media_type == TYPE_VOD: endpoint = 'GOgetVODConfig' site_id = VOD_SITEID else: endpoint = 'GOgetLiveConfig' site_id = LIVE_SITEID params = { 'rate': 'WIREDHIGH', 'plt': PLT_DEVICE, 'appID': 'PLAY2', 'deviceCaps': hashlib.md5('TR3V0RwAZH3r3L00kingA7SumStuFF{}'.format('L1').encode( 'utf8')).hexdigest().lower(), 'format': 'json', } if settings.getBool('legacy_mode', False): url = 'https://foxtel-go-sw.foxtelplayer.foxtel.com.au/now-mobile-140/api/playback.class.api.php/{endpoint}/{site_id}/1/{id}' else: params['plt'] = 'ipstb' url = 'https://foxtel-go-sw.foxtelplayer.foxtel.com.au/now-box-140/api/playback.class.api.php/{endpoint}/{site_id}/1/{id}' data = self._session.post(url.format(endpoint=endpoint, site_id=site_id, id=id), params=params, data=payload).json() error = data.get('errorMessage') if error: raise APIError(_(_.PLAYBACK_ERROR, msg=error)) streams = sorted(data['media'].get('streams', []), key=lambda s: STREAM_PRIORITY.get( s['profile'].upper(), STREAM_PRIORITY['DEFAULT']), reverse=True) if not streams: raise APIError(_.NO_STREAM_ERROR) playback_url = streams[0]['url'].replace( 'cm=yes&', '') #replace cm=yes to fix playback license_url = data['fullLicenceUrl'] return playback_url, license_url
def play(self, video_id): codecs = '' if settings.getBool('vp9', False): codecs += 'vp9+' if settings.getBool('h265', False): codecs += 'hevc+' if settings.getBool('h264', True): codecs += 'h264+' codecs = codecs.rstrip('+') params = { 'capabilities[]': ['codecs={}'.format(codecs), 'multiaudio'], 'encoding': 'mpd_widevine_modular', 'subscription_status': 'full', 'mode': 'paid', 'showmax_rating': '18-plus', 'lang': self._language, # 'content_country': 'ZA', } data = self._session.get('playback/play/{}'.format(video_id), params=params).json() if 'url' not in data: raise APIError(data.get('message')) 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': '18-plus', 'mode': 'paid', 'subscription_status': 'full', 'lang': self._language, } data = self._session.post('playback/verify', params=params, data=data).json() if 'license_request' not in data: raise APIError(data.get('message')) license_request = data['license_request'] license_url = API_URL.format( 'drm/widevine_modular?license_request={}'.format(license_request)) return url, license_url
def new_session(self): self.logged_in = True if userdata.get('_cookies') else False if not settings.getBool('save_password', False): userdata.delete(PASSWORD_KEY) if self.logged_in and settings.getBool( 'save_password', True) and not userdata.get(PASSWORD_KEY): self.logout() gui.ok(_.SAVE_PASSWORD_RELOGIN)
def _create_session(self, force=False): self._config = self.get_config() platform = self._config['alpha_networks_dash'][REGION] self._session._base_url = platform['platform_url'] + '{}' self._session.headers.update({ 'X-AN-WebService-IdentityKey': platform['hss_key'], # hss_key, hls_key, chromecast_key }) if not self.logged_in or (not force and time.time() < userdata.get('token_expires')): return login_type = settings.getEnum('login_type', choices=LOGIN_TYPE, default=LOGIN_MULTI_IP) if login_type == LOGIN_MULTI_IP: # Single device, changing IP address (same as app) data = self._session.post('proxy/loginDevice', headers=self._auth_headers).json() elif login_type == LOGIN_MULTI_DEVICE: # Multiple device, static IP address data = self._session.post('proxy/casAvailableDevice', headers=self._auth_headers).json() elif login_type == LOGIN_PASSWORD: # Supports multiple devices and multiple IP address as long (as others also using password) data = { 'password': userdata.get('password'), 'deviceId': userdata.get('device_id'), 'email': userdata.get('username'), } data = self._session.post('proxy/login', data=data).json() if data['error']: error = _(_.TOKEN_ERROR, msg=data['error']['message']) if data['error']['code'] == -1: self.logout() gui.refresh() if login_type == LOGIN_MULTI_IP: error = _.LOGIN_MULTI_IP_ERROR elif login_type == LOGIN_MULTI_DEVICE: error = _.LOGIN_MULTI_DEVICE_ERROR raise APIError(error) if 'deviceAuthToken' in data['result']: userdata.set('device_token', data['result']['deviceAuthToken']) self._set_auth(data['result']['newAuthToken'])
def channels(self, events=2): data = self._request_json( 'v7/epg-service/channels/events;genre={genre};platformId={platform};country={country};packageId={package};count={events};utcOffset=+00:00' .format(genre='ALL', platform=PLATFORM_ID, country=userdata.get('country', DEFAULT_COUNTRY), package=userdata.get('package', DEFAULT_PACKAGE), events=events)) return data['items']
def _set_authentication(self): token = userdata.get('access_token') if not token: return self._session.headers.update( {'authorization': 'Bearer {}'.format(token)}) self._session.headers.update( {'x-user-profile': userdata.get('profile_id')}) self.logged_in = True
def _set_profile(profile, notify=True): api.set_profile(profile['id']) if settings.getBool('kid_lockdown', False) and profile['isKidsProfile']: userdata.set('kid_lockdown', True) if notify: gui.notification(_.PROFILE_ACTIVATED, heading=userdata.get('profile_name'), icon=userdata.get('profile_icon'))
def watchlist(self): self._check_token() params = { 'jwToken': userdata.get('token'), } url = '/watchlist/v1/users/{user_id}/profiles/{profile_id}/watchlistitems'.format( user_id=userdata.get('user_id'), profile_id=userdata.get('profile_id')) return self._session.get(url, params=params).json()
def _refresh_token(self, force=False): if not force and userdata.get('expires', 0) > time(): return payload = { 'refresh_token': userdata.get('refresh_token'), 'grant_type': 'refresh_token', 'platform': 'android', } self._oauth_token(payload)
def profiles(self): self._check_token() params = { 'jwToken': userdata.get('token'), } return self._session.get( '/accounts/v1/users/{user_id}/profiles'.format( user_id=userdata.get('user_id')), params=params).json()
def _refresh_token(self, force=False): if not force and userdata.get('expires', 0) > time(): return payload = { 'refresh_token': userdata.get('refresh_token'), 'grant_type': 'refresh_token', 'scope': 'browse video_playback device', } self._oauth_token(payload, {'Authorization': None})
def _set_authentication(self): access_token = userdata.get('access_token') if not access_token: self._session.headers.update( {'authorization': 'Bearer {}'.format(DEFAULT_TOKEN)}) return self._session.headers.update({ 'authorization': 'Bearer {}'.format(userdata.get('access_token')) }) self.logged_in = True
def delete_profile(self, profile_id): self._check_token() params = { 'jwToken': userdata.get('token'), 'profileId': profile_id, } return self._session.delete( '/accounts/v1/users/{user_id}/profiles'.format( user_id=userdata.get('user_id')), params=params).ok
def _renew_token(self): if time.time() < userdata.get('token_expires'): return data = { 'authType': 'renew', 'deviceID': userdata.get('device_id'), 'profileId': userdata.get('profile_id'), 'rememberMe': True, } resp = self._session.post('/login/renew', json=data) self._process_login(resp)
def _set_authentication(self): device_token = userdata.get('device_token') auth_token = userdata.get('auth_token') if not device_token or not auth_token: return self._auth_headers = { 'X-AN-WebService-CustomerAuthToken': auth_token, 'X-AN-WebService-DeviceAuthToken': device_token, } self.logged_in = True
def home(**kwargs): folder = plugin.Folder() if not plugin.logged_in: folder.add_item(label=_(_.LOGIN, _bold=True), path=plugin.url_for(login), bookmark=False) else: folder.add_item(label=_(_.LIVE_TV, _bold=True), path=plugin.url_for(live_tv)) folder.add_item(label=_(_.SERIES, _bold=True), path=plugin.url_for(content, title=_.SERIES, tags='TV Shows')) folder.add_item(label=_(_.MOVIES, _bold=True), path=plugin.url_for(content, title=_.MOVIES, tags='Movies')) folder.add_item(label=_(_.SPORT, _bold=True), path=plugin.url_for(content, title=_.SPORT, tags='Sport')) folder.add_item(label=_(_.KIDS, _bold=True), path=plugin.url_for(content, title=_.KIDS, tags='Kids')) folder.add_item(label=_(_.SEARCH, _bold=True), path=plugin.url_for(search)) if settings.getBool('bookmarks', True): folder.add_item(label=_(_.BOOKMARKS, _bold=True), path=plugin.url_for(plugin.ROUTE_BOOKMARKS), bookmark=False) folder.add_item(label=_.SELECT_PROFILE, path=plugin.url_for(select_profile), art={'thumb': userdata.get('avatar')}, info={'plot': userdata.get('profile_name')}, _kiosk=False, bookmark=False) folder.add_item(label=_.LOGOUT, path=plugin.url_for(logout), _kiosk=False, bookmark=False) folder.add_item(label=_.SETTINGS, path=plugin.url_for(plugin.ROUTE_SETTINGS), _kiosk=False, bookmark=False) return folder
def _refresh_token(self, force=False): if not force and userdata.get('expires', 0) > time() or not self.logged_in: return log.debug('Refreshing token') payload = { 'platformId': 'android', 'regsource': '7plus', 'refreshToken': userdata.get('refresh_token'), } self._oauth_token(payload)