quvi/util: Add json_get function
[libquvi-scripts.git] / share / lua / website / quvi / util.lua
blobb2154b4cfc45d660f8eeea878fe18e9eb516a989
2 -- libquvi-scripts
3 -- Copyright (C) 2010,2011,2013 Toni Gundogdu <legatvs@gmail.com>
4 --
5 -- This file is part of libquvi-scripts <http://quvi.sourceforge.net/>.
6 --
7 -- This library is free software; you can redistribute it and/or
8 -- modify it under the terms of the GNU Lesser General Public
9 -- License as published by the Free Software Foundation; either
10 -- version 2.1 of the License, or (at your option) any later version.
12 -- This library 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 GNU
15 -- Lesser General Public License for more details.
17 -- You should have received a copy of the GNU Lesser General Public
18 -- License along with this library; if not, write to the Free Software
19 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 -- 02110-1301 USA
23 local M = {}
25 -- http://www.lua.org/pil/20.3.html
26 function M.decode (s)
27 r = {}
28 for n,v in s:gmatch ("([^&=]+)=([^&=]+)") do
29 n = M.unescape (n)
30 r[n] = v
31 end
32 return r
33 end
35 -- http://www.lua.org/pil/20.3.html
36 function M.unescape (s)
37 s = s:gsub ('+', ' ')
38 s = s:gsub ('%%(%x%x)', function (h)
39 return string.char (tonumber (h, 16))
40 end)
41 return s
42 end
44 function M.slash_unescape (s)
45 s = s:gsub ('\\(.)', '%1')
46 return s
47 end
49 function M.base64_decode(s)
50 local itbl='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
52 s = s:gsub('[^' .. itbl .. '=]', '')
54 return (s:gsub('.', function(x)
55 local r = ''
57 if (x ~= '=') then
58 local f = (itbl:find(x) - 1)
60 for i = 6, 1, -1 do
61 r = r .. (f % 2 ^ i - f % 2 ^ (i - 1) > 0 and '1' or '0')
62 end
63 end
65 return r;
66 end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
67 local c = 0
69 if (#x == 8) then
70 for i = 1, 8 do
71 c = c + (x:sub(i, i) == '1' and 2 ^ (8 - i) or 0)
72 end
73 end
75 return string.char(c)
76 end))
77 end
79 -- handles
80 -- Check whether a website script can "handle" the specified URL
81 -- Params:
82 -- url .. video page URL
83 -- domains .. table of domain names
84 -- paths .. table of URL path patterns to match
85 -- queries .. table of URL query patterns to match
86 function M.handles(url, domains, paths, queries)
87 if not url or not domains then
88 return false
89 end
90 local U = require 'quvi/url'
91 local t = U.parse(url)
92 -- for k,v in pairs(t) do print(k,v) end
93 local r = M.contains(t.host, domains)
94 if r then
95 if paths then
96 r = M.contains(t.path, paths)
97 end
98 if r then
99 if queries then
100 if t.query then
101 r = M.contains(t.query, queries)
102 else
103 r = false
108 return r
111 function M.contains(s,t)
112 if not s then return false end
113 for k,v in pairs(t) do
114 if s:find(v) then return true end
116 return false
119 function M.ends(s,e) -- http://lua-users.org/wiki/StringRecipes
120 return e == '' or s:sub(-#e) == e
123 function M.is_higher_quality(a,b)
124 if a.height > b.height then
125 if a.width > b.width then
126 if a['bitrate'] then -- Optional: bitrate
127 if a.bitrate > b.bitrate then
128 return true
130 else
131 return true
135 return false
138 function M.is_lower_quality(a,b)
139 if a.height < b.height then
140 if a.width < b.width then
141 if a['bitrate'] then -- Optiona: bitrate
142 if a.bitrate < b.bitrate then
143 return true
145 else
146 return true
150 return false
153 function M.choose_format(self,
154 formats,
155 callback_choose_best,
156 callback_choose_default,
157 callback_to_s)
158 local r_fmt = self.requested_format
160 if r_fmt == 'best' then
161 return callback_choose_best(formats)
164 for _,v in pairs(formats) do
165 if r_fmt == callback_to_s(v) then
166 return v
170 return callback_choose_default(formats)
173 function M.to_timestamp(s) -- Based on <http://is.gd/ee9ZTD>
174 local p = "%a+, (%d+) (%a+) (%d+) (%d+):(%d+):(%d+)"
176 local d,m,y,hh,mm,ss = s:match(p)
177 if not d then error('no match: date') end
179 local MON = {Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8,
180 Sep=9, Oct=10, Nov=11, Dec=12}
182 local m = MON[m]
184 local offset = os.time() - os.time(os.date("!*t"))
186 return os.time({day=d,month=m,year=y,
187 hour=hh,min=mm,sec=ss}) + offset
190 -- For very simple XML value extraction.
191 function M.xml_get(d, e, is_cdata)
192 local p = is_cdata and '.-%w+%[(.-)%].-' or '(.-)'
193 local t = {'<',e,'>', p, '</',e,'>'}
194 return d:match(table.concat(t))
195 or error(table.concat({'no match: element: ',e}))
198 -- For very simple JSON value extraction.
199 function M.json_get(p, e, is_num)
200 local c = is_num and '(%d+)' or '"(.-)"'
201 local t = {'"',e,'":',c}
202 return p:match(table.concat(t)) or ((is_num) and 0 or '')
205 return M
207 -- vim: set ts=4 sw=4 tw=72 expandtab: