1 --[==========================================================================[
2 httprequests.lua: code for processing httprequests commands and output
3 --[==========================================================================[
4 Copyright (C) 2007 the VideoLAN team
7 Authors: Antoine Cellerier <dionoea at videolan dot org>
8 Rob Jonson <rob at hobbyistsoftware.com>
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.
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.
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 --]==========================================================================]
25 module("httprequests",package.seeall)
30 local function stripslashes(s)
31 return string.gsub(s,"\\(.)","%1")
34 function strsplit(text, delimiter)
35 local strfind = string.find
36 local strsub = string.sub
37 local tinsert = table.insert
40 if strfind("", delimiter, 1) then -- this would result in endless loops
41 error("delimiter matches empty string!")
46 local first, last = strfind(text, delimiter, pos)
47 if first then -- found?
48 tinsert(list,i, strsub(text, pos, first-1))
51 tinsert(list,i, strsub(text, pos))
59 --main function to process commands sent with the request
61 processcommands = function ()
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
72 if command == "in_play" then
74 vlc.msg.err( "<options>" )
75 for a,b in ipairs(options) do
78 vlc.msg.err( "</options>" )
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
89 elseif command == "pl_pause" then
90 if vlc.playlist.status() == "stopped" then
99 elseif command == "pl_forcepause" then
100 if vlc.playlist.status() == "playing" then
103 elseif command == "pl_forceresume" then
104 if vlc.playlist.status() == "paused" then
107 elseif command == "pl_stop" then
109 elseif command == "pl_next" then
111 elseif command == "pl_previous" then
113 elseif command == "pl_delete" then
114 vlc.playlist.delete(id)
115 elseif command == "pl_empty" then
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
123 elseif command == "pl_repeat" then
124 vlc.playlist.repeat_()
125 elseif command == "pl_sd" then
126 if vlc.sd.is_loaded(val) then
131 elseif command == "fullscreen" then
132 vlc.video.fullscreen()
133 elseif command == "snapshot" then
135 elseif command == "volume" then
137 elseif command == "seek" then
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)
145 elseif command == "rate" then
146 if vlc.object.input() and tonumber(val) >= 0 then
147 vlc.var.set(vlc.object.input(),"rate",val)
149 elseif command == "subdelay" then
150 if vlc.object.input() then
151 vlc.var.set(vlc.object.input(),"spu-delay",val)
162 --utilities for formatting output
164 local function xmlString(s)
165 if (type(s)=="string") then
166 return vlc.strings.convert_xml_special_chars(s)
172 local printJsonKeyValue = function (k,v,indent)
174 for i=1,indent do print(" ") end
176 print("\""..k.."\":")
179 if (type(v)=="number") then
181 elseif (type(v)=="table") then
182 if (v._array==NULL) then
184 printTableAsJson(v,indent+2)
188 printArrayAsJson(v._array,indent+2)
192 print("\""..xmlString(v).."\"")
197 printArrayAsJson = function(array,indent)
199 for i,v in ipairs(array) do
200 if not first then print(",") end
201 printJsonKeyValue(NULL,v,indent)
206 printTableAsJson = function (dict,indent)
208 for k,v in pairs(dict) do
209 if not first then print(",") end
210 printJsonKeyValue(k,v,indent)
215 local printXmlKeyValue = function (k,v,indent)
217 for i=1,indent do print(" ") end
222 if (type(v)=="table") then
223 printTableAsXml(v,indent+2)
233 printTableAsXml = function (dict,indent)
234 for k,v in pairs(dict) do
235 printXmlKeyValue(k,v,indent)
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
253 getplaylist = function ()
256 if _GET["search"] then
257 if _GET["search"] ~= "" then
258 _G.search_key = _GET["search"]
262 local key = vlc.strings.decode_uri(_GET["search"])
263 p = vlc.playlist.search(key)
265 p = vlc.playlist.get()
268 --logTable(p) --Uncomment to debug
273 parseplaylist = function (item)
274 if item.flags.disabled then return end
276 if (item.children) then
278 local name = vlc.strings.convert_xml_special_chars(item.name or "")
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"
285 --store children in an array
286 --we use _array as a proxy for arrays
288 result.children._array={}
290 for _, child in ipairs(item.children) do
291 local nextChild=parseplaylist(child)
292 table.insert(result.children._array,nextChild)
298 local name, path = vlc.strings.convert_xml_special_chars(item.name or "", item.path or "")
299 local current_item = vlc.input.item()
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"
308 result["type"]="leaf"
309 result.id=tostring(item.id)
310 result.uri=tostring(path)
312 result.ro=item.flags.ro and "ro" or "rw"
313 result.duration=math.floor(item.duration)
320 playlisttable = function ()
322 local basePlaylist=getplaylist()
324 return parseplaylist(basePlaylist)
328 getstatus = function (includecategories)
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()
339 --update api version when new data/commands added
341 s.version=vlc.misc.version()
342 s.volume=vlc.volume.get()
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")
361 s.fullscreen=vlc.var.get(vout,"fullscreen")
366 local filters=vlc.var.get(aout,"audio-filter")
367 local temp=strsplit(filters,":")
370 for i,j in pairs(temp) do
371 s.audiofilters['filter_'..id]=j
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")
380 if (includecategories and item) then
382 s.information.category={}
383 s.information.category.meta=item:metas()
385 local info = item:info()
386 for k, v in pairs(info) do
388 for k2, v2 in pairs(v) do
389 local tag = string.gsub(k2," ","_")
390 streamTable[xmlString(tag)]=xmlString(v2)
393 s.information.category[xmlString(k)]=streamTable
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)