Beispiel #1
0
class ard_live(Plugin):
    swf_url = "http://live.daserste.de/lib/br-player/swf/main.swf"
    _url_re = re.compile(r"https?://(www.)?daserste.de/", re.I)
    _player_re = re.compile(r'''dataURL\s*:\s*(?P<q>['"])(?P<url>.*?)(?P=q)''')
    _player_url_schema = validate.Schema(
        validate.transform(_player_re.search),
        validate.any(None, validate.all(validate.get("url"), validate.text)))
    _livestream_schema = validate.Schema(
        validate.xml_findall(".//assets"),
        validate.filter(lambda x: x.attrib.get("type") != "subtitles"),
        validate.get(0), validate.xml_findall(".//asset"), [
            validate.union({
                "url": validate.xml_findtext("./fileName"),
                "bitrate": validate.xml_findtext("./bitrateVideo")
            })
        ])

    @classmethod
    def can_handle_url(cls, url):
        return cls._url_re.match(url) is not None

    def _get_streams(self):
        data_url = http.get(self.url, schema=self._player_url_schema)
        if data_url:
            res = http.get(urljoin(self.url, data_url))
            stream_info = http.xml(res, schema=self._livestream_schema)

            for stream in stream_info:
                url = stream["url"]
                try:
                    if ".m3u8" in url:
                        for s in HLSStream.parse_variant_playlist(
                                self.session, url, name_key="bitrate").items():
                            yield s
                    elif ".f4m" in url:
                        for s in HDSStream.parse_manifest(
                                self.session,
                                url,
                                pvswf=self.swf_url,
                                is_akamai=True).items():
                            yield s
                    elif ".mp4" in url:
                        yield "{0}k".format(stream["bitrate"]), HTTPStream(
                            self.session, url)
                except IOError as err:
                    self.logger.warning("Error parsing stream: {0}", err)
    def test_xml_findtext(self):
        el = Element("foo")
        el.text = "bar"

        assert validate(xml_findtext("."), el) == "bar"
Beispiel #3
0
class Neulion(Plugin):
    """Livecli Plugin for websites based on Neulion
       Example urls can be found in tests/test_plugin_neulion.py
    """

    url_re = re.compile(
        r"""https?://
        (?P<domain>
            www\.(?:
                ufc\.tv
                |
                elevensports\.(?:be|lu|pl|sg|tw)
                |
                tennischanneleverywhere\.com
                )
            |
            watch\.(?:
                nba\.com
                |
                rugbypass\.com
                )
            |
            fanpass\.co\.nz
        )
        /(?P<vtype>channel|game|video)/.+""", re.VERBOSE)
    video_info_re = re.compile(r"""program\s*=\s*(\{.*?});""", re.DOTALL)
    channel_info_re = re.compile(r"""g_channel\s*=\s(\{.*?});""", re.DOTALL)
    current_video_re = re.compile(
        r"""(?:currentVideo|video)\s*=\s*(\{[^;]+});""", re.DOTALL)
    info_fallback_re = re.compile(
        r"""
        var\s?
        (?:
            currentGameId
        |
            programId
        )
        \s?=\s?["']?(?P<id>\d+)["']?;
        """, re.VERBOSE)

    stream_api_url = "https://{0}/service/publishpoint"
    auth_url = "https://{0}/secure/authenticate"
    auth_schema = validate.Schema(validate.xml_findtext("code"))

    options = PluginOptions({"username": None, "password": None})

    @classmethod
    def can_handle_url(cls, url):
        return cls.url_re.match(url) is not None

    @property
    def _domain(self):
        match = self.url_re.match(self.url)
        return match.group("domain")

    @property
    def _vtype(self):
        match = self.url_re.match(self.url)
        return match.group("vtype")

    def _get_stream_url(self, video_id, vtype):
        try:
            res = http.post(self.stream_api_url.format(self._domain),
                            data={
                                "id": video_id,
                                "type": vtype,
                                "format": "json"
                            },
                            headers={"User-Agent": useragents.IPHONE_6})
        except Exception as e:
            if "400 Client Error" in str(e):
                self.logger.error("Login required")
                return
            else:
                raise e

        data = http.json(res)
        return data.get("path")

    def _get_info(self, text):
        # try to find video info first
        m = self.video_info_re.search(text)
        if not m:
            m = self.current_video_re.search(text)
        if not m:
            # and channel info if that fails
            m = self.channel_info_re.search(text)
        if m:
            js_data = m.group(1)
            try:
                return_data = js_to_json(js_data)
                self.logger.debug("js_to_json")
            except Exception:
                self.logger.debug("js_to_json_regex_fallback")
                return_data = js_to_json_regex_fallback(js_data)
            finally:
                return return_data

    def _get_info_fallback(self, text):
        info_id = self.info_fallback_re.search(text)
        if info_id:
            self.logger.debug("Found id from _get_info_fallback")
            return {"id": info_id.group("id")}

    def _login(self, username, password):
        res = http.post(self.auth_url.format(self._domain),
                        data={
                            "username": username,
                            "password": password,
                            "cookielink": False
                        })
        login_status = http.xml(res, schema=self.auth_schema)
        self.logger.debug("Login status for {0}: {1}", username, login_status)
        if login_status == "loginlocked":
            self.logger.error(
                "The account {0} has been locked, the password needs to be reset"
            )
        return login_status == "loginsuccess"

    def _get_streams(self):
        login_username = self.get_option("username")
        login_password = self.get_option("password")
        if login_username and login_password:
            self.logger.debug("Attempting login as {0}", login_username)
            if self._login(login_username, login_password):
                self.logger.info("Successfully logged in as {0}",
                                 login_username)
            else:
                self.logger.info("Failed to login as {0}", login_username)

        res = http.get(self.url)
        video = self._get_info(res.text)
        if not video:
            video = self._get_info_fallback(res.text)

        if video:
            self.logger.debug("Found {type}: {name}".format(
                type=video.get("type", self._vtype),
                name=video.get("name", "???")))
            surl = self._get_stream_url(video["id"],
                                        video.get("type", self._vtype))
            if surl:
                surl = surl.replace("_iphone", "")
                return HLSStream.parse_variant_playlist(self.session, surl)
            else:
                self.logger.error(
                    "Could not get stream URL for video: {name} ({id})".format(
                        id=video.get("id", "???"),
                        name=video.get("name", "???"),
                    ))
        else:
            self.logger.error("Could not find any video info on the page")
