File: httprequests.lua

package info (click to toggle)
vlc 3.0.23-2
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 208,024 kB
  • sloc: ansic: 443,448; cpp: 111,223; objc: 36,399; sh: 6,737; makefile: 6,627; javascript: 4,902; xml: 1,611; asm: 1,355; yacc: 644; python: 321; lex: 88; perl: 77; sed: 16
file content (572 lines) | stat: -rw-r--r-- 16,602 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
--[==========================================================================[
 httprequests.lua: code for processing httprequests commands and output
--[==========================================================================[
 Copyright (C) 2007 the VideoLAN team

 Authors: Antoine Cellerier <dionoea at videolan dot org>
 Rob Jonson <rob at hobbyistsoftware.com>

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
--]==========================================================================]

local httprequests = {}

local common = require ("common")
local dkjson = require ("dkjson")



--Round the number to the specified precision
function round(what, precision)
    if type(what) == "string" then
        what = common.us_tonumber(what)
    end
    if type(what) == "number" then
        return math.floor(what*math.pow(10,precision)+0.5) / math.pow(10,precision)
    end
    return nil
end
httprequests.round = round

--split text where it matches the delimiter
function strsplit(text, delimiter)
    local strfind = string.find
    local strsub = string.sub
    local tinsert = table.insert
    local list = {}
    local pos = 1
    if strfind("", delimiter, 1) then -- this would result in endless loops
        error("delimiter matches empty string!")
    end
    local i=1
    while 1 do
        local first, last = strfind(text, delimiter, pos)
        if first then -- found?
            tinsert(list,i, strsub(text, pos, first-1))
            pos = last+1
        else
            tinsert(list,i, strsub(text, pos))
            break
        end
        i = i+1
    end
    return list
end
httprequests.strsplit = strsplit

--main function to process commands sent with the request

processcommands = function ()

    local input = _GET['input']
    local command = _GET['command']
    local id = tonumber(_GET['id'] or -1)
    local val = _GET['val']
    local options = _GET['option']
    local band = tonumber(_GET['band'])
    local name = _GET['name']
    local duration = tonumber(_GET['duration'])
    if type(options) ~= "table" then -- Deal with the 0 or 1 option case
        options = { options }
    end

    if command == "in_play" then
        --[[
        vlc.msg.err( "<options>" )
        for a,b in ipairs(options) do
        vlc.msg.err(b)
        end
        vlc.msg.err( "</options>" )
        --]]
        vlc.playlist.add({{path=vlc.strings.make_uri(input),options=options,name=name,duration=duration}})
    elseif command == "addsubtitle" then
        vlc.input.add_subtitle (val)
    elseif command == "in_enqueue" then
        vlc.playlist.enqueue({{path=vlc.strings.make_uri(input),options=options,name=name,duration=duration}})
    elseif command == "pl_play" then
        if id == -1 then
            vlc.playlist.play()
        else
            vlc.playlist.gotoitem(id)
        end
    elseif command == "pl_pause" then
        if vlc.playlist.status() == "stopped" then
            if id == -1 then
                vlc.playlist.play()
            else
                vlc.playlist.gotoitem(id)
            end
        else
            vlc.playlist.pause()
        end
    elseif command == "pl_forcepause" then
        if vlc.playlist.status() == "playing" then
            vlc.playlist.pause()
        end
    elseif command == "pl_forceresume" then
        if vlc.playlist.status() == "paused" then
            vlc.playlist.pause()
        end
    elseif command == "pl_stop" then
        vlc.playlist.stop()
    elseif command == "pl_next" then
        vlc.playlist.next()
    elseif command == "pl_previous" then
        vlc.playlist.prev()
    elseif command == "pl_delete" then
        vlc.playlist.delete(id)
    elseif command == "pl_empty" then
        vlc.playlist.clear()
    elseif command == "pl_sort" then
        vlc.playlist.sort( val, id > 0 )
    elseif command == "pl_random" then
        vlc.playlist.random()
    elseif command == "pl_loop" then
        --if loop is set true, then repeat needs to be set false
        if vlc.playlist.loop() then
            vlc.playlist.repeat_("off")
        end
    elseif command == "pl_repeat" then
        --if repeat is set true, then loop needs to be set false
        if vlc.playlist.repeat_() then
            vlc.playlist.loop("off")
        end
    elseif command == "pl_sd" then
        if vlc.sd.is_loaded(val) then
            vlc.sd.remove(val)
        else
            vlc.sd.add(val)
        end
    elseif command == "fullscreen" then
        if vlc.object.vout() then
            vlc.video.fullscreen()
        end
    elseif command == "snapshot" then
        common.snapshot()
    elseif command == "volume" then
        common.volume(val)
    elseif command == "seek" then
        common.seek(val)
    elseif command == "key" then
        common.hotkey("key-"..val)
    elseif command == "audiodelay" then
        if vlc.object.input() and val then
            val = common.us_tonumber(val)
            vlc.var.set(vlc.object.input(),"audio-delay",val * 1000000)
        end
    elseif command == "rate" then
        val = common.us_tonumber(val)
        if vlc.object.input() and val >= 0 then
            vlc.var.set(vlc.object.input(),"rate",val)
        end
    elseif command == "subdelay" then
        if vlc.object.input() then
            val = common.us_tonumber(val)
            vlc.var.set(vlc.object.input(),"spu-delay",val * 1000000)
        end
    elseif command == "aspectratio" then
        if vlc.object.vout() then
            vlc.var.set(vlc.object.vout(),"aspect-ratio",val)
        end
    elseif command == "preamp" then
        val = common.us_tonumber(val)
        vlc.equalizer.preampset(val)
    elseif command == "equalizer" then
        val = common.us_tonumber(val)
        vlc.equalizer.equalizerset(band,val)
    elseif command == "enableeq" then
        if val == '0' then vlc.equalizer.enable(false) else vlc.equalizer.enable(true) end
    elseif command == "setpreset" then
        vlc.equalizer.setpreset(val)
    elseif command == "title" then
        vlc.var.set(vlc.object.input(), "title", val)
    elseif command == "chapter" then
        vlc.var.set(vlc.object.input(), "chapter", val)
    elseif command == "audio_track" then
        vlc.var.set(vlc.object.input(), "audio-es", val)
    elseif command == "video_track" then
        vlc.var.set(vlc.object.input(), "video-es", val)
    elseif command == "subtitle_track" then
        vlc.var.set(vlc.object.input(), "spu-es", val)
    end

    local input = nil
    local command = nil
    local id = nil
    local val = nil

end
httprequests.processcommands = processcommands

--utilities for formatting output

function xmlString(s)
    if (type(s)=="string") then
        return vlc.strings.convert_xml_special_chars(s)
    elseif (type(s)=="number") then
        return common.us_tostring(s)
    else
        return tostring(s)
    end
end
httprequests.xmlString = xmlString

--dkjson outputs numbered tables as arrays
--so we don't need the array indicators
function removeArrayIndicators(dict)
    local newDict=dict

    for k,v in pairs(dict) do
        if (type(v)=="table") then
            local arrayEntry=v._array
            if arrayEntry then
                v=arrayEntry
            end

            dict[k]=removeArrayIndicators(v)
        end
    end

    return newDict
end
httprequests.removeArrayIndicators = removeArrayIndicators

printTableAsJson = function (dict)
    dict=removeArrayIndicators(dict)

    local output=dkjson.encode (dict, { indent = true })
    print(output)
end
httprequests.printTableAsJson = printTableAsJson

local printXmlKeyValue = function (k,v,indent)
    print("\n")
    for i=1,indent do print(" ") end
    if (k) then
        print("<"..k..">")
    end

    if (type(v)=="table") then
        printTableAsXml(v,indent+2)
    else
        print(xmlString(v))
    end

    if (k) then
        xs=xmlString(k)
        space_loc=string.find(xs," ")
        if space_loc == nil then
            print("</"..xs..">")
        else
            xs=string.sub(xs,1,space_loc)
            print("</"..xs..">")
        end
    end
end
httprequests.printXmlKeyValue = printXmlKeyValue

printTableAsXml = function (dict,indent)
    for k,v in pairs(dict) do
        printXmlKeyValue(k,v,indent)
    end
end
httprequests.printTableAsXml = printTableAsXml

--[[
function logTable(t,pre)
local pre = pre or ""
for k,v in pairs(t) do
vlc.msg.err(pre..tostring(k).." : "..tostring(v))
if type(v) == "table" then
a(v,pre.."  ")
end
end
end
--]]

--main accessors

getplaylist = function ()
    local p

    if _GET["search"] then
        if _GET["search"] ~= "" then
            _G.search_key = _GET["search"]
        else
            _G.search_key = nil
        end
        local key = vlc.strings.decode_uri(_GET["search"])
        p = vlc.playlist.search(key)
    else
        p = vlc.playlist.get()
    end

    --logTable(p) --Uncomment to debug

    return p
end
httprequests.getplaylist = getplaylist

parseplaylist = function (item)
    if item.flags.disabled then return end

    if (item.children) then
        local result={}
        local name = (item.name or "")

        result["type"]="node"
        result.id=tostring(item.id)
        result.name=tostring(name)
        result.ro=item.flags.ro and "ro" or "rw"

        --store children in an array
        --we use _array as a proxy for arrays
        result.children={}
        result.children._array={}

        for _, child in ipairs(item.children) do
            local nextChild=parseplaylist(child)
            table.insert(result.children._array,nextChild)
        end

        return result
    else
        local result={}
        local name, path = item.name or ""
        local path = item.path or ""
        local current_item_id = vlc.playlist.current()

        -- Is the item the one currently played
        if(current_item_id ~= nil) then
            if(current_item_id == item.id) then
                result.current = "current"
            end
        end

        result["type"]="leaf"
        result.id=tostring(item.id)
        result.uri=tostring(path)
        result.name=name
        result.ro=item.flags.ro and "ro" or "rw"
        result.duration=math.floor(item.duration)

        return result
    end

end
httprequests.parseplaylist = parseplaylist

playlisttable = function ()

    local basePlaylist=getplaylist()

    return parseplaylist(basePlaylist)
end
httprequests.playlisttable = playlisttable

getbrowsetable = function ()

    --paths are returned as an array of elements
    local result = { element = { _array = {} } }

    local dir
    --uri takes precedence, but fall back to dir
    if _GET["uri"] then
        if _GET["uri"] == "file://~" then
            dir = "~"
        else
            local uri = string.gsub(_GET["uri"], "[?#].*$", "")
            if not string.match(uri, "/$") then
                uri = uri.."/"
            end
            dir = vlc.strings.make_path(common.realpath(uri))
        end
    elseif _GET["dir"] then
        dir = _GET["dir"]

        -- "" dir means listing all drive letters e.g. "A:\", "C:\"...
        --however the opendir() API won't resolve "X:\.." to that behavior,
        --so we offer this resolution as "backwards compatibility"
        if string.match(dir, '^[a-zA-Z]:[\\/]*%.%.$') or
           string.match(dir, '^[a-zA-Z]:[\\/]*%.%.[\\/]') then
            dir = ""
        end

        if dir ~= "" and dir ~= "~" then
            dir = dir.."/" --luckily Windows accepts '/' as '\'
        end
    end
    if not dir then
        return result
    end

    if dir == "~" then
        dir = vlc.config.homedir().."/"
    end

    local d = vlc.net.opendir(dir)
    table.sort(d)

    --FIXME: this is the wrong place to do this, but this still offers
    --some useful mitigation: see #25021
    if #d == 0 and dir ~= "" then
        table.insert(d, "..")
    end

    for _,f in pairs(d) do
        if f == ".." or not string.match(f,"^%.") then
            local path = dir..f
            local element={}

            local s = vlc.net.stat(path)
            if (s) then
                for k,v in pairs(s) do
                    element[k]=v
                end
            else
                element["type"]="unknown"
            end
            element["path"]=path
            element["name"]=f

            local uri=vlc.strings.make_uri(path)
            if uri then
                element["uri"]=common.realpath(uri)
            end

            table.insert(result.element._array,element)
        end
    end

    return result;
end
httprequests.getbrowsetable = getbrowsetable


getstatus = function (includecategories)


    local input = vlc.object.input()
    local item = vlc.input.item()
    local playlist = vlc.object.playlist()
    local vout = vlc.object.vout()
    local aout = vlc.object.aout()

    local s ={}

    --update api version when new data/commands added
    s.apiversion=3
    s.version=vlc.misc.version()
    s.volume=vlc.volume.get()
    s.seek_sec = vlc.config.get("short-jump-size")

    if input then
        s.time=math.floor(vlc.var.get(input,"time") / 1000000)
        s.position=vlc.var.get(input,"position")
        s.currentplid=vlc.playlist.current()
        s.audiodelay=vlc.var.get(input,"audio-delay") / 1000000
        s.rate=vlc.var.get(input,"rate")
        s.subtitledelay=vlc.var.get(input,"spu-delay") / 1000000
    else
        s.time=0
        s.position=0
        s.currentplid=-1
        s.audiodelay=0
        s.rate=1
        s.subtitledelay=0
    end

    if item then
        s.length=math.floor(item:duration())
    else
        s.length=0
    end

    if vout then
        s.fullscreen=vlc.var.get(vout,"fullscreen")
        s.aspectratio=vlc.var.get(vout,"aspect-ratio");
        if s.aspectratio=="" then s.aspectratio = "default" end
    else
        s.fullscreen=0
    end

    if aout then
        local filters=vlc.var.get(aout,"audio-filter")
        local temp=strsplit(filters,":")
        s.audiofilters={}
        local id=0
        for i,j in pairs(temp) do
            s.audiofilters['filter_'..id]=j
            id=id+1
        end
    end

    s.videoeffects={}
    s.videoeffects.hue=round(vlc.config.get("hue"),2)
    s.videoeffects.brightness=round(vlc.config.get("brightness"),2)
    s.videoeffects.contrast=round(vlc.config.get("contrast"),2)
    s.videoeffects.saturation=round(vlc.config.get("saturation"),2)
    s.videoeffects.gamma=round(vlc.config.get("gamma"),2)

    s.state=vlc.playlist.status()
    s.random=vlc.var.get(playlist,"random")
    s.loop=vlc.var.get(playlist,"loop")
    s["repeat"]=vlc.var.get(playlist,"repeat")

    s.equalizer={}
    s.equalizer.preamp=round(vlc.equalizer.preampget(),2)
    s.equalizer.bands=vlc.equalizer.equalizerget()
    if s.equalizer.bands ~= null then
        for k,i in pairs(s.equalizer.bands) do s.equalizer.bands[k]=round(i,2) end
        s.equalizer.presets=vlc.equalizer.presets()
    end

    if (includecategories and item) then
        s.information={}
        s.information.category={}
        s.information.category.meta=item:metas()

        local info = item:info()
        for k, v in pairs(info) do
            local streamTable={}
            for k2, v2 in pairs(v) do
                local tag = string.gsub(k2," ","_")
                streamTable[tag]=v2
            end

            s.information.category[k]=streamTable
        end

        s.stats={}

        local statsdata = item:stats()
        for k,v in pairs(statsdata) do
            local tag = string.gsub(k,"_","")
            s.stats[tag]=v
        end

        s.information.chapter=vlc.var.get(input, "chapter")
        s.information.title=vlc.var.get(input, "title")

        s.information.chapters=vlc.var.get_list(input, "chapter")
        s.information.titles=vlc.var.get_list(input, "title")

    end
    return s
end
httprequests.getstatus = getstatus

_G.httprequests = httprequests
return httprequests