1
0
mirror of https://github.com/spaam/svtplay-dl.git synced 2024-11-24 04:05:39 +01:00
svtplay-dl/lib/svtplay_dl/service/plutotv.py
2024-04-08 19:35:01 +02:00

120 lines
4.7 KiB
Python

import datetime
import logging
import re
import uuid
from urllib.parse import urlparse
from svtplay_dl.error import ServiceError
from svtplay_dl.fetcher.hls import hlsparse
from svtplay_dl.service import OpenGraphThumbMixin
from svtplay_dl.service import Service
from svtplay_dl.subtitle import subtitle
class Plutotv(Service, OpenGraphThumbMixin):
supported_domains = ["pluto.tv"]
urlreg = r"/on-demand/(movies|series)/([^/]+)(/season/\d+/episode/([^/]+))?"
urlreg2 = r"/on-demand/(movies|series)/([^/]+)(/episode/([^/]+))?"
def get(self):
self.data = self.get_urldata()
parse = urlparse(self.url)
urlmatch = re.search(self.urlreg, parse.path)
if not urlmatch:
yield ServiceError("Can't find what video it is or live is not supported")
return
self.slug = urlmatch.group(2)
episodename = urlmatch.group(4)
if episodename is None:
urlmatch = re.search(self.urlreg2, parse.path)
if not urlmatch:
yield ServiceError("Can't find what video it is or live is not supported")
return
self.slug = urlmatch.group(2)
episodename = urlmatch.group(4)
self._janson()
HLSplaylist = None
for vod in self.janson["VOD"]:
self.output["title"] = vod["name"]
if "seasons" in vod:
for season in vod["seasons"]:
if "episodes" in season:
for episode in season["episodes"]:
if episode["_id"] == episodename:
self.output["season"] = season["number"]
self.output["episodename"] = episode["name"]
for stich in episode["stitched"]["paths"]:
if stich["type"] == "hls":
HLSplaylist = f"{self.mediaserver}{stich['path']}?{self.stitcherParams}"
if self.http.request("get", HLSplaylist).status_code < 400:
break
if not HLSplaylist:
yield ServiceError("Can't find video info")
return
playlists = hlsparse(
self.config,
self.http.request("get", HLSplaylist, headers={"Authorization": f"Bearer {self.sessionToken}"}),
HLSplaylist,
self.output,
filter=True,
)
for playlist in playlists:
if self.config.get("subtitle") and isinstance(playlist, subtitle):
logging.warning("Subtitles are no longer supported for pluto.tv")
continue
yield playlist
def find_all_episodes(self, options):
episodes = []
self.data = self.get_urldata()
parse = urlparse(self.url)
urlmatch = re.search(self.urlreg, parse.path)
if urlmatch is None:
logging.error("Can't find what video it is or live is not supported")
return episodes
if urlmatch.group(1) != "series":
return episodes
self.slug = urlmatch.group(2)
self._janson()
match = re.search(r"^/([^\/]+)/", parse.path)
language = match.group(1)
for vod in self.janson["VOD"]:
if "seasons" in vod:
for season in vod["seasons"]:
seasonnr = season["number"]
if "episodes" in season:
for episode in season["episodes"]:
episodes.append(f"https://pluto.tv/{language}/on-demand/series/{self.slug}/season/{seasonnr}/episode/{episode['_id']}")
return episodes
def _janson(self) -> None:
self.appversion = re.search('appVersion" content="([^"]+)"', self.data)
self.query = {
"appName": "web",
"appVersion": self.appversion.group(1) if self.appversion else "na",
"deviceVersion": "119.0.0",
"deviceModel": "web",
"deviceMake": "firefox",
"deviceType": "web",
"clientID": uuid.uuid1(),
"clientModelNumber": "1.0.0",
"seriesIDs": self.slug,
"serverSideAds": "false",
"constraints": "",
"drmCapabilities": "widevine%3AL3",
"clientTime": datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
}
res = self.http.request("get", "https://boot.pluto.tv/v4/start", params=self.query)
self.janson = res.json()
self.mediaserver = self.janson["servers"]["stitcher"]
self.stitcherParams = self.janson["stitcherParams"]
self.sessionToken = self.janson["sessionToken"]