update 2022-08-12 20:21:57

This commit is contained in:
github-actions[bot] 2022-08-12 20:21:57 +08:00
parent d06e3cc193
commit 8688e8e292
16 changed files with 734 additions and 629 deletions

View File

@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=Open App Filter Module
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+kmod-oaf +appfilter
LUCI_DEPENDS:=+appfilter
PKG_NAME:=luci-app-oaf
PKG_VERSION:=5.0
PKG_RELEASE:=1

View File

@ -8,10 +8,26 @@ function index()
end
local page
page = entry({"admin", "network", "appfilter"}, arcombine(cbi("appfilter/appfilter"), cbi("appfilter/dev_status", {hideapplybtn=true, hidesavebtn=true, hideresetbtn=true})), _("App Filter"), 100)
entry({"admin", "services", "appfilter"},
alias("admin", "services", "appfilter", "user_list"),
_("应用过滤"), 20).dependent = true
page.leaf = true
page.subindex = true
entry({"admin", "services", "appfilter", "user_list"},
arcombine(cbi("appfilter/user_list",{hideapplybtn=true, hidesavebtn=true, hideresetbtn=true}),
cbi("appfilter/dev_status", {hideapplybtn=true, hidesavebtn=true, hideresetbtn=true})),
_("用户列表"), 21).leaf=true
entry({"admin", "services", "appfilter", "base_setting"},
cbi("appfilter/base_setting"), _("应用过滤规则"), 22).leaf=true
entry({"admin", "services", "appfilter", "user_setting"},
cbi("appfilter/user_setting"), _("生效用户"), 23).leaf=true
entry({"admin", "services", "appfilter", "time_setting"},
cbi("appfilter/time_setting"), _("生效时间"), 24).leaf=true
entry({"admin", "services", "appfilter", "feature"},
cbi("appfilter/feature", {hideapplybtn=true, hidesavebtn=true, hideresetbtn=true}), _("特征库升级"), 25).leaf=true
page = entry({"admin", "network", "user_status"}, call("user_status"), nil)
page.leaf = true

View File

