2017-09-16 23:45:29 +02:00
|
|
|
from __future__ import absolute_import
|
2017-11-13 18:36:06 +01:00
|
|
|
from __future__ import unicode_literals
|
2017-09-16 23:45:29 +02:00
|
|
|
import re
|
|
|
|
import copy
|
|
|
|
import os
|
2018-01-30 22:07:21 +01:00
|
|
|
from urllib.parse import urljoin, urlparse
|
2017-09-16 23:45:29 +02:00
|
|
|
|
|
|
|
from svtplay_dl.service import Service
|
2017-09-18 22:16:54 +02:00
|
|
|
from svtplay_dl.log import log
|
2017-09-16 23:45:29 +02:00
|
|
|
from svtplay_dl.fetcher.dash import dashparse
|
|
|
|
from svtplay_dl.subtitle import subtitle
|
2018-03-13 00:33:39 +01:00
|
|
|
from svtplay_dl.utils.text import filenamify
|
2017-09-16 23:45:29 +02:00
|
|
|
from svtplay_dl.error import ServiceError
|
|
|
|
|
2018-01-30 20:11:37 +01:00
|
|
|
|
2017-09-16 23:45:29 +02:00
|
|
|
class Cmore(Service):
|
2018-02-24 17:39:26 +01:00
|
|
|
supported_domains = ['www.cmore.se', 'www.cmore.dk', 'www.cmore.no', 'www.cmore.fi']
|
2017-09-16 23:45:29 +02:00
|
|
|
|
|
|
|
def get(self):
|
2017-09-16 23:51:54 +02:00
|
|
|
if not self.options.username or not self.options.password:
|
|
|
|
yield ServiceError("You need username and password to download things from this site.")
|
|
|
|
return
|
2018-02-24 17:39:26 +01:00
|
|
|
|
2017-09-18 22:16:54 +02:00
|
|
|
token, message = self._login()
|
2017-09-16 23:45:29 +02:00
|
|
|
if not token:
|
2017-09-18 22:16:54 +02:00
|
|
|
yield ServiceError(message)
|
2017-09-16 23:45:29 +02:00
|
|
|
return
|
2018-02-24 17:39:26 +01:00
|
|
|
|
2017-09-16 23:45:29 +02:00
|
|
|
res = self.http.get(self.url)
|
2017-11-13 18:32:16 +01:00
|
|
|
match = re.search('data-asset-id="([^"]+)"', res.text)
|
2017-09-16 23:45:29 +02:00
|
|
|
if not match:
|
|
|
|
yield ServiceError("Can't find video id")
|
|
|
|
return
|
2018-02-24 17:39:26 +01:00
|
|
|
|
|
|
|
tld = self._gettld()
|
|
|
|
url = "https://restapi.cmore.{0}/api/tve_web/asset/{1}/play.json?protocol=VUDASH".format(tld, match.group(1))
|
2017-09-16 23:45:29 +02:00
|
|
|
res = self.http.get(url, headers={"authorization": "Bearer {0}".format(token)})
|
|
|
|
janson = res.json()
|
2018-02-24 17:39:26 +01:00
|
|
|
if "error" in janson:
|
|
|
|
yield ServiceError("This video is geoblocked")
|
|
|
|
return
|
2017-09-16 23:45:29 +02:00
|
|
|
|
|
|
|
if self.options.output_auto:
|
|
|
|
directory = os.path.dirname(self.options.output)
|
|
|
|
self.options.service = "cmore"
|
|
|
|
basename = self._autoname(match.group(1))
|
|
|
|
if basename is None:
|
|
|
|
yield ServiceError("Cant find vid id for autonaming")
|
|
|
|
return
|
2017-10-09 22:35:13 +02:00
|
|
|
title = "{0}-{1}-{2}".format(basename, match.group(1), self.options.service)
|
2017-09-16 23:45:29 +02:00
|
|
|
title = filenamify(title)
|
|
|
|
if len(directory):
|
|
|
|
self.options.output = os.path.join(directory, title)
|
|
|
|
else:
|
|
|
|
self.options.output = title
|
|
|
|
|
|
|
|
if self.exclude():
|
|
|
|
yield ServiceError("Excluding video")
|
|
|
|
return
|
|
|
|
|
|
|
|
if "drmProtected" in janson["playback"]:
|
|
|
|
if janson["playback"]["drmProtected"]:
|
|
|
|
yield ServiceError("DRM protected. Can't do anything")
|
|
|
|
return
|
|
|
|
|
|
|
|
if isinstance(janson["playback"]["items"]["item"], list):
|
|
|
|
for i in janson["playback"]["items"]["item"]:
|
|
|
|
if i["mediaFormat"] == "ism":
|
|
|
|
streams = dashparse(self.options, self.http.request("get", i["url"]), i["url"])
|
|
|
|
if streams:
|
|
|
|
for n in list(streams.keys()):
|
|
|
|
yield streams[n]
|
|
|
|
if i["mediaFormat"] == "webvtt":
|
|
|
|
yield subtitle(copy.copy(self.options), "wrst", i["url"])
|
|
|
|
else:
|
|
|
|
i = janson["playback"]["items"]["item"]
|
|
|
|
if i["mediaFormat"] == "ism":
|
|
|
|
streams = dashparse(self.options, self.http.request("get", i["url"]), i["url"])
|
|
|
|
if streams:
|
|
|
|
for n in list(streams.keys()):
|
|
|
|
yield streams[n]
|
|
|
|
|
|
|
|
def _autoname(self, vid):
|
2018-02-24 17:39:26 +01:00
|
|
|
url = "https://restapi.cmore.{0}/api/tve_web/asset/{1}.json?expand=metadata".format(self._gettld(), vid)
|
2017-09-16 23:45:29 +02:00
|
|
|
res = self.http.get(url)
|
|
|
|
janson = res.json()["asset"]["metadata"]
|
2017-09-18 22:24:27 +02:00
|
|
|
if isinstance(janson["title"], list):
|
|
|
|
for i in janson["title"]:
|
2018-02-24 17:39:26 +01:00
|
|
|
if self._gettld() == "se":
|
|
|
|
if i["@xml:lang"] == "sv_SE":
|
|
|
|
name = i["$"]
|
|
|
|
elif self._gettld() == "dk":
|
|
|
|
if i["@xml:lang"] == "da_DK":
|
|
|
|
name = i["$"]
|
|
|
|
elif self._gettld() == "no":
|
|
|
|
if i["@xml:lang"] == "nb_NO":
|
|
|
|
name = i["$"]
|
|
|
|
elif self._gettld() == "fi":
|
|
|
|
if i["@xml:lang"] == "fi_FI":
|
|
|
|
name = i["$"]
|
2017-09-18 22:24:27 +02:00
|
|
|
else:
|
|
|
|
name = janson["title"]["$"]
|
2017-09-16 23:45:29 +02:00
|
|
|
|
|
|
|
if "season" in janson:
|
|
|
|
season = "{0:02d}".format(int(janson["season"]["$"]))
|
|
|
|
name = "{0}.S{1}E{2:02d}".format(name, season, int(janson["episode"]["$"]))
|
|
|
|
return name
|
|
|
|
|
|
|
|
def find_all_episodes(self, options):
|
|
|
|
episodes = []
|
|
|
|
|
2017-09-18 22:16:54 +02:00
|
|
|
token, message = self._login()
|
|
|
|
if not token:
|
|
|
|
log.error(message)
|
|
|
|
return
|
2017-09-16 23:45:29 +02:00
|
|
|
res = self.http.get(self.url)
|
|
|
|
tags = re.findall('<a class="card__link" href="([^"]+)"', res.text)
|
|
|
|
for i in tags:
|
2018-02-24 17:39:26 +01:00
|
|
|
url = urljoin("https://www.cmore.{}/".format(self._gettld()), i)
|
2017-09-16 23:45:29 +02:00
|
|
|
if url not in episodes:
|
|
|
|
episodes.append(url)
|
|
|
|
|
|
|
|
if options.all_last > 0:
|
|
|
|
return sorted(episodes[-options.all_last:])
|
|
|
|
return sorted(episodes)
|
|
|
|
|
2018-02-24 17:39:26 +01:00
|
|
|
def _gettld(self):
|
|
|
|
if isinstance(self.url, list):
|
|
|
|
parse = urlparse(self.url[0])
|
|
|
|
else:
|
|
|
|
parse = urlparse(self.url)
|
|
|
|
return re.search('\.(\w{2})$', parse.netloc).group(1)
|
|
|
|
|
2017-09-16 23:45:29 +02:00
|
|
|
def _login(self):
|
2018-02-24 17:39:26 +01:00
|
|
|
tld = self._gettld()
|
|
|
|
url = "https://www.cmore.{}/login".format(tld)
|
2017-09-16 23:45:29 +02:00
|
|
|
res = self.http.get(url, cookies=self.cookies)
|
2017-09-19 00:30:11 +02:00
|
|
|
if self.options.cmoreoperator:
|
|
|
|
post = {"username": self.options.username, "password": self.options.password,
|
2018-02-24 17:39:26 +01:00
|
|
|
"operator": self.options.cmoreoperator, "country_code": tld}
|
2017-09-19 00:30:11 +02:00
|
|
|
else:
|
2018-02-24 17:07:14 +01:00
|
|
|
post = {"username": self.options.username, "password": self.options.password}
|
2018-02-24 17:39:26 +01:00
|
|
|
res = self.http.post("https://account.cmore.{}/session?client=cmore-web-prod".format(tld), json=post, cookies=self.cookies)
|
2017-09-19 00:30:11 +02:00
|
|
|
if res.status_code >= 400:
|
2017-09-18 22:16:54 +02:00
|
|
|
return None, "Wrong username or password"
|
2017-09-16 23:45:29 +02:00
|
|
|
janson = res.json()
|
|
|
|
token = janson["data"]["vimond_token"]
|
2017-09-18 22:16:54 +02:00
|
|
|
return token, None
|
2017-09-19 00:30:11 +02:00
|
|
|
|
|
|
|
def operatorlist(self):
|
2018-02-24 17:39:26 +01:00
|
|
|
res = self.http.get("https://tve.cmore.se/country/{0}/operator?client=cmore-web".format(self._gettld()))
|
2018-02-24 17:07:14 +01:00
|
|
|
for i in res.json()["data"]["operators"]:
|
|
|
|
print("operator: '{0}'".format(i["name"].lower()))
|