]> code.delx.au - webdl/blob - sbs.py
Fixed sbs.py to work with SBS website changes
[webdl] / sbs.py
1 #!/usr/bin/env python
2 # vim:ts=4:sts=4:sw=4:noet
3
4 from common import 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 print VIDEO_URL % self.video_id
35 meta_video = doc.xpath("//meta[@property='og:video']")[0]
36 swf_url = meta_video.attrib["content"]
37 swf_url_qs = urlparse.parse_qs(urlparse.urlparse(swf_url).query)
38 desc_url = swf_url_qs["releaseUrl"][0]
39
40 doc = grab_xml(desc_url, 0)
41 video = doc.xpath("//smil:video", namespaces=NS)[0]
42 video_url = video.attrib["src"]
43 ext = urlparse.urlsplit(video_url).path.rsplit(".", 1)[1]
44 filename = self.title + "." + ext
45 video_url = append_to_qs(video_url, VIDEO_MAGIC)
46 return download_urllib(filename, video_url, referrer=SWF_URL)
47
48 class SbsNavNode(Node):
49 def __init__(self, title, parent, url):
50 Node.__init__(self, title, parent)
51 self.url = url
52
53 def fill_children(self):
54 try:
55 doc = grab_json(BASE + self.url, 3600)
56 except ValueError:
57 # SBS sends XML as an error message :\
58 return
59 if len(doc.get("entries", [])) == 0:
60 return
61 for entry in doc["entries"]:
62 self.fill_entry(entry)
63
64 def fill_entry(self, entry):
65 title = entry["title"]
66 video_id = entry["id"]
67 SbsNode(title, self, video_id)
68
69 class SbsRootNode(Node):
70 def __init__(self, parent=None):
71 Node.__init__(self, "SBS", parent)
72
73 def fill_children(self):
74 menu = grab_json(VIDEO_MENU, 3600, skip_assignment=True)
75 for name in menu.keys():
76 self.fill_category(self, menu[name])
77
78 def create_nav_node(self, name, parent, cat_data, url_key):
79 try:
80 url = cat_data[url_key]
81 except KeyError:
82 return
83 if url.strip():
84 SbsNavNode(name, parent, url)
85
86 def fill_category(self, parent, cat_data):
87 if not cat_data.has_key("children"):
88 name = cat_data["name"]
89 self.create_nav_node(name, parent, cat_data, "url")
90 return
91
92 node = Node(cat_data["name"], parent)
93 self.create_nav_node("-Featured", node, cat_data, "furl")
94 self.create_nav_node("-Latest", node, cat_data, "url")
95 self.create_nav_node("-Most Popular", node, cat_data, "purl")
96
97 children = cat_data.get("children", [])
98 if isinstance(children, dict):
99 children = [children[k] for k in sorted(children.keys())]
100 for child_cat in children:
101 self.fill_category(node, child_cat)
102
103 def fill_nodes(root_node):
104 SbsRootNode(root_node)
105