]>
code.delx.au - webdl/blob - sbs.py
3 from common
import grab_html
, grab_json
, grab_xml
, download_hls
, Node
7 BASE
= "http://www.sbs.com.au"
8 FULL_VIDEO_LIST
= BASE
+ "/api/video_feed/f/Bgtm9B/sbs-section-programs/?form=json"
9 VIDEO_URL
= BASE
+ "/ondemand/video/single/%s"
12 "smil": "http://www.w3.org/2005/SMIL21/Language",
16 class SbsVideoNode(Node
):
17 def __init__(self
, title
, parent
, url
):
18 Node
.__init
__(self
, title
, parent
)
19 self
.video_id
= url
.split("/")[-1]
20 self
.can_download
= True
23 doc
= grab_html(VIDEO_URL
% self
.video_id
, 0)
24 player_params
= self
.get_player_params(doc
)
25 release_url
= player_params
["releaseUrls"]["html"]
27 doc
= grab_xml(release_url
, 0)
28 video
= doc
.xpath("//smil:video", namespaces
=NS
)[0]
29 video_url
= video
.attrib
["src"]
31 raise Exception("Unsupported video %s: %s" % (self
.video_id
, self
.title
))
32 filename
= self
.title
+ ".ts"
33 return download_hls(filename
, video_url
)
35 def get_player_params(self
, doc
):
36 for script
in doc
.xpath("//script"):
39 for line
in script
.text
.split("\n"):
40 s
= "var playerParams = {"
42 p1
= line
.find(s
) + len(s
) - 1
43 p2
= line
.find("};", p1
) + 1
44 if p1
>= 0 and p2
> 0:
45 return json
.loads(line
[p1
:p2
])
46 raise Exception("Unable to find player params for %s: %s" % (self
.video_id
, self
.title
))
49 class SbsNavNode(Node
):
50 def create_video_node(self
, entry_data
):
51 SbsVideoNode(entry_data
["title"], self
, entry_data
["id"])
53 def find_existing_child(self
, path
):
54 for child
in self
.children
:
55 if child
.title
== path
:
58 class SbsRootNode(SbsNavNode
):
59 def __init__(self
, parent
):
60 Node
.__init
__(self
, "SBS", parent
)
62 def fill_children(self
):
63 full_video_list
= grab_json(FULL_VIDEO_LIST
, 3600)
64 category_and_entry_data
= self
.explode_videos_to_unique_categories(full_video_list
)
65 for category_path
, entry_data
in category_and_entry_data
:
66 nav_node
= self
.create_nav_node(self
, category_path
)
67 nav_node
.create_video_node(entry_data
)
69 def explode_videos_to_unique_categories(self
, full_video_list
):
70 for entry_data
in full_video_list
["entries"]:
71 for category_data
in entry_data
["media$categories"]:
72 category_path
= self
.calculate_category_path(
73 category_data
["media$scheme"],
74 category_data
["media$name"],
77 yield category_path
, entry_data
79 def calculate_category_path(self
, scheme
, name
):
84 name
= name
.split("/")
86 name
.insert(0, scheme
)
89 def create_nav_node(self
, parent
, category_path
):
93 current_path
= category_path
[0]
94 current_node
= parent
.find_existing_child(current_path
)
96 current_node
= SbsNavNode(current_path
, parent
)
97 return self
.create_nav_node(current_node
, category_path
[1:])
99 def fill_nodes(root_node
):
100 SbsRootNode(root_node
)