]> code.delx.au - webdl/blob - sbs.py
Fixed SBS
[webdl] / sbs.py
1 #!/usr/bin/env python
2 # vim:ts=4:sts=4:sw=4:noet
3
4 from common import grab_text, grab_html, grab_json, grab_xml, download_rtmp, download_urllib, Node, append_to_qs
5
6 import collections
7 import urlparse
8
9 BASE = "http://www.sbs.com.au"
10 VIDEO_MENU = BASE + "/ondemand/js/video-menu"
11 VIDEO_URL = BASE + "/ondemand/video/single/%s"
12 VIDEO_MAGIC = {
13 "v": "2.5.14",
14 "fp": "MAC 11,1,102,55",
15 "r": "FLQDD",
16 "g": "YNANAXRIYFYO",
17 }
18 SWF_URL = "http://resources.sbs.com.au/vod/theplatform/core/current/swf/flvPlayer.swf"
19
20 NS = {
21 "smil": "http://www.w3.org/2005/SMIL21/Language",
22 }
23
24
25 class SbsNode(Node):
26 def __init__(self, title, parent, video_id):
27 Node.__init__(self, title, parent)
28 self.title = title
29 self.video_id = video_id.split("/")[-1]
30 self.can_download = True
31
32 def download(self):
33 doc = grab_html(VIDEO_URL % self.video_id, 0)
34 meta_video = doc.xpath("//meta[@property='og:video']")[0]
35 swf_url = meta_video.attrib["content"]
36 swf_url_qs = urlparse.parse_qs(urlparse.urlparse(swf_url).query)
37 desc_url = swf_url_qs["v"][0]
38
39 doc = grab_text(desc_url, 0)
40 doc_qs = urlparse.parse_qs(doc)
41 desc_url = doc_qs["releaseUrl"][0]
42
43 doc = grab_xml(desc_url, 0)
44 video = doc.xpath("//smil:video", namespaces=NS)[0]
45 video_url = video.attrib["src"]
46 ext = urlparse.urlsplit(video_url).path.rsplit(".", 1)[1]
47 filename = self.title + "." + ext
48 video_url = append_to_qs(video_url, VIDEO_MAGIC)
49 return download_urllib(filename, video_url, referrer=SWF_URL)
50
51 class SbsNavNode(Node):
52 def __init__(self, title, parent, url):
53 Node.__init__(self, title, parent)
54 self.url = url
55
56 def fill_children(self):
57 try:
58 doc = grab_json(BASE + self.url, 3600)
59 except ValueError:
60 # SBS sends XML as an error message :\
61 return
62 if len(doc.get("entries", [])) == 0:
63 return
64 for entry in doc["entries"]:
65 self.fill_entry(entry)
66
67 def fill_entry(self, entry):
68 title = entry["title"]
69 video_id = entry["id"]
70 SbsNode(title, self, video_id)
71
72 class SbsRootNode(Node):
73 def __init__(self, parent):
74 Node.__init__(self, "SBS", parent)
75
76 def fill_children(self):
77 menu = grab_json(VIDEO_MENU, 3600, skip_assignment=True)
78 for name in menu.keys():
79 self.fill_category(self, menu[name])
80
81 def create_nav_node(self, name, parent, cat_data, url_key):
82 try:
83 url = cat_data[url_key]
84 except KeyError:
85 return
86 if url.strip():
87 SbsNavNode(name, parent, url)
88
89 def fill_category(self, parent, cat_data):
90 if not cat_data.has_key("children"):
91 name = cat_data["name"]
92 self.create_nav_node(name, parent, cat_data, "url")
93 return
94
95 node = Node(cat_data["name"], parent)
96 self.create_nav_node("-Featured", node, cat_data, "furl")
97 self.create_nav_node("-Latest", node, cat_data, "url")
98 self.create_nav_node("-Most Popular", node, cat_data, "purl")
99
100 children = cat_data.get("children", [])
101 if isinstance(children, dict):
102 children = [children[k] for k in sorted(children.keys())]
103 for child_cat in children:
104 self.fill_category(node, child_cat)
105
106 def fill_nodes(root_node):
107 SbsRootNode(root_node)
108