EVOLUTION-MANAGER
Edit File: lua_utils_generic.lua
-- -- (C) 2014-24 - ntop.org -- -- This require is okay, it just adds up a couple of utilities require "string_utils" require "check_redis_prefs" -- GENERIC UTILS -- split function split(s, delimiter) result = {}; if(s ~= nil) then if delimiter == nil then -- No delimiter, split all characters for match in s:gmatch"." do table.insert(result, match); end else -- Split by delimiter for match in (s..delimiter):gmatch("(.-)"..delimiter) do table.insert(result, match); end end end return result; end -- strsplit function strsplit(s, delimiter) result = {}; for match in (s..delimiter):gmatch("(.-)"..delimiter) do if(match ~= "") then result[match] = true end end return result; end -- isempty function isempty(array) local count = 0 for _,__ in pairs(array) do count = count + 1 end return (count == 0) end -- isin function isin(s, array) if (s == nil or s == "" or array == nil or isempty(array)) then return false end for _, v in pairs(array) do if (s == v) then return true end end return false end -- hasKey function hasKey(key, theTable) if((theTable == nil) or (theTable[key] == nil)) then return(false) else return(true) end end -- ############################################### -- TODO: improve this function function jsonencode(what) what = string.gsub(what, '"', "'") -- everything but all ASCII characters from the space to the tilde what = string.gsub(what, "[^ -~]", " ") -- cleanup line feeds and carriage returns what = string.gsub(what, "\n", " ") what = string.gsub(what, "\r", " ") -- escape all the remaining backslashes what = string.gsub(what, "\\", "\\\\") -- max 1 sequential whitespace what = string.gsub(what, " +"," ") return(what) end -- ########################################### -- Merges table a and table b into a new table. If some elements are presents in -- both a and b, b elements will have precedence. -- NOTE: this does *not* perform a deep merge. Only first level is merged. function table.merge(a, b, nodup) local merged = {} a = a or {} b = b or {} if((a[1] ~= nil) and (b[1] ~= nil)) then -- index based tables for _, t in ipairs({a, b}) do for _,v in pairs(t) do if not nodup or not table.contains(merged, v) then merged[#merged + 1] = v end end end else -- key based tables for _, t in ipairs({a, b}) do for k,v in pairs(t) do merged[k] = v end end end return merged end -- ########################################### -- Performs a deep copy of the table. function table.clone(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in next, orig, nil do copy[table.clone(orig_key)] = table.clone(orig_value) end setmetatable(copy, table.clone(getmetatable(orig))) else -- number, string, boolean, etc copy = orig end return copy end -- ########################################### -- From http://lua-users.org/lists/lua-l/2014-09/msg00421.html -- Returns true if tables are equal function table.compare(t1, t2, ignore_mt) local ty1 = type(t1) local ty2 = type(t2) if ty1 ~= ty2 then return false end if ty1 ~= 'table' and ty2 ~= 'table' then return t1 == t2 end local mt = getmetatable(t1) if not ignore_mt and mt and mt.__eq then return t1 == t2 end for k1,v1 in pairs(t1) do local v2 = t2[k1] if v2 == nil or not table.compare(v1, v2) then return false end end for k2,v2 in pairs(t2) do local v1 = t1[k2] if v1 == nil or not table.compare(v1, v2) then return false end end return true end -- ############################################## -- returns the MAXIMUM value found in a table t, together with the corresponding -- index argmax. a pair argmax, max is returned. function tmax(t) local argmx, mx = nil, nil if (type(t) ~= "table") then return nil, nil end for k, v in pairs(t) do -- first iteration if mx == nil and argmx == nil then mx = v argmx = k elseif (v == mx and k > argmx) or v > mx then -- if there is a tie, prefer the greatest argument -- otherwise grab the maximum argmx = k mx = v end end return argmx, mx end -- ############################################## -- returns the MINIMUM value found in a table t, together with the corresponding -- index argmin. a pair argmin, min is returned. function tmin(t) local argmn, mn = nil, nil if (type(t) ~= "table") then return nil, nil end for k, v in pairs(t) do -- first iteration if mn == nil and argmn == nil then mn = v argmn = k elseif (v == mn and k > argmn) or v < mn then -- if there is a tie, prefer the greatest argument -- otherwise grab the minimum argmn = k mn = v end end return argmn, mn end -- ########################################### function toboolean(s) if not isEmptyString(s) and ( s == "true" or s == true or s == "1" or s == 1) then return true else return false end end -- ########################################### -- -- Find the highest divisor which divides input value. -- val_idx can be used to index divisors values. -- Returns the highest_idx -- function highestDivisor(divisors, value, val_idx, iterator_fn) local highest_idx = nil local highest_val = nil iterator_fn = iterator_fn or ipairs for i, v in iterator_fn(divisors) do local cmp_v if val_idx ~= nil then v = v[val_idx] end if((highest_val == nil) or ((v > highest_val) and (value % v == 0))) then highest_val = v highest_idx = i end end return highest_idx end -- ########################################### --- Test if each element inside the table t satisfies the predicate function --- @param t table The table containing values to test --- @param predicate function The function that return a boolean value (true|false) --- @return boolean function table.all(t, predicate) if type(t) ~= 'table' then traceError(TRACE_DEBUG, TRACE_CONSOLE, "the first paramater is not a table!") return false end if type(predicate) ~= 'function' then traceError(TRACE_DEBUG, TRACE_CONSOLE, "the passed predicate is not a function!") return false end if t == nil then return false end for _, value in pairs(t) do -- check if the value satisfies the boolean predicate local term = predicate(value) -- if the return value is valid and true then do nothing -- otherwise stop the loop and return false if term == nil then -- inform the client about the nil value traceError(TRACE_DEBUG, TRACE_CONSOLE, "a null term has been returned from the predicate function!") return false elseif not term then return false end end -- each entry satisfies the predicate return true end -- ########################################### --- Perform a linear search to check if an element is inside a table --- @param t table The table to scan --- @param needle any The element to search --- @param comp function The compare function used to compare the searched element with others --- @return boolean True if the element is insie the table, False otherwise function table.contains(t, needle, comp) if (t == nil) then return false end if (type(t) ~= "table") then return false end if (#t == 0) then return false end local default_compare = (function(e) return e == needle end) comp = comp or default_compare for _, element in ipairs(t) do if comp(element) then return true end end return false end -- ########################################### --- Insert an element inside the table if is not present function table.insertIfNotPresent(t, element, comp) if table.contains(t, element, comp) then return end t[#t+1] = element end -- ########################################### --- Fold right table with a custom function --- @param t table Table to fold --- @param func function Function to execute on table values --- @param val any The returned default value function table.foldr(t, func, val) for i,v in pairs(t) do val = func(val, v) end return val end -- ########################################### function table.has_key(table, key) return table[key] ~= nil end function table.slice(t, start_table, end_table) if t == nil then error("The array to slice cannot be nil!") end if end_table > #t then end_table = #t end if start_table < 1 then error("Invalid bounds!") end local res = {} for i = start_table, end_table, 1 do res[#res + 1] = t[i] end return res end if(trace_script_duration ~= nil) then io.write(debug.getinfo(1,'S').source .." executed in ".. (os.clock()-clock_start)*1000 .. " ms\n") end -- ############################################## function convertDate(vardate) local m,d,y,h,i,s = string.match(vardate, '(%d+)/(%d+)/(%d+) (%d+):(%d+):(%d+)') local key = ntop.getPref('ntopng.user.' .. _SESSION["user"] .. '.date_format') if(key == "little_endian") then return string.format('%s/%s/%s %s:%s:%s', d,m,y,h,i,s) elseif( key == "middle_endian") then return string.format('%s/%s/%s %s:%s:%s', m,d,y,h,i,s) else return string.format('%s/%s/%s %s:%s:%s', y,m,d,h,i,s) end end -- ############################################## -- compare two tables for equality function table.is_equal(t1, t2, ignore_keys) local ty1 = type(t1) local ty2 = type(t2) if ty1 ~= ty2 then return false end -- non-table types can be directly compared if ty1 ~= 'table' and ty2 ~= 'table' then return t1 == t2 end -- as well as tables which have the metamethod __eq local mt = getmetatable(t1) if mt and mt.__eq then return t1 == t2 end for k1,v1 in pairs(t1) do if((ignore_keys == nil) or (ignore_keys[k1] == nil)) then local v2 = t2[k1] if v2 == nil or not table.is_equal(v1,v2) then --tprint("Change in key (1) "..k1) if(k1 == "ntopng.prefs.snmp_configuration") then -- tprint(v1) -- tprint(v2) end return false end end end for k2,v2 in pairs(t2) do if((ignore_keys == nil) or (ignore_keys[k2] == nil)) then local v1 = t1[k2] if v1 == nil or not table.is_equal(v1,v2) then -- tprint("Change in key (2) "..k2) return false end end end return true end -- ############################################## function printInterfaceIndex(idx) local ifaces local basedir = "/sys/class/net" if((idx == nil) or (idx == "")) then return end idx = tostring(idx) if(idx == "0") then return end ifaces = ntop.readdir(basedir) for k,v in pairs(ifaces) do local path = basedir .. "/" .. k.. "/" .. "ifindex" local f = io.open(path, "r") if(f ~= nil) then local if_idx = trimString(f:read("*all")) io.close(f) if(if_idx == idx) then print("[ <span class=\"fas fa-ethernet\"></span> " .. k .. " ]") return end --tprint(k.." = "..if_idx) end end end -- ########################################### function swapKeysValues(tbl) local new_tbl = {} for k, v in pairs(tbl or {}) do new_tbl[v] = k end return new_tbl end if(trace_script_duration ~= nil) then io.write(debug.getinfo(1,'S').source .." executed in ".. (os.clock()-clock_start)*1000 .. " ms\n") end -- ########################################### function isInteger(str) return not (str == "" or str:find("%D")) -- str:match("%D") also works end