]> git.sesse.net Git - vlc/blob - share/lua/intf/modules/httprequests.lua
use make_uri on mrl inputs
[vlc] / share / lua / intf / modules / httprequests.lua
1 --[==========================================================================[
2  httprequests.lua: code for processing httprequests commands and output
3 --[==========================================================================[
4  Copyright (C) 2007 the VideoLAN team
5  $Id$
6
7  Authors: Antoine Cellerier <dionoea at videolan dot org>
8  Rob Jonson <rob at hobbyistsoftware.com>
9
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License
21  along with this program; if not, write to the Free Software
22  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 --]==========================================================================]
24
25 module("httprequests",package.seeall)
26
27
28
29
30 --Round the number to the specified precision
31 function round(what, precision)
32   if what then return math.floor(what*math.pow(10,precision)+0.5) / math.pow(10,precision) else return "" end
33 end
34
35 --split text where it matches the delimiter
36 function strsplit(text, delimiter)
37         local strfind = string.find
38         local strsub = string.sub
39         local tinsert = table.insert
40         local list = {}
41         local pos = 1
42         if strfind("", delimiter, 1) then -- this would result in endless loops
43                 error("delimiter matches empty string!")
44         end
45         local i=1
46         while 1 do
47                 i=i+1
48                 local first, last = strfind(text, delimiter, pos)
49                 if first then -- found?
50                         tinsert(list,i, strsub(text, pos, first-1))
51                         pos = last+1
52                 else
53                         tinsert(list,i, strsub(text, pos))
54                 break
55                 end
56         end
57         return list
58 end
59
60 function round(what, precision)
61 if what then return math.floor(what*math.pow(10,precision)+0.5) / math.pow(10,precision) else return "" end
62 end
63
64 --main function to process commands sent with the request
65
66 processcommands = function ()
67
68         local input = _GET['input']
69         local command = _GET['command']
70         local id = tonumber(_GET['id'] or -1)
71         local val = _GET['val']
72         local options = _GET['option']
73         local band = _GET['band']
74         if type(options) ~= "table" then -- Deal with the 0 or 1 option case
75           options = { options }
76         end
77
78         if command == "in_play" then
79           --[[
80           vlc.msg.err( "<options>" )
81           for a,b in ipairs(options) do
82                 vlc.msg.err(b)
83           end
84           vlc.msg.err( "</options>" )
85           --]]
86           vlc.playlist.add({{path=vlc.strings.make_uri(input),options=options}})
87         elseif command == "addsubtitle" then
88           vlc.input.add_subtitle (vlc.strings.make_uri(val))
89         elseif command == "in_enqueue" then
90           vlc.playlist.enqueue({{path=vlc.strings.make_uri(input),options=options}})
91         elseif command == "pl_play" then
92           if id == -1 then
93                 vlc.playlist.play()
94           else
95                 vlc.playlist.goto(id)
96           end
97         elseif command == "pl_pause" then
98           if vlc.playlist.status() == "stopped" then
99                 if id == -1 then
100                   vlc.playlist.play()
101                 else
102                   vlc.playlist.goto(id)
103                 end
104           else
105                 vlc.playlist.pause()
106           end
107         elseif command == "pl_forcepause" then
108           if vlc.playlist.status() == "playing" then
109                 vlc.playlist.pause()
110           end
111         elseif command == "pl_forceresume" then
112           if vlc.playlist.status() == "paused" then
113                 vlc.playlist.pause()
114           end
115         elseif command == "pl_stop" then
116           vlc.playlist.stop()
117         elseif command == "pl_next" then
118           vlc.playlist.next()
119         elseif command == "pl_previous" then
120           vlc.playlist.prev()
121         elseif command == "pl_delete" then
122           vlc.playlist.delete(id)
123         elseif command == "pl_empty" then
124           vlc.playlist.clear()
125         elseif command == "pl_sort" then
126           vlc.playlist.sort( val, id > 0 )
127         elseif command == "pl_random" then
128           vlc.playlist.random()
129         elseif command == "pl_loop" then
130         --if loop is set true, then repeat needs to be set false
131           if vlc.playlist.loop() then
132                 vlc.playlist.repeat_("off")
133           end
134         elseif command == "pl_repeat" then
135         --if repeat is set true, then loop needs to be set false
136           if vlc.playlist.repeat_() then
137                 vlc.playlist.loop("off")
138           end
139         elseif command == "pl_sd" then
140           if vlc.sd.is_loaded(val) then
141                 vlc.sd.remove(val)
142           else
143                 vlc.sd.add(val)
144           end
145         elseif command == "fullscreen" then
146           vlc.video.fullscreen()
147         elseif command == "snapshot" then
148           common.snapshot()
149         elseif command == "volume" then
150           common.volume(val)
151         elseif command == "seek" then
152           common.seek(val)
153         elseif command == "key" then
154           common.hotkey("key-"..val)
155         elseif command == "audiodelay" then
156           if vlc.object.input() and val then
157            vlc.var.set(vlc.object.input(),"audio-delay",val)
158           end
159         elseif command == "rate" then
160           if vlc.object.input() and tonumber(val) >= 0 then
161            vlc.var.set(vlc.object.input(),"rate",val)
162           end
163         elseif command == "subdelay" then
164           if vlc.object.input() then
165            vlc.var.set(vlc.object.input(),"spu-delay",val)
166           end
167         elseif command == "aspectratio" then
168           if vlc.object.vout() then
169            vlc.var.set(vlc.object.vout(),"aspect-ratio",val)
170           end
171         elseif command == "preamp" then
172           vlc.equalizer.preampset(val)
173         elseif command == "equalizer" then
174           vlc.equalizer.equalizerset(band,val)
175         elseif command == "enableeq" then
176           if val == '0' then vlc.equalizer.enable(false) else vlc.equalizer.enable(true) end
177         elseif command == "setpreset" then 
178           vlc.equalizer.setpreset(val)
179         end
180
181         local input = nil
182         local command = nil
183         local id = nil
184         local val = nil
185
186 end
187
188 --utilities for formatting output
189
190 function xmlString(s)
191   if (type(s)=="string") then
192         return vlc.strings.convert_xml_special_chars(s)
193   else
194         return tostring(s)
195   end
196 end
197
198 local printJsonKeyValue = function (k,v,indent)
199         print("\n")
200         for i=1,indent do print(" ") end
201         if (k) then
202                 print("\""..k.."\":")
203         end
204
205         if (type(v)=="number") then
206                 print(xmlString(v))
207         elseif (type(v)=="table") then
208                  if (v._array==NULL) then
209                 print("{\n")
210                 printTableAsJson(v,indent+2)
211                 print("\n}")
212           else
213                 print("[")
214                 printArrayAsJson(v._array,indent+2)
215                 print("\n]")
216           end
217         else
218         print("\""..xmlString(v).."\"")
219     end
220 end
221
222
223 printArrayAsJson = function(array,indent)
224         first=true
225         for i,v in ipairs(array) do
226                 if not first then print(",") end
227                 printJsonKeyValue(NULL,v,indent)
228                 first=false
229         end
230 end
231
232 printTableAsJson = function (dict,indent)
233         first=true
234         for k,v in pairs(dict) do
235                 if not first then print(",") end
236                 printJsonKeyValue(k,v,indent)
237                 first=false
238     end
239 end
240
241 local printXmlKeyValue = function (k,v,indent)
242         print("\n")
243         for i=1,indent do print(" ") end
244         if (k) then
245                 print("<"..k..">")
246         end
247
248         if (type(v)=="table") then
249                 printTableAsXml(v,indent+2)
250         else
251         print(xmlString(v))
252     end
253
254     if (k) then
255                 print("</"..xmlString(k)..">")
256         end
257 end
258
259 printTableAsXml = function (dict,indent)
260         for k,v in pairs(dict) do
261         printXmlKeyValue(k,v,indent)
262     end
263 end
264
265 --[[
266 function logTable(t,pre)
267   local pre = pre or ""
268   for k,v in pairs(t) do
269     vlc.msg.err(pre..tostring(k).." : "..tostring(v))
270     if type(v) == "table" then
271       a(v,pre.."  ")
272     end
273   end
274 end
275 --]]
276
277 --main accessors
278
279 getplaylist = function ()
280         local p
281
282         if _GET["search"] then
283           if _GET["search"] ~= "" then
284                 _G.search_key = _GET["search"]
285           else
286                 _G.search_key = nil
287           end
288           local key = vlc.strings.decode_uri(_GET["search"])
289           p = vlc.playlist.search(key)
290         else
291           p = vlc.playlist.get()
292         end
293
294         --logTable(p) --Uncomment to debug
295
296         return p
297 end
298
299 parseplaylist = function (item)
300         if item.flags.disabled then return end
301
302         if (item.children) then
303                 local result={}
304                 local name = (item.name or "")
305
306                 result["type"]="node"
307                 result.id=tostring(item.id)
308                 result.name=tostring(name)
309                 result.ro=item.flags.ro and "ro" or "rw"
310
311                 --store children in an array
312                 --we use _array as a proxy for arrays
313                 result.children={}
314                 result.children._array={}
315
316                 for _, child in ipairs(item.children) do
317                         local nextChild=parseplaylist(child)
318             table.insert(result.children._array,nextChild)
319         end
320
321                 return result
322         else
323                 local result={}
324                 local name, path = item.name or ""
325                 local path = item.path or ""
326                 local current_item = vlc.input.item()
327
328                 -- Is the item the one currently played
329                 if(current_item ~= nil) then
330             if(vlc.input.item().uri(current_item) == path) then
331                 result.current = "current"
332             end
333         end
334
335                 result["type"]="leaf"
336                 result.id=tostring(item.id)
337                 result.uri=tostring(path)
338                 result.name=name
339                 result.ro=item.flags.ro and "ro" or "rw"
340                 result.duration=math.floor(item.duration)
341
342                 return result
343         end
344
345 end
346
347 playlisttable = function ()
348
349         local basePlaylist=getplaylist()
350
351         return parseplaylist(basePlaylist)
352 end
353
354 getbrowsetable = function ()
355
356         local dir = nil
357         local uri = _GET["uri"]
358         --uri takes precedence, but fall back to dir
359         if uri then
360                 dir = vlc.strings.make_path(uri)
361         else
362                 dir = _GET["dir"]
363         end
364
365         local result={}
366         --paths are returned as an array of elements
367         result.element={}
368         result.element._array={}
369
370         if dir then
371                 if dir == "~" then dir = vlc.misc.homedir() end
372                         dir = common.realpath(dir.."/")
373                         local d = vlc.net.opendir(dir)
374                         table.sort(d)
375
376                         for _,f in pairs(d) do
377                                 if f == ".." or not string.match(f,"^%.") then
378                                 local df = common.realpath(dir..f)
379                                 local s = vlc.net.stat(df)
380                                 local path, name =  df, f
381                                 local element={}
382
383                                 for k,v in pairs(s) do
384                                         element[k]=v
385                                 end
386                                 element["path"]=path
387                                 element["name"]=name
388
389                                 local uri=vlc.strings.make_uri(df)
390                                 --windows paths are returned with / separators, but make_uri expects \ for windows and returns nil
391                                 if not uri then
392                                         --convert failed path to windows format and try again
393                                         path=string.gsub(path,"/","\\")
394                                         uri=vlc.strings.make_uri(df)
395                                 end
396                                 element["uri"]=uri
397
398                                 table.insert(result.element._array,element)
399                         end
400
401                 end
402         end
403
404         return result;
405 end
406
407
408 getstatus = function (includecategories)
409
410
411 local input = vlc.object.input()
412 local item = vlc.input.item()
413 local playlist = vlc.object.playlist()
414 local vout = vlc.object.vout()
415 local aout = vlc.object.aout()
416
417         local s ={}
418
419         --update api version when new data/commands added
420         s.apiversion=1
421         s.version=vlc.misc.version()
422         s.volume=vlc.volume.get()
423
424         if input then
425                 s.length=math.floor(vlc.var.get(input,"length"))
426                 s.time=math.floor(vlc.var.get(input,"time"))
427                 s.position=vlc.var.get(input,"position")
428                 s.audiodelay=vlc.var.get(input,"audio-delay")
429                 s.rate=vlc.var.get(input,"rate")
430                 s.subtitledelay=vlc.var.get(input,"spu-delay")
431         else
432                 s.length=0
433                 s.time=0
434                 s.position=0
435                 s.audiodelay=0
436                 s.rate=1
437                 s.subtitledelay=0
438         end
439
440         if vout then
441                 s.fullscreen=vlc.var.get(vout,"fullscreen")
442                 s.aspectratio=vlc.var.get(vout,"aspect-ratio");
443                 if s.aspectratio=="" then s.aspectratio = "default" end
444         else
445                 s.fullscreen=0
446         end
447
448         if aout then
449                 local filters=vlc.var.get(aout,"audio-filter")
450                 local temp=strsplit(filters,":")
451                 s.audiofilters={}
452                 local id=0
453                 for i,j in pairs(temp) do
454                         s.audiofilters['filter_'..id]=j
455                         id=id+1
456                 end
457         end
458
459         s.videoeffects={}
460         s.videoeffects.hue=round(vlc.config.get("hue"),2)
461         s.videoeffects.brightness=round(vlc.config.get("brightness"),2)
462         s.videoeffects.contrast=round(vlc.config.get("contrast"),2)
463         s.videoeffects.saturation=round(vlc.config.get("saturation"),2)
464         s.videoeffects.gamma=round(vlc.config.get("gamma"),2)
465
466         s.state=vlc.playlist.status()
467         s.random=vlc.var.get(playlist,"random")
468         s.loop=vlc.var.get(playlist,"loop")
469         s["repeat"]=vlc.var.get(playlist,"repeat")
470
471         s.equalizer={}
472                 s.equalizer.preamp=round(vlc.equalizer.preampget(),2)
473                 s.equalizer.bands=vlc.equalizer.equalizerget()
474                 if s.equalizer.bands ~= null then
475                         for k,i in pairs(s.equalizer.bands) do s.equalizer.bands[k]=round(i,2) end
476                         s.equalizer.presets=vlc.equalizer.presets()
477                 end
478
479         if (includecategories and item) then
480                 s.information={}
481                 s.information.category={}
482                 s.information.category.meta=item:metas()
483
484                 local info = item:info()
485                 for k, v in pairs(info) do
486                         local streamTable={}
487                         for k2, v2 in pairs(v) do
488                                 local tag = string.gsub(k2," ","_")
489                                 streamTable[tag]=v2
490                         end
491
492                         s.information.category[k]=streamTable
493                 end
494
495                 s.stats={}
496
497                 local statsdata = item:stats()
498         for k,v in pairs(statsdata) do
499                 local tag = string.gsub(k,"_","")
500         s.stats[tag]=v
501       end
502         end
503         return s
504 end
505