]> git.sesse.net Git - vlc/blob - share/lua/intf/modules/httprequests.lua
Add json capabilities to http requests
[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 --main function to process commands sent with the request
35
36 processcommands = function ()
37         
38         local input = _GET['input']
39         local command = _GET['command']
40         local id = tonumber(_GET['id'] or -1)
41         local val = _GET['val']
42         local options = _GET['option']
43         if type(options) ~= "table" then -- Deal with the 0 or 1 option case
44           options = { options }
45         end
46         
47         if command == "in_play" then
48           --[[
49           vlc.msg.err( "<options>" )
50           for a,b in ipairs(options) do
51                 vlc.msg.err(b)
52           end
53           vlc.msg.err( "</options>" )
54           --]]
55           vlc.playlist.add({{path=stripslashes(input),options=options}})
56         elseif command == "in_enqueue" then
57           vlc.playlist.enqueue({{path=stripslashes(input),options=options}})
58         elseif command == "pl_play" then
59           if id == -1 then
60                 vlc.playlist.play()
61           else
62                 vlc.playlist.goto(id)
63           end
64         elseif command == "pl_pause" then
65           if vlc.playlist.status() == "stopped" then
66                 if id == -1 then
67                   vlc.playlist.play()
68                 else
69                   vlc.playlist.goto(id)
70                 end
71           else
72                 vlc.playlist.pause()
73           end
74         elseif command == "pl_forcepause" then
75           if vlc.playlist.status() == "playing" then
76                 vlc.playlist.pause()
77           end
78         elseif command == "pl_forceresume" then
79           if vlc.playlist.status() == "paused" then
80                 vlc.playlist.pause()
81           end
82         elseif command == "pl_stop" then
83           vlc.playlist.stop()
84         elseif command == "pl_next" then
85           vlc.playlist.next()
86         elseif command == "pl_previous" then
87           vlc.playlist.prev()
88         elseif command == "pl_delete" then
89           vlc.playlist.delete(id)
90         elseif command == "pl_empty" then
91           vlc.playlist.clear()
92         elseif command == "pl_sort" then
93           vlc.playlist.sort( val, id > 0 )
94         elseif command == "pl_random" then
95           vlc.playlist.random()
96         elseif command == "pl_loop" then
97           vlc.playlist.loop()
98         elseif command == "pl_repeat" then
99           vlc.playlist.repeat_()
100         elseif command == "pl_sd" then
101           if vlc.sd.is_loaded(val) then
102                 vlc.sd.remove(val)
103           else
104                 vlc.sd.add(val)
105           end
106         elseif command == "fullscreen" then
107           vlc.video.fullscreen()
108         elseif command == "snapshot" then
109           common.snapshot()
110         elseif command == "volume" then
111           common.volume(val)
112         elseif command == "seek" then
113           common.seek(val)
114         elseif command == "key" then
115           common.hotkey("key-"..val)
116         elseif command == "audiodelay" then
117           if vlc.object.input() and val then
118            vlc.var.set(vlc.object.input(),"audio-delay",val)
119           end
120         elseif command == "rate" then
121           if vlc.object.input() and tonumber(val) >= 0 then
122            vlc.var.set(vlc.object.input(),"rate",val)
123           end
124         elseif command == "subdelay" then
125           if vlc.object.input() then
126            vlc.var.set(vlc.object.input(),"spu-delay",val)
127           end
128         end
129         
130         local input = nil
131         local command = nil
132         local id = nil
133         local val = nil
134
135 end
136
137 --utilities for formatting output
138
139 local function xmlString(s)
140   if (type(s)=="string") then
141         return vlc.strings.convert_xml_special_chars(s)
142   else
143         return tostring(s)
144   end
145 end
146
147 local printJsonKeyValue = function (k,v,indent)
148         print("\n")
149         for i=1,indent do print(" ") end
150         if (k) then
151                 print("\""..k.."\":")
152         end
153         
154         if (type(v)=="number") then
155                 print(xmlString(v))
156         elseif (type(v)=="table") then 
157                  if (v._array==NULL) then                       
158                 print("{\n")
159                 printTableAsJson(v,indent+2)
160                 print("\n}")  
161           else 
162                 print("[")
163                 printArrayAsJson(v._array,indent+2)
164                 print("\n]") 
165           end
166         else
167         print("\""..xmlString(v).."\"")
168     end
169 end
170
171
172 printArrayAsJson = function(array,indent)
173         first=true
174         for i,v in ipairs(array) do
175                 if not first then print(",") end
176                 printJsonKeyValue(NULL,v,indent)        
177                 first=false
178         end
179 end
180
181 printTableAsJson = function (dict,indent)
182         first=true
183         for k,v in pairs(dict) do
184                 if not first then print(",") end
185                 printJsonKeyValue(k,v,indent)
186                 first=false
187     end
188 end
189
190 local printXmlKeyValue = function (k,v,indent)
191         print("\n")
192         for i=1,indent do print(" ") end
193         if (k) then
194                 print("<"..k..">")
195         end
196         
197         if (type(v)=="table") then
198                 printTableAsXml(v,indent+2)
199         else
200         print(xmlString(v))
201     end
202     
203     if (k) then
204                 print("</"..k..">")
205         end
206 end
207
208 printTableAsXml = function (dict,indent)
209         for k,v in pairs(dict) do
210         printXmlKeyValue(k,v,indent)
211     end
212 end
213
214 --[[
215 function logTable(t,pre)
216   local pre = pre or ""
217   for k,v in pairs(t) do
218     vlc.msg.err(pre..tostring(k).." : "..tostring(v))
219     if type(v) == "table" then
220       a(v,pre.."  ")
221     end
222   end
223 end
224 --]]
225
226 --main accessors
227
228 getplaylist = function ()
229         local p
230         
231         if _GET["search"] then
232           if _GET["search"] ~= "" then
233                 _G.search_key = _GET["search"]
234           else
235                 _G.search_key = nil
236           end
237           local key = vlc.strings.decode_uri(_GET["search"])
238           p = vlc.playlist.search(key)
239         else
240           p = vlc.playlist.get()
241         end
242         
243         --logTable(p) --Uncomment to debug
244         
245         return p
246 end
247
248 parseplaylist = function (item)
249         if item.flags.disabled then return end
250         
251         if (item.children) then
252                 local result={}
253                 local name = vlc.strings.convert_xml_special_chars(item.name or "")
254                 
255                 result["type"]="node"
256                 result.id=tostring(item.id)
257                 result.name=tostring(name)
258                 result.ro=item.flags.ro and "ro" or "rw"
259                 
260                 --store children in an array
261                 --we use _array as a proxy for arrays
262                 result.children={}
263                 result.children._array={}
264                 
265                 for _, child in ipairs(item.children) do
266                         local nextChild=parseplaylist(child)
267             table.insert(result.children._array,nextChild)
268         end 
269                 
270                 return result
271         else
272                 local result={}
273                 local name, path = vlc.strings.convert_xml_special_chars(item.name or "", item.path or "")
274                 local current_item = vlc.input.item()
275                 
276                 -- Is the item the one currently played
277                 if(current_item ~= nil) then
278             if(vlc.input.item().uri(current_item) == path) then
279                 result.current = "current"
280             end
281         end
282                 
283                 result["type"]="leaf"
284                 result.id=tostring(item.id)
285                 result.uri=tostring(path)
286                 result.name=name
287                 result.ro=item.flags.ro and "ro" or "rw"
288                 result.duration=math.floor(item.duration)
289                 
290                 return result
291         end
292
293 end
294
295 playlisttable = function ()
296
297         local basePlaylist=getplaylist()
298         
299         return parseplaylist(basePlaylist)
300 end
301
302
303 getstatus = function (includecategories)
304
305
306 local input = vlc.object.input()
307 local item = vlc.input.item()
308 local playlist = vlc.object.playlist()
309 local vout = input and vlc.object.find(input,'vout','child')
310
311         local s ={}
312         
313         --update api version when new data/commands added
314         s.apiversion=1
315         s.version=vlc.misc.version()
316         s.volume=vlc.volume.get()
317         
318         if input then 
319                 s.length=math.floor(vlc.var.get(input,"length"))
320                 s.time=math.floor(vlc.var.get(input,"time"))
321                 s.position=vlc.var.get(input,"position")
322                 s.audiodelay=vlc.var.get(input,"audio-delay")
323                 s.rate=vlc.var.get(input,"rate")
324                 s.subtitledelay=vlc.var.get(input,"spu-delay")
325         else 
326                 s.length=0
327                 s.time=0
328                 s.position=0
329                 s.audiodelay=0
330                 s.rate=1
331                 s.subtitledelay=0
332         end
333         
334         if vout then
335                 s.fullscreen=vlc.var.get(vout,"fullscreen")
336         else
337                 s.fullscreen=0
338         end
339         
340         s.state=vlc.playlist.status()
341         s.random=vlc.var.get(playlist,"random")
342         s.loop=vlc.var.get(playlist,"loop")
343         s["repeat"]=vlc.var.get(playlist,"repeat")
344         
345         if (includecategories and item) then
346                 s.information={}
347                 s.information.category={}
348                 s.information.category.meta=item:metas()
349                 
350                 local info = item:info()
351                 for k, v in pairs(info) do
352                         local streamTable={}
353                         for k2, v2 in pairs(v) do
354                                 local tag = string.gsub(k2," ","_")
355                                 streamTable[xmlString(tag)]=xmlString(v2)
356                         end
357                         
358                         s.information.category[xmlString(k)]=streamTable
359                 end
360                 
361                 s.stats={}
362                 
363                 local statsdata = item:stats()
364         for k,v in pairs(statsdata) do
365                 local tag = string.gsub(k,"_","")
366         s.stats[tag]=xmlString(v)
367       end
368                 
369                 
370         end
371
372         return s
373 end