""" $description Live and on-demand video service from World Wrestling Entertainment, Inc. $url network.wwe.com $type live, vod $account Required """ import json import logging import re from functools import lru_cache from urllib.parse import parse_qsl, urlparse from streamlink.plugin import Plugin, PluginError, pluginargument, pluginmatcher from streamlink.plugin.api import useragents from streamlink.stream.hls import HLSStream from streamlink.utils.times import seconds_to_hhmmss log = logging.getLogger(__name__) @pluginmatcher(re.compile( r"https?://watch\.wwe\.com/(channel)?", )) @pluginargument( "email", required=True, requires=["password"], metavar="EMAIL", help="The email associated with your WWE Network account, required to access any WWE Network stream.", ) @pluginargument( "password", required=True, sensitive=True, metavar="PASSWORD", help="A WWE Network account password to use with --wwenetwork-email.", ) class WWENetwork(Plugin): site_config_re = re.compile(r"""">window.__data = (\{.*?\})""") stream_url = "https://dce-frontoffice.imggaming.com/api/v2/stream/{id}" live_url = "https://dce-frontoffice.imggaming.com/api/v2/event/live" login_url = "https://dce-frontoffice.imggaming.com/api/v2/login" page_config_url = "https://cdn.watch.wwe.com/api/page" API_KEY = "cca51ea0-7837-40df-a055-75eb6347b2e7" customer_id = 16 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.session.http.headers.update({"User-Agent": useragents.CHROME}) self.auth_token = None def get_title(self): return self.item_config["title"] def request(self, method, url, **kwargs): headers = kwargs.pop("headers", {}) headers.update({"x-api-key": self.API_KEY, "Origin": "https://watch.wwe.com", "Referer": "https://watch.wwe.com/signin", "Accept": "application/json", "Realm": "dce.wwe"}) if self.auth_token: headers["Authorization"] = "Bearer {0}".format(self.auth_token) kwargs["raise_for_status"] = False log.debug("API request: {0} {1}".format(method, url)) res = self.session.http.request(method, url, headers=headers, **kwargs) data = self.session.http.json(res) if "status" in data and data["status"] != 200: log.debug("API request failed: {0}:{1} ({2})".format( data["status"], data.get("code"), "; ".join(data.get("messages", [])), )) return data def login(self, email, password): log.debug("Attempting login as {0}".format(email)) # sets some required cookies to login data = self.request("POST", self.login_url, data=json.dumps({"id": email, "secret": password}), headers={"Content-Type": "application/json"}) if "authorisationToken" in data: self.auth_token = data["authorisationToken"] return self.auth_token @property # type: ignore @lru_cache(maxsize=128) # noqa: B019 def item_config(self): log.debug("Loading page config") p = urlparse(self.url) res = self.session.http.get(self.page_config_url, params=dict(device="web_browser", ff="idp,ldp", item_detail_expand="all", lang="en-US", list_page_size="1", max_list_prefetch="1", path=p.path, segments="es", sub="Registered", text_entry_format="html")) data = self.session.http.json(res) return data["item"] def _get_media_info(self, content_id): """ Get the info about the content, based on the ID :param content_id: contentId for the video :return: """ info = self.request("GET", self.stream_url.format(id=content_id)) return self.request("GET", info.get("playerUrlCallback")) def _get_video_id(self): # check the page to find the contentId log.debug("Searching for content ID") try: if self.item_config["type"] == "channel": return self._get_live_id() else: return "vod/{id}".format(id=self.item_config["customFields"]["DiceVideoId"]) except KeyError: log.error("Could not find video ID") return def _get_live_id(self): log.debug("Loading live event") res = self.request("GET", self.live_url) for event in res.get("events", []): return "event/{sportId}/{propertyId}/{tournamentId}/{id}".format(**event) def _get_streams(self): if not self.login(self.get_option("email"), self.get_option("password")): raise PluginError("Login failed") try: start_point = int(float(dict(parse_qsl(urlparse(self.url).query)).get("startPoint", 0.0))) if start_point > 0: log.info("Stream will start at {0}".format(seconds_to_hhmmss(start_point))) except ValueError: start_point = 0 content_id = self._get_video_id() if content_id: log.debug("Found content ID: {0}".format(content_id)) info = self._get_media_info(content_id) if info.get("hlsUrl"): yield from HLSStream.parse_variant_playlist( self.session, info["hlsUrl"], start_offset=start_point, ).items() else: log.error("Could not find the HLS URL") __plugin__ = WWENetwork