aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Christopher Rosell <chrippa@tanuki.se>2012-08-25 15:14:56 +0200
committerGravatar Christopher Rosell <chrippa@tanuki.se>2012-08-25 15:14:56 +0200
commitb854a388135782a80ce00329aa0f4e1e32d47bec (patch)
tree83ba2bf18b2a81fa860e2f3d996acba612be0792
parent91363e5628dd30e34ab254c619246a298333f8bc (diff)
livestreamer.plugins.gomtv: A few tweaks and fixes.
- Python 3.x compatible. - Fix cookie handling. - Remove unused methods and variables. - Coding style tweaks.
-rw-r--r--src/livestreamer/compat.py9
-rw-r--r--src/livestreamer/plugins/gomtv.py149
2 files changed, 80 insertions, 78 deletions
diff --git a/src/livestreamer/compat.py b/src/livestreamer/compat.py
index 61711fb..f023bd8 100644
--- a/src/livestreamer/compat.py
+++ b/src/livestreamer/compat.py
@@ -7,10 +7,11 @@ is_win32 = os.name == "nt"
if is_py2:
input = raw_input
stdout = sys.stdout
+ _str = str
str = unicode
def bytes(b, enc="ascii"):
- return str(b)
+ return _str(b)
elif is_py3:
bytes = bytes
@@ -25,9 +26,13 @@ except ImportError:
try:
from urllib.parse import urlparse, parse_qs, urlencode
+ import http.cookies as cookies
+ import http.cookiejar as cookiejar
except ImportError:
from urlparse import urlparse, parse_qs
from urllib import urlencode
+ import Cookie as cookies
+ import cookielib as cookiejar
__all__ = ["is_py2", "is_py3", "is_win32", "input", "stdout", "str",
- "bytes", "urllib", "urlparse", "parse_qs"]
+ "bytes", "urllib", "urlparse", "parse_qs", "cookies", "cookiejar"]
diff --git a/src/livestreamer/plugins/gomtv.py b/src/livestreamer/plugins/gomtv.py
index b2aa494..3c8562c 100644
--- a/src/livestreamer/plugins/gomtv.py
+++ b/src/livestreamer/plugins/gomtv.py
@@ -1,7 +1,6 @@
-'''
-This is derived from https://github.com/sjp/GOMstreamer
-
-and carries the following licence
+"""
+This plugin is derived from https://github.com/sjp/GOMstreamer
+and carries the following license.
Copyright 2010 Simon Potter, Tomas Herman
Copyright 2011 Simon Potter
@@ -20,16 +19,15 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-'''
-from livestreamer.compat import str, bytes, urlencode
+"""
+
+from livestreamer.compat import str, bytes, urlencode, urllib, cookies, cookiejar
from livestreamer.plugins import Plugin, PluginError, NoStreamsError
from livestreamer.stream import HTTPStream
-from livestreamer.utils import urlget, urllib
+from livestreamer.utils import urlget
from livestreamer.options import Options
import xml.dom.minidom, re
-import cookielib
-import Cookie
class GomTV(Plugin):
options = Options({
@@ -42,27 +40,22 @@ class GomTV(Plugin):
def can_handle_url(self, url):
return "gomtv.net" in url
-
def _get_streams(self):
options = self.options
# Setting urllib up so that we can store cookies
- self.cookiejar = cookielib.LWPCookieJar()
+ self.cookiejar = cookiejar.LWPCookieJar()
self.opener = urllib.build_opener(urllib.HTTPCookieProcessor(self.cookiejar))
if options.get("cookie"):
- self.authenticate(cookie=options.get("cookie"))
+ self.authenticate(cookies=options.get("cookie"))
else:
self.authenticate(options.get("username"), options.get("password"))
streams = {}
qualities = ["HQ", "SQ", "HQTest", "SQTest"]
- streamChoice = "both"
response = self.grabLivePage(self.url)
- goxUrls = []
- validGoxFound = False
- failedGoxAll = False
for quality in qualities:
urls = self.parseHTML(response, quality)
@@ -71,132 +64,136 @@ class GomTV(Plugin):
goxFile = urlget(url, opener=self.opener)
# The response for the GOX XML if an incorrect stream quality is chosen is 1002.
- if (goxFile != '1002' and goxFile != ''):
+ 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)
- validGoxFound = True
return streams
- def authenticate(self, username=None, password=None, cookie=None):
- if (username is None or password is None) and cookie is 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")
-
-
- if cookie is not None:
- name,value = cookie.split("=")
-
- c = cookielib.Cookie(version=0, name=name, value=value,
- 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)
+
+
+ if cookies is not None:
+ for cookie in cookies.split(";"):
+ try:
+ name, value = cookie.split("=")
+ except ValueError:
+ continue
+
+ c = cookiejar.Cookie(version=0, name=name, value=value,
+ 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)
else:
values = {
- 'cmd': 'login',
- 'rememberme': '1',
- 'mb_username': username,
- 'mb_password': password
- }
- data = urlencode(values)
- # Now expects to log in only via the website. Thanks chrippa.
- headers = {'Referer': 'http://www.gomtv.net/'}
- request = urllib.Request('https://ssl.gomtv.net/userinfo/loginProcess.gom', data, headers)
+ "cmd": "login",
+ "rememberme": "1",
+ "mb_username": username,
+ "mb_password": password
+ }
+ data = bytes(urlencode(values), "ascii")
+ headers = {"Referer": "http://www.gomtv.net/"}
+ request = urllib.Request("https://ssl.gomtv.net/userinfo/loginProcess.gom", data, headers)
urlget(request, opener=self.opener)
-
- req = urllib.Request('http://www.gomtv.net/forum/list.gom?m=my')
- if 'Please need login' in urlget(req, opener=self.opener):
- raise PluginError("Authentication failed")
- # The real response that we want are the cookies, so returning None is fine.
- return
+ req = urllib.Request("http://www.gomtv.net/forum/list.gom?m=my")
+ if b"Please need login" in urlget(req, opener=self.opener):
+ raise PluginError("Authentication failed")
def getEventLivePageURL(self, gomtvLiveURL, response):
match = re.search(' \"(.*)\";', response)
- assert match, 'Event Live Page URL not found'
- return urljoin(gomtvLiveURL, match.group(1))
- def getSeasonURL(self, gomtvURL):
- # Getting season url from the 'Go Live!' button on the main page.
- match = re.search('.*liveicon"><a href="([^"]*)"', urlget(gomtvURL, opener=self.opener))
- assert match, 'golive_btn href not found'
- return match.group(1)
+ if not match:
+ raise PluginError("Event Live Page URL not found")
+
+ return urljoin(gomtvLiveURL, match.group(1))
def grabLivePage(self, gomtvLiveURL):
response = urlget(gomtvLiveURL, opener=self.opener)
+
# If a special event occurs, we know that the live page response
# will just be some JavaScript that redirects the browser to the
# real live page. We assume that the entireity of this JavaScript
# is less than 200 characters long, and that real live pages are
# more than that.
+
if len(response) < 200:
# Grabbing the real live page URL
gomtvLiveURL = self.getEventLivePageURL(gomtvLiveURL, response)
response = urlget(gomtvLiveURL, opener=self.opener)
+
return response
def parseHTML(self, response, quality):
urlFromHTML = 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 = r'[^/]+var.+(http://www.gomtv.net/gox[^;]+;)'
+ patternHTML = b"[^/]+var.+(http://www.gomtv.net/gox[^;]+;)"
urlFromHTML = re.search(patternHTML, response).group(1)
- urlFromHTML = re.sub(r'\" \+ playType \+ \"', quality, urlFromHTML)
+ urlFromHTML = re.sub(b'\" \+ playType \+ \"', bytes(quality, "utf8"), urlFromHTML)
except AttributeError:
- pass
+ raise PluginError("Unable to find the majority of the GOMtv XML URL on the Live page.")
# Finding the title of the stream, probably not necessary but
# done for completeness
try:
- patternTitle = r'this\.title[^;]+;'
+ patternTitle = b"this\.title[^;]+;"
titleFromHTML = re.search(patternTitle, response).group(0)
- titleFromHTML = re.search(r'\"(.*)\"', titleFromHTML).group(0)
- titleFromHTML = re.sub(r'"', '', titleFromHTML)
- urlFromHTML = re.sub(r'"\+ tmpThis.title[^;]+;', titleFromHTML, urlFromHTML)
+ titleFromHTML = re.search(b'\"(.*)\"', titleFromHTML).group(0)
+ titleFromHTML = re.sub(b'"', b"", titleFromHTML)
+ urlFromHTML = re.sub(b'"\+ tmpThis.title[^;]+;', titleFromHTML, urlFromHTML)
except AttributeError:
- pass
+ 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 = r'<a\shref=\"/live/index.gom\?conid=(?P<conid>\d+)\"\sclass=\"live_now\"\stitle=\"(?P<title>[^\"]+)'
+ patternLive = b'<a\shref=\"/live/index.gom\?conid=(?P<conid>\d+)\"\sclass=\"live_now\"\stitle=\"(?P<title>[^\"]+)'
live_streams = re.findall(patternLive, response)
if len(live_streams) > 1:
liveUrls = []
- options = range(len(live_streams))
- for i in options:
+ for stream in live_streams:
# Modify the urlFromHTML according to the user
- singleUrlFromHTML = re.sub(r'conid=\d+', 'conid=' + live_streams[i][0], urlFromHTML)
- singleTitleHTML = '+'.join(live_streams[i][1].split(' '))
- singleUrlFromHTML = re.sub(r'title=[\w|.|+]*', 'title=' + singleTitleHTML, singleUrlFromHTML)
- liveUrls.append(singleUrlFromHTML)
+ 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"))
+
return liveUrls
else:
if urlFromHTML is None:
return []
else:
- return [urlFromHTML]
+ return [str(urlFromHTML, "utf8")]
def parseStreamURL(self, response):
# Grabbing the gomcmd URL
try:
- streamPattern = r'<REF href="([^"]*)"\s*/>'
+ streamPattern = b'<REF href="([^"]*)"\s*/>'
regexResult = re.search(streamPattern, response).group(1)
except AttributeError:
- return None
+ raise PluginError("Unable to find the gomcmd URL in the GOX XML file.")
+ regexResult = str(regexResult, "utf8")
+ regexResult = regexResult.replace("&amp;", "&")
regexResult = urllib.unquote(regexResult)
- regexResult = re.sub(r'&amp;', '&', regexResult)
+
# SQ and SQTest streams can be gomp2p links, with actual stream address passed as a parameter.
- if regexResult.startswith('gomp2p://'):
- regexResult, n = re.subn(r'^.*LiveAddr=', '', regexResult)
+ if regexResult.startswith("gomp2p://"):
+ regexResult, n = re.subn("^.*LiveAddr=", "", regexResult)
+
# Cosmetics, getting rid of the HTML entity, we don't
# need either of the " character or &quot;
- regexResult = regexResult.replace('&quot;', '')
+ regexResult = regexResult.replace("&quot;", "")
+
return regexResult
__plugin__ = GomTV