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