]> code.delx.au - webdl/blob - iview.py
Merged
[webdl] / iview.py
1 #!/usr/bin/env python
2 # vim:ts=4:sts=4:sw=4:noet
3
4 from common import grab_xml, grab_json, download_rtmp, Node
5 from datetime import datetime
6
7 BASE_URL = "http://www.abc.net.au/iview/"
8 CONFIG_URL = BASE_URL + "xml/config.xml"
9 HASH_URL = BASE_URL + "images/iview.jpg"
10 NS = {
11 "auth": "http://www.abc.net.au/iView/Services/iViewHandshaker",
12 }
13 PLAYPATH_PREFIXES = {
14 "akamai": "flash/playback/_definst_/",
15 }
16
17 class IviewNode(Node):
18 def __init__(self, title, parent, params, vpath):
19 Node.__init__(self, title, parent)
20 self.params = params
21 self.vpath = vpath
22 self.can_download = True
23
24 def download(self):
25 auth_doc = grab_xml(self.params["auth"], 0)
26 host = auth_doc.xpath("//auth:host/text()", namespaces=NS)[0]
27 playpath_prefix = PLAYPATH_PREFIXES.get(host.lower(), "")
28 vbase = auth_doc.xpath("//auth:server/text()", namespaces=NS)[0]
29 token = auth_doc.xpath("//auth:token/text()", namespaces=NS)[0]
30 vbase += "?auth=" + token
31 vpath, ext = self.vpath.rsplit(".", 1)
32 vpath = playpath_prefix + vpath
33 vpath = ext + ":" + vpath
34 filename = self.title + "." + ext
35 return download_rtmp(filename, vbase, vpath, HASH_URL)
36
37
38 class IviewSeriesNode(Node):
39 def __init__(self, title, parent, params, series_id):
40 Node.__init__(self, title, parent)
41 self.params = params
42 self.series_id = series_id
43
44 def fill_children(self):
45 series_doc = grab_json(self.params["api"] + "series=" + self.series_id, 3600)
46 if not series_doc:
47 return
48 for episode in series_doc[0]["f"]:
49 vpath = episode["n"]
50 episode_title = episode["b"].strip()
51 if not episode_title.startswith(self.title):
52 episode_title = self.title + " " + episode_title
53 if episode_title.lower().endswith(" (final)"):
54 episode_title = episode_title[:-8]
55 IviewNode(episode_title, self, self.params, vpath)
56
57 class IviewRootNode(Node):
58 def __init__(self, parent):
59 Node.__init__(self, "ABC iView", parent)
60
61 def fill_children(self):
62 config_doc = grab_xml(CONFIG_URL, 24*3600)
63 params = dict((p.attrib["name"], p.attrib["value"]) for p in config_doc.xpath("/config/param"))
64
65 categories_doc = grab_xml(BASE_URL + params["categories"], 24*3600)
66 categories_map = {}
67 for category in categories_doc.xpath("//category[@genre='true']"):
68 cid = category.attrib["id"]
69 category_name = category.xpath("name/text()")[0]
70 category_node = Node(category_name, self)
71 categories_map[cid] = category_node
72
73 # Create a duplicate of each series within each category that it appears
74 series_list_doc = grab_json(params["api"] + "seriesIndex", 3600)
75 for series in series_list_doc:
76 categories = series["e"].split()
77 sid = series["a"]
78
79 series_title = series["b"].replace("&", "&")
80 for cid in categories:
81 category_node = categories_map.get(cid, None)
82 if category_node:
83 IviewSeriesNode(series_title, category_node, params, sid)
84
85
86
87 def fill_nodes(root_node):
88 IviewRootNode(root_node)
89