2018-02-12 00:55:51 +01:00
|
|
|
import json
|
2019-08-25 00:40:39 +02:00
|
|
|
import re
|
|
|
|
from urllib.parse import quote
|
|
|
|
from urllib.parse import urlparse
|
2018-02-12 00:55:51 +01:00
|
|
|
|
|
|
|
from svtplay_dl.error import ServiceError
|
2019-08-25 00:40:39 +02:00
|
|
|
from svtplay_dl.fetcher.hls import hlsparse
|
|
|
|
from svtplay_dl.service import Service
|
2018-02-12 00:55:51 +01:00
|
|
|
|
|
|
|
|
|
|
|
class Eurosport(Service):
|
2019-08-25 00:27:31 +02:00
|
|
|
supported_domains_re = [r"^([^.]+\.)*eurosportplayer.com"]
|
2018-02-12 00:55:51 +01:00
|
|
|
|
|
|
|
def get(self):
|
|
|
|
parse = urlparse(self.url)
|
2019-08-25 00:27:31 +02:00
|
|
|
match = re.search("window.server_path = ({.*});", self.get_urldata())
|
2018-02-12 00:55:51 +01:00
|
|
|
if not match:
|
|
|
|
yield ServiceError("Cant find api key")
|
|
|
|
return
|
|
|
|
|
|
|
|
janson = json.loads(match.group(1))
|
|
|
|
clientapikey = janson["sdk"]["clientApiKey"]
|
|
|
|
|
2021-02-28 22:05:15 +01:00
|
|
|
header = {"authorization": f"Bearer {clientapikey}"}
|
2021-12-18 21:37:09 +01:00
|
|
|
res = self.http.post(
|
|
|
|
"https://eu.edge.bamgrid.com/devices",
|
|
|
|
headers=header,
|
|
|
|
json={"deviceFamily": "browser", "applicationRuntime": "firefox", "deviceProfile": "macosx", "attributes": {}},
|
|
|
|
)
|
|
|
|
res = self.http.post(
|
|
|
|
"https://eu.edge.bamgrid.com/token",
|
|
|
|
headers=header,
|
|
|
|
data={
|
|
|
|
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
|
|
|
|
"latitude": 0,
|
|
|
|
"longitude": 0,
|
|
|
|
"platform": "browser",
|
|
|
|
"subject_token": res.json()["assertion"],
|
|
|
|
"subject_token_type": "urn:bamtech:params:oauth:token-type:device",
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
header = {"authorization": f"Bearer {res.json()['access_token']}"}
|
|
|
|
res = self.http.post(
|
|
|
|
"https://eu.edge.bamgrid.com/idp/login",
|
|
|
|
headers=header,
|
|
|
|
json={"email": self.config.get("username"), "password": self.config.get("password")},
|
|
|
|
)
|
2018-02-12 00:55:51 +01:00
|
|
|
if res.status_code > 400:
|
|
|
|
yield ServiceError("Wrong username or password")
|
|
|
|
return
|
|
|
|
|
2018-11-14 00:42:52 +01:00
|
|
|
grant = "https://eu.edge.bamgrid.com/accounts/grant"
|
2021-12-18 21:37:09 +01:00
|
|
|
res = self.http.post(grant, headers=header, json={"id_token": res.json()["id_token"]})
|
2021-02-28 22:05:15 +01:00
|
|
|
header = {"authorization": f"Bearer {clientapikey}"}
|
2021-12-18 21:37:09 +01:00
|
|
|
res = self.http.post(
|
|
|
|
"https://eu.edge.bamgrid.com/token",
|
|
|
|
headers=header,
|
|
|
|
data={
|
|
|
|
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
|
|
|
|
"latitude": 0,
|
|
|
|
"longitude": 0,
|
|
|
|
"platform": "browser",
|
|
|
|
"subject_token": res.json()["assertion"],
|
|
|
|
"subject_token_type": "urn:bamtech:params:oauth:token-type:account",
|
|
|
|
},
|
|
|
|
)
|
2018-02-12 00:55:51 +01:00
|
|
|
access_token = res.json()["access_token"]
|
|
|
|
|
2019-09-06 22:49:49 +02:00
|
|
|
query = {"preferredLanguages": ["en"], "mediaRights": ["GeoMediaRight"], "uiLang": "en", "include_images": True}
|
2018-02-12 00:55:51 +01:00
|
|
|
|
2018-11-14 00:42:52 +01:00
|
|
|
if parse.path[:11] == "/en/channel":
|
2018-02-12 00:55:51 +01:00
|
|
|
pagetype = "channel"
|
2019-08-25 00:27:31 +02:00
|
|
|
match = re.search("/([^/]+)$", parse.path)
|
2018-02-12 00:55:51 +01:00
|
|
|
if not match:
|
|
|
|
yield ServiceError("Cant find channel")
|
|
|
|
return
|
|
|
|
|
2020-05-03 11:38:40 +02:00
|
|
|
(vid,) = match.groups()
|
2018-02-12 00:55:51 +01:00
|
|
|
query["pageType"] = pagetype
|
|
|
|
query["channelCallsign"] = vid
|
|
|
|
query["channelCallsigns"] = vid
|
|
|
|
query["onAir"] = True
|
|
|
|
|
2018-05-13 13:06:45 +02:00
|
|
|
self.config.set("live", True) # lets override to true
|
2018-02-12 00:55:51 +01:00
|
|
|
|
2019-08-25 00:27:31 +02:00
|
|
|
url = (
|
|
|
|
"https://search-api.svcs.eurosportplayer.com/svc/search/v2/graphql/persisted/"
|
2021-12-18 19:52:08 +01:00
|
|
|
f"query/eurosport/web/Airings/onAir?variables={quote(json.dumps(query))}"
|
2019-08-25 00:27:31 +02:00
|
|
|
)
|
2018-02-12 00:55:51 +01:00
|
|
|
res = self.http.get(url, headers={"authorization": access_token})
|
|
|
|
vid2 = res.json()["data"]["Airings"][0]["channel"]["id"]
|
2021-02-28 22:05:15 +01:00
|
|
|
url = f"https://global-api.svcs.eurosportplayer.com/channels/{vid2}/scenarios/browser"
|
2019-09-06 22:49:49 +02:00
|
|
|
res = self.http.get(url, headers={"authorization": access_token, "Accept": "application/vnd.media-service+json; version=1"})
|
2018-02-12 00:55:51 +01:00
|
|
|
hls_url = res.json()["stream"]["slide"]
|
|
|
|
else:
|
|
|
|
pagetype = "event"
|
2019-08-25 00:27:31 +02:00
|
|
|
match = re.search("/([^/]+)/([^/]+)$", parse.path)
|
2018-02-12 00:55:51 +01:00
|
|
|
if not match:
|
|
|
|
yield ServiceError("Cant fint event id")
|
|
|
|
return
|
|
|
|
|
|
|
|
query["title"], query["contentId"] = match.groups()
|
|
|
|
query["pageType"] = pagetype
|
|
|
|
|
2021-12-18 19:52:08 +01:00
|
|
|
url = f"https://search-api.svcs.eurosportplayer.com/svc/search/v2/graphql/persisted/query/eurosport/Airings?variables={quote(json.dumps(query))}"
|
2018-02-12 00:55:51 +01:00
|
|
|
res = self.http.get(url, headers={"authorization": access_token})
|
|
|
|
programid = res.json()["data"]["Airings"][0]["programId"]
|
|
|
|
mediaid = res.json()["data"]["Airings"][0]["mediaId"]
|
|
|
|
|
2021-02-28 22:05:15 +01:00
|
|
|
url = f"https://global-api.svcs.eurosportplayer.com/programs/{programid}/media/{mediaid}/scenarios/browser"
|
2019-09-06 22:49:49 +02:00
|
|
|
res = self.http.get(url, headers={"authorization": access_token, "Accept": "application/vnd.media-service+json; version=1"})
|
2018-02-12 00:55:51 +01:00
|
|
|
hls_url = res.json()["stream"]["complete"]
|
|
|
|
|
2021-05-16 02:22:37 +02:00
|
|
|
yield from hlsparse(self.config, self.http.request("get", hls_url), hls_url, authorization=access_token, output=self.output)
|