From d5942525de7b54f7559402d52e89ec08fd987152 Mon Sep 17 00:00:00 2001 From: Christopher Rosell Date: Fri, 7 Sep 2012 12:39:17 +0200 Subject: Get rid of urllib and use requests instead. --- src/livestreamer/plugins/gomtv.py | 179 +++++++++++++++++++------------------- 1 file changed, 88 insertions(+), 91 deletions(-) (limited to 'src/livestreamer/plugins/gomtv.py') diff --git a/src/livestreamer/plugins/gomtv.py b/src/livestreamer/plugins/gomtv.py index 8d7c3c9..5a44227 100644 --- a/src/livestreamer/plugins/gomtv.py +++ b/src/livestreamer/plugins/gomtv.py @@ -21,13 +21,15 @@ limitations under the License. """ -from livestreamer.compat import str, bytes, urlencode, urllib, urlparse, cookiejar +from livestreamer.compat import str, bytes, urlparse, urljoin, unquote from livestreamer.plugins import Plugin, PluginError, NoStreamsError from livestreamer.stream import HTTPStream -from livestreamer.utils import urlget +from livestreamer.utils import urlget, urlopen from livestreamer.options import Options -import xml.dom.minidom, re +import re +import requests +import xml.dom.minidom class GomTV(Plugin): BaseURL = "http://www.gomtv.net" @@ -35,6 +37,15 @@ class GomTV(Plugin): LoginURL = "https://ssl.gomtv.net/userinfo/loginProcess.gom" LoginCheckURL = BaseURL + "/forum/list.gom?m=my" + LoginHeaders = { + "Referer": BaseURL + } + + StreamHeaders = { + "User-Agent": "KPeerClient" + } + + options = Options({ "cookie": None, "username": None, @@ -55,39 +66,37 @@ class GomTV(Plugin): Plugin.__init__(self, url) def _get_streams(self): - options = self.options - # Setting urllib up so that we can store cookies - self.cookiejar = cookiejar.CookieJar() - self.opener = urllib.build_opener(urllib.HTTPCookieProcessor(self.cookiejar)) + self.rsession = requests.session(prefetch=True) + options = self.options if options.get("cookie"): - self.authenticate(cookies=options.get("cookie")) + self._authenticate(cookies=options.get("cookie")) else: - self.authenticate(options.get("username"), options.get("password")) + self._authenticate(options.get("username"), options.get("password")) streams = {} qualities = ["HQ", "SQ", "HQTest", "SQTest"] - response = self.grabLivePage(self.url) + res = self._get_live_page(self.url) + urls = self._find_stream_urls(res.text) for quality in qualities: - urls = self.parseHTML(response, quality) - for url in urls: # Grab the response of the URL listed on the Live page for a stream - goxFile = urlget(url, opener=self.opener) + url = url.format(quality=quality) + res = urlget(url, session=self.rsession) # The response for the GOX XML if an incorrect stream quality is chosen is 1002. - if goxFile != b"1002" and len(goxFile) > 0: - streamUrl = self.parseStreamURL(goxFile) - req = urllib.Request(streamUrl, headers={"User-Agent": "KPeerClient"}) - streams[quality] = HTTPStream(self.session, req) + if res.text != "1002" and len(res.text) > 0: + streamurl = self._parse_gox_file(res.text) + streams[quality] = HTTPStream(self.session, streamurl, + headers=self.StreamHeaders) return streams - def authenticate(self, username=None, password=None, cookies=None): + def _authenticate(self, username=None, password=None, cookies=None): if (username is None or password is None) and cookies is None: - raise PluginError("GOMTV.net Requires a username and password or cookie") + raise PluginError("GOMTV.net requires a username and password or a cookie") if cookies is not None: for cookie in cookies.split(";"): @@ -96,49 +105,38 @@ class GomTV(Plugin): except ValueError: continue - c = cookiejar.Cookie(version=0, name=name.strip(), value=value.strip(), - port=None, port_specified=False, domain="gomtv.net", - domain_specified=False, domain_initial_dot=False, path="/", - path_specified=True, secure=False, expires=None, discard=True, - comment=None, comment_url=None, rest={"HttpOnly": None}, - rfc2109=False) - self.cookiejar.set_cookie(c) + self.rsession.cookies[name.strip()] = value.strip() self.logger.info("Attempting to authenticate with cookies") else: - values = { - "cmd": "login", - "rememberme": "1", - "mb_username": username, - "mb_password": password - } - data = bytes(urlencode(values), "ascii") - headers = {"Referer": self.BaseURL} - request = urllib.Request(self.LoginURL, data, headers) - - self.logger.info("Attempting to authenticate with username/password") - urlget(request, opener=self.opener) - - - req = urllib.Request(self.LoginCheckURL) - if b"Please need login" in urlget(req, opener=self.opener): + form = dict(cmd="login", rememberme="1", + mb_username=username, + mb_password=password) + + self.logger.info("Attempting to authenticate with username and password") + + urlopen(self.LoginURL, data=form, headers=self.LoginHeaders, + session=self.rsession) + + res = urlget(self.LoginCheckURL, session=self.rsession) + + if "Please need login" in res.text: raise PluginError("Authentication failed") - for cookie in self.cookiejar: - if cookie.name == "SES_USERNICK": - self.logger.info(("Successfully logged in as {0}").format(cookie.value)) - break + if "SES_USERNICK" in self.rsession.cookies: + username = self.rsession.cookies["SES_USERNICK"] + self.logger.info(("Successfully logged in as {0}").format(username)) - def getEventLivePageURL(self, gomtvLiveURL, response): - match = re.search(' \"(.*)\";', response) + def _get_event_url(self, prefix, data): + match = re.search(' \"(.*)\";', data) if not match: - raise PluginError("Event Live Page URL not found") + raise PluginError("Event live page URL not found") - return urljoin(gomtvLiveURL, match.group(1)) + return urljoin(prefix, match.group(1)) - def grabLivePage(self, gomtvLiveURL): - response = urlget(gomtvLiveURL, opener=self.opener) + def _get_live_page(self, url): + res = urlget(url, session=self.rsession) # If a special event occurs, we know that the live page response # will just be some JavaScript that redirects the browser to the @@ -146,77 +144,76 @@ class GomTV(Plugin): # is less than 200 characters long, and that real live pages are # more than that. - if len(response) < 200: + if len(res.text) < 200: # Grabbing the real live page URL - gomtvLiveURL = self.getEventLivePageURL(gomtvLiveURL, response) - response = urlget(gomtvLiveURL, opener=self.opener) + url = self._parse_event_url(url, res.text) + res = urlget(url, session=self.rsession) - return response + return res - def parseHTML(self, response, quality): - urlFromHTML = None + def _find_stream_urls(self, data): + url = None # Parsing through the live page for a link to the gox XML file. # Quality is simply passed as a URL parameter e.g. HQ, SQ, SQTest try: - patternHTML = b"[^/]+var.+(http://www.gomtv.net/gox[^;]+;)" - urlFromHTML = re.search(patternHTML, response).group(1) - urlFromHTML = re.sub(b'\" \+ playType \+ \"', bytes(quality, "utf8"), urlFromHTML) + patternhtml = "[^/]+var.+(http://www.gomtv.net/gox[^;]+;)" + url = re.search(patternhtml, data).group(1) + url = re.sub('\" \+ playType \+ \"', "{quality}", url) except AttributeError: - raise PluginError("Unable to find the majority of the GOMtv XML URL on the Live page.") + raise PluginError("Unable to find the majority of the GOMTV.net XML URL on the Live page") # Finding the title of the stream, probably not necessary but # done for completeness try: - patternTitle = b"this\.title[^;]+;" - titleFromHTML = re.search(patternTitle, response).group(0) - titleFromHTML = re.search(b'\"(.*)\"', titleFromHTML).group(0) - titleFromHTML = re.sub(b'"', b"", titleFromHTML) - urlFromHTML = re.sub(b'"\+ tmpThis.title[^;]+;', titleFromHTML, urlFromHTML) + patterntitle = "this\.title[^;]+;" + title = re.search(patterntitle, data).group(0) + title = re.search('\"(.*)\"', title).group(0) + title = re.sub('"', "", title) + url = re.sub('"\+ tmpThis.title[^;]+;', title, url) except AttributeError: - raise PluginError("Unable to find the stream title on the Live page.") + raise PluginError("Unable to find the stream title on the Live page") # Check for multiple streams going at the same time, and extract the conid and the title # Those streams have the class "live_now" - patternLive = b'\d+)\"\sclass=\"live_now\"\stitle=\"(?P[^\"]+)' - live_streams = re.findall(patternLive, response) + patternlive = '<a\shref=\"/live/index.gom\?conid=(?P<conid>\d+)\"\sclass=\"live_now\"\stitle=\"(?P<title>[^\"]+)' + streams = re.findall(patternlive, data) - if len(live_streams) > 1: - liveUrls = [] - for stream in live_streams: + if len(streams) > 1: + urls = [] + for stream in streams: # Modify the urlFromHTML according to the user - singleUrlFromHTML = re.sub(b"conid=\d+", b"conid=" + stream[0], urlFromHTML) - singleTitleHTML = b"+".join(stream[0].split(b" ")) - singleUrlFromHTML = re.sub(b"title=[\w|.|+]*", b"title=" + singleTitleHTML, singleUrlFromHTML) - liveUrls.append(str(singleUrlFromHTML, "utf8")) + singleurl = re.sub("conid=\d+", "conid=" + stream[0], url) + singletitlehtml = "+".join(stream[0].split(" ")) + singleurl = re.sub("title=[\w|.|+]*", "title=" + singletitlehtml, singleurl) + urls.append(singleurl) - return liveUrls + return urls else: - if urlFromHTML is None: + if url is None: return [] else: - return [str(urlFromHTML, "utf8")] + return [url] - def parseStreamURL(self, response): + def _parse_gox_file(self, data): # Grabbing the gomcmd URL try: - streamPattern = b'<REF href="([^"]*)"\s*/>' - regexResult = re.search(streamPattern, response).group(1) + patternstream = '<REF href="([^"]*)"\s*/>' + match = re.search(patternstream, data).group(1) except AttributeError: - raise PluginError("Unable to find the gomcmd URL in the GOX XML file.") + raise PluginError("Unable to find the gomcmd URL in the GOX XML file") - regexResult = str(regexResult, "utf8") - regexResult = regexResult.replace("&", "&") - regexResult = urllib.unquote(regexResult) + match = match.replace("&", "&") + match = unquote(match) # SQ and SQTest streams can be gomp2p links, with actual stream address passed as a parameter. - if regexResult.startswith("gomp2p://"): - regexResult, n = re.subn("^.*LiveAddr=", "", regexResult) + if match.startswith("gomp2p://"): + match, n = re.subn("^.*LiveAddr=", "", match) # Cosmetics, getting rid of the HTML entity, we don't # need either of the " character or " - regexResult = regexResult.replace(""", "") + match = match.replace(""", "") - return regexResult + return match __plugin__ = GomTV -- cgit v1.2.3