mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-30 07:59:35 +00:00
Fixes #2198 Since the daily script always failed, no top talkers sampling aggregations were applied and raw samplings where computed
478 lines
15 KiB
Lua
478 lines
15 KiB
Lua
local setmetatable = setmetatable
|
|
local loadstring = loadstring
|
|
local loadchunk
|
|
local tostring = tostring
|
|
local setfenv = setfenv
|
|
local require = require
|
|
local capture
|
|
local concat = table.concat
|
|
local assert = assert
|
|
local prefix
|
|
local write = io.write
|
|
local pcall = pcall
|
|
local phase
|
|
local open = io.open
|
|
local load = load
|
|
local type = type
|
|
local dump = string.dump
|
|
local find = string.find
|
|
local gsub = string.gsub
|
|
local byte = string.byte
|
|
local null
|
|
local sub = string.sub
|
|
local ngx = ngx
|
|
local jit = jit
|
|
local var
|
|
|
|
local _VERSION = _VERSION
|
|
local _ENV = _ENV
|
|
local _G = _G
|
|
|
|
local HTML_ENTITIES = {
|
|
["&"] = "&",
|
|
["<"] = "<",
|
|
[">"] = ">",
|
|
['"'] = """,
|
|
["'"] = "'",
|
|
["/"] = "/"
|
|
}
|
|
|
|
local CODE_ENTITIES = {
|
|
["{"] = "{",
|
|
["}"] = "}",
|
|
["&"] = "&",
|
|
["<"] = "<",
|
|
[">"] = ">",
|
|
['"'] = """,
|
|
["'"] = "'",
|
|
["/"] = "/"
|
|
}
|
|
|
|
local VAR_PHASES
|
|
|
|
--local ok, newtab = pcall(require, "table.new")
|
|
newtab = function() return {} end
|
|
|
|
local caching = true
|
|
local template = newtab(0, 12)
|
|
|
|
template._VERSION = "1.9"
|
|
template.cache = {}
|
|
|
|
local function enabled(val)
|
|
if val == nil then return true end
|
|
return val == true or (val == "1" or val == "true" or val == "on")
|
|
end
|
|
|
|
local function trim(s)
|
|
return gsub(gsub(s, "^%s+", ""), "%s+$", "")
|
|
end
|
|
|
|
local function rpos(view, s)
|
|
while s > 0 do
|
|
local c = sub(view, s, s)
|
|
if c == " " or c == "\t" or c == "\0" or c == "\x0B" then
|
|
s = s - 1
|
|
else
|
|
break
|
|
end
|
|
end
|
|
return s
|
|
end
|
|
|
|
local function escaped(view, s)
|
|
if s > 1 and sub(view, s - 1, s - 1) == "\\" then
|
|
if s > 2 and sub(view, s - 2, s - 2) == "\\" then
|
|
return false, 1
|
|
else
|
|
return true, 1
|
|
end
|
|
end
|
|
return false, 0
|
|
end
|
|
|
|
local function readfile(path)
|
|
local file = open(path, "rb")
|
|
if not file then return nil end
|
|
local content = file:read "*a"
|
|
file:close()
|
|
return content
|
|
end
|
|
|
|
local function loadlua(path)
|
|
return readfile(path) or path
|
|
end
|
|
|
|
local function loadngx(path)
|
|
local vars = VAR_PHASES[phase()]
|
|
local file, location = path, vars and var.template_location
|
|
if sub(file, 1) == "/" then file = sub(file, 2) end
|
|
if location and location ~= "" then
|
|
if sub(location, -1) == "/" then location = sub(location, 1, -2) end
|
|
local res = capture(concat{ location, '/', file})
|
|
if res.status == 200 then return res.body end
|
|
end
|
|
local root = vars and (var.template_root or var.document_root) or prefix
|
|
if sub(root, -1) == "/" then root = sub(root, 1, -2) end
|
|
return readfile(concat{ root, "/", file }) or path
|
|
end
|
|
|
|
do
|
|
if ngx then
|
|
VAR_PHASES = {
|
|
set = true,
|
|
rewrite = true,
|
|
access = true,
|
|
content = true,
|
|
header_filter = true,
|
|
body_filter = true,
|
|
log = true
|
|
}
|
|
template.print = ngx.print or write
|
|
template.load = loadngx
|
|
prefix, var, capture, null, phase = ngx.config.prefix(), ngx.var, ngx.location.capture, ngx.null, ngx.get_phase
|
|
if VAR_PHASES[phase()] then
|
|
caching = enabled(var.template_cache)
|
|
end
|
|
else
|
|
template.print = write
|
|
template.load = loadlua
|
|
end
|
|
if _VERSION == "Lua 5.1" then
|
|
local context = { __index = function(t, k)
|
|
return t.context[k] or t.template[k] or _G[k]
|
|
end }
|
|
if jit then
|
|
loadchunk = function(view)
|
|
return assert(load(view, nil, nil, setmetatable({ template = template }, context)))
|
|
end
|
|
else
|
|
loadchunk = function(view)
|
|
local func = assert(loadstring(view))
|
|
setfenv(func, setmetatable({ template = template }, context))
|
|
return func
|
|
end
|
|
end
|
|
else
|
|
local context = { __index = function(t, k)
|
|
return t.context[k] or t.template[k] or _ENV[k]
|
|
end }
|
|
loadchunk = function(view)
|
|
return assert(load(view, nil, nil, setmetatable({ template = template }, context)))
|
|
end
|
|
end
|
|
end
|
|
|
|
function template.caching(enable)
|
|
if enable ~= nil then caching = enable == true end
|
|
return caching
|
|
end
|
|
|
|
function template.output(s)
|
|
if s == nil or s == null then return "" end
|
|
if type(s) == "function" then return template.output(s()) end
|
|
return tostring(s)
|
|
end
|
|
|
|
function template.escape(s, c)
|
|
if type(s) == "string" then
|
|
if c then return gsub(s, "[}{\">/<'&]", CODE_ENTITIES) end
|
|
return gsub(s, "[\">/<'&]", HTML_ENTITIES)
|
|
end
|
|
return template.output(s)
|
|
end
|
|
|
|
function template.new(view, layout)
|
|
assert(view, "view was not provided for template.new(view, layout).")
|
|
local render, compile = template.render, template.compile
|
|
if layout then
|
|
if type(layout) == "table" then
|
|
return setmetatable({ render = function(self, context)
|
|
local context = context or self
|
|
context.blocks = context.blocks or {}
|
|
context.view = compile(view)(context)
|
|
layout.blocks = context.blocks or {}
|
|
layout.view = context.view or ""
|
|
return layout:render()
|
|
end }, { __tostring = function(self)
|
|
local context = self
|
|
context.blocks = context.blocks or {}
|
|
context.view = compile(view)(context)
|
|
layout.blocks = context.blocks or {}
|
|
layout.view = context.view
|
|
return tostring(layout)
|
|
end })
|
|
else
|
|
return setmetatable({ render = function(self, context)
|
|
local context = context or self
|
|
context.blocks = context.blocks or {}
|
|
context.view = compile(view)(context)
|
|
return render(layout, context)
|
|
end }, { __tostring = function(self)
|
|
local context = self
|
|
context.blocks = context.blocks or {}
|
|
context.view = compile(view)(context)
|
|
return compile(layout)(context)
|
|
end })
|
|
end
|
|
end
|
|
return setmetatable({ render = function(self, context)
|
|
return render(view, context or self)
|
|
end }, { __tostring = function(self)
|
|
return compile(view)(self)
|
|
end })
|
|
end
|
|
|
|
function template.precompile(view, path, strip)
|
|
local chunk = dump(template.compile(view), strip ~= false)
|
|
if path then
|
|
local file = open(path, "wb")
|
|
file:write(chunk)
|
|
file:close()
|
|
end
|
|
return chunk
|
|
end
|
|
|
|
function template.compile(view, key, plain)
|
|
assert(view, "view was not provided for template.compile(view, key, plain).")
|
|
if key == "no-cache" then
|
|
return loadchunk(template.parse(view, plain)), false
|
|
end
|
|
key = key or view
|
|
local cache = template.cache
|
|
if cache[key] then return cache[key], true end
|
|
local func = loadchunk(template.parse(view, plain))
|
|
if caching then cache[key] = func end
|
|
return func, false
|
|
end
|
|
|
|
function template.parse(view, plain)
|
|
assert(view, "view was not provided for template.parse(view, plain).")
|
|
if not plain then
|
|
view = template.load(view)
|
|
if byte(view, 1, 1) == 27 then return view end
|
|
end
|
|
local j = 2
|
|
local c = {[[
|
|
context=... or {}
|
|
local function include(v, c) return template.compile(v)(c or context) end
|
|
local ___,blocks,layout={},blocks or {}
|
|
]] }
|
|
local i, s = 1, find(view, "{", 1, true)
|
|
while s do
|
|
local t, p = sub(view, s + 1, s + 1), s + 2
|
|
if t == "{" then
|
|
local e = find(view, "}}", p, true)
|
|
if e then
|
|
local z, w = escaped(view, s)
|
|
if i < s - w then
|
|
c[j] = "___[#___+1]=[=[\n"
|
|
c[j+1] = sub(view, i, s - 1 - w)
|
|
c[j+2] = "]=]\n"
|
|
j=j+3
|
|
end
|
|
if z then
|
|
i = s
|
|
else
|
|
c[j] = "___[#___+1]=template.escape("
|
|
c[j+1] = trim(sub(view, p, e - 1))
|
|
c[j+2] = ")\n"
|
|
j=j+3
|
|
s, i = e + 1, e + 2
|
|
end
|
|
end
|
|
elseif t == "*" then
|
|
local e = find(view, "*}", p, true)
|
|
if e then
|
|
local z, w = escaped(view, s)
|
|
if i < s - w then
|
|
c[j] = "___[#___+1]=[=[\n"
|
|
c[j+1] = sub(view, i, s - 1 - w)
|
|
c[j+2] = "]=]\n"
|
|
j=j+3
|
|
end
|
|
if z then
|
|
i = s
|
|
else
|
|
c[j] = "___[#___+1]=template.output("
|
|
c[j+1] = trim(sub(view, p, e - 1))
|
|
c[j+2] = ")\n"
|
|
j=j+3
|
|
s, i = e + 1, e + 2
|
|
end
|
|
end
|
|
elseif t == "%" then
|
|
local e = find(view, "%}", p, true)
|
|
if e then
|
|
local z, w = escaped(view, s)
|
|
if z then
|
|
if i < s - w then
|
|
c[j] = "___[#___+1]=[=[\n"
|
|
c[j+1] = sub(view, i, s - 1 - w)
|
|
c[j+2] = "]=]\n"
|
|
j=j+3
|
|
end
|
|
i = s
|
|
else
|
|
local n = e + 2
|
|
if sub(view, n, n) == "\n" then
|
|
n = n + 1
|
|
end
|
|
local r = rpos(view, s - 1)
|
|
if i <= r then
|
|
c[j] = "___[#___+1]=[=[\n"
|
|
c[j+1] = sub(view, i, r)
|
|
c[j+2] = "]=]\n"
|
|
j=j+3
|
|
end
|
|
c[j] = trim(sub(view, p, e - 1))
|
|
c[j+1] = "\n"
|
|
j=j+2
|
|
s, i = n - 1, n
|
|
end
|
|
end
|
|
elseif t == "(" then
|
|
local e = find(view, ")}", p, true)
|
|
if e then
|
|
local z, w = escaped(view, s)
|
|
if i < s - w then
|
|
c[j] = "___[#___+1]=[=[\n"
|
|
c[j+1] = sub(view, i, s - 1 - w)
|
|
c[j+2] = "]=]\n"
|
|
j=j+3
|
|
end
|
|
if z then
|
|
i = s
|
|
else
|
|
local f = sub(view, p, e - 1)
|
|
local x = find(f, ",", 2, true)
|
|
if x then
|
|
c[j] = "___[#___+1]=include([=["
|
|
c[j+1] = trim(sub(f, 1, x - 1))
|
|
c[j+2] = "]=],"
|
|
c[j+3] = trim(sub(f, x + 1))
|
|
c[j+4] = ")\n"
|
|
j=j+5
|
|
else
|
|
c[j] = "___[#___+1]=include([=["
|
|
c[j+1] = trim(f)
|
|
c[j+2] = "]=])\n"
|
|
j=j+3
|
|
end
|
|
s, i = e + 1, e + 2
|
|
end
|
|
end
|
|
elseif t == "[" then
|
|
local e = find(view, "]}", p, true)
|
|
if e then
|
|
local z, w = escaped(view, s)
|
|
if i < s - w then
|
|
c[j] = "___[#___+1]=[=[\n"
|
|
c[j+1] = sub(view, i, s - 1 - w)
|
|
c[j+2] = "]=]\n"
|
|
j=j+3
|
|
end
|
|
if z then
|
|
i = s
|
|
else
|
|
c[j] = "___[#___+1]=include("
|
|
c[j+1] = trim(sub(view, p, e - 1))
|
|
c[j+2] = ")\n"
|
|
j=j+3
|
|
s, i = e + 1, e + 2
|
|
end
|
|
end
|
|
elseif t == "-" then
|
|
local e = find(view, "-}", p, true)
|
|
if e then
|
|
local x, y = find(view, sub(view, s, e + 1), e + 2, true)
|
|
if x then
|
|
local z, w = escaped(view, s)
|
|
if z then
|
|
if i < s - w then
|
|
c[j] = "___[#___+1]=[=[\n"
|
|
c[j+1] = sub(view, i, s - 1 - w)
|
|
c[j+2] = "]=]\n"
|
|
j=j+3
|
|
end
|
|
i = s
|
|
else
|
|
y = y + 1
|
|
x = x - 1
|
|
if sub(view, y, y) == "\n" then
|
|
y = y + 1
|
|
end
|
|
local b = trim(sub(view, p, e - 1))
|
|
if b == "verbatim" or b == "raw" then
|
|
if i < s - w then
|
|
c[j] = "___[#___+1]=[=[\n"
|
|
c[j+1] = sub(view, i, s - 1 - w)
|
|
c[j+2] = "]=]\n"
|
|
j=j+3
|
|
end
|
|
c[j] = "___[#___+1]=[=["
|
|
c[j+1] = sub(view, e + 2, x)
|
|
c[j+2] = "]=]\n"
|
|
j=j+3
|
|
else
|
|
if sub(view, x, x) == "\n" then
|
|
x = x - 1
|
|
end
|
|
local r = rpos(view, s - 1)
|
|
if i <= r then
|
|
c[j] = "___[#___+1]=[=[\n"
|
|
c[j+1] = sub(view, i, r)
|
|
c[j+2] = "]=]\n"
|
|
j=j+3
|
|
end
|
|
c[j] = 'blocks["'
|
|
c[j+1] = b
|
|
c[j+2] = '"]=include[=['
|
|
c[j+3] = sub(view, e + 2, x)
|
|
c[j+4] = "]=]\n"
|
|
j=j+5
|
|
end
|
|
s, i = y - 1, y
|
|
end
|
|
end
|
|
end
|
|
elseif t == "#" then
|
|
local e = find(view, "#}", p, true)
|
|
if e then
|
|
local z, w = escaped(view, s)
|
|
if i < s - w then
|
|
c[j] = "___[#___+1]=[=[\n"
|
|
c[j+1] = sub(view, i, s - 1 - w)
|
|
c[j+2] = "]=]\n"
|
|
j=j+3
|
|
end
|
|
if z then
|
|
i = s
|
|
else
|
|
e = e + 2
|
|
if sub(view, e, e) == "\n" then
|
|
e = e + 1
|
|
end
|
|
s, i = e - 1, e
|
|
end
|
|
end
|
|
end
|
|
s = find(view, "{", s + 1, true)
|
|
end
|
|
s = sub(view, i)
|
|
if s and s ~= "" then
|
|
c[j] = "___[#___+1]=[=[\n"
|
|
c[j+1] = s
|
|
c[j+2] = "]=]\n"
|
|
j=j+3
|
|
end
|
|
c[j] = "return layout and include(layout,setmetatable({view=table.concat(___),blocks=blocks},{__index=context})) or table.concat(___)"
|
|
return concat(c)
|
|
end
|
|
|
|
function template.render(view, context, key, plain)
|
|
assert(view, "view was not provided for template.render(view, context, key, plain).")
|
|
return template.print(template.compile(view, key, plain)(context))
|
|
end
|
|
|
|
return template
|