media/canalplus.lua: Relicense under AGPLv3+
[libquvi-scripts.git] / share / media / canalplus.lua
blobf9ec4cc3b201c1bf379064810595d7dedc405be3
1 -- libquvi-scripts
2 -- Copyright (C) 2013 Mohamed El Morabity <melmorabity@fedoraproject.org>
3 -- Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
5 -- This file is part of libquvi-scripts <http://quvi.sourceforge.net/>.
6 --
7 -- This program is free software: you can redistribute it and/or
8 -- modify it under the terms of the GNU Affero General Public
9 -- License as published by the Free Software Foundation, either
10 -- version 3 of the License, or (at your option) any later version.
12 -- This program is distributed in the hope that it will be useful,
13 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
14 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 -- GNU Affero General Public License for more details.
17 -- You should have received a copy of the GNU Affero General
18 -- Public License along with this program. If not, see
19 -- <http://www.gnu.org/licenses/>.
22 local CanalPlus = {} -- Utility functions unique to to this script.
24 -- Identify the media script.
25 function ident(qargs)
26 return {
27 can_parse_url = CanalPlus.can_parse_url(qargs),
28 domains = table.concat({'canalplus.fr', 'd8.tv', 'd17.tv'}, ',')
30 end
32 -- Parse media properties.
33 function parse(qargs)
34 local J = require 'json'
36 local p = quvi.http.fetch(qargs.input_url).data
38 -- Make mandatory: needed to fetch the video data JSON.
39 qargs.id = p:match('videoId%s*=%s*"?(%d+)"?')
40 or error('no match: media ID')
42 -- Get the channel ID.
43 local channel = p:match('src="http://player%.canalplus%.fr/common/js/'
44 .. 'canalPlayer%.js%?param=(.-)"')
45 or error('no match: channel ID')
47 -- Fetch the video data JSON.
48 local t = {
49 'http://service.canal-plus.com/video/rest/getVideos/', channel, '/',
50 qargs.id, '?format=json'
53 local c = quvi.http.fetch(table.concat(t)).data
54 j = J.decode(c)
56 qargs.thumb_url = j['MEDIA']['IMAGES']['GRAND']
58 qargs.title = j['INFOS']['TITRAGE']['TITRE']
60 qargs.streams = CanalPlus.iter_streams(j)
62 return qargs
63 end
66 -- Utility functions
69 function CanalPlus.can_parse_url(qargs)
70 local U = require 'socket.url'
71 local t = U.parse(qargs.input_url)
72 if t and t.scheme and t.scheme:lower():match('^http$')
73 and t.host and (t.host:lower():match('canalplus%.fr$')
74 or t.host:lower():match('d8%.tv$')
75 or t.host:lower():match('d17%.tv$'))
76 and t.path and t.path:lower():match('/pid%d+') then
77 return true
78 else
79 return false
80 end
81 end
83 function CanalPlus.iter_streams(j)
84 local S = require 'quvi/stream'
86 local d = j['MEDIA']['VIDEOS']
87 local r = {}
89 for q, v in pairs(d) do
90 if v ~= ''
91 -- Some streams have denied accessed, just ignore them.
92 and q ~= 'HDS' and q ~= 'HLS' and q ~= 'IPHONE' and q ~= 'IPAD' then
93 local t = S.stream_new(v)
94 t.nostd = { quality = q } -- Ignored by libquvi.
95 t.id = CanalPlus.to_id(t)
96 table.insert(r, t)
97 end
98 end
100 if #r >1 then
101 CanalPlus.ch_best(S, r)
104 return r
107 function CanalPlus.ch_best(S, t)
108 -- Available video qualities.
109 -- HD -> High definition
110 -- HAUT_DEBIT -> Broadband access
111 -- BAS_DEBIT -> Dial-up access
112 -- MOBILE -> Mobile access
113 local q = { HD = 4, HAUT_DEBIT = 3, BAS_DEBIT = 2, MOBILE = 1 }
114 local r = t[1]
115 r.flags.best = true
116 for _,v in pairs(t) do
117 if q[v.nostd.quality] > q[r.nostd.quality] then
118 r = S.swap_best(r, v)
123 function CanalPlus.to_id(t)
124 return t.nostd.quality:lower()
127 -- vim: set ts=2 sw=2 tw=72 expandtab: