]> code.delx.au - webdl/blob - sbs.py
d4570cac155166b0037e7aae27cec4ccec135e73
[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, download_urllib, 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 if doc.xpath("//smil:meta/@base", namespaces=NS):
45 vbase = doc.xpath("//smil:meta/@base", namespaces=NS)[0]
46 vpath = doc.xpath("//smil:video/@src", namespaces=NS)[0]
47 ext = vpath.rsplit(".", 1)[1]
48 filename = self.title + "." + ext
49 return download_rtmp(filename, vbase, vpath)
50 else:
51 from lxml import etree
52 url = doc.xpath("//smil:video/@src", namespaces=NS)[0]
53 ext = url.rsplit(".", 1)[1]
54 filename = self.title + "." + ext
55 url += "?v=2.5.14&fp=MAC%2011,1,102,55&r=FLQDD&g=YNANAXRIYFYO"
56 return download_urllib(filename, url)
57
58 def fill_entry(get_catnode, entry):
59 title = entry["title"]
60 video_id = entry["id"]
61 info = collections.defaultdict(list)
62 for d in entry["media$categories"]:
63 if not d.has_key("media$scheme"):
64 continue
65 info[d["media$scheme"]].append(d["media$name"])
66
67 if "Section/Promos" in info.get("Section", []):
68 # ignore promos
69 return
70
71 for category in info.get("Genre", ["$UnknownCategory$"]):
72 category = CATEGORY_MAP.get(category, category)
73 parent_node = get_catnode(category)
74 SbsNode(title, parent_node, video_id)
75
76
77 def fill_section(get_catnode, section):
78 index = 1
79 while True:
80 doc = grab_json(BASE + MENU_URL % (section, index), 3600)
81 if len(doc.get("entries", [])) == 0:
82 break
83 for entry in doc["entries"]:
84 fill_entry(get_catnode, entry)
85 index += doc["itemsPerPage"]
86
87 class SbsRoot(Node):
88 def __init__(self, title, parent=None):
89 Node.__init__(self, title, parent)
90 self.catnodes = {}
91
92 def get_catnode(self, name):
93 try:
94 return self.catnodes[name]
95 except KeyError:
96 n = Node(name, self)
97 self.catnodes[name] = n
98 return n
99
100 def get_children(self):
101 if self.children:
102 return self.children
103 for section in SECTIONS:
104 fill_section(self.get_catnode, section)
105 return self.children
106
107 def fill_nodes(root_node):
108 SbsRoot("SBS", root_node)
109