@ -1,228 +0,0 @@
local ds = require "luci.dispatcher"
local nxo = require "nixio"
local nfs = require "nixio.fs"
local ipc = require "luci.ip"
local sys = require "luci.sys"
local utl = require "luci.util"
local dsp = require "luci.dispatcher"
local uci = require "luci.model.uci"
local lng = require "luci.i18n"
local jsc = require "luci.jsonc"
local http = luci.http
local SYS = require "luci.sys"
local m, s
m = Map("appfilter",
translate("App Filter"),
translate(""))
s = m:section(TypedSection, "global", translate("Basic Settings"))
s:option(Flag, "enable", translate("Enable App Filter"),translate(""))
s.anonymous = true
local rule_count=0
local version=""
if nixio.fs.access("/tmp/feature.cfg") then
rule_count=tonumber(SYS.exec("cat /tmp/feature.cfg | wc -l"))
version=SYS.exec("cat /tmp/feature.cfg |grep \"#version\" | awk '{print $2}'")
end
local display_str="<strong>当前版本: </strong>"..version.."<br><strong>特征码个数:</strong> "..rule_count.."<br><strong> 下载地址:</strong><a href=\"https://destan19.github.io\">https://destan19.github.io</a>"
s = m:section(TypedSection, "feature", translate("Update feature"), display_str )
fu = s:option(FileUpload, "")
fu.template = "cbi/oaf_upload"
s.anonymous = true
um = s:option(DummyValue, "rule_data")
s=m:section(TypedSection,"time",translate("Time Setting")) s.anonymous = true
hv = s:option(Value, "start_time", translate("Start Time")) hv.default="00:00"
hv.optional=false
hv = s:option(Value, "end_time", translate("End Time")) hv.default="23:59"
hv.optional=false days = s:option(MultiValue, "days", "", translate(""))
days.widget="checkbox" days.size=10
days:value("0", translate("Sun"));
days:value("1", translate("Mon"));
days:value("2", translate("Tue"));
days:value("3", translate("Wed"));
days:value("4", translate("Thur"));
days:value("5", translate("Fri"));
days:value("6", translate("Sat"));
s = m:section(TypedSection, "appfilter", translate("App Filter Rules"))
s.anonymous = true
s.addremove = false
local class_fd = io.popen("find /tmp/appfilter/ -type f -name '*.class'")
if class_fd then
while true do
local apps
local class
local path = class_fd:read("*l")
if not path then
break
end
class = path:match("([^/]+)%.class$")
s:tab(class, translate(class))
apps = s:taboption(class, MultiValue, class.."apps", translate(""))
apps.rmempty=true
apps.widget="checkbox"
apps.size=10
local fd = io.open(path)
if fd then
local line
while true do
local cmd
local cmd_fd
line = fd:read("*l")
if not line then break end
if string.len(line) < 5 then break end
if not string.find(line,"#") then
cmd = "echo "..line.."|awk '{print $1}'"
cmd_fd = io.popen(cmd)
id = cmd_fd:read("*l");
cmd_fd:close()
cmd = "echo "..line.."|awk '{print $2}'"
cmd_fd = io.popen(cmd)
name = cmd_fd:read("*l")
cmd_fd:close()
if not id then break end
if not name then break end
apps:value(id, name)
end
end
fd:close()
end
end
class_fd:close()
end
function get_hostname_by_mac(dst_mac)
leasefile="/tmp/dhcp.leases"
local fd = io.open(leasefile, "r")
if not fd then return end
while true do
local ln = fd:read("*l")
if not ln then
break
end
local ts, mac, ip, name, duid = ln:match("^(%d+) (%S+) (%S+) (%S+) (%S+)")
print(ln)
if dst_mac == mac then
fd:close()
return name
end
end
fd:close()
return nil
end
function get_cmd_result(command)
local fd
local result
fd = io.popen(command);
if not fd then return "" end
result = fd:read("*l");
fd:close()
return result
end
s=m:section(TypedSection,"user",translate("Select users"))
s.anonymous = true
users = s:option(MultiValue, "users", "", translate("Select at least one user, otherwise it will take effect for all users"))
users.widget="checkbox"
--users.widget="select"
users.size=6
local fd = io.open("/tmp/dev_list", "r")
if not fd then return m end
while true do
local line = fd:read("*l")
if not line then
break
end
if not string.match(line, "^Id") then
local ip=get_cmd_result(string.format("echo '%s' | awk '{print $3}'", line))
local mac=get_cmd_result(string.format("echo '%s' | awk '{print $2}'", line))
local hostname=get_cmd_result(string.format("echo '%s' | awk '{print $4}'", line))
if mac ~= nil then
if not hostname or hostname == "*" then
users:value(mac, mac);
else
users:value(mac, hostname.."("..mac..")");
end
end
end
end
fd:close()
local config_users=m.uci:get_all("appfilter.user.users")
if config_users~=nil and config_users~=false then
local r=utl.split(config_users, "%s+", nil, true)
local max = table.getn(r)
for i=1,max,1 do
users:value(r[i], r[i]);
end
end
m:section(SimpleSection).template = "admin_network/user_status"
local dir, fd
dir = "/tmp/upload/"
nixio.fs.mkdir(dir)
http.setfilehandler(
function(meta, chunk, eof)
if not fd then
if not meta then return end
if meta and chunk then fd = nixio.open(dir .. meta.file, "w") end
if not fd then
return
end
end
if chunk and fd then
fd:write(chunk)
end
if eof and fd then
fd:close()
local fd2 = io.open("/tmp/upload/"..meta.file)
local line=fd2:read("*l");
fd2:close()
local ret=string.match(line, "#version")
local lang=m.uci:get_all("luci.main.lang")
local feature_file=""
if "" == lang or "auto" == lang then
feature_file="/etc/appfilter/feature.cfg"
else
feature_file="/etc/appfilter/feature_"..lang..".cfg"
end
if ret ~= nil then
local cmd="cp /tmp/upload/"..meta.file.." "..feature_file;
os.execute(cmd);
os.execute("chmod 666 "..feature_file);
os.execute("rm /tmp/appfilter -fr");
luci.sys.exec("/etc/init.d/appfilter restart &");
um.value = translate("Update the feature file successfully, please refresh the page")
else
um.value = translate("Failed to update feature file, format error")
end
os.execute("rm /tmp/upload/* -fr");
end
end
)
if luci.http.formvalue("upload") then
local f = luci.http.formvalue("ulfile")
if #f <= 0 then
--um.value = translate("No specify upload file.")
end
elseif luci.http.formvalue("download") then
Download()
end
return m

View File

@ -0,0 +1,85 @@
local ds = require "luci.dispatcher"
local nxo = require "nixio"
local nfs = require "nixio.fs"
local ipc = require "luci.ip"
local sys = require "luci.sys"
local utl = require "luci.util"
local dsp = require "luci.dispatcher"
local uci = require "luci.model.uci"
local lng = require "luci.i18n"
local jsc = require "luci.jsonc"
local http = luci.http
local SYS = require "luci.sys"
local m, s
m = Map("appfilter", translate("App Filter"), translate(
"目前不支持旁路模式,请先关闭所有加速(acc)、广告过滤、多拨等可能冲突的模块"))
s = m:section(TypedSection, "global", translate("Basic Settings"))
s:option(Flag, "enable", translate("Enable App Filter"), translate(""))
s.anonymous = true
local rule_count = 0
local version = ""
s = m:section(TypedSection, "appfilter", translate("App Filter Rules"))
s.anonymous = true
s.addremove = false
local class_fd = io.popen("find /tmp/appfilter/ -type f -name '*.class'")
if class_fd then
while true do
local apps
local class
local path = class_fd:read("*l")
if not path then
break
end
class = path:match("([^/]+)%.class$")
s:tab(class, translate(class))
apps = s:taboption(class, MultiValue, class .. "apps", translate(""))
apps.rmempty = true
apps.widget = "checkbox"
apps.size = 10
local fd = io.open(path)
if fd then
local line
while true do
local cmd
local cmd_fd
line = fd:read("*l")
if not line then
break
end
if string.len(line) < 5 then
break
end
if not string.find(line, "#") then
cmd = "echo " .. line .. "|awk '{print $1}'"
cmd_fd = io.popen(cmd)
id = cmd_fd:read("*l");
cmd_fd:close()
cmd = "echo " .. line .. "|awk '{print $2}'"
cmd_fd = io.popen(cmd)
name = cmd_fd:read("*l")
cmd_fd:close()
if not id then
break
end
if not name then
break
end
apps:value(id, name)
end
end
fd:close()
end
end
class_fd:close()
end
return m