Beispiel #4
0
__livecli_docs__ = {
    "domains": [
        "nhk.or.jp",
    ],
    "geo_blocked": [],
    "notes": "",
    "live": True,
    "vod": False,
    "last_update": "2016-11-24",
}

API_URL = "http://{}.nhk.or.jp/nhkworld/app/tv/hlslive_web.xml"

_url_re = re.compile(r"http(?:s)?://(?:(\w+)\.)?nhk.or.jp/nhkworld")
_schema = validate.Schema(validate.xml_findtext("./main_url/wstrm"))


class NHKWorld(Plugin):
    @classmethod
    def can_handle_url(cls, url):
        return _url_re.match(url) is not None

    def _get_streams(self):
        # get the HLS xml from the same sub domain as the main url, defaulting to www
        sdomain = _url_re.match(self.url).group(1) or "www"
        res = http.get(API_URL.format(sdomain))

        stream_url = http.xml(res, schema=_schema)
        return HLSStream.parse_variant_playlist(self.session, stream_url)
    ],
    "geo_blocked": [],
    "notes": "rtmpdump K-S-V",
    "live": True,
    "vod": False,
    "last_update": "2014-07-13",
}

SWF_URL = "http://play.streamingvideoprovider.com/player2.swf"
API_URL = "http://player.webvideocore.net/index.php"

_url_re = re.compile(
    r"http(s)?://(\w+\.)?streamingvideoprovider.co.uk/(?P<channel>[^/&?]+)")
_hls_re = re.compile(r"'(http://.+\.m3u8)'")

_rtmp_schema = validate.Schema(validate.xml_findtext("./info/url"),
                               validate.url(scheme="rtmp"))
_hls_schema = validate.Schema(
    validate.transform(_hls_re.search),
    validate.any(
        None,
        validate.all(
            validate.get(1),
            validate.url(scheme="http", path=validate.endswith("m3u8")))))


class Streamingvideoprovider(Plugin):
    @classmethod
    def can_handle_url(self, url):
        return _url_re.match(url)
Beispiel #6
0
                validate.optional("device_cd"): validate.text,
                validate.optional("ss1_prm"): validate.text,
                validate.optional("ss2_prm"): validate.text,
                validate.optional("ss3_prm"): validate.text
            }
        ),
        "clientlibs": validate.all(
            validate.transform(_clientlibs_re.search),
            validate.get(2),
            validate.text
        )
    })
)

_language_schema = validate.Schema(
    validate.xml_findtext("./country_code")
)

