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