View File

@ -1,4 +1,3 @@
local ds = require "luci.dispatcher"
local nxo = require "nixio"
local nfs = require "nixio.fs"
@ -12,13 +11,11 @@ local jsc = require "luci.jsonc"
local m, s
arg[1] = arg[1] or ""
m = Map("appfilter",
translate("Data Statistics").."("..arg[1]..")",
translate(""))
m = Map("appfilter", translate("Data Statistics") .. "(" .. arg[1] .. ")", translate(""))
local v
v=m:section(SimpleSection)
v.template="admin_network/dev_status"
v.mac=arg[1]
m.redirect = luci.dispatcher.build_url("admin", "network", "appfilter")
v = m:section(SimpleSection)
v.template = "admin_network/dev_status"
v.mac = arg[1]
m.redirect = luci.dispatcher.build_url("admin", "services", "appfilter")
return m

View File

@ -0,0 +1,91 @@
local ds = require "luci.dispatcher"
local nxo = require "nixio"
local nfs = require "nixio.fs"
local ipc = require "luci.ip"
local sys = require "luci.sys"
local utl = require "luci.util"
local dsp = require "luci.dispatcher"
local uci = require "luci.model.uci"
local lng = require "luci.i18n"
local jsc = require "luci.jsonc"
local http = luci.http
local SYS = require "luci.sys"
local m, s
m = Map("appfilter", translate(""),
translate("特征库用于描述app特征app过滤效果和个数依赖特征库"))
local rule_count = 0
local version = ""
if nixio.fs.access("/tmp/feature.cfg") then
rule_count = tonumber(SYS.exec("cat /tmp/feature.cfg | wc -l"))
version = SYS.exec("cat /tmp/feature.cfg |grep \"#version\" | awk '{print $2}'")
end
local display_str = "<strong>当前版本: </strong>" .. version .. "<br><strong>特征码个数:</strong> " ..
rule_count ..
"<br><strong> 下载地址:</strong><a href=\"https://destan19.github.io\">https://destan19.github.io</a>"
s = m:section(TypedSection, "feature", translate("Update feature"), display_str)
fu = s:option(FileUpload, "")
fu.template = "cbi/oaf_upload"
s.anonymous = true
um = s:option(DummyValue, "rule_data")
um.template = "cbi/oaf_dvalue"
local dir, fd
dir = "/tmp/upload/"
nixio.fs.mkdir(dir)
http.setfilehandler(function(meta, chunk, eof)
if not fd then
if not meta then
return
end
if meta and chunk then
fd = nixio.open(dir .. meta.file, "w")
end
if not fd then
return
end
end
if chunk and fd then
fd:write(chunk)
end
if eof and fd then
fd:close()
local fd2 = io.open("/tmp/upload/" .. meta.file)
local line = fd2:read("*l");
fd2:close()
local ret = string.match(line, "#version")
local lang = m.uci:get_all("luci.main.lang")
local feature_file = ""
if "" == lang or "auto" == lang then
feature_file = "/etc/appfilter/feature.cfg"
else
feature_file = "/etc/appfilter/feature_" .. lang .. ".cfg"
end
if ret ~= nil then
local cmd = "cp /tmp/upload/" .. meta.file .. " " .. feature_file;
os.execute(cmd);
os.execute("chmod 666 " .. feature_file);
os.execute("rm /tmp/appfilter -fr");
luci.sys.exec("/etc/init.d/appfilter restart &");
um.value = translate("Update the feature file successfully, please refresh the page")
else
um.value = translate("Failed to update feature file, format error")
end
os.execute("rm /tmp/upload/* -fr");
end
end)
if luci.http.formvalue("upload") then
local f = luci.http.formvalue("ulfile")
if #f <= 0 then
-- um.value = translate("No specify upload file.")
end
elseif luci.http.formvalue("download") then
Download()
end
return m

View File

@ -0,0 +1,36 @@
local ds = require "luci.dispatcher"
local nxo = require "nixio"
local nfs = require "nixio.fs"
local ipc = require "luci.ip"
local sys = require "luci.sys"
local utl = require "luci.util"
local dsp = require "luci.dispatcher"
local uci = require "luci.model.uci"
local lng = require "luci.i18n"
local jsc = require "luci.jsonc"
local http = luci.http
local SYS = require "luci.sys"
local m, s
m = Map("appfilter", translate(""), translate(""))
s = m:section(TypedSection, "time", translate("Time Setting"))
s.anonymous = true
hv = s:option(Value, "start_time", translate("Start Time"))
hv.default = "00:00"
hv.optional = false
hv = s:option(Value, "end_time", translate("End Time"))
hv.default = "23:59"
hv.optional = false
days = s:option(MultiValue, "days", "", translate(""))
days.widget = "checkbox"
days.size = 10
days:value("0", translate("Sun"));
days:value("1", translate("Mon"));
days:value("2", translate("Tue"));
days:value("3", translate("Wed"));
days:value("4", translate("Thur"));
days:value("5", translate("Fri"));
days:value("6", translate("Sat"));
return m

