def play(self, channel): manifest_url = self.get_manifest(channel) device_id = PluginCache.get_by_key("device_id") customer_id = PluginCache.get_by_key("entitlements")["customer_id"] is_helper = inputstreamhelper.Helper(PROTOCOL, drm=DRM) if is_helper.check_inputstream(): from addon import plugin play_item = xbmcgui.ListItem(path=manifest_url) play_item.setMimeType('application/xml+dash') play_item.setContentLookup(False) if kodi_version_major() >= 19: play_item.setProperty('inputstream', is_helper.inputstream_addon) else: play_item.setProperty('inputstreamaddon', is_helper.inputstream_addon) play_item.setProperty('inputstream.adaptive.manifest_type', PROTOCOL) play_item.setProperty('inputstream.adaptive.license_type', DRM) play_item.setProperty('inputstream.adaptive.manifest_update_parameter', 'full') play_item.setProperty('inputstream.adaptive.license_key', '%(url)s|Content-Type=text/plain;charset=UTF-8&User-Agent=%(ua)s|b{%(payload)s}|JBlicense' % dict( url=LICENSE_URL, ua=quote(USER_AGENT), payload=widevine_payload_package(device_id, customer_id), )) play_item.setProperty('inputstream.adaptive.license_flags', "persistent_storage") xbmcplugin.setResolvedUrl(plugin.handle, True, listitem=play_item)
def _start_stream(self, channel): response_data = None max_iterations = 2 current_iteration = 0 device_id = PluginCache.get_by_key("device_id") while current_iteration < max_iterations: oauth_tokens = PluginCache.get_by_key("OAuthTokens") try: response = self.session.post( BASE_URL + "/stream/start", headers={ "Content-Type": "application/json;charset=utf-8", "X-Yelo-DeviceId": device_id, "Authorization": authorization_payload(oauth_tokens["accessToken"]) }, data=stream_payload(device_id, channel)) try: response_data = response.json() except ValueError as exc: _LOGGER.error(exc) current_iteration += 1 if response.status_code == 401: raise NotAuthorizedException("Unauthorized") if response.status_code == 403: raise ForbiddenException("Forbidden") break except NotAuthorizedException: self._refresh_oauth_token() except ForbiddenException: stream = response_data.get('stream') if stream is None: self._display_error_message(response_data) return None if stream.get('authorizationResult') is None or stream.get( 'authorizationResult').get('resultCode').upper( ) != "DEVICE_AUTHORIZATION_REQUIRED": self._display_error_message(response_data) return None self._check_registered_devices(response_data) return response_data
def _customer_features(self): device_id = PluginCache.get_by_key("device_id") oauth_tokens = PluginCache.get_by_key("OAuthTokens") if not oauth_tokens: return {} resp = self.session.get( BASE_URL + "/session/lookup?include=customerFeatures", headers={ "Content-Type": "application/json;charset=utf-8", "X-Yelo-DeviceId": device_id, "Authorization": authorization_payload(oauth_tokens.get('accessToken')) }) return resp.json()
def _check_registered_devices(self, response_data): devices_registered = response_data["stream"]["authorizationResult"][ "authorizedDevices"] devices_maximum = response_data["stream"]["authorizationResult"][ "allowedDevices"] if devices_maximum - devices_registered == 0: self._display_error_message(response_data) return self._register_device() device_id = PluginCache.get_by_key("device_id") return self._device_authorize(device_id)
def _request_oauth_tokens(self): auth_token = PluginCache.get_by_key("auth_token") device_id = PluginCache.get_by_key("device_id") resp = self.session.post(BASE_URL + "/oauth/token", headers={ "Content-Type": "application/json;charset=utf-8", "X-Yelo-DeviceId": device_id }, data=oauth_payload(auth_token, CALLBACK_URL), allow_redirects=False) try: json_data = resp.json() oauth_data = json_data.get('OAuthTokens') if oauth_data and oauth_data.get('status').upper() == 'SUCCESS': PluginCache.set_data({"OAuthTokens": oauth_data}) except (ValueError, KeyError) as exc: _LOGGER.error(exc)
def _get_entitlements(self): if not PluginCache.get_by_key("entitlements"): try: customer_features = self._customer_features() entitlements = [ int(item["id"]) for item in customer_features["linked"] ["customerFeatures"]["entitlements"] ] customer_id = customer_features["loginSession"]["user"][ "links"]["customerFeatures"] PluginCache.set_data({ "entitlements": { "entitlementId": entitlements, "customer_id": customer_id } }) except (ValueError, KeyError) as exc: _LOGGER.error(exc) return PluginCache.get_by_key("entitlements")
def _device_authorize(self, device_id): oauth_tokens = PluginCache.get_by_key("OAuthTokens") resp = self.session.post(BASE_URL + "/device/authorize", headers={ "Content-Type": "application/json;charset=utf-8", "X-Yelo-DeviceId": device_id, "Authorization": authorization_payload( oauth_tokens["accessToken"]) }, data=device_authorize(device_id, "YeloPlay")) return resp
def _get_entitled_channels(tv_channels): allowed_channels = [] entitlements = PluginCache.get_by_key('entitlements') if not entitlements: return [] entitlement_ids = entitlements.get('entitlementId') if not entitlement_ids: return [] for tv_channel in tv_channels: if (bool(tv_channel["channelProperties"]["live"]) and any(tv_channel["channelPolicies"]["linearEndpoints"]) and any(x in entitlement_ids for x in tv_channel["channelAvailability"]["oasisId"])): allowed_channels.append(tv_channel) return allowed_channels