_xml_to_srt_schema = validate.Schema(
    validate.xml_findall(".//body/div"),
    [
        validate.union([validate.all(
            validate.getattr("attrib"),
            validate.get("{http://www.w3.org/XML/1998/namespace}lang")
        ),
            validate.all(
                validate.xml_findall("./p"),
                validate.transform(lambda x: list(enumerate(x, 1))),
                [
                    validate.all(
                        validate.union({
Beispiel #7
0
class WWENetwork(Plugin):
    url_re = re.compile(r"https?://network.wwe.com")
    content_id_re = re.compile(r'''"content_id" : "(\d+)"''')
    playback_scenario = "HTTP_CLOUD_WIRED"
    login_url = "https://secure.net.wwe.com/workflow.do"
    login_page_url = "https://secure.net.wwe.com/enterworkflow.do?flowId=account.login&forwardUrl=http%3A%2F%2Fnetwork.wwe.com"
    api_url = "https://ws.media.net.wwe.com/ws/media/mf/op-findUserVerifiedEvent/v-2.3"
    _info_schema = validate.Schema(
        validate.union({
            "status": validate.union({
                "code": validate.all(validate.xml_findtext(".//status-code"), validate.transform(int)),
                "message": validate.xml_findtext(".//status-message"),
            }),
            "urls": validate.all(
                validate.xml_findall(".//url"),
                [validate.getattr("text")]
            ),
            validate.optional("fingerprint"): validate.xml_findtext(".//updated-fingerprint"),
            validate.optional("session_key"): validate.xml_findtext(".//session-key"),
            "session_attributes": validate.all(
                validate.xml_findall(".//session-attribute"),
                [validate.getattr("attrib"),
                 validate.union({
                     "name": validate.get("name"),
                     "value": validate.get("value")
                 })]
            )
        })
    )
    options = PluginOptions({
        "email": None,
        "password": None,
    })

    def __init__(self, url):
        super(WWENetwork, self).__init__(url)
        http.headers.update({"User-Agent": useragents.CHROME})
        self._session_attributes = Cache(filename="plugin-cache.json", key_prefix="wwenetwork:attributes")
        self._session_key = self.cache.get("session_key")
        self._authed = self._session_attributes.get("ipid") and self._session_attributes.get("fprt")

    @classmethod
    def can_handle_url(cls, url):
        return cls.url_re.match(url) is not None

    def login(self, email, password):
        self.logger.debug("Attempting login as {0}", email)
        # sets some required cookies to login
        http.get(self.login_page_url)
        # login
        res = http.post(self.login_url, data=dict(registrationAction='identify',
                                                  emailAddress=email,
                                                  password=password,
                                                  submitButton=""),
                        headers={"Referer": self.login_page_url},
                        allow_redirects=False)

        self._authed = "Authentication Error" not in res.text
        if self._authed:
            self._session_attributes.set("ipid", res.cookies.get("ipid"), expires=3600 * 1.5)
            self._session_attributes.set("fprt", res.cookies.get("fprt"), expires=3600 * 1.5)

        return self._authed

    def _update_session_attribute(self, key, value):
        if value:
            self._session_attributes.set(key, value, expires=3600 * 1.5)  # 1h30m expiry
            http.cookies.set(key, value)

    @property
    def session_key(self):
        return self._session_key

    @session_key.setter
    def session_key(self, value):
        self.cache.set("session_key", value)
        self._session_key = value

    def _get_media_info(self, content_id):
        """
        Get the info about the content, based on the ID
        :param content_id:
        :return:
        """
        params = {"identityPointId": self._session_attributes.get("ipid"),
                  "fingerprint": self._session_attributes.get("fprt"),
                  "contentId": content_id,
                  "playbackScenario": self.playback_scenario,
                  "platform": "WEB_MEDIAPLAYER_5",
                  "subject": "LIVE_EVENT_COVERAGE",
                  "frameworkURL": "https://ws.media.net.wwe.com",
                  "_": int(time.time())}
        if self.session_key:
            params["sessionKey"] = self.session_key
        url = self.api_url.format(id=content_id)
        res = http.get(url, params=params)
        return http.xml(res, ignore_ns=True, schema=self._info_schema)

    def _get_content_id(self):
        #  check the page to find the contentId
        res = http.get(self.url)
        m = self.content_id_re.search(res.text)
        if m:
            return m.group(1)

    def _get_streams(self):
        email = self.get_option("email")
        password = self.get_option("password")

        if not self._authed and (not email and not password):
            self.logger.error("A login for WWE Network is required, use --wwenetwork-email/"
                              "--wwenetwork-password to set them")
            return

        if not self._authed:
            if not self.login(email, password):
                self.logger.error("Failed to login, check your username/password")
                return

        content_id = self._get_content_id()
        if content_id:
            self.logger.debug("Found content ID: {0}", content_id)
            info = self._get_media_info(content_id)
            if info["status"]["code"] == 1:
                # update the session attributes
                self._update_session_attribute("fprt", info.get("fingerprint"))
                for attr in info["session_attributes"]:
                    self._update_session_attribute(attr["name"], attr["value"])

                if info.get("session_key"):
                    self.session_key = info.get("session_key")
                for url in info["urls"]:
                    for s in HLSStream.parse_variant_playlist(self.session, url, name_fmt="{pixels}_{bitrate}").items():
                        yield s
            else:
                raise PluginError("Could not load streams: {message} ({code})".format(**info["status"]))