View File

@ -0,0 +1,19 @@
local ds = require "luci.dispatcher"
local nxo = require "nixio"
local nfs = require "nixio.fs"
local ipc = require "luci.ip"
local sys = require "luci.sys"
local utl = require "luci.util"
local dsp = require "luci.dispatcher"
local uci = require "luci.model.uci"
local lng = require "luci.i18n"
local jsc = require "luci.jsonc"
local http = luci.http
local SYS = require "luci.sys"
local m, s
m = Map("appfilter", translate(""), translate(""))
m:section(SimpleSection).template = "admin_network/user_status"
return m

View File

@ -0,0 +1,91 @@
local ds = require "luci.dispatcher"
local nxo = require "nixio"
local nfs = require "nixio.fs"
local ipc = require "luci.ip"
local sys = require "luci.sys"
local utl = require "luci.util"
local dsp = require "luci.dispatcher"
local uci = require "luci.model.uci"
local lng = require "luci.i18n"
local jsc = require "luci.jsonc"
local http = luci.http
local SYS = require "luci.sys"
local m, s
m = Map("appfilter", translate("App Filter"), translate(""))
function get_hostname_by_mac(dst_mac)
leasefile = "/tmp/dhcp.leases"
local fd = io.open(leasefile, "r")
if not fd then
return
end
while true do
local ln = fd:read("*l")
if not ln then
break
end
local ts, mac, ip, name, duid = ln:match("^(%d+) (%S+) (%S+) (%S+) (%S+)")
print(ln)
if dst_mac == mac then
fd:close()
return name
end
end
fd:close()
return nil
end
function get_cmd_result(command)
local fd
local result
fd = io.popen(command);
if not fd then
return ""
end
result = fd:read("*l");
fd:close()
return result
end
s = m:section(TypedSection, "user", translate("Select users"))
s.anonymous = true
users = s:option(MultiValue, "users", "", translate(
"It takes effect for all users by default, and only takes effect for the selected users when checked"))
users.widget = "checkbox"
-- users.widget="select"
users.size = 1
local fd = io.open("/tmp/dev_list", "r")
if not fd then
return m
end
while true do
local line = fd:read("*l")
if not line then
break
end
if not string.match(line, "^Id") then
local ip = get_cmd_result(string.format("echo '%s' | awk '{print $3}'", line))
local mac = get_cmd_result(string.format("echo '%s' | awk '{print $2}'", line))
local hostname = get_cmd_result(string.format("echo '%s' | awk '{print $4}'", line))
if mac ~= nil then
if not hostname or hostname == "*" then
users:value(mac, mac);
else
users:value(mac, hostname .. "(" .. mac .. ")");
end
end
end
end
fd:close()
local config_users = m.uci:get_all("appfilter.user.users")
if config_users ~= nil and config_users ~= false then
local r = utl.split(config_users, "%s+", nil, true)
local max = table.getn(r)
for i = 1, max, 1 do
users:value(r[i], r[i]);
end
end
return m

View File

@ -1,50 +1,52 @@
<style type="text/css">
<%
local dsp = require "luci.dispatcher"
-%>
<% local dsp=require "luci.dispatcher"
#display{
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 20px;
}
#main{
min-width: 600px;
height: 300px;
display: inline-block;
flex: 2 2 10%;
}
#main2{
min-width: 600px;
height: 300px;
display: inline-block;
flex: 2 2 10%;
}
table.imagetable {
font-family: verdana,arial,sans-serif;
font-size:11px;
color:#333333;
border-width: 1px;
border-color: #999999;
border-collapse: collapse;
padding-top:10px;
}
<!--
table.imagetable th {
background:#f5f5f5
border-width: 0px;
padding: 5px;
border-style: solid;
border-color: #999999;
}
table.imagetable td {
background:#ffffffff
border-width: 0px;
padding: 5px;
border-style: solid;
border-color: #999999;
}-->
-%>#display {
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 20px;
}
#main {
min-width: 600px;
height: 300px;
display: inline-block;
flex: 2 2 10%;
}
#main2 {
min-width: 600px;
height: 300px;
display: inline-block;
flex: 2 2 10%;
}
table.imagetable {
font-family: verdana, arial, sans-serif;
font-size: 11px;
color: #333333;
border-width: 1px;
border-color: #999999;
border-collapse: collapse;
padding-top: 10px;
}
< !-- table.imagetable th {
background: #f5f5f5 border-width: 0px;
padding: 5px;
border-style: solid;
border-color: #999999;
}
table.imagetable td {
background: #ffffffff border-width: 0px;
padding: 5px;
border-style: solid;
border-color: #999999;
}
-->
</style>
@ -52,320 +54,329 @@ table.imagetable td {
<script type="text/javascript" src="<%=resource%>/echarts.min.js?v=5.0"></script>
<script type="text/javascript">//<![CDATA[
window.onload =function(){
window.onload = function () {
}
var app_class_data;
var app_time_data;
var mac='<%=self.mac%>';
function get_display_time(total_time){
var hour=parseInt(total_time / 3600);
var seconds=total_time % 3600;
var min=parseInt(seconds / 60)
var seconds2=seconds % 60;
var mac = '<%=self.mac%>';
function get_display_time(total_time) {
var hour = parseInt(total_time / 3600);
var seconds = total_time % 3600;
var min = parseInt(seconds / 60)
var seconds2 = seconds % 60;
var total_time_str;
if (hour > 0)
total_time_str=hour + "<%:h%>" + min + "<%:m%>"
else{
total_time_str = hour + "<%:h%>" + min + "<%:m%>"
else {
if (min == 0 && seconds2 != 0)
min = 1;
total_time_str=min + "<%:m%>"
total_time_str = min + "<%:m%>"
}
return total_time_str;
}
function display_app_visit_view(data){
function display_app_visit_view(data) {
var myChart = echarts.init(document.getElementById('main2'));
var dev_array=new Array();
var m2R2Data=new Array()
var total_time=0
for(var i = 0; i < data.length; i++){
var dev_array = new Array();
var m2R2Data = new Array()
var total_time = 0
for (var i = 0; i < data.length; i++) {
var dev_obj = data[i];
var m2_obj={};
m2_obj.value=dev_obj.visit_time;
m2_obj.legendname=dev_obj.app_id;
var m2_obj = {};
m2_obj.value = dev_obj.visit_time;
m2_obj.legendname = dev_obj.app_id;
var tmp_time = get_display_time(dev_obj.visit_time);
m2_obj.name=dev_obj.app_id + " " + tmp_time;
total_time+=dev_obj.visit_time
m2_obj.name = dev_obj.app_id + " " + tmp_time;
total_time += dev_obj.visit_time
m2R2Data.push(m2_obj);
}
var total_time_str = get_display_time(total_time);
option = {
title: [
{
text: "<%:App Time Statistics%>",
textStyle: {
fontSize: 16,
color: "black"
},
left: "2%"
},
{
text: '',
subtext: total_time_str,
textStyle:{
fontSize:15,
color:"black"
},
subtextStyle: {
fontSize: 15,
color: 'black'
},
textAlign:"center",
x: '34.5%',
y: '44%',
}],
tooltip: {
trigger: 'item',
formatter:function (parms){
var total_time = get_display_time(parms.data.value);
var str= parms.seriesName+"</br>"+
parms.marker+""+parms.data.legendname+"</br>"+
"<%:Visit Time%>: "+ total_time+"</br>"+
"<%:Percentage%>: "+ parms.percent+"%";
return str ;
}
},
legend: {
type:"scroll",
orient: 'vertical',
left:'70%',
align:'left',
top:'middle',
textStyle: {
color:'#8C8C8C'
},
height:250
},
series: [
{
name: "<%:Visit Time%>",
type:'pie',
center: ['35%', '50%'],
radius: ['40%', '65%'],
clockwise: false,
avoidLabelOverlap: false,
label: {
normal: {
show: true,
position: 'outter',
formatter:function (parms){
return parms.data.legendname
}
}
},
labelLine: {
normal: {
length:8,
length2:7,
smooth:true,
}
},
data:m2R2Data
}
]
};
myChart.setOption(option);
}
function display_app_class_view(data){
console.log("begin display.");
var myChart = echarts.init(document.getElementById('main'));
var dev_array=new Array();
var m2R2Data=new Array()
var total_time=0
for(var i = 0; i < data.length; i++){
var dev_obj = data[i];
if (dev_obj.visit_time == 0)
continue;
var m2_obj={};
m2_obj.value=dev_obj.visit_time;
m2_obj.legendname=dev_obj.name;
var tmp_time = get_display_time(dev_obj.visit_time);
m2_obj.name=dev_obj.name + " " + tmp_time;
total_time+=dev_obj.visit_time
m2R2Data.push(m2_obj);
}
var total_time_str = get_display_time(total_time);
option = {
title: [
{
text: "<%:App classification time statistics%>",
textStyle: {
fontSize: 16,
color: "black"
{
text: "<%:App Time Statistics%>",
textStyle: {
fontSize: 16,
color: "black"
},
left: "2%"
},
left: "2%"
},
{
text: '',
subtext: total_time_str,
textStyle:{
fontSize:15,
color:"black"
},
subtextStyle: {
fontSize: 15,
color: 'black'
},
textAlign:"center",
x: '34.5%',
y: '44%',
}],
{
text: '',
subtext: total_time_str,
textStyle: {
fontSize: 15,
color: "black"
},
subtextStyle: {
fontSize: 15,
color: 'black'
},
textAlign: "center",
x: '34.5%',
y: '44%',
}],
tooltip: {
trigger: 'item',
formatter:function (parms){
formatter: function (parms) {
var total_time = get_display_time(parms.data.value);
var str= parms.seriesName+"</br>"+
parms.marker+""+parms.data.legendname+"</br>"+"<%:Visit Time%>: "+ total_time +"</br>" +
"<%:Percentage%>: "+ parms.percent+"%";
return str ;
var str = parms.seriesName + "</br>" +
parms.marker + "" + parms.data.legendname + "</br>" +
"<%:Visit Time%>: " + total_time + "</br>" +
"<%:Percentage%>: " + parms.percent + "%";
return str;
}
},
legend: {
type:"scroll",
type: "scroll",
orient: 'vertical',
left:'70%',
align:'left',
top:'middle',
left: '70%',
align: 'left',
top: 'middle',
textStyle: {
color:'#8C8C8C'
color: '#8C8C8C'
},
height:250
height: 250
},
series: [
{
name:"<%:Visit Time%>",
type:'pie',
name: "<%:Visit Time%>",
type: 'pie',
center: ['35%', '50%'],
radius: ['40%', '65%'],
clockwise: false,
clockwise: false,
avoidLabelOverlap: false,
label: {
normal: {
show: true,
position: 'outter',
formatter:function (parms){
formatter: function (parms) {
return parms.data.legendname
}
}
},
labelLine: {
normal: {
length:8,
length2:7,
smooth:true,
length: 8,
length2: 7,
smooth: true,
}
},
data:m2R2Data
data: m2R2Data
}
]
};
myChart.setOption(option);
}
new XHR().get('<%=url('admin/network/app_class_visit_time')%>/' + mac, null,
function(x, st)
{
function display_app_class_view(data) {
console.log("begin display.");
var myChart = echarts.init(document.getElementById('main'));
var dev_array = new Array();
var m2R2Data = new Array()
var total_time = 0
for (var i = 0; i < data.length; i++) {
var dev_obj = data[i];
if (dev_obj.visit_time == 0)
continue;
var m2_obj = {};
m2_obj.value = dev_obj.visit_time;
m2_obj.legendname = dev_obj.name;
var tmp_time = get_display_time(dev_obj.visit_time);
m2_obj.name = dev_obj.name + " " + tmp_time;
total_time += dev_obj.visit_time
m2R2Data.push(m2_obj);
}
var total_time_str = get_display_time(total_time);
option = {
title: [
{
text: "<%:App classification time statistics%>",
textStyle: {
fontSize: 16,
color: "black"
},
left: "2%"
},
{
text: '',
subtext: total_time_str,
textStyle: {
fontSize: 15,
color: "black"
},
subtextStyle: {
fontSize: 15,
color: 'black'
},
textAlign: "center",
x: '34.5%',
y: '44%',
}],
tooltip: {
trigger: 'item',
formatter: function (parms) {
var total_time = get_display_time(parms.data.value);
var str = parms.seriesName + "</br>" +
parms.marker + "" + parms.data.legendname + "</br>" + "<%:Visit Time%>: " + total_time + "</br>" +
"<%:Percentage%>: " + parms.percent + "%";
return str;
}
},
legend: {
type: "scroll",
orient: 'vertical',
left: '70%',
align: 'left',
top: 'middle',
textStyle: {
color: '#8C8C8C'
},
height: 250
},
series: [
{
name: "<%:Visit Time%>",
type: 'pie',
center: ['35%', '50%'],
radius: ['40%', '65%'],
clockwise: false,
avoidLabelOverlap: false,
label: {
normal: {
show: true,
position: 'outter',
formatter: function (parms) {
return parms.data.legendname
}
}
},
labelLine: {
normal: {
length: 8,
length2: 7,
smooth: true,
}
},
data: m2R2Data
}
]
};
myChart.setOption(option);
}
new XHR().get('<%=url('admin/network/app_class_visit_time')%>/' + mac, null,
function (x, st) {
display_app_class_view(st);
}
);
}
);
new XHR().get('<%=url('admin/network/dev_visit_time')%>/' + mac, null,
function(x, st)
{
function (x, st) {
display_app_visit_view(st);
}
);
}
);
new XHR().get('<%=url('admin/network/dev_visit_list')%>/' + mac, null,
function(x, st)
{
var tb = document.getElementById('user_status_table');
var str=JSON.stringify(st);
if (st && tb)
{
/* clear all rows */
while(tb.rows.length > 1)
tb.deleteRow(1);
for(var i = 0; i < st.length; i++ )
{
var action_status=""
if(st[i].latest_action == 1)
action_status="<%:Filtered%>"
else
action_status="<%:Unfiltered%>"
var hostname=""
if(st[i].hostname == "" || st[i].hostname == "*"){
hostname="--";
}
else{
hostname=st[i].hostname;
}
var tr = tb.insertRow(-1);
tr.className = 'tr cbi-rowstyle-' + ((i % 2) + 1);
tr.insertCell(-1).innerHTML = st[i].appname;
tr.insertCell(-1).innerHTML = hostname;
tr.insertCell(-1).innerHTML = st[i].mac;
tr.insertCell(-1).innerHTML = st[i].first_time;
var hour=parseInt(st[i].total_time / 3600);
var seconds=st[i].total_time % 3600;
var min=parseInt(seconds / 60)
var total_time_str;
if (st[i].latest_action == 1)
total_time_str="-"
else {
if (hour > 0)
total_time_str=hour + "<%:h%>" + min + "<%:m%>"
else{
if (min == 0)
min = 1;
total_time_str=min + "<%:m%>"
}
}
new XHR().get('<%=url('admin/network/dev_visit_list')%>/' + mac, null,
function (x, st) {
var tb = document.getElementById('user_status_table');
var str = JSON.stringify(st);
if (st && tb) {
/* clear all rows */
while (tb.rows.length > 1)
tb.deleteRow(1);
for (var i = 0; i < st.length; i++) {
var action_status = ""
if (st[i].latest_action == 1)
action_status = "<%:Filtered%>"
else
action_status = "<%:Unfiltered%>"
var hostname = ""
if (st[i].hostname == "" || st[i].hostname == "*") {
hostname = "--";
}
else {
hostname = st[i].hostname;
}
var tr = tb.insertRow(-1);
tr.className = 'tr cbi-rowstyle-' + ((i % 2) + 1);
tr.insertCell(-1).innerHTML = st[i].appname;
tr.insertCell(-1).innerHTML = hostname;
tr.insertCell(-1).innerHTML = st[i].mac;
tr.insertCell(-1).innerHTML = st[i].first_time;
var hour = parseInt(st[i].total_time / 3600);
var seconds = st[i].total_time % 3600;
var min = parseInt(seconds / 60)
var total_time_str;
if (st[i].latest_action == 1)
total_time_str = "-"
else {
if (hour > 0)
total_time_str = hour + "<%:h%>" + min + "<%:m%>"
else {
if (min == 0)
min = 1;
total_time_str = min + "<%:m%>"
}
}
tr.insertCell(-1).innerHTML = total_time_str;
tr.insertCell(-1).innerHTML = action_status;
var childs = tr.childNodes;
Array.prototype.forEach.call(childs,function(child){
child.className = 'td';
});
tr.insertCell(-1).innerHTML = total_time_str;
tr.insertCell(-1).innerHTML = action_status;
var childs = tr.childNodes;
Array.prototype.forEach.call(childs, function (child) {
child.className = 'td';
}
}
}
);
});
}
}
}
);
//]]></script>
<div class="cbi-section cbi-tblsection">
<div id="display">
<div id="main" class="main left"></div>
<div id="main2" class="main2 left"></div>
<div id="main" class="main left"></div>
<div id="main2" class="main2 left"></div>
</div>
<table class="table cbi-section-table" id="user_status_table">
<tr class="tr table-titles">
<th class="th"><%:App Name%></th>
<th class="th"><%:Hostname%></th>
<th class="th"><%:Mac%></th>
<th class="th"><%:Start Time%></th>
<th class="th"><%:Visit Time%></th>
<th class="th"><%:Filter Status%></th>
</tr>
<tr class="tr table-titles">
<td class="td" colspan="8"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
<table class="table cbi-section-table" id="user_status_table">
<tr class="tr table-titles">
<th class="th">
<%:App Name%>
</th>
<th class="th">
<%:Hostname%>
</th>
<th class="th">
<%:Mac%>
</th>
<th class="th">
<%:Start Time%>
</th>
<th class="th">
<%:Visit Time%>
</th>
<th class="th">
<%:Filter Status%>
</th>
</tr>
<tr class="tr table-titles">
<td class="td" colspan="8"><em><br />
<%:Collecting data...%>
</em></td>
</tr>
</table>
</div>
</div>

View File

@ -1,74 +1,82 @@
<%
local dsp = require "luci.dispatcher"
-%>
<script type="text/javascript">//<![CDATA[
XHR.poll(5, '<%=url('admin/network/dev_app_status')%>', null,
function(x, st)
{
var tb = document.getElementById('user_status_table');
var dev_list_str=JSON.stringify(st);
if (st && tb)
{
while(tb.rows.length > 1)
tb.deleteRow(1);
var devlist = st.devlist
for(var i = 0; i < devlist.length; i++ )
{
var hostname=""
if(devlist[i].hostname == "" || devlist[i].hostname == "*"){
hostname="--";
<% local dsp=require "luci.dispatcher" -%>
<script type="text/javascript">//<![CDATA[
XHR.poll(5, '<%=url('admin/network/dev_app_status')%>', null,
function (x, st) {
var tb = document.getElementById('user_status_table');
var dev_list_str = JSON.stringify(st);
if (st && tb) {
while (tb.rows.length > 1)
tb.deleteRow(1);
var devlist = st.devlist
for (var i = 0; i < devlist.length; i++) {
var hostname = ""
if (devlist[i].hostname == "" || devlist[i].hostname == "*") {
hostname = "--";
}
else {
hostname = devlist[i].hostname;
}
var tr = tb.insertRow(-1);
tr.className = 'tr cbi-rowstyle-' + ((i % 2) + 1);
tr.insertCell(-1).innerHTML = i + 1;
tr.insertCell(-1).innerHTML = hostname;
tr.insertCell(-1).innerHTML = "<a href='<%=url('admin/services/appfilter/user_list/')%>" + devlist[i].mac + "'>" + devlist[i].mac + "</a>";
tr.insertCell(-1).innerHTML = devlist[i].ip;
var app_list_str = "";
for (var j = 0; j < devlist[i].applist.length; j++) {
console.log(devlist[i].applist[j].name);
app_list_str += devlist[i].applist[j].name;
if (j != devlist[i].applist.length - 1)
app_list_str += ","
}
if (app_list_str == "") {
app_list_str = "--"
}
tr.insertCell(-1).innerHTML = app_list_str;
if (devlist[i].online == 1) {
tr.insertCell(-1).innerHTML = "<%:Online%>";
} else {
tr.insertCell(-1).innerHTML = "<%:Offline%>";
}
var childs = tr.childNodes;
Array.prototype.forEach.call(childs, function (child) {
child.className = 'td';
});
}
else{
hostname=devlist[i].hostname;
}
var tr = tb.insertRow(-1);
tr.className = 'tr cbi-rowstyle-' + ((i % 2) + 1);
tr.insertCell(-1).innerHTML = i + 1;
tr.insertCell(-1).innerHTML = hostname;
tr.insertCell(-1).innerHTML = "<a href='<%=url('admin/network/appfilter/')%>"+devlist[i].mac+"'>"+devlist[i].mac+"</a>";
tr.insertCell(-1).innerHTML = devlist[i].ip;
var app_list_str="";
for (var j = 0; j < devlist[i].applist.length; j++){
console.log(devlist[i].applist[j].name);
app_list_str+=devlist[i].applist[j].name;
if (j != devlist[i].applist.length - 1)
app_list_str+=","
}
if(app_list_str == ""){
app_list_str="--"
}
tr.insertCell(-1).innerHTML = app_list_str;
if (devlist[i].online == 1){
tr.insertCell(-1).innerHTML = "<%:Online%>";
}else{
tr.insertCell(-1).innerHTML = "<%:Offline%>";
}
var childs = tr.childNodes;
Array.prototype.forEach.call(childs,function(child){
child.className = 'td';
});
}
}
}
);
);
//]]></script>
<div class="cbi-section cbi-tblsection">
<h3><%:Client List%></h3>
<table class="table cbi-section-table" id="user_status_table">
<tr class="tr table-titles">
<th class="th"><%:Id%></th>
<th class="th"><%:Hostname%></th>
<th class="th"><%:Mac%></th>
<th class="th"><%:Ip%></th>
<th class="th"><%:Common App(TOP5)%></th>
<th class="th"><%:Online Status%></th>
</tr>
<tr class="tr">
<td class="td" colspan="8"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</div>
<div class="cbi-section cbi-tblsection">
<table class="table cbi-section-table" id="user_status_table">
<tr class="tr table-titles">
<th class="th">
<%:Id%>
</th>
<th class="th">
<%:Hostname%>
</th>
<th class="th">
<%:Mac%>
</th>
<th class="th">
<%:Ip%>
</th>
<th class="th">
<%:Common App(TOP5)%>
</th>
<th class="th">
<%:Online Status%>
</th>
</tr>
<tr class="tr">
<td class="td" colspan="8"><em><br />
<%:Collecting data...%>
</em></td>
</tr>
</table>
</div>

View File

@ -44,8 +44,8 @@ msgstr "基本设置"
msgid "App Filter Rules"
msgstr "应用过滤规则"
msgid "Select at least one user, otherwise it will take effect for all users"
msgstr "至少选择一个用户,否则对所有用户生效"
msgid "It takes effect for all users by default, and only takes effect for the selected users when checked"
msgstr "默认对所有用户生效,勾选后只对选择的用户生效"
msgid "Select users"
msgstr "选择用户"

View File

@ -1,14 +0,0 @@
#!/bin/sh
# replace existing mwan ucitrack entry
uci -q batch <<-EOF >/dev/null
del ucitrack.@appfilter[-1]
add ucitrack appfilter
set ucitrack.@appfilter[-1].exec="/usr/bin/oaf_rule reload"
commit ucitrack
EOF
# remove LuCI cache
rm -rf /tmp/luci-indexcache /tmp/luci-modulecache
exit 0

View File

@ -1,8 +0,0 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
set appfilter.user=user
appfilter.feature=feature
commit appfilter
EOF
exit 0

View File

@ -1,14 +1,14 @@
msgid ""
msgstr ""
"PO-Revision-Date: 2020-09-21 12:51+0000\n"
"Last-Translator: Weblate Admin <contact@openmptcprouter.com>\n"
"PO-Revision-Date: 2022-02-21 21:14+0000\n"
"Last-Translator: Deleted User <noreply+28@weblate.org>\n"
"Language-Team: Italian <http://weblate.openmptcprouter.com/projects/omr/"
"luciapplicationssnmpd/it/>\n"
"Language: it\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.0.4\n"
"X-Generator: Weblate 4.10.1\n"
#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:82
msgid "Access"
@ -51,13 +51,13 @@ msgstr "Abilitato"
#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:132
msgid "Exec"
msgstr ""
msgstr "Esegui"
#: luci-app-snmpd/luasrc/model/cbi/snmpd.lua:6
#: luci-app-snmpd/luasrc/view/snmpd.htm:21
#: luci-app-snmpd/luasrc/view/snmpd.htm:48
msgid "General"
msgstr ""
msgstr "Generale"
#: luci-app-snmpd/root/usr/share/rpcd/acl.d/luci-app-snmpd.json:3
msgid "Grant UCI access for luci-app-snmpd"

View File

@ -1,4 +1,5 @@
config global global
option enable '0'
config appfilter appfilter
@ -8,4 +9,4 @@ config time 'time'
option end_time '23:59'
option days '0 1 2 3 4 5 6'
option start_time '00:00'
config user user
config user user