]> code.delx.au - webdl/blob - sbs.py
b95a67b7555ca87db06d8863ccb0180102f9a1a5
[webdl] / sbs.py
1 #!/usr/bin/env python
2 # vim:ts=4:sts=4:sw=4:noet
3
4 from common import grab_json, grab_xml, download_rtmp, Node
5
6 import collections
7
8 BASE = "http://www.sbs.com.au"
9 MENU_URL = "/api/video_feed/f/dYtmxB/%s?startIndex=%d"
10 VIDEO_URL = BASE + "/api/video_feed/f/dYtmxB/CxeOeDELXKEv/%s?form=json"
11
12 NS = {
13 "smil": "http://www.w3.org/2005/SMIL21/Language",
14 }
15
16 SECTIONS = [
17 "section-sbstv",
18 "section-programs",
19 ]
20
21 CATEGORY_MAP = {
22 "Factual": "Documentary",
23 }
24
25
26 class SbsNode(Node):
27 def __init__(self, title, parent, video_id):
28 Node.__init__(self, title, parent)
29 self.title = title
30 self.video_id = video_id.split("/")[-1]
31 self.can_download = True
32
33 def download(self):
34 doc = grab_json(VIDEO_URL % self.video_id, 0)
35 best_url = None
36 best_bitrate = 0
37 for d in doc["media$content"]:
38 bitrate = d["plfile$bitrate"]
39 if bitrate > best_bitrate or best_url is None:
40 best_bitrate = bitrate
41 best_url = d["plfile$url"]
42
43 doc = grab_xml(best_url, 3600)
44 vbase = doc.xpath("//smil:meta/@base", namespaces=NS)[0]
45 vpath = doc.xpath("//smil:video/@src", namespaces=NS)[0]
46 ext = vpath.rsplit(".", 1)[1]
47 filename = self.title + "." + ext
48
49 return download_rtmp(filename, vbase, vpath)
50
51 def fill_entry(get_catnode, entry):
52 title = entry["title"]
53 video_id = entry["id"]
54 info = collections.defaultdict(list)
55 for d in entry["media$categories"]:
56 if not d.has_key("media$scheme"):
57 continue
58 info[d["media$scheme"]].append(d["media$name"])
59
60 if "Section/Promos" in info.get("Section", []):
61 # ignore promos
62 return
63
64 for category in info.get("Genre", ["$UnknownCategory$"]):
65 category = CATEGORY_MAP.get(category, category)
66 parent_node = get_catnode(category)
67 SbsNode(title, parent_node, video_id)
68
69
70 def fill_section(get_catnode, section):
71 index = 1
72 while True:
73 doc = grab_json(BASE + MENU_URL % (section, index), 3600)
74 if len(doc.get("entries", [])) == 0:
75 break
76 for entry in doc["entries"]:
77 fill_entry(get_catnode, entry)
78 index += doc["itemsPerPage"]
79
80 def fill_nodes(root_node):
81 catnodes = {}
82 def get_catnode(name):
83 try:
84 return catnodes[name]
85 except KeyError:
86 n = Node(name, root_node)
87 catnodes[name] = n
88 return n
89
90 for section in SECTIONS:
91 fill_section(get_catnode, section)
92
93