1
2-- libquvi-scripts v0.4.21
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.
11--
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.
16--
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
21--
22
23local M = {}
24
25-- http://www.lua.org/pil/20.3.html
26function 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
33end
34
35-- http://www.lua.org/pil/20.3.html
36function 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
42end
43
44function M.slash_unescape (s)
45    s = s:gsub ('\\(.)', '%1')
46    return s
47end
48
49function M.base64_decode(s)
50    local itbl='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
51
52    s = s:gsub('[^' .. itbl .. '=]', '')
53
54    return (s:gsub('.', function(x)
55        local r = ''
56
57        if (x ~= '=') then
58            local f = (itbl:find(x) - 1)
59
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
64
65        return r;
66    end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
67        local c = 0
68
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
74
75        return string.char(c)
76    end))
77end
78
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
86function 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
104                end
105            end
106        end
107    end
108    return r
109end
110
111function 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
115    end
116    return false
117end
118
119function M.ends(s,e) -- http://lua-users.org/wiki/StringRecipes
120    return e == '' or s:sub(-#e) == e
121end
122
123function 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
129                end
130            else
131                return true
132            end
133        end
134    end
135    return false
136end
137
138function 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
144                end
145            else
146                return true
147            end
148        end
149    end
150    return false
151end
152
153function 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
159
160    if r_fmt == 'best' then
161        return callback_choose_best(formats)
162    end
163
164    for _,v in pairs(formats) do
165        if r_fmt == callback_to_s(v) then
166            return v
167        end
168    end
169
170    return callback_choose_default(formats)
171end
172
173function M.to_timestamp(s) -- Based on <http://is.gd/ee9ZTD>
174    local p = "%a+, (%d+) (%a+) (%d+) (%d+):(%d+):(%d+)"
175
176    local d,m,y,hh,mm,ss = s:match(p)
177    if not d then error('no match: date') end
178
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}
181
182    local m = MON[m]
183
184    local offset = os.time() - os.time(os.date("!*t"))
185
186    return os.time({day=d,month=m,year=y,
187                    hour=hh,min=mm,sec=ss}) + offset
188end
189
190-- For very simple XML value extraction.
191function 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}))
196end
197
198-- For very simple JSON value extraction.
199function 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 '')
203end
204
205return M
206
207-- vim: set ts=4 sw=4 tw=72 expandtab:
208