def _authenticate(self, email, password):
        csrf_token = http.get(LOGIN_PAGE_URL, schema=_csrf_token_schema)
        if not csrf_token:
            raise PluginError("Unable to find CSRF token")

        data = {
            "authenticity_token": csrf_token,
            "channel_id": "",
            "commit": "Login",
            "plan_id": "",
            "session[email]": email,
            "session[password]": password,
            "utf8": "\xE2\x9C\x93",  # Check Mark Character
        }

        res = http.post(LOGIN_POST_URL,
                        data=data,
                        acceptable_status=(200, 422))
        result = http.json(res, schema=_login_schema)

        errors = result.get("errors")
        if errors:
            errors = ", ".join(errors)
            raise PluginError("Unable to authenticate: {0}".format(errors))

        self.logger.info("Successfully logged in as {0}", result["email"])
Exemple #2
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        channel_name = match.group("channel")

        form = {
            "cid": channel_name,
            "watchTime": 0,
            "firstConnect": 1,
            "ip": "NaN"
        }
        res = http.post(API_URL, data=form, headers=HEADERS)
        params = parse_query(res.text, schema=_schema)

        if params["status"] <= 0:
            return

        if params["block_type"] != 0:
            if params["block_type"] == BLOCK_TYPE_VIEWING_LIMIT:
                msg = BLOCKED_MSG_FORMAT.format(
                    params.get("block_time", "UNKNOWN"),
                    params.get("reconnect_time", "UNKNOWN"))
                raise PluginError(msg)
            elif params["block_type"] == BLOCK_TYPE_NO_SLOTS:
                raise PluginError("No free slots available")
            else:
                raise PluginError("Blocked for unknown reasons")

        if "token" not in params:
            raise PluginError("Server seems busy, retry again later")

        streams = {}
        stream_names = ["sd"]
        if params["multibitrate"]:
            stream_names += ["hd"]

        for stream_name in stream_names:
            playpath = params["playpath"]
            if stream_name == "hd":
                playpath += "HI"

            stream = RTMPStream(
                self.session, {
                    "rtmp": "{0}/{1}".format(params["rtmp"], playpath),
                    "pageUrl": self.url,
                    "swfVfy": SWF_URL,
                    "weeb": params["token"],
                    "live": True
                })
            streams[stream_name] = stream

        return streams
Exemple #3
0
    def _get_streams(self):
        streams = {}

        # streaming.media.ccc.de
        match = _url_streaming_media_re.match(self.url)
        if match:
            query_url    = API_URL_STREAMING_MEDIA
            live_streams = parse_streaming_media_json(get_json(query_url),\
                                                      match.group('room'))

            for stream_name, stream_url in live_streams.items():
                if re.search(r"m3u8", live_streams[stream_name]):
                    streams[stream_name] = HLSStream(self.session,\
                                                        stream_url)
                else:
                    streams[stream_name] = HTTPStream(self.session,\
                                                        stream_url)

        # media.ccc.de
        elif _url_media_re.search(self.url):
            event_id   = get_event_id(self.url)
            query_url  = "%s/public/events/%i" % (API_URL_MEDIA, event_id)
            recordings = parse_media_json(get_json(query_url))

            for name, stream_url in recordings.items():
                streams[name] = HTTPStream(self.session, stream_url)

        if not streams:
            raise PluginError("This plugin does not support your "
                              "selected video.")

        return streams
    def _create_api(self):
        """Creates a new CrunchyrollAPI object, initiates it's session and
        tries to authenticate it either by using saved credentials or the
        user's username and password.
        """
        if self.options.get("purge_credentials"):
            self.cache.set("session_id", None, 0)
            self.cache.set("auth", None, 0)

        current_time = datetime.datetime.utcnow()
        device_id = self._get_device_id()
        api = CrunchyrollAPI(
            self.cache.get("session_id"), self.cache.get("auth")
        )

        self.logger.debug("Creating session")
        try:
            api.session_id = api.start_session(device_id, schema=_session_schema)
        except CrunchyrollAPIError as err:
            if err.code == "bad_session":
                self.logger.debug("Current session has expired, creating a new one")
                api = CrunchyrollAPI()
                api.session_id = api.start_session(device_id, schema=_session_schema)
            else:
                raise err

        # Save session and hope it lasts for a few hours
        self.cache.set("session_id", api.session_id, 4 * 60 * 60)
        self.logger.debug("Session created")

        if api.auth:
            self.logger.debug("Using saved credentials")
        elif self.options.get("username"):
            try:
                self.logger.info("Attempting to login using username and password")
                login = api.login(
                    self.options.get("username"),
                    self.options.get("password"),
                    schema=_login_schema
                )
                api.auth = login["auth"]

                self.logger.info("Successfully logged in as '{0}'",
                                 login["user"]["username"])

                expires = (login["expires"] - current_time).total_seconds()
                self.cache.set("auth", login["auth"], expires)
            except CrunchyrollAPIError as err:
                raise PluginError(u"Authentication error: {0}".format(err.msg))
        else:
            self.logger.warning(
                "No authentication provided, you won't be able to access "
                "premium restricted content"
            )

        return api
Exemple #5
0
    def _get_streams(self):
        info = self._get_stream_info(self.url)
        if not info:
            return

        formats = info.get("fmt_list")
        streams = {}
        protected = False
        for stream_info in info.get("url_encoded_fmt_stream_map", []):
            if stream_info.get("s"):
                protected = True
                continue

            stream = HTTPStream(self.session, stream_info["url"])
            name = formats.get(stream_info["itag"]) or stream_info["quality"]

            if stream_info.get("stereo3d"):
                name += "_3d"

            streams[name] = stream

        # Extract audio streams from the DASH format list
        for stream_info in info.get("adaptive_fmts", []):
            if stream_info.get("s"):
                protected = True
                continue

            stream_type, stream_format = stream_info["type"]
            if stream_type != "audio":
                continue

            stream = HTTPStream(self.session, stream_info["url"])
            name = "audio_{0}".format(stream_format)

            streams[name] = stream

        hls_playlist = info.get("hlsvp")
        if hls_playlist:
            try:
                hls_streams = HLSStream.parse_variant_playlist(
                    self.session,
                    hls_playlist,
                    headers=HLS_HEADERS,
                    namekey="pixels")
                streams.update(hls_streams)
            except IOError as err:
                self.logger.warning("Failed to extract HLS streams: {0}", err)

        if not streams and protected:
            raise PluginError("This plugin does not support protected videos, "
                              "try youtube-dl instead")

        return streams
Exemple #6
0
    def _get_streams(self):
        stream_id = _id_map[self.channel_path]
        hls_url = "http://iphonelive.rtve.es/{0}_LV3_IPH/{0}_LV3_IPH.m3u8".format(
            stream_id)

        # Check if the stream is available
        res = http.head(hls_url, raise_for_status=False)
        if res.status_code == 404:
            raise PluginError(
                "The program is not available due to rights restrictions")

        return HLSStream.parse_variant_playlist(self.session, hls_url)
Exemple #7
0
def get_event_id(url):
    """Extract event id from talk html page.

    Raises :exc:`PluginError` on failure.

    :param url: talk URL

    """
    match = re.search(r"{event_id:\s(?P<event_id>\d+),.*}", http.get(url).text)

    try:
        event_id = int(match.group('event_id'))
    except:
        raise PluginError("Failed to get event id from URL.")

    return event_id
    def _get_streams(self):
        api = self._create_api()
        match = _url_re.match(self.url)
        media_id = int(match.group("media_id"))

        try:
            info = api.get_info(media_id, fields=["media.stream_data"],
                                schema=_media_schema)
        except CrunchyrollAPIError as err:
            raise PluginError(u"Media lookup error: {0}".format(err.msg))

        if not info:
            return

        # TODO: Use dict comprehension here after dropping Python 2.6 support.
        return dict(
            (stream["quality"], HLSStream(self.session, stream["url"]))
            for stream in info["streams"]
        )
Exemple #9
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        video_id = match.group("video_id")
        params = {
            "client_name": API_CLIENT_NAME,
            "context": API_CONTEXT,
            "raw_user_input": 1,
            "api_key": API_KEY,
            "vid": video_id,
            "r": random()
        }
        res = http.get(API_URL_VIDEO, params=params)
        video = http.json(res, schema=_video_schema)

        error = video.get("error")
        if error:
            raise PluginError(error)

        result = video.get("result")
        if not result:
            return

        url = result["url"]
        if url.startswith("http"):
            stream = HTTPStream(self.session, url)
        elif url.startswith("rtmp"):
            stream = RTMPStream(
                self.session, {
                    "rtmp": url,
                    "playpath": result["id"],
                    "pageUrl": self.url,
                    "live": True
                })

        width, height = result["size"].split("x")
        name = "{0}p".format(height)

        return {name: stream}