]> code.delx.au - monosys/blob - scripts/sbs-downloader
Kill terminfo
[monosys] / scripts / sbs-downloader
1 #!/usr/bin/env python
2
3 from lxml import etree
4 import shutil
5 import signal
6 import subprocess
7 import urllib
8
9
10 BASE_URL = "http://player.sbs.com.au"
11
12 def grab_xml(path):
13 f = urllib.urlopen(BASE_URL + path)
14 doc = etree.parse(f)
15 f.close()
16 return doc
17
18 def choose(options, allow_multi):
19 skeys = sorted(options.keys())
20 for i, key in enumerate(skeys):
21 print " %d) %s" % (i+1, key)
22 print " 0) Back"
23 while True:
24 try:
25 values = map(int, raw_input("Choose> ").split())
26 if len(values) == 0:
27 continue
28 if 0 in values:
29 return
30 values = [options[skeys[value-1]] for value in values]
31 if allow_multi:
32 return values
33 else:
34 if len(values) == 1:
35 return values[0]
36 except ValueError:
37 pass
38
39 def get_menu_list():
40 settings = grab_xml("/playerassets/programs/config/standalone_settings.xml")
41 menu_url = settings.xpath("/settings/setting[@name='menuURL']/@value")[0]
42
43 root_menu = grab_xml(menu_url)
44 menu_list = {}
45 for menu in root_menu.xpath("//menu"):
46 try:
47 title = menu.xpath("title/text()")[0]
48 playlist_url = menu.xpath("playlist/@xmlSrc")[0]
49 if title in menu_list:
50 i = 2
51 while True:
52 if (title+str(i)) not in menu_list:
53 title += str(i)
54 break
55 i += 1
56 menu_list[title] = playlist_url
57 except IndexError:
58 continue
59
60 return menu_list
61
62 def get_video_list(playlist_url):
63 video_list = {}
64 playlist = grab_xml(playlist_url)
65 for video_desc in playlist.xpath("//video"):
66 video_desc_url = video_desc.xpath("@src")[0]
67 title = video_desc.xpath("title/text()")[0].strip()
68 video_list[title] = (title, video_desc_url)
69 return video_list
70
71 def download_video(title, video_desc_url):
72 video = grab_xml(video_desc_url)
73 vbase = video.xpath("//meta/@base")[0]
74 bestrate = 0
75 bestvpath = None
76 for vpath in video.xpath("//switch/video"):
77 rate = float(vpath.xpath("@system-bitrate")[0])
78 if rate > bestrate:
79 bestrate = rate
80 bestvpath = vpath.xpath("@src")[0]
81 filename = title + "." + bestvpath.rsplit(".", 1)[1]
82 if vbase.startswith("rtmp://"):
83 download_rtmp(filename, vbase, bestvpath)
84 else:
85 download_urllib(filename, vbase + bestvpath)
86
87 def download_rtmp(filename, vbase, vpath):
88 if vpath.endswith(".flv"):
89 vpath = vpath[:-4]
90 cmd = [
91 "rtmpdump",
92 "-o", filename,
93 "-r", vbase,
94 "-y", vpath,
95 ]
96 try:
97 p = subprocess.Popen(cmd)
98 p.wait()
99 except KeyboardInterrupt:
100 print "Cancelled", cmd
101 try:
102 p.terminate()
103 p.wait()
104 except KeyboardInterrupt:
105 p.send_signal(signal.SIGKILL)
106 p.wait()
107
108 def download_urllib(filename, url):
109 print "Downloading: %s -> %s" % (url, filename)
110 try:
111 src = urllib.urlopen(url)
112 dst = open(filename, "w")
113 shutil.copyfileobj(src, dst)
114 except KeyboardInterrupt:
115 print "\nCancelled", url
116 finally:
117 src.close()
118 dst.close()
119
120 def main():
121 while True:
122 menu_list = get_menu_list()
123 playlist_url = choose(menu_list, allow_multi=False)
124 if playlist_url is None:
125 continue
126 video_list = get_video_list(playlist_url)
127 while True:
128 generator = choose(video_list, allow_multi=True)
129 if generator is None:
130 break
131 for title, video_desc_url in generator:
132 download_video(title, video_desc_url)
133
134 if __name__ == "__main__":
135 try:
136 main()
137 except (KeyboardInterrupt, EOFError):
138 print "\nExiting..."
139