]>
code.delx.au - webdl/blob - iview.py
d0e0e58e2c203ea1d1bdf2af062f6e0022c11e5d
1 from common
import grab_json
, grab_xml
, Node
, download_hls
4 API_URL
= "http://iview.abc.net.au/api"
5 AUTH_URL
= "http://iview.abc.net.au/auth"
7 def format_episode_title(series
, ep
):
9 return series
+ " " + ep
13 class IviewEpisodeNode(Node
):
14 def __init__(self
, title
, parent
, video_key
):
15 Node
.__init
__(self
, title
, parent
)
16 self
.video_key
= video_key
17 self
.filename
= title
+ ".ts"
18 self
.can_download
= True
20 def find_hls_url(self
, playlist
):
21 for video
in playlist
:
22 if video
["type"] == "program":
23 return video
["hls-high"]
24 raise Exception("Missing hls-high program stream for " + self
.video_key
)
26 def get_auth_details(self
):
27 auth_doc
= grab_xml(AUTH_URL
, 0)
29 "auth": "http://www.abc.net.au/iView/Services/iViewHandshaker",
31 token
= auth_doc
.xpath("//auth:tokenhd/text()", namespaces
=NS
)[0]
32 token_url
= auth_doc
.xpath("//auth:server/text()", namespaces
=NS
)[0]
33 token_hostname
= urlparse
.urlparse(token_url
).netloc
34 return token
, token_hostname
36 def add_auth_token_to_url(self
, video_url
, token
, token_hostname
):
37 parsed_url
= urlparse
.urlparse(video_url
)
38 hacked_url
= parsed_url
._replace
(netloc
=token_hostname
, query
="hdnea=" + token
)
39 video_url
= urlparse
.urlunparse(hacked_url
)
43 info
= grab_json(API_URL
+ "/programs/" + self
.video_key
, 3600)
44 video_url
= self
.find_hls_url(info
["playlist"])
45 token
, token_hostname
= self
.get_auth_details()
46 video_url
= self
.add_auth_token_to_url(video_url
, token
, token_hostname
)
47 return download_hls(self
.filename
, video_url
)
50 class IviewIndexNode(Node
):
51 def __init__(self
, title
, parent
, url
):
52 Node
.__init
__(self
, title
, parent
)
56 def add_episode(self
, ep_info
):
57 video_key
= ep_info
["episodeHouseNumber"]
58 series_title
= ep_info
["seriesTitle"]
59 title
= ep_info
.get("title", None)
60 episode_title
= format_episode_title(series_title
, title
)
62 series_node
= self
.series_map
.get(series_title
, None)
64 series_node
= Node(series_title
, self
)
65 self
.series_map
[series_title
] = series_node
67 IviewEpisodeNode(episode_title
, series_node
, video_key
)
69 def fill_children(self
):
70 info
= grab_json(self
.url
, 3600)
71 for index_list
in info
["index"]:
72 for ep_info
in index_list
["episodes"]:
73 self
.add_episode(ep_info
)
75 class IviewFlatNode(Node
):
76 def __init__(self
, title
, parent
, url
):
77 Node
.__init
__(self
, title
, parent
)
80 def add_episode(self
, ep_info
):
81 video_key
= ep_info
["episodeHouseNumber"]
82 series_title
= ep_info
["seriesTitle"]
83 title
= ep_info
.get("title", None)
84 episode_title
= format_episode_title(series_title
, title
)
86 IviewEpisodeNode(episode_title
, self
, video_key
)
88 def fill_children(self
):
89 info
= grab_json(self
.url
, 3600)
91 self
.add_episode(ep_info
)
94 class IviewRootNode(Node
):
95 def load_categories(self
):
96 by_category_node
= Node("By Category", self
)
97 def category(name
, slug
):
98 IviewIndexNode(name
, by_category_node
, API_URL
+ "/category/" + slug
)
100 category("Arts & Culture", "arts")
101 category("Comedy", "comedy")
102 category("Documentary", "docs")
103 category("Drama", "drama")
104 category("Education", "education")
105 category("Lifestyle", "lifestyle")
106 category("News & Current Affairs", "news")
107 category("Panel & Discussion", "panel")
108 category("Sport", "sport")
110 def load_channels(self
):
111 by_channel_node
= Node("By Channel", self
)
112 def channel(name
, slug
):
113 IviewIndexNode(name
, by_channel_node
, API_URL
+ "/channel/" + slug
)
115 channel("ABC1", "abc1")
116 channel("ABC2", "abc2")
117 channel("ABC3", "abc3")
118 channel("ABC4Kids", "abc4kids")
119 channel("iView Exclusives", "iview")
121 def load_featured(self
):
122 IviewFlatNode("Featured", self
, API_URL
+ "/featured")
124 def fill_children(self
):
125 self
.load_categories()
130 def fill_nodes(root_node
):
131 IviewRootNode("ABC iView", root_node
)