-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathapache-browser.lua
101 lines (84 loc) · 2.97 KB
/
apache-browser.lua
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
--[[
An addon for mpv-file-browser which adds support for apache http directory indexes
]]--
local mp = require 'mp'
local msg = require 'mp.msg'
local utils = require 'mp.utils'
local fb = require "file-browser"
--decodes a URL address
--this piece of code was taken from: https://stackoverflow.com/questions/20405985/lua-decodeuri-luvit/20406960#20406960
---@type fun(s: string): string
local decodeURI
do
local char, gsub, tonumber = string.char, string.gsub, tonumber
local function _(hex) return char(tonumber(hex, 16)) end
function decodeURI(s)
s = gsub(s, '%%(%x%x)', _)
return s
end
end
---@type ParserConfig
local apache = {
priority = 80,
api_version = "1.1.0"
}
---@param name string
---@return boolean
function apache:can_parse(name)
return name:find("^https?://") ~= nil
end
---Send curl errors through the browser empty_text.
---@param str string
---@return List
---@return Opts
local function send_error(str)
return {}, {empty_text = "curl error: "..str}
end
---@async
---@param args string[]
---@return MPVSubprocessResult
local function execute(args)
msg.trace(utils.to_string(args))
---@type boolean, MPVSubprocessResult
local _, cmd = fb.get_parse_state():yield(
mp.command_native_async({
name = "subprocess",
playback_only = false,
capture_stdout = true,
capture_stderr = true,
args = args
}, fb.coroutine.callback())
)
return cmd
end
---@async
function apache:parse(directory)
msg.verbose(directory)
local test = execute({"curl", "-k", "-l", "-I", directory})
local response = test.stdout:match("(%d%d%d [^\n\r]+)")
if test.stdout:match("Content%-Type: ([^\r\n/]+)") ~= "text" then return nil end
if response ~= "200 OK" then return send_error(response) end
local html = execute({"curl", "-k", "-l", directory})
if html.status ~= 0 then return send_error(tostring(html.status))
elseif not html.stdout:find("%[PARENTDIR%]") then return nil end
local html_body = html.stdout
local list = {}
for str in string.gmatch(html_body, "[^\r\n]+") do
local valid = true
if str:sub(1,4) ~= "<tr>" then valid = false end
local link = str:match('href="(.-)"')
local alt = str:match('alt="%[(.-)%]"')
if valid and not alt or not link then valid = false end
if valid and alt == "PARENTDIR" or alt == "ICO" then valid = false end
if valid and link:find("[:?<>|]") then valid = false end
local is_dir = (alt == "DIR")
if valid and is_dir and not self.valid_dir(link) then valid = false end
if valid and not is_dir and not self.valid_file(link) then valid = false end
if valid then
msg.trace(alt..": "..link)
table.insert(list, { name = link, type = (is_dir and "dir" or "file"), label = decodeURI(link) })
end
end
return list, {filtered = true, directory_label = decodeURI(directory)}
end
return apache