def test_parse_xml(self): assert validate(parse_xml( ), '<?xml version="1.0" encoding="utf-8"?><root></root>').tag == "root" with self.assertRaises(ValueError) as cm: validate(parse_xml(), None) assert str(cm.exception ) == "Unable to parse XML: can only parse strings (None)"
def test_failure(self): with pytest.raises(validate.ValidationError) as cm: validate.validate(validate.parse_xml(), None) assert_validationerror( cm.value, """ ValidationError: Unable to parse XML: can only parse strings (None) """)
class Rtve(Plugin): _re_idAsset = re.compile(r"\"idAsset\":\"(\d+)\"") secret_key = base64.b64decode("eWVMJmRhRDM=") cdn_schema = validate.Schema( validate.parse_xml(invalid_char_entities=True), validate.xml_findall(".//preset"), [ validate.union({ "quality": validate.all(validate.getattr("attrib"), validate.get("type")), "urls": validate.all(validate.xml_findall(".//url"), [validate.getattr("text")]) }) ]) subtitles_api = "https://www.rtve.es/api/videos/{id}/subtitulos.json" subtitles_schema = validate.Schema( {"page": { "items": [{ "src": validate.url(), "lang": validate.text }] }}, validate.get("page"), validate.get("items")) video_api = "https://www.rtve.es/api/videos/{id}.json" video_schema = validate.Schema( { "page": { "items": [{ "qualities": [{ "preset": validate.text, "height": int }] }] } }, validate.get("page"), validate.get("items"), validate.get(0)) arguments = PluginArguments(PluginArgument("mux-subtitles", is_global=True)) def __init__(self, url): super().__init__(url) self.zclient = ZTNRClient(self.secret_key, self.session) def _get_subtitles(self, content_id): res = self.session.http.get(self.subtitles_api.format(id=content_id)) return self.session.http.json(res, schema=self.subtitles_schema) def _get_quality_map(self, content_id): res = self.session.http.get(self.video_api.format(id=content_id)) data = self.session.http.json(res, schema=self.video_schema) qmap = {} for item in data["qualities"]: qname = { "MED": "Media", "HIGH": "Alta", "ORIGINAL": "Original" }.get(item["preset"], item["preset"]) qmap[qname] = f"{item['height']}p" return qmap def _get_streams(self): res = self.session.http.get(self.url) m = self._re_idAsset.search(res.text) if m: content_id = m.group(1) log.debug(f"Found content with id: {content_id}") stream_data = self.zclient.get_cdn_list(content_id, schema=self.cdn_schema) quality_map = None streams = [] for stream in stream_data: # only use one stream _one_m3u8 = False _one_mp4 = False for url in stream["urls"]: p_url = urlparse(url) if p_url.path.endswith(".m3u8"): if _one_m3u8: continue try: streams.extend( HLSStream.parse_variant_playlist( self.session, url).items()) _one_m3u8 = True except OSError as err: log.error(str(err)) elif p_url.path.endswith(".mp4"): if _one_mp4: continue if quality_map is None: # only make the request when it is necessary quality_map = self._get_quality_map(content_id) # rename the HTTP sources to match the HLS sources quality = quality_map.get(stream["quality"], stream["quality"]) streams.append((quality, HTTPStream(self.session, url))) _one_mp4 = True subtitles = None if self.get_option("mux_subtitles"): subtitles = self._get_subtitles(content_id) if subtitles: substreams = {} for i, subtitle in enumerate(subtitles): substreams[subtitle["lang"]] = HTTPStream( self.session, subtitle["src"]) for q, s in streams: yield q, MuxedStream(self.session, s, subtitles=substreams) else: for s in streams: yield s
def test_success(self): assert validate.validate( validate.parse_xml(), """<?xml version="1.0" encoding="utf-8"?><root></root>""", ).tag == "root"