Beispiel #1
0
    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