share/Makefile.am: Reorganize blocks, comments
[libquvi-scripts.git] / share / lua / common / quvi / util.lua
blob4b8eddb627c4e1c2b297c703cad0fb73e9da8306
1 -- libquvi-scripts
2 -- Copyright (C) 2010-2012 Toni Gundogdu <legatvs@gmail.com>
3 --
4 -- This file is part of libquvi-scripts <http://quvi.sourceforge.net/>.
5 --
6 -- This library is free software; you can redistribute it and/or
7 -- modify it under the terms of the GNU Lesser General Public
8 -- License as published by the Free Software Foundation; either
9 -- version 2.1 of the License, or (at your option) any later version.
11 -- This library is distributed in the hope that it will be useful,
12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 -- Lesser General Public License for more details.
16 -- You should have received a copy of the GNU Lesser General Public
17 -- License along with this library; if not, write to the Free Software
18 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 -- 02110-1301 USA
22 local M = {}
24 --[[
25 Check whether a string A ends with string B.
26 Parameters:
27 a .. String A
28 b .. String B
29 Returns:
30 true if string A ends with string B.
31 ]]--
32 function M.ends(a, b) -- http://lua-users.org/wiki/StringRecipes
33 return a:sub(-#b) == b
34 end
36 --[[
37 Compare quality properties of two media entities. Compares the height, then
38 the width, followed by the bitrate property comparison (if it is set).
39 Parameters:
40 a .. Media entity A
41 b .. Media entity B
42 Returns:
43 true if entity A is the higher quality, otherwise false.
44 ]]--
45 function M.is_higher_quality(a, b)
46 if a.height > b.height then
47 if a.width > b.width then
48 if a['bitrate'] then -- Optional
49 if a.bitrate > b.bitrate then return true end
50 else
51 return true
52 end
53 end
54 end
55 return false
56 end
58 --[[
59 Compare quality properties of two media entities. Compares the height, then
60 the width, followed by the bitrate property comparison (if it is set).
61 Parameters:
62 a .. Media entity A
63 b .. Media entity B
64 Returns:
65 true if entity A is the lower quality, otherwise false.
66 ]]--
67 function M.is_lower_quality(a, b)
68 if a.height < b.height then
69 if a.width < b.width then
70 if a['bitrate'] then -- Optional
71 if a.bitrate < b.bitrate then return true end
72 else
73 return true
74 end
75 end
76 end
77 return false
78 end
80 --[[
81 Choose a media entity best matching the "requested format" which is string
82 set by an application using libquvi API.
83 Parameters:
84 qargs .. Library args (containing .req_format)
85 t .. Table containing the media properties (incl. media stream URLs)
86 cb_best .. Best format callback function
87 cb_def .. Default format callback function
88 cb_to_s .. Format to string callback function
89 Returns:
90 Chosen media entity.
92 The req_format string may be an array of format strings (e.g.
93 "foo,bar,baz").
95 A format string may be:
96 - default .. Use whatever a media script determines the 'default'
97 - croak .. Fail if nothing matched
98 - best .. Whatever a media script determines to be the 'best'
100 By default, the function falls back to 'default' format if nothing
101 matches. To override this, 'croak' may be used to trigger an error
102 instead.
103 ]]--
104 function M.choose_format(qargs, t, cb_default, cb_best, cb_fmt_to_s)
105 for f in M.tokenize(qargs.req_format, '[%w-_]+') do
106 if f == 'croak' then error('no match: requested format')
107 elseif f == 'best' then return cb_best(t)
108 else
109 for _,v in pairs(t) do -- Match to user format string.
110 if f == cb_fmt_to_s(v) then return v end
114 return cb_default(t) -- Fall back to the 'default' format.
117 --[[
118 Try to match an array of patterns to a string.
119 Parameters:
120 t .. Array of patterns (if nil, simply return false)
121 s .. A string
122 Returns:
123 true if a pattern matched, otherwise false.
124 ]]--
125 function M.match_any(t, s)
126 if not s then return false end
127 for _,p in pairs(t) do
128 if s:match(p) then return true end
130 return false
133 --[[
134 Tokenize a string.
135 Parameters:
136 s .. String to tokenize
137 p .. Pattern (e.g. "[%w-_]+")
138 Returns:
139 An array of tokens.
140 ]]--
141 function M.tokenize(s, p)
142 return s:gmatch(p)
145 --[[
146 Convert a string to a timestamp.
147 Parameters:
148 s .. String to convert
149 Returns:
150 Converted string.
151 ]]--
152 function M.to_timestamp(s) -- Based on <http://is.gd/ee9ZTD>
153 local p = "%a+, (%d+) (%a+) (%d+) (%d+):(%d+):(%d+)"
155 local d,m,y,hh,mm,ss = s:match(p)
156 if not d then error('no match: date') end
158 local MON = {Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8,
159 Sep=9, Oct=10, Nov=11, Dec=12}
161 local m = MON[m]
162 local offset = os.time() - os.time(os.date("!*t"))
164 return os.time({day=d,month=m,year=y,
165 hour=hh,min=mm,sec=ss}) + offset
168 --[[
169 Decode a string.
170 Parameters:
171 s .. String to decode
172 Returns:
173 Decoded string.
174 ]]--
175 function M.decode(s) -- http://www.lua.org/pil/20.3.html
176 r = {}
177 for n,v in s:gmatch ("([^&=]+)=([^&=]+)") do
178 n = M.unescape(n)
179 r[n] = v
181 return r
184 --[[
185 Unescape a string.
186 Parameters:
187 s .. String to unescape
188 Returns:
189 Unescaped string
190 ]]--
191 function M.unescape(s) -- http://www.lua.org/pil/20.3.html
192 s = s:gsub('+', ' ')
193 return (s:gsub('%%(%x%x)',
194 function(h)
195 return string.char(tonumber(h, 16))
196 end))
199 --[[
200 Unescape slashed string.
201 Parameters:
202 s .. String to unescape
203 Returns:
204 Unescaped string
205 ]]--
206 function M.slash_unescape(s)
207 return (s:gsub('\\(.)', '%1'))
210 return M
212 -- vim: set ts=2 sw=2 tw=72 expandtab: