🐶 Sync 2026-04-18 02:04:09

This commit is contained in:
github-actions[bot] committed 2026-04-18 02:04:09 +08:00
1 parent 411261cf2a
commit 50677d77a8
207 files changed
+3148 -3426

No files matched your search

+2 -1
View File
@@ -9,9 +9,10 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI Access Control Configuration
LUCI_DEPENDS:=
LUCI_PKGARCH:=all
PKG_NAME:=luci-app-accesscontrol
PKG_VERSION:=1
PKG_RELEASE:=1
PKG_RELEASE:=2
include $(TOPDIR)/feeds/luci/luci.mk
@@ -5,10 +5,7 @@ function index()
return
end
local page = entry({"admin", "services", "mia"}, cbi("mia"), _("Internet Access Schedule Control"), 30)
page.dependent = true
page.acl_depends = { "luci-app-accesscontrol" }
entry({"admin", "services", "mia"}, cbi("mia"), _("Internet Access Schedule Control"), 30).dependent = true
entry({"admin", "services", "mia", "status"}, call("act_status")).leaf = true
end
@@ -1,5 +1,7 @@
a = Map("mia")
a.title = translate("Internet Access Schedule Control")
a.description = translate("Access Schedule Control Settins")
a = Map("mia", translate("Internet Access Schedule Control"), translate("Access Schedule Control Settins"))
a:section(SimpleSection).template = "mia/mia_status"
t = a:section(TypedSection, "basic")
@@ -9,8 +11,8 @@ e = t:option(Flag, "enable", translate("Enabled"))
e.rmempty = false
e = t:option(Flag, "strict", translate("Strict Mode"))
e.rmempty = false
e.description = translate("Strict Mode will degrade CPU performance, but it can achieve better results")
e.rmempty = false
t = a:section(TypedSection, "macbind", translate("Client Rules"))
t.template = "cbi/tblsection"
@@ -28,12 +30,12 @@ e:value(t,"%s (%s)"%{t,a})
end)
e = t:option(Value, "timeon", translate("Start time"))
e.default = "00:00"
e.optional = false
e.default = "00:00"
e = t:option(Value, "timeoff", translate("End time"))
e.default = "23:59"
e.optional = false
e.default = "23:59"
e = t:option(Flag, "z1", translate("Mon"))
e.rmempty = true
-1
View File
@@ -1 +0,0 @@
zh_Hans
@@ -28,9 +28,6 @@ msgstr "开始时间"
msgid "End time"
msgstr "结束时间"
msgid "Enabled"
msgstr "启用"
msgid "Mon"
msgstr "一"
+1
View File
@@ -0,0 +1 @@
zh-cn
+1 -1
View File
@@ -1 +1 @@
/etc/init.d/mia restart
/etc/init.d/mia restart
@@ -13,6 +13,7 @@ uci -q batch <<-EOF >/dev/null
add ucitrack mia
set ucitrack.@mia[-1].init=mia
commit ucitrack
delete firewall.mia
set firewall.mia=include
set firewall.mia.type=script
-13
View File
@@ -1,13 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 ImmortalWrt.org
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI app for AList
LUCI_DEPENDS:=+alist
LUCI_PKGARCH:=all
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
@@ -1,151 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
'use strict';
'require form';
'require poll';
'require rpc';
'require uci';
'require validation';
'require view';
var callServiceList = rpc.declare({
object: 'service',
method: 'list',
params: ['name'],
expect: { '': {} }
});
function getServiceStatus() {
return L.resolveDefault(callServiceList('alist'), {}).then(function (res) {
var isRunning = false;
try {
isRunning = res['alist']['instances']['instance1']['running'];
} catch (e) { }
return isRunning;
});
}
function renderStatus(isRunning, port) {
var spanTemp = '<span style="color:%s"><strong>%s %s</strong></span>';
var renderHTML;
if (isRunning) {
var button = String.format('&#160;<a class="btn cbi-button" href="http://%s:%s" target="_blank" rel="noreferrer noopener">%s</a>',
window.location.hostname, port, _('Open Web Interface'));
renderHTML = spanTemp.format('green', _('AList'), _('RUNNING')) + button;
} else {
renderHTML = spanTemp.format('red', _('AList'), _('NOT RUNNING'));
}
return renderHTML;
}
var stubValidator = {
factory: validation,
apply: function(type, value, args) {
if (value != null)
this.value = value;
return validation.types[type].apply(this, args);
},
assert: function(condition) {
return !!condition;
}
};
return view.extend({
load: function() {
return Promise.all([
uci.load('alist')
]);
},
render: function(data) {
var m, s, o;
var webport = uci.get(data[0], 'config', 'listen_http_port') || '5244';
m = new form.Map('alist', _('AList'),
_('A file list/WebDAV program that supports multiple storages, powered by Gin and Solidjs.<br />' +
'Default login username is <code>admin</code> and password is <code>password</code>.'));
s = m.section(form.TypedSection);
s.anonymous = true;
s.render = function () {
poll.add(function () {
return L.resolveDefault(getServiceStatus()).then(function (res) {
var view = document.getElementById('service_status');
view.innerHTML = renderStatus(res, webport);
});
});
return E('div', { class: 'cbi-section', id: 'status_bar' }, [
E('p', { id: 'service_status' }, _('Collecting data...'))
]);
}
s = m.section(form.NamedSection, 'config', 'alist');
o = s.option(form.Flag, 'enabled', _('Enable'));
o.default = o.disabled;
o.rmempty = false;
o = s.option(form.Value, 'listen_addr', _('Listen address'));
o.default = '0.0.0.0';
o.rmempty = false;
o.validate = function(section_id, value) {
if (!value)
return _('Expecting: %s').format(_('non-empty value'));
var m4 = value.match(/^([^\[\]:]+)$/),
m6 = value.match(/^\[(.+)\]$/ );
if ((!m4 && !m6) || !stubValidator.apply('ipaddr', m4 ? m4[1] : m6[1]))
return _('Expecting: %s').format(_('valid IP address'));
return true;
}
o = s.option(form.Value, 'listen_http_port', _('Listen port'));
o.datatype = 'port';
o.default = '5244';
o.rmempty = false;
o = s.option(form.Value, 'site_login_expire', _('Login expiration time'),
_('User login expiration time (in hours).'));
o.datatype = 'uinteger';
o.default = '48';
o.rmempty = false;
o = s.option(form.Value, 'site_max_connections', _('Max connections'),
_('The maximum number of concurrent connections at the same time (0 = unlimited).'));
o.datatype = 'uinteger';
o.default = '0';
o.rmempty = false;
o = s.option(form.Flag, 'site_tls_insecure', _('Allow insecure connection'),
_('Allow connection even if the remote TLS certificate is invalid (<strong>not recommended</strong>).'));
o.default = o.disabled;
o = s.option(form.Flag, 'log_enable', _('Enable logging'));
o.default = o.enabled;
o = s.option(form.Value, 'log_max_size', _('Max log size'),
_('The maximum size in megabytes of the log file before it gets rotated.'));
o.datatype = 'uinteger';
o.default = '5';
o.depends('log_enable', '1');
o = s.option(form.Value, 'log_max_backups', _('Max log backups'),
_('The maximum number of old log files to retain.'));
o.datatype = 'uinteger';
o.default = '1';
o.depends('log_enable', '1');
o = s.option(form.Value, 'log_max_age', _('Max log age'),
_('The maximum days of the log file to retain.'));
o.datatype = 'uinteger';
o.default = '15';
o.depends('log_enable', '1');
return m.render();
}
});
@@ -1,75 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
'use strict';
'require dom';
'require fs';
'require poll';
'require uci';
'require view';
return view.extend({
render: function() {
/* Thanks to luci-app-aria2 */
var css = ' \
#log_textarea { \
padding: 10px; \
text-align: left; \
} \
#log_textarea pre { \
padding: .5rem; \
word-break: break-all; \
margin: 0; \
} \
.description { \
background-color: #33ccff; \
}';
var log_textarea = E('div', { 'id': 'log_textarea' },
E('img', {
'src': L.resource(['icons/loading.gif']),
'alt': _('Loading...'),
'style': 'vertical-align:middle'
}, _('Collecting data...'))
);
poll.add(L.bind(function() {
return fs.read_direct('/var/run/alist/log/alist.log', 'text')
.then(function(res) {
var log = E('pre', { 'wrap': 'pre' }, [
res.trim() || _('Log is empty.')
]);
dom.content(log_textarea, log);
}).catch(function(err) {
var log;
if (err.toString().includes('NotFoundError'))
log = E('pre', { 'wrap': 'pre' }, [
_('Log file does not exist.')
]);
else
log = E('pre', { 'wrap': 'pre' }, [
_('Unknown error: %s').format(err)
]);
dom.content(log_textarea, log);
});
}));
return E([
E('style', [ css ]),
E('div', {'class': 'cbi-map'}, [
E('div', {'class': 'cbi-section'}, [
log_textarea,
E('div', {'style': 'text-align:right'},
E('small', {}, _('Refresh every %s seconds.').format(L.env.pollinterval))
)
])
])
]);
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});
-146
View File
@@ -1,146 +0,0 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:67
msgid ""
"A file list/WebDAV program that supports multiple storages, powered by Gin "
"and Solidjs.<br />Default login username is <code>admin</code> and password "
"is <code>password</code>."
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:34
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:36
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:66
#: applications/luci-app-alist/root/usr/share/luci/menu.d/luci-app-alist.json:3
msgid "AList"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:125
msgid ""
"Allow connection even if the remote TLS certificate is invalid (<strong>not "
"recommended</strong>)."
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:124
msgid "Allow insecure connection"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:81
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/log.js:32
msgid "Collecting data..."
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:87
msgid "Enable"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:128
msgid "Enable logging"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:96
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:102
msgid "Expecting: %s"
msgstr ""
#: applications/luci-app-alist/root/usr/share/rpcd/acl.d/luci-app-alist.json:3
msgid "Grant access to AList configuration"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:91
msgid "Listen address"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:107
msgid "Listen port"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/log.js:30
msgid "Loading..."
msgstr ""
#: applications/luci-app-alist/root/usr/share/luci/menu.d/luci-app-alist.json:22
msgid "Log"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/log.js:48
msgid "Log file does not exist."
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/log.js:39
msgid "Log is empty."
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:112
msgid "Login expiration time"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:118
msgid "Max connections"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:143
msgid "Max log age"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:137
msgid "Max log backups"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:131
msgid "Max log size"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:36
msgid "NOT RUNNING"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:33
msgid "Open Web Interface"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:34
msgid "RUNNING"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/log.js:65
msgid "Refresh every %s seconds."
msgstr ""
#: applications/luci-app-alist/root/usr/share/luci/menu.d/luci-app-alist.json:14
msgid "Settings"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:144
msgid "The maximum days of the log file to retain."
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:119
msgid ""
"The maximum number of concurrent connections at the same time (0 = "
"unlimited)."
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:138
msgid "The maximum number of old log files to retain."
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:132
msgid "The maximum size in megabytes of the log file before it gets rotated."
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/log.js:52
msgid "Unknown error: %s"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:113
msgid "User login expiration time (in hours)."
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:96
msgid "non-empty value"
msgstr ""
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:102
msgid "valid IP address"
msgstr ""
-1
View File
@@ -1 +0,0 @@
zh_Hans
-155
View File
@@ -1,155 +0,0 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Project-Id-Version: PACKAGE VERSION\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: zh-Hans\n"
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:67
msgid ""
"A file list/WebDAV program that supports multiple storages, powered by Gin "
"and Solidjs.<br />Default login username is <code>admin</code> and password "
"is <code>password</code>."
msgstr ""
"一个支持多存储的 文件列表/WebDAV 程序,使用 Gin 和 Solidjs。<br />默认登录用"
"户名 <code>admin</code> 密码 <code>password</code>。"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:34
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:36
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:66
#: applications/luci-app-alist/root/usr/share/luci/menu.d/luci-app-alist.json:3
msgid "AList"
msgstr "AList"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:125
msgid ""
"Allow connection even if the remote TLS certificate is invalid (<strong>not "
"recommended</strong>)."
msgstr "即使远程 TLS 证书无效,也允许连接(<strong>不推荐</strong>)。"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:124
msgid "Allow insecure connection"
msgstr "允许不安全连接"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:81
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/log.js:32
msgid "Collecting data..."
msgstr "收集数据中..."
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:87
msgid "Enable"
msgstr "启用"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:128
msgid "Enable logging"
msgstr "启用日志"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:96
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:102
msgid "Expecting: %s"
msgstr "请输入:%s"
#: applications/luci-app-alist/root/usr/share/rpcd/acl.d/luci-app-alist.json:3
msgid "Grant access to AList configuration"
msgstr "授予访问 AList 配置的权限"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:91
msgid "Listen address"
msgstr "监听地址"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:107
msgid "Listen port"
msgstr "监听端口"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/log.js:30
msgid "Loading..."
msgstr "加载中..."
#: applications/luci-app-alist/root/usr/share/luci/menu.d/luci-app-alist.json:22
msgid "Log"
msgstr "日志"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/log.js:48
msgid "Log file does not exist."
msgstr "日志文件不存在。"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/log.js:39
msgid "Log is empty."
msgstr "日志为空。"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:112
msgid "Login expiration time"
msgstr "登录过期时间"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:118
msgid "Max connections"
msgstr "最大连接数"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:143
msgid "Max log age"
msgstr "日志最长保留时间"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:137
msgid "Max log backups"
msgstr "日志最大备份数"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:131
msgid "Max log size"
msgstr "日志最大大小"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:36
msgid "NOT RUNNING"
msgstr "未运行"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:33
msgid "Open Web Interface"
msgstr "打开 Web 界面"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:34
msgid "RUNNING"
msgstr "运行中"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/log.js:65
msgid "Refresh every %s seconds."
msgstr "每 %s 秒刷新。"
#: applications/luci-app-alist/root/usr/share/luci/menu.d/luci-app-alist.json:14
msgid "Settings"
msgstr "设置"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:144
msgid "The maximum days of the log file to retain."
msgstr "日志文件的最长保存天数。"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:119
msgid ""
"The maximum number of concurrent connections at the same time (0 = "
"unlimited)."
msgstr "允许的最大并发连接数(0 = 不限制)。"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:138
msgid "The maximum number of old log files to retain."
msgstr "要保留的最大旧日志文件数量。"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:132
msgid "The maximum size in megabytes of the log file before it gets rotated."
msgstr "轮换前的最大日志大小(单位:MB)。"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/log.js:52
msgid "Unknown error: %s"
msgstr "未知错误:%s"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:113
msgid "User login expiration time (in hours)."
msgstr "用户登录过期时间(单位:小时)。"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:96
msgid "non-empty value"
msgstr "非空值"
#: applications/luci-app-alist/htdocs/luci-static/resources/view/alist/config.js:102
msgid "valid IP address"
msgstr "有效 IP 地址"
@@ -1,29 +0,0 @@
{
"admin/services/alist": {
"title": "AList",
"order": 10,
"action": {
"type": "firstchild"
},
"depends": {
"acl": [ "luci-app-alist" ],
"uci": { "alist": true }
}
},
"admin/services/alist/config": {
"title": "Settings",
"order": 10,
"action": {
"type": "view",
"path": "alist/config"
}
},
"admin/services/alist/log": {
"title": "Log",
"order": 20,
"action": {
"type": "view",
"path": "alist/log"
}
}
}
@@ -1,17 +0,0 @@
{
"luci-app-alist": {
"description": "Grant access to AList configuration",
"read": {
"file": {
"/var/run/alist/log/alist.log": [ "read" ]
},
"ubus": {
"service": [ "list" ]
},
"uci": [ "alist" ]
},
"write": {
"uci": [ "alist" ]
}
}
}
-17
View File
@@ -1,17 +0,0 @@
## Copyright (C) 2018 By-Ameng Openwrt.org
#
## This is free software, licensed under the Apache License, Version 2.0 .
#
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=luci-app-cifs
LUCI_DEPENDS:=+kmod-fs-cifs +kmod-nls-utf8 +kmod-nls-base +kmod-crypto-hmac +kmod-crypto-md5 +kmod-crypto-misc +cifsmount
LUCI_PKGARCH:=all
PKG_VERSION:=1.0
PKG_RELEASE:=1
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
-24
View File
@@ -1,24 +0,0 @@
-- Copyright 2015
-- Matthew
-- Licensed to the public under the Apache License 2.0.
module("luci.controller.cifs", package.seeall)
function index()
if not nixio.fs.access("/etc/config/cifs") then
return
end
local page = entry({"admin", "services", "cifs"}, cbi("cifs"), _("Mounting NAT drives"))
page.dependent = true
page.acl_depends = { "luci-app-cifs" }
entry({"admin", "services", "cifs", "status"}, call("act_status")).leaf = true
end
function act_status()
local e = {}
e.running = luci.sys.call("pidof cifsd > /dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
-97
View File
@@ -1,97 +0,0 @@
-- Copyright 2015
-- Matthew
-- Licensed to the public under the Apache License 2.0.
local fs = require "nixio.fs"
m = Map("cifs", translate("Mounting NAT drives"))
m.description = translate("Allows you mounting Nat drives")
m:section(SimpleSection).template = "cifs/cifs_status"
s = m:section(TypedSection, "cifs", "Cifs")
s.anonymous = true
s:tab("general", translate("General Settings"))
switch = s:taboption("general", Flag, "enabled", translate("Enable"))
switch.rmempty = false
workgroup = s:taboption("general", Value, "workgroup", translate("Workgroup"))
workgroup.default = "WORKGROUP"
mountarea = s:taboption("general", Value, "mountarea", translate("Mount Area"))
mountarea.description = translate("All the Mounted NAT Drives will be centralized into this folder.")
mountarea.default = "/tmp/mnt"
mountarea.rmempty = false
delay = s:taboption("general", Value, "delay", translate("Delay"))
delay.description = translate("Delay command runing for wait till your drivers online.\n Only work in start mode(/etc/init.d/cifs start) ")
delay:value("0")
delay:value("3")
delay:value("5")
delay:value("7")
delay:value("10")
delay.default = "5"
iocharset = s:taboption("general", Value, "iocharset", translate("Iocharset"))
iocharset.description = translate("Character Encoding")
iocharset.default = "utf8"
s = m:section(TypedSection, "natshare", translate("NAT Drivers"))
s.anonymous = true
s.addremove = true
s.template = "cbi/tblsection"
server = s:option(Value, "server", translate("Server"))
server.description = translate("Server Name/IP")
server.size = 6
server.rmempty = false
name = s:option(Value, "name", translate("Name"))
name.description = translate("Mouting Folder Name")
name.size = 6
name.rmempty = false
sec = s:option(Value, "sec", translate("Choose Safety Mode"))
sec:value("none")
sec:value("krb5")
sec:value("krb5i")
sec:value("ntlm")
sec:value("ntlmi")
sec:value("ntlmv2")
sec:value("ntlmv2i")
sec.rmempty = true
sec.size = 7
agm = s:option(Value, "agm", translate("Arguments"))
agm:value("rm", translate"rm: Read Only")
agm:value("rw", translate"rw: Read and Write")
agm:value("noperm")
agm:value("noacl")
agm:value("sfu")
agm:value("dirctio")
agm:value("file_mode=0755,dir_mode=0n755")
agm:value("nounix", translate"nounix: Disable Unix Extensions")
agm.rmempty = true
agm.size = 8
guest = s:option(Flag, "guest", translate("Using Guest"))
guest.rmempty = false
guest.enabled = "1"
guest.disabled = "0"
users = s:option(Value, "users", translate("Users"))
users.size = 3
users.rmempty = true
pwd = s:option(Value, "pwd", translate("password"))
pwd.rmempty = true
pwd.size = 3
local apply = luci.http.formvalue("cbi.apply")
if apply then
io.popen("/etc/init.d/cifs restart")
end
return m
-22
View File
@@ -1,22 +0,0 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[cifs]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('cifs_status');
if (data && tb) {
if (data.running) {
var links = '<em><b><font color=green><%:Mounting NAT drives%> <%:RUNNING%></font></b></em>';
tb.innerHTML = links;
} else {
tb.innerHTML = '<em><b><font color=red><%:Mounting NAT drives%> <%:NOT RUNNING%></font></b></em>';
}
}
}
);
//]]>
</script>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<fieldset class="cbi-section">
<p id="cifs_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>
-1
View File
@@ -1 +0,0 @@
zh_Hans
-41
View File
@@ -1,41 +0,0 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8\n"
msgid "Mounting NAT drives"
msgstr "挂载网络驱动器"
msgid "Allows you mounting Nat drives"
msgstr "允许挂载网络驱动器"
msgid "Mount Area"
msgstr "挂载目录"
msgid "All the Mounted NAT Drives will be centralized into this folder."
msgstr "所有安装的网络驱动器都将集中到这个文件夹中。"
msgid "Delay"
msgstr "延迟"
msgid "Delay command runing for wait till your drivers online.\n Only work in start mode(/etc/init.d/cifs start) "
msgstr "延迟命令运行,等待驱动程序联机。\n仅在启动模式下工作(/etc/init.d/cifs start)"
msgid "Iocharset"
msgstr "编码"
msgid "Character Encoding"
msgstr "字符编码"
msgid "NAT Drivers"
msgstr "网络硬盘"
msgid "Server Name/IP"
msgstr "服务器名称/ip地址"
msgid "Mouting Folder Name"
msgstr "共享目录/名称"
msgid "Choose Safety Mode"
msgstr "安全模式"
msgid "Arguments"
msgstr "共享权限"
-7
View File
@@ -1,7 +0,0 @@
config cifs
option enabled '0'
option workgroup 'WORKGROUP'
option iocharset 'utf8'
option delay '5'
option mountarea '/tmp/mnt'
-184
View File
@@ -1,184 +0,0 @@
#!/bin/sh /etc/rc.common
START=99
ENABLED=0
MOUNTAREA=0
WORKGROUPD=0
IOCHARSET=0
DELAY=0
GUEST=""
USERS=""
SEC=""
AGM=""
cifs_header() {
local enabled
local workgroup
local mountarea
local delay
local iocharset
config_get enabled $1 enabled
config_get mountarea $1 mountarea
config_get workgroup $1 workgroup
config_get delay $1 delay
config_get iocharset $1 iocharset
ENABLED=$enabled
MOUNTAREA=$mountarea
WORKGROUPD=$workgroup
IOCHARSET=$iocharset
if [ $delay != 0 ]
then
DELAY=$delay
fi
}
mount_natshare() {
local server
local name
local guest
local users
local pwd
local sec
local agm
local _mount_path
local _agm
config_get server $1 server
config_get name $1 name
config_get guest $1 guest
config_get users $1 users
config_get pwd $1 pwd
config_get sec $1 sec
config_get agm $1 agm
if [ $guest == 1 ]
then
GUEST="guest,"
USERS=""
else if [ $guest == 0 ]
then {
if [ $users ]
then
USERS="username=$users,password=$pwd,"
GUEST=""
else
USERS=""
GUEST="guest,"
fi
}
fi
fi
if [ $sec ]
then
SEC=",sec=$sec"
else
SEC=""
fi
if [ $agm ]
then
AGM=",$agm"
else
AGM=""
fi
natpath="//${server}/$name"
append _mount_path "$MOUNTAREA/$name"
append _agm "-o ${USERS}${GUEST},dom=$WORKGROUPD,iocharset=$IOCHARSET,$SEC,$AGM,vers=1.0"
sleep 1
mkdir -p $_mount_path
mount -t cifs $natpath $_mount_path $_agm
}
umount_natshare() {
local server
local name
local _mount_path
config_get server $1 server
config_get name $1 name
append _mount_path "$MOUNTAREA/$name"
sleep 1
umount -d -l $_mount_path
rm -r -f $_mount_path
}
change_natshare() {
sleep 1
}
start() {
config_load cifs
config_foreach cifs_header cifs
echo "Checking..."
if [ $ENABLED == 1 ]
then {
echo "Cifs Mount is Enabled."
echo "Starting..."
if [ $DELAY != 0 ]
then
sleep $DELAY
echo "DELAY Operation ${DELAY}s"
else
echo "Not DELAY ${DELAY}s"
fi
config_foreach mount_natshare natshare
echo "Cifs Mount succeed."
}
else
echo "Cifs Mount is Disabled.Please enter The Web Cotrol Center to enable it."
fi
}
stop() {
echo "Umounting..."
config_load cifs
config_foreach cifs_header cifs
config_foreach umount_natshare natshare
echo "Cifs Umount succeed."
}
restart() {
echo 'Umounting... '
config_load cifs
config_foreach cifs_header cifs
config_foreach umount_natshare natshare
echo "Cifs Umount succeed."
echo ''
echo 'Checking... '
if [ $ENABLED == 1 ]
then {
echo 'Cifs Mmount is Enabled. '
echo 'Starting... '
config_foreach mount_natshare natshare
echo "Cifs Mount succeed."
}
else
/etc/init.d/cifs disable
echo "Cifs Mount is Disabled.Please enter The Web Cotrol Center to enable it."
fi
}
@@ -1,22 +0,0 @@
#!/bin/sh
[ ! -f "/usr/share/ucitrack/luci-app-cifs.json" ] && {
cat > /usr/share/ucitrack/luci-app-cifs.json << EEOF
{
"config": "cifs",
"init": "cifs"
}
EEOF
}
uci -q batch <<-EOF >/dev/null
delete ucitrack.@cifs[-1]
add ucitrack cifs
set ucitrack.@cifs[-1].init=cifs
commit ucitrack
EOF
/etc/init.d/cifs stop >/dev/null 2>&1
/etc/init.d/cifs disable >/dev/null 2>&1
rm -f /tmp/luci-indexcache
exit 0
@@ -1,11 +0,0 @@
{
"luci-app-cifs": {
"description": "Grant UCI access for luci-app-cifs",
"read": {
"uci": [ "cifs" ]
},
"write": {
"uci": [ "cifs" ]
}
}
}
@@ -1,4 +0,0 @@
{
"config": "cifs",
"init": "cifs"
}
+3 -3
View File
@@ -6,9 +6,9 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for Fileassistant
LUCI_PKGARCH:=all
PKG_VERSION:=1.0
PKG_RELEASE:=1
PKG_VERSION:=1.0-5
PKG_RELEASE:=2
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
# call BuildPackage - OpenWrt buildroot signature
@@ -91,6 +91,40 @@ String.prototype.replaceAll = function(search, replacement) {
}
}
function chmodPath(filename, isdir) {
var newmod = prompt('请输入新的权限位(支持八进制权限位或者a+x格式):', isdir === "1" ? "0755" : "0644");
if (newmod) {
iwxhr.get('/cgi-bin/luci/admin/nas/fileassistant/chmod',
{
filepath: concatPath(currentPath, filename),
newmod: newmod
},
function (x, res) {
if (res.ec === 0) {
refresh_list(res.data, currentPath);
}
}
);
}
}
function chownPath(filename) {
var newown = prompt('请输入新的用户名(支持用户名或用户名:群组格式):', "root");
if (newown) {
iwxhr.get('/cgi-bin/luci/admin/nas/fileassistant/chown',
{
filepath: concatPath(currentPath, filename),
newown: newown
},
function (x, res) {
if (res.ec === 0) {
refresh_list(res.data, currentPath);
}
}
);
}
}
function openpath(filename, dirname) {
dirname = dirname || currentPath;
window.open('/cgi-bin/luci/admin/nas/fileassistant/open?path='
@@ -130,6 +164,13 @@ String.prototype.replaceAll = function(search, replacement) {
else if (targetElem.className.indexOf('cbi-button-edit') > -1) {
renamePath(targetElem.parentNode.parentNode.dataset['filename']);
}
else if (targetElem.className.indexOf('cbi-button-chmod') > -1) {
infoElem = targetElem.parentNode.parentNode;
chmodPath(infoElem.dataset['filename'] , infoElem.dataset['isdir']);
}
else if (targetElem.className.indexOf('cbi-button-chown') > -1) {
chownPath(targetElem.parentNode.parentNode.dataset['filename']);
}
else if (targetElem = getFileElem(targetElem)) {
if (targetElem.className.indexOf('parent-icon') > -1) {
update_list(currentPath.replace(/\/[^/]+($|\/$)/, ''));
@@ -156,7 +197,14 @@ String.prototype.replaceAll = function(search, replacement) {
}
}
function refresh_list(filenames, path) {
var listHtml = '<table class="cbi-section-table"><tbody>';
var listHtml = '<table class="cbi-section-table"><thead><tr class="cbi-section-table-row cbi-rowstyle-2">'
+'<td class="cbi-value-field">文件</td>'
+'<td class="cbi-value-field">所有者</td>'
+'<td class="cbi-value-field">修改时间</td>'
+'<td class="cbi-value-field">大小</td>'
+'<td class="cbi-value-field">权限</td>'
+'<td class="cbi-section-table-cell">操作</td>'
+'</tr></thead><tbody>';
if (path !== '/') {
listHtml += '<tr class="cbi-section-table-row cbi-rowstyle-2"><td class="parent-icon" colspan="6"><strong>..</strong></td></tr>';
}
@@ -196,7 +244,9 @@ String.prototype.replaceAll = function(search, replacement) {
+ '<td class="cbi-value-field cbi-value-perm">'+o.perms+'</td>'
+ '<td class="cbi-section-table-cell">\
<button class="cbi-button cbi-button-edit">重命名</button>\
<button class="cbi-button cbi-button-remove">删除</button>'
<button class="cbi-button cbi-button-remove">删除</button>\
<button class="cbi-button cbi-button-apply cbi-button-chmod">改权限</button>\
<button class="cbi-button cbi-button-apply cbi-button-chown">改用户</button>'
+ install_btn
+ '</td>'
+ '</tr>';
@@ -270,6 +320,26 @@ String.prototype.replaceAll = function(search, replacement) {
}
};
document.getElementById('mkdir-toggle').onclick = function() {
var dirname = null;
if (dirname = prompt("请输入文件夹名称:")) {
var formData = new FormData();
formData.append('path', currentPath);
formData.append('dirname', dirname);
var xhr = new XMLHttpRequest();
xhr.open("POST", "/cgi-bin/luci/admin/nas/fileassistant/mkdir", true);
xhr.onload = function() {
if (xhr.status == 200) {
var res = JSON.parse(xhr.responseText);
refresh_list(res.data, currentPath);
}
else {
alert('创建失败,请稍后再试...');
}
};
xhr.send(formData);
}
};
document.addEventListener('DOMContentLoaded', function(evt) {
var initPath = '/';
if (/path=([/\w]+)/.test(location.search)) {
@@ -6,7 +6,6 @@ function index()
page = entry({"admin", "system", "fileassistant"}, template("fileassistant"), _("文件管理"), 50)
page.i18n = "base"
page.dependent = true
page.acl_depends = { "luci-app-fileassistant" }
page = entry({"admin", "nas", "fileassistant", "list"}, call("fileassistant_list"), nil)
page.leaf = true
@@ -26,6 +25,14 @@ function index()
page = entry({"admin", "nas", "fileassistant", "install"}, call("fileassistant_install"), nil)
page.leaf = true
page = entry({"admin", "nas", "fileassistant", "mkdir"}, call("fileassistant_mkdir"), nil)
page.leaf = true
page = entry({"admin", "nas", "fileassistant", "chmod"}, call("fileassistant_chmod"), nil)
page.leaf = true
page = entry({"admin", "nas", "fileassistant", "chown"}, call("fileassistant_chown"), nil)
page.leaf = true
end
function list_response(path, success)
@@ -109,15 +116,18 @@ function installIPK(filepath)
end
function fileassistant_upload()
local filecontent = luci.http.formvalue("upload-file")
local filename = luci.http.formvalue("upload-filename")
local uploaddir = luci.http.formvalue("upload-dir")
local filepath = uploaddir..filename
local fp
-- MUST setfilehandler before formvalue,
-- beacuse formvalue will parse form and write body to /tmp if filehandler not present
luci.http.setfilehandler(
function(meta, chunk, eof)
if not fp and meta and meta.name == "upload-file" then
local filename = luci.http.formvalue("upload-filename")
local uploaddir = luci.http.formvalue("upload-dir")
if not uploaddir or not filename then
error("uploaddir or filename is nil")
end
local filepath = uploaddir..filename
fp = io.open(filepath, "w")
end
if fp and chunk then
@@ -129,7 +139,28 @@ function fileassistant_upload()
end
)
list_response(uploaddir, true)
list_response(luci.http.formvalue("upload-dir"), true)
end
function fileassistant_mkdir()
local path = luci.http.formvalue("path")
local dirname = luci.http.formvalue("dirname")
local success = os.execute('sh -c \'cd "'..path..'" && mkdir -p "'..dirname..'"\'')
list_response(path, success)
end
function fileassistant_chmod()
local path = luci.http.formvalue("filepath")
local newmod = luci.http.formvalue("newmod")
local success = os.execute('chmod '..newmod..' "'..path..'"')
list_response(nixio.fs.dirname(path), success)
end
function fileassistant_chown()
local path = luci.http.formvalue("filepath")
local newown = luci.http.formvalue("newown")
local success = os.execute('chown '..newown..' "'..path..'"')
list_response(nixio.fs.dirname(path), success)
end
function scandir(directory)
@@ -1,12 +1,13 @@
<%+header%>
<link rel="stylesheet" href="/luci-static/resources/fileassistant/fb.css?v=@ver">
<link rel="stylesheet" href="/luci-static/resources/fileassistant/fb.css<%# ?v=PKG_VERSION %>">
<h2 name="content">文件助手</h2>
<fieldset class="cbi-section fb-container">
<input id="current-path" type="text" class="current-path cbi-input-text" value="/"/>
<div class="panel-container">
<div class="panel-title">文件列表</div>
<button id="upload-toggle" class="upload-toggle cbi-button cbi-button-edit">上传</button>
<button id="mkdir-toggle" class="upload-toggle cbi-button cbi-button-edit">新建文件夹&hellip; </button>
</div>
<div class="upload-container" id="upload-container">
<input id="upload-file" name="upload-file" class="upload-file" type="file">
@@ -15,6 +16,6 @@
<div id="list-content"></div>
</fieldset>
<script src="/luci-static/resources/fileassistant/fb.js?v=@ver"></script>
<script src="/luci-static/resources/fileassistant/fb.js<%# ?v=PKG_VERSION %>"></script>
<%+footer%>
@@ -1,11 +0,0 @@
{
"luci-app-fileassistant": {
"description": "Grant UCI access for luci-app-fileassistant",
"read": {
"uci": [ "fileassistant" ]
},
"write": {
"uci": [ "fileassistant" ]
}
}
}
+5 -3
View File
@@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=luci for haproxy and shadowsocks
LUCI_DEPENDS:=+haproxy
LUCI_PKGARCH:=all
PKG_NAME:=luci-app-haproxy-tcp
PKG_VERSION=1.4
PKG_RELEASE:=1
PKG_MAINTAINER:=Alex Zhuo <1886090@gmail.com>
PKG_RELEASE:=2
include $(TOPDIR)/feeds/luci/luci.mk
PKG_MAINTAINER:=Alex Zhuo <1886090@gmail.com>
define Package/$(PKG_NAME)/postinst
#!/bin/sh
@@ -24,4 +24,6 @@ echo stopping haproxy
echo haproxy disabled
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
@@ -1,9 +1,9 @@
module("luci.controller.haproxy", package.seeall)
function index()
if not nixio.fs.access("/etc/config/haproxy") then
return
end
local page = entry({"admin", "services", "haproxy"}, cbi("haproxy"), _("HAProxy"))
page.dependent = true
page.acl_depends = { "luci-app-haproxy-tcp" }
end
if not nixio.fs.access("/etc/config/haproxy") then
return
end
entry({"admin", "services", "haproxy"}, cbi("haproxy"), _("HAProxy")).dependent = true
end
@@ -16,11 +16,11 @@ if haproxy_on then
else
state_msg = "<b><font color=\"red\">" .. translate("Not running") .. "</font></b>"
end
m=Map("haproxy",translate("HAProxy"),translate("HAProxy能够检测Shadowsocks服务器的连通情况,从而实现负载均衡和高可用的功能,支持主备用服务器宕机自动切换,并且可以设置多个主服务器用于分流,规定每个分流节点的流量比例等。前提条件是你的所有Shadowsocks服务器的【加密方式】和【密码】一致。<br><br>使用方法:配置好你的Shadowsocks服务器ip地址和端口,然后开启Shadowsocks服务,将服务器地址填写为【127.0.0.1】,端口【2222】,其他参数和之前一样即可,你可以通过访问【路由器的IP:1111/haproxy】输入用户名admin,密码root来观察各节点健康状况,红色为宕机,绿色正常,使用说明请<a href='http://www.right.com.cn/forum/thread-198649-1-1.html'>点击这里</a>") .. "<br><br>后台监控页面:<a href='http://" .. router_ip .. ":1111/haproxy'>" .. router_ip .. ":1111/haproxy</a> 用户名admin,密码root" .. "<br><br>状态 - " .. state_msg)
s=m:section(TypedSection,"arguments","")
s.addremove=false
s.anonymous=true
view_enable = s:option(Flag,"enabled",translate("Enable"))
m = Map("haproxy", translate("HAProxy"), translate("HAProxy能够检测Shadowsocks服务器的连通情况,从而实现负载均衡和高可用的功能,支持主备用服务器宕机自动切换,并且可以设置多个主服务器用于分流,规定每个分流节点的流量比例等。前提条件是你的所有Shadowsocks服务器的【加密方式】和【密码】一致。<br><br>使用方法:配置好你的Shadowsocks服务器ip地址和端口,然后开启Shadowsocks服务,将服务器地址填写为【127.0.0.1】,端口【2222】,其他参数和之前一样即可,你可以通过访问【路由器的IP:1111/haproxy】输入用户名admin,密码root来观察各节点健康状况,红色为宕机,绿色正常,使用说明请<a href='http://www.right.com.cn/forum/thread-198649-1-1.html'>点击这里</a>") .. "<br><br>后台监控页面:<a href='http://" .. router_ip .. ":1111/haproxy'>" .. router_ip .. ":1111/haproxy</a> 用户名admin,密码root" .. "<br><br>状态 - " .. state_msg)
s = m:section(TypedSection,"arguments","")
s.addremove = false
s.anonymous = true
view_enable = s:option(Flag, "enabled", translate("Enable"))
--通过读写配置文件控制HAProxy这种方式已经弃用
--view_cfg = s:option(TextValue, "1", nil)
--view_cfg.rmempty = false
@@ -32,36 +32,37 @@ s=m:section(TypedSection,"arguments","")
--function view_cfg.write(self, section, value)
-- sync_value_to_file(value, "/etc/haproxy.cfg")
--end
s=m:section(TypedSection,"main_server","<b>" .. translate("Main Server List") .. "<b>")
s.anonymous=true
s.addremove=true
o=s:option(Value,"server_name",translate("Display Name"),translate("Only English Characters,No spaces"))
s = m:section(TypedSection, "main_server","<b>" .. translate("Main Server List") .. "<b>")
s.anonymous = true
s.addremove = true
o = s:option(Value, "server_name", translate("Display Name"), translate("Only English Characters,No spaces"))
o.rmempty = false
o=s:option(Flag,"validate",translate("validate"))
o = s:option(Flag,"validate",translate("validate"))
o=s:option(Value,"server_ip",translate("Proxy Server IP"))
o = s:option(Value, "server_ip", translate("Proxy Server IP"))
o=s:option(Value,"server_port",translate("Proxy Server Port"))
o.datatype="uinteger"
o=s:option(Value,"server_weight",translate("Weight"))
o.datatype="uinteger"
o = s:option(Value, "server_port", translate("Proxy Server Port"))
o.datatype = "uinteger"
o = s:option(Value, "server_weight", translate("Weight"))
o.datatype = "uinteger"
s=m:section(TypedSection,"backup_server","<b>" .. translate("Backup Server List") .. "<b>")
s.anonymous=true
s.addremove=true
o=s:option(Value,"server_name",translate("Display Name"),translate("Only English Characters,No spaces"))
s = m:section(TypedSection,"backup_server","<b>" .. translate("Backup Server List") .. "<b>")
s.anonymous = true
s.addremove = true
o = s:option(Value, "server_name", translate("Display Name"), translate("Only English Characters,No spaces"))
o.rmempty = false
o=s:option(Flag,"validate",translate("validate"))
o = s:option(Flag, "validate", translate("validate"))
o=s:option(Value,"server_ip",translate("Proxy Server IP"))
o = s:option(Value, "server_ip", translate("Proxy Server IP"))
o=s:option(Value,"server_port",translate("Proxy Server Port"))
o.datatype="uinteger"
o = s:option(Value, "server_port", translate("Proxy Server Port"))
o.datatype = "uinteger"
-- ---------------------------------------------------
local apply = luci.http.formvalue("cbi.apply")
if apply then
os.execute("/etc/haproxy_init.sh restart >/dev/null 2>&1 &")
end
return m
-1
View File
@@ -1 +0,0 @@
zh_Hans
@@ -0,0 +1,34 @@
msgid "Running"
msgstr "运行中"
msgid "Not running"
msgstr "未运行"
msgid "Main Server List"
msgstr "主服务器列表"
msgid "Display Name"
msgstr "服务器名称"
msgid "Only English Characters,No spaces"
msgstr "仅限英文字母,不要有空格"
msgid "Proxy Server IP"
msgstr "代理服务器IP或域名"
msgid "Proxy Server Port"
msgstr "代理服务器端口"
msgid "Weight"
msgstr "分流权重"
msgid "Backup Server List"
msgstr "备用服务器列表"
msgid "validate"
msgstr "生效"
+1
View File
@@ -0,0 +1 @@
zh-cn
@@ -1,69 +0,0 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Project-Id-Version: PACKAGE VERSION\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: zh-Hans\n"
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
#: luasrc/model/cbi/haproxy.lua:50
msgid "Backup Server List"
msgstr "备用服务器列表"
#: luasrc/model/cbi/haproxy.lua:38 luasrc/model/cbi/haproxy.lua:53
msgid "Display Name"
msgstr "服务器名称"
#: luasrc/model/cbi/haproxy.lua:23
msgid "Enable"
msgstr ""
#: luasrc/controller/haproxy.lua:6 luasrc/model/cbi/haproxy.lua:19
msgid "HAProxy"
msgstr ""
#: luasrc/model/cbi/haproxy.lua:19
msgid ""
"HAProxy能够检测Shadowsocks服务器的连通情况,从而实现负载均衡和高可用的功能,"
"支持主备用服务器宕机自动切换,并且可以设置多个主服务器用于分流,规定每个分流"
"节点的流量比例等。前提条件是你的所有Shadowsocks服务器的【加密方式】和【密码】"
"一致。<br><br>使用方法:配置好你的Shadowsocks服务器ip地址和端口,然后开启"
"Shadowsocks服务,将服务器地址填写为【127.0.0.1】,端口【2222】,其他参数和之"
"前一样即可,你可以通过访问【路由器的IP:1111/haproxy】输入用户名admin,密码"
"root来观察各节点健康状况,红色为宕机,绿色正常,使用说明请<a href='http://www."
"right.com.cn/forum/thread-198649-1-1.html'>点击这里</a>"
msgstr ""
#: luasrc/model/cbi/haproxy.lua:35
msgid "Main Server List"
msgstr "主服务器列表"
#: luasrc/model/cbi/haproxy.lua:17
msgid "Not running"
msgstr "未运行"
#: luasrc/model/cbi/haproxy.lua:38 luasrc/model/cbi/haproxy.lua:53
msgid "Only English Characters,No spaces"
msgstr "仅限英文字母,不要有空格"
#: luasrc/model/cbi/haproxy.lua:43 luasrc/model/cbi/haproxy.lua:58
msgid "Proxy Server IP"
msgstr "代理服务器IP或域名"
#: luasrc/model/cbi/haproxy.lua:45 luasrc/model/cbi/haproxy.lua:60
msgid "Proxy Server Port"
msgstr "代理服务器端口"
#: luasrc/model/cbi/haproxy.lua:15
msgid "Running"
msgstr "运行中"
#: luasrc/model/cbi/haproxy.lua:47
msgid "Weight"
msgstr "分流权重"
#: luasrc/model/cbi/haproxy.lua:41 luasrc/model/cbi/haproxy.lua:56
msgid "validate"
msgstr "生效"
@@ -22,10 +22,10 @@ start(){
log 127.0.0.1 local0 #[日志输出配置,所有日志都记录在本机,通过local0输出]
log 127.0.0.1 local1 notice #定义haproxy 日志级别[error warringinfo debug]
daemon #以后台形式运行harpoxy
nbproc 1 #设置进程数量
#nbproc 1 #设置进程数量
pidfile /var/run/haproxy.pid
ulimit-n 1024 #ulimit 的数量限制
maxconn 1024 #默认最大连接数,需考虑ulimit-n限制
#ulimit-n 1024 #ulimit 的数量限制
#maxconn 2048 #默认最大连接数,需考虑ulimit-n限制
#chroot /usr/local/haproxy
defaults
log global
@@ -130,4 +130,4 @@ restart(){
else
stop;
fi
}
}
-19
View File
@@ -1,19 +0,0 @@
# Copyright (C) 2018 XiaoShan mivm.cn
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI Support for k3usb3.0 on or off
LUCI_DEPENDS:=@TARGET_bcm53xx_generic_DEVICE_phicomm_k3
LUCI_PKGARCH:=all
PKG_NAME:=luci-app-k3usb
PKG_VERSION:=1.1.0
PKG_RELEASE:=1
PKG_LICENSE:=GPLv3
PKG_LICENSE_FILES:=LICENSE
PKG_MAINTAINER:=Shenzt <shenzt@gmail.com>
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
@@ -1,13 +0,0 @@
-- Copyright (C) 2018 XiaoShan mivm.cn
module("luci.controller.k3usb", package.seeall)
function index()
if not nixio.fs.access("/etc/config/k3usb") then
return
end
local page = entry({"admin", "system", "k3usb"}, cbi("k3usb"), _("k3usb"), 60)
page.dependent = true
page.acl_depends = { "luci-app-k3usb" }
end
-15
View File
@@ -1,15 +0,0 @@
-- Copyright (C) 2018 XiaoShan mivm.cn
local m, s, o
m = Map("k3usb", translate("k3usb"))
m.description = translate("k3 usb mode")
s = m:section(TypedSection, "config", translate("usb mode"))
s.anonymous = true
o = s:option(Flag, "usb3_enable", translate("usb3 enable :"))
o.description = translate("usb3 mode enable")
o.default = 1
return m
-1
View File
@@ -1 +0,0 @@
zh_Hans
-17
View File
@@ -1,17 +0,0 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8\n"
msgid "usb3 enable :"
msgstr "USB3 开启:"
msgid "usb3 mode enable"
msgstr "是否开启USB3模式,修改此选项设备将会自动重启"
msgid "k3usb"
msgstr "K3USB管理"
msgid "k3 usb mode"
msgstr "开启或禁用USB3"
msgid "usb mode"
msgstr "USB3管理模式"
-3
View File
@@ -1,3 +0,0 @@
config config usb
option usb3_enable '0'
-62
View File
@@ -1,62 +0,0 @@
#!/bin/sh /etc/rc.common
START=55
STOP=55
usb3_enable=$(uci get k3usb.usb.usb3_enable 2>/dev/null)
kernel=$(uname -a | awk '{print $3}')
boot(){
if [ "$usb3_enable" == "1" ]; then
#usb3
kmodloader /usr/k3usb/45-phy-bcm-ns-usb3
kmodloader /usr/k3usb/54-usb3
#usb2
kmodloader /usr/k3usb/35-usb-ehci
kmodloader /usr/k3usb/40-usb2
kmodloader /usr/k3usb/45-phy-bcm-ns-usb2
kmodloader /usr/k3usb/50-usb-ohci
echo "usb switch to usb3 mode!"
else
#usb2
kmodloader /usr/k3usb/35-usb-ehci
kmodloader /usr/k3usb/40-usb2
kmodloader /usr/k3usb/45-phy-bcm-ns-usb2
kmodloader /usr/k3usb/50-usb-ohci
echo "usb switch to usb2 mode!"
fi
kmodloader /usr/k3usb/usb-storage
kmodloader /usr/k3usb/usb-storage-extras
}
start(){
if [ "$usb3_enable" == "1" ]; then
if [ -z "$(lsmod | grep usb3)" ]; then
echo "usb change to usb3 mode, will reboot!"
reboot
else
echo "usb mode is usb3 , nothing to do"
fi
else
if [ -n "$(lsmod | grep usb3)" ]; then
echo "usb change usb2 mode, will reboot!"
reboot
else
echo "usb mode is usb2 , nothing to do"
fi
fi
}
stop(){
echo "nothing do"
}
restart(){
start
}
@@ -1,19 +0,0 @@
#!/bin/sh
[ ! -f "/usr/share/ucitrack/luci-app-k3usb.json" ] && {
cat > /usr/share/ucitrack/luci-app-k3usb.json << EEOF
{
"config": "k3usb",
"init": "k3usb"
}
EEOF
}
uci -q batch <<-EOF >/dev/null
delete ucitrack.@k3usb[-1]
add ucitrack k3usb
set ucitrack.@k3usb[-1].init=k3usb
commit ucitrack
EOF
rm -rf /tmp/luci-*
exit 0
@@ -1 +0,0 @@
ehci-hcd
-4
View File
@@ -1,4 +0,0 @@
ehci-hcd
ehci-platform
ehci-orion
ehci-atmel
@@ -1 +0,0 @@
phy-bcm-ns-usb2
@@ -1 +0,0 @@
phy-bcm-ns-usb3
@@ -1,3 +0,0 @@
ohci-hcd
ohci-platform
ohci-at91
-3
View File
@@ -1,3 +0,0 @@
xhci-hcd
xhci-pci
xhci-plat-hcd
View File
Whitespace-only changes.
@@ -1 +0,0 @@
usb-storage
@@ -1,10 +0,0 @@
ums-alauda
ums-cypress
ums-datafab
ums-freecom
ums-isd200
ums-jumpshot
ums-karma
ums-sddr09
ums-sddr55
ums-usbat
@@ -1,11 +0,0 @@
{
"luci-app-k3usb": {
"description": "Grant UCI access for luci-app-k3usb",
"read": {
"uci": [ "k3usb" ]
},
"write": {
"uci": [ "k3usb" ]
}
}
}
@@ -1,4 +0,0 @@
{
"config": "k3usb",
"init": "k3usb"
}
+14
View File
@@ -0,0 +1,14 @@
#
# Copyright (C) 2008-2014 The LuCI Team <luci@lists.subsignal.org>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI Support for Lantiq Devices
LUCI_DEPENDS:=@BROKEN
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
@@ -0,0 +1,40 @@
-- Copyright 2019 John Crispin <blogic@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
module("luci.controller.ltqtapi", package.seeall)
function index()
if not nixio.fs.access("/etc/config/telephony") then
return
end
page = node("admin", "telephony")
page.target = firstchild()
page.title = _("VoIP")
page.order = 90
entry({"admin", "telephony", "account"}, cbi("luci_ltqtapi/account") , _("Account"), 10)
entry({"admin", "telephony", "contact"}, cbi("luci_ltqtapi/contact") , _("Contacts"), 20)
entry({"admin", "telephony", "status"}, call("tapi_status")).leaf = true
end
function tapi_status()
local st = { }
local state = require "luci.model.uci".cursor_state()
state:load("telephony")
st.status = "Offline";
if state:get("telephony", "state", "port1", "0") == "0" then
st.line1 = "Idle";
else
st.line1 = "Calling";
end
if state:get("telephony", "state", "port2", "0") == "0" then
st.line2 = "Idle";
else
st.line2 = "Calling";
end
luci.http.prepare_content("application/json")
luci.http.write_json(st)
end
@@ -0,0 +1,16 @@
-- Copyright 2010 John Crispin <blogic@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
m = Map("telephony", translate("VoIP"))
m.on_after_commit = function() luci.sys.call("/etc/init.d/telephony restart") end
s = m:section(TypedSection, "account", translate("Account"), translate("Here You can specify the SIP account that you want to use."))
s.anonymous = true
s.addremove = true
s:option(Value, "realm", translate("Realm"))
s:option(Value, "username", translate("Username"))
s:option(Value, "password", translate("Password"))
s:option(Flag, "disabled", translate("Disabled"))
return m
@@ -0,0 +1,20 @@
-- Copyright 2010 John Crispin <blogic@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
m = Map("telephony", translate("VoIP"))
m.on_after_commit = function() luci.sys.call("/etc/init.d/telephony reload") end
s = m:section(TypedSection, "contact", translate("Contact"), translate("Here You can specify the SIP contacts that you want to use."))
s.anonymous = true
s.addremove = true
s.template = "cbi/tsection"
s:option(Value, "desc", translate("Name"))
s:option(Value, "code", translate("Shortdial"))
s:option(Value, "dial", translate("Dial"))
t = s:option(ListValue, "type", translate("Type"))
t:value("sip", "SIP")
t:value("realm", "Landline")
return m
@@ -0,0 +1 @@
<%+telephony_status%>
@@ -0,0 +1,32 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(5, '<%=url('admin/telephony/status')%>', null,
function(x, st)
{
var tb = document.getElementById('telephony_status_table');
if (st && tb)
{
tb.deleteRow(1);
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-1';
tr.insertCell(-1).innerHTML = st.status;
tr.insertCell(-1).innerHTML = st.line1;
tr.insertCell(-1).innerHTML = st.line2;
}
}
);
//]]></script>
<fieldset class="cbi-section">
<legend><%:Current Telephony State%></legend>
<table class="cbi-section-table" id="telephony_status_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Uplink%></th>
<th class="cbi-section-table-cell"><%:Port1%></th>
<th class="cbi-section-table-cell"><%:Port2%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="5"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>
-13
View File
@@ -1,13 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-minieap
PKG_VERSION=1.0
PKG_RELEASE:=1
LUCI_TITLE:=minieap 802.1X Client for LuCI
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+minieap
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
@@ -1,20 +0,0 @@
module("luci.controller.minieap", package.seeall)
function index()
if not nixio.fs.access("/etc/config/minieap") then
return
end
if luci.sys.call("command -v minieap >/dev/null") ~= 0 then
return
end
local page = entry({"admin", "services", "minieap"}, alias("admin", "services", "minieap", "general"), _("minieap"))
page.order = 10
page.dependent = true
page.acl_depends = { "luci-app-minieap" }
entry({"admin", "services", "minieap", "general"}, cbi("minieap/general"), _("minieap Settings"), 10).leaf = true
-- entry({"admin", "services", "minieap", "customfile"}, cbi("minieap/customfile"), _("custom configfiles"), 20).leaf = true
entry({"admin", "services", "minieap", "log"}, cbi("minieap/log"), _("minieap LOG"), 30).leaf = true
end
@@ -1,8 +0,0 @@
require("luci.sys")
local f = SimpleForm("minieap",
translate("minieap LOG"),
translate("Log file:/var/log/minieap.log"))
return f
@@ -1,182 +0,0 @@
local function is_running(name)
if luci.sys.call("pidof %s >/dev/null" %{name}) == 0 then
return translate("RUNNING")
else
return translate("NOT RUNNING")
end
end
local function is_online(ipaddr)
if ipaddr == "0.0.0.0" or ipaddr == "nil" then
return translate("Pinghost not set")
end
if luci.sys.call("ping -c1 -w1 %s >/dev/null 2>&1" %{ipaddr}) == 0 then
return translate("ONLINE")
else
return translate("NOT ONLINE")
end
end
require("luci.sys")
m = Map("minieap", translate("minieap"))
m.description = translate("Configure minieap 802.11x.")
s = m:section(TypedSection, "minieap", translate("Status"))
s.anonymous = true
status = s:option(DummyValue,"_minieap_status", "minieap")
status.value = "<span id=\"_minieap_status\">%s</span>" %{is_running("minieap")}
status.rawhtml = true
t = io.popen('uci get minieap.@minieap[0].pinghost')
netstat = is_online(tostring(t:read("*line")))
t:close()
if netstat ~= "" then
netstatus = s:option(DummyValue,"_network_status", translate("Network Status"))
netstatus.value = "<span id=\"_network_status\">%s</span>" %{netstat}
netstatus.rawhtml = true
end
o = m:section(TypedSection, "minieap", translate("Settings"))
o.addremove = false
o.anonymous = true
o:tab("base", translate("Normal Settings"))
o:tab("advanced", translate("Advanced Settings"))
o:tab("plugins", translate("Plugins List"))
o:tab("ruijie", translate("Ruijie EAP Settings"))
enable = o:taboption("base", Flag, "enable", translate("Enable"))
name = o:taboption("base", Value, "username", translate("Username"))
name.description = translate("The username given to you by your network administrator")
pass = o:taboption("base", Value, "password", translate("Password"))
pass.description = translate("The password you set or given to you by your network administrator")
pass.password = true
ifname = o:taboption("base", ListValue, "nic", translate("Interfaces"))
ifname.description = translate("Physical interface of WAN")
for k, v in ipairs(luci.sys.net.devices()) do
if v ~= "lo" then
ifname:value(v)
end
end
pinghost = o:taboption("base", Value, "pinghost", translate("PingHost"))
pinghost.description = translate("Ping host for drop detection, 0.0.0.0 to turn off this feature.")
pinghost.default = "0.0.0.0"
pingintval = o:taboption("base", Value, "pingintval", translate("Ping intval"))
pingintval.description = translate("Interval of each ping. (in second) [default: 30]")
pingintval.default = "30"
pingcommand = o:taboption("base", Value, "pingcommand", translate("Offline command"))
pingcommand.description = translate("Run Command when ping failed. [default: minieap -k 1]")
pingcommand:value("minieap -k 1")
pingcommand.default = "minieap -k 1"
stage_timeout = o:taboption("advanced", Value, "stage_timeout", translate("Auth Timeout"))
stage_timeout.description = translate("802.11X auth timeout (in second). [default: 5]")
stage_timeout.default = "5"
wait_after_fail = o:taboption("advanced", Value, "wait_after_fail", translate("Wait after failed"))
wait_after_fail.description = translate("Wait time between failed and next time (in second). [default: 30]")
wait_after_fail.default = "30"
max_fail = o:taboption("advanced", Value, "max_fail", translate("Max fail"))
max_fail.description = translate("Maximum allowed number of failures. [default: 3]")
max_fail.default = "3"
no_auto_reauth = o:taboption("advanced", ListValue, "no_auto_reauth", translate("Disable auto reauth"))
no_auto_reauth.description = translate("Disable auto reauth after offline. [default: True]")
no_auto_reauth:value(0, translate("False"))
no_auto_reauth:value(1, translate("True"))
no_auto_reauth.default = 1
proxy_lan_iface = o:taboption("advanced", Value, "proxy_lan_iface", translate("Proxy LAN's name"))
proxy_lan_iface.description = translate("Name of LAN interface when use proxy auth. [default: None]")
proxy_lan_iface.default = ""
auth_round = o:taboption("advanced", Value, "auth_round", translate("Auth times"))
auth_round.description = translate("Number of times required for auth. [default: 1]")
auth_round.default = "1"
max_retries = o:taboption("advanced", Value, "max_retries", translate("Max timeout"))
max_retries.description = translate("Maximum retry time after timeout. [default: 3]")
max_retries.default = "3"
pid_file = o:taboption("advanced", Value, "pid_file", translate("PID file"))
pid_file.description = translate("Path of PID file. (Set 'None' to disable) [default: /var/run/minieap.pid]")
pid_file:value("/var/run/minieap.pid")
pid_file.default = "/var/run/minieap.pid"
if_impl = o:taboption("advanced", ListValue, "if_impl", translate("Network Module"))
if_impl.description = translate("Network module for send and recv packages (openwrt support sockraw only)")
if_impl:value("sockraw")
if_impl.default = "sockraw"
plugins = o:taboption("plugins", DynamicList, "module", translate("Plugins list"))
plugins.description = translate("Packets flow through these plug-ins in sequence. Pay attention to the order in the environment where the package plug-in is modified")
plugins:value("printer", translate("printer: Print length of packets"))
plugins:value("rjv3", translate('rjv3: Ruijie 802.11X. Support V3 verification algorithm'))
heartbeat = o:taboption("ruijie", Value, "heartbeat", translate("Heartbeat interval"))
heartbeat.description = translate("Interval for sending Heartbeat packets (seconds) [Default: 60]")
heartbeat.default = "60"
eap_bcast_addr = o:taboption("ruijie", ListValue, "eap_bcast_addr", translate("Broadcast address"))
eap_bcast_addr.description = translate("Broadcast address type when searching for servers [Default: Standard]")
eap_bcast_addr:value(0, translate("Standard"))
eap_bcast_addr:value(1, translate("Ruijie private"))
eap_bcast_addr.default = 0
dhcp_type = o:taboption("ruijie", ListValue, "dhcp_type", translate("DhcpMode"))
dhcp_type.description = translate("DHCP method [Default: After certification]")
dhcp_type:value(0, translate("None"))
dhcp_type:value(1, translate("Secondary authentication"))
dhcp_type:value(2, translate("Before certification"))
dhcp_type:value(3, translate("After certification"))
dhcp_type.default = 3
dhcp_script = o:taboption("ruijie", Value, "dhcp_script", translate("DhcpScript"))
dhcp_script.description = translate("DHCP script [Default: None]")
dhcp_script.default = ""
service = o:taboption("ruijie", Value, "service", translate("Service"))
service.description = translate("Service From Ruijie Server [Default: internet]")
service.default = "internet"
version_str = o:taboption("ruijie", Value, "version_str", translate("Version String"))
version_str.description = translate("Custom version [Default: RG-SU For Linux V1.0]")
version_str:value("RG-SU For Linux V1.0")
version_str.default = "RG-SU For Linux V1.0"
fake_dns1 = o:taboption("ruijie", Value, "fake_dns1", translate("Main DNS server"))
fake_dns1.description = translate("Custom main DNS server [Default: FromSystem]")
fake_dns2 = o:taboption("ruijie", Value, "fake_dns2", translate("Second DNS server"))
fake_dns2.description = translate("Custom second DNS server [Default: FromSystem]")
fake_serial = o:taboption("ruijie", Value, "fake_serial", translate("Disk serial"))
fake_serial.description = translate("Custom disk serial [Default: From /etc/mtab]")
max_dhcp_count = o:taboption("ruijie", Value, "max_dhcp_count", translate("DHCP try times"))
max_dhcp_count.description = translate("DHCP try times [Default: 3]")
max_dhcp_count.default = "3"
rj_option = o:taboption("ruijie", DynamicList, "rj_option", translate("Custom EAP Options"))
rj_option.description = translate("Format &lt;type&gt;:&lt;value&gt;[:r]. Add a option type: &lt;type&gt;, value: &lt;value&gt;. :r for replace")
if nixio.fs.mkdir("/etc/minieap.conf.d") == true then
nixio.fs.symlink("/etc/minieap.conf.d/minieap.conf.utf8", "/etc/minieap.conf")
end
local apply = luci.http.formvalue("cbi.apply")
if apply then
luci.sys.call("minieap-conver | sort > /etc/minieap.conf.d/minieap.conf.utf8")
io.popen("/etc/init.d/minieap restart")
end
return m
@@ -1,23 +0,0 @@
local fs = require "nixio.fs"
local f = SimpleForm("minieap",
translate("minieap LOG"),
translate("Log file:/var/log/minieap.log"))
local o = f:field(Value, "minieap_log")
o.template = "cbi/tvalue"
o.rows = 32
function o.cfgvalue(self, section)
return fs.readfile("/var/log/minieap.log")
end
function o.write(self, section, value)
require("luci.sys").call('cat /dev/null > /var/log/minieap.log 2>/dev/null')
end
f.submit = translate("Clear log")
f.reset = false
return f
-1
View File
@@ -1 +0,0 @@
zh_Hans
-227
View File
@@ -1,227 +0,0 @@
msgid "minieap Settings"
msgstr "minieap 设置"
msgid "minieap LOG"
msgstr "minieap 日志"
msgid "Log file:/var/log/minieap.log"
msgstr "日志文件: /var/log/minieap.log"
msgid "RUNNING"
msgstr "运行中"
msgid "NOT RUNNING"
msgstr "未运行"
msgid "Pinghost not set"
msgstr "没有设置Ping主机"
msgid "ONLINE"
msgstr "能访问互联网"
msgid "NOT ONLINE"
msgstr "不能访问互联网"
msgid "Configure minieap 802.11x."
msgstr "配置minieap 802.11x验证。"
msgid "Network Status"
msgstr "网络状态"
msgid "Settings"
msgstr "设置"
msgid "Normal Settings"
msgstr "常规设置"
msgid "Plugins List"
msgstr "插件列表"
msgid "Ruijie EAP Settings"
msgstr "锐捷认证设置"
msgid "The username given to you by your network administrator"
msgstr "您的用户名(或管理员分配的用户名)"
msgid "The password you set or given to you by your network administrator"
msgstr "您的密码(或管理员分配的密码)"
msgid "Physical interface of WAN"
msgstr "WAN口的物理接口"
msgid "PingHost"
msgstr "Ping主机"
msgid "Ping host for drop detection, 0.0.0.0 to turn off this feature."
msgstr "Ping主机,用于掉线检测,0.0.0.0表示关闭该功能"
msgid "Packets flow through these plug-ins in sequence. Pay attention to the order in the environment where the package plug-in is modified"
msgstr "数据包会按顺序流经这些插件。在有修改数据包插件的环境中请注意顺序"
msgid "printer: Print length of packets"
msgstr "printer:打印流入流出数据包的大小"
msgid "rjv3: Ruijie 802.11X. Support V3 verification algorithm"
msgstr "rjv3:锐捷认证,支持V3算法"
msgid "Heartbeat interval"
msgstr "心跳间隔"
msgid "Interval for sending Heartbeat packets (seconds) [Default: 60]"
msgstr "发送心跳包的间隔(秒)[默认:60]"
msgid "Broadcast address"
msgstr "广播地址类型"
msgid "Broadcast address type when searching for servers [Default: Standard]"
msgstr "寻找服务器时的广播地址类型 [默认:标准]"
msgid "Standard"
msgstr "标准"
msgid "Ruijie private"
msgstr "锐捷私有"
msgid "DhcpMode"
msgstr "DHCP方式"
msgid "DHCP method [Default: After certification]"
msgstr "DHCP方式 [默认:认证后]"
msgid "None"
msgstr "无"
msgid "Secondary authentication"
msgstr "二次认证"
msgid "Before certification"
msgstr "认证前"
msgid "After certification"
msgstr "认证后"
msgid "DhcpScript"
msgstr "DHCP脚本"
msgid "DHCP script [Default: None]"
msgstr "DHCP脚本 [默认:无]"
msgid "Service"
msgstr "服务"
msgid "Service From Ruijie Server [Default: internet]"
msgstr "锐捷认证服务器上配置的用户服务"
msgid "Version String"
msgstr "版本信息"
msgid "Custom version [Default: RG-SU For Linux V1.0]"
msgstr "自定义版本信息 [默认:RG-SU For Linux V1.0]"
msgid "Main DNS server"
msgstr "主DNS服务器"
msgid "Custom main DNS server [Default: FromSystem]"
msgstr "自定义主DNS服务器 [默认:自动获取]"
msgid "Second DNS server"
msgstr "从DNS服务器"
msgid "Custom second DNS server [Default: FromSystem]"
msgstr "自定义从DNS服务器 [默认:自动获取]"
msgid "Disk serial"
msgstr "磁盘序列号"
msgid "Custom disk serial [Default: From /etc/mtab]"
msgstr "自定义磁盘序列号 [默认:自动获取]"
msgid "DHCP try times"
msgstr "DHCP尝试次数"
msgid "DHCP try times [Default: 3]"
msgstr "二次认证的DHCP尝试次数 [默认:3]"
msgid "Custom EAP Options"
msgstr "自定义EAP字段"
msgid "Format &lt;type&gt;:&lt;value&gt;[:r]. Add a option type: &lt;type&gt;, value: &lt;value&gt;. :r for replace"
msgstr "格式: &lt;type&gt;:&lt;value&gt;[:r]。 不带r为增加字段,带r为替换字段"
msgid "Configfile encoding"
msgstr "配置文件编码"
msgid "Auth Timeout"
msgstr "认证超时"
msgid "802.11X auth timeout (in second). [default: 5]"
msgstr "单个认证阶段的超时时间 [默认:5]"
msgid "Wait after failed"
msgstr "认证失败等待"
msgid "Wait time between failed and next time (in second). [default: 30]"
msgstr "认证失败后重新认证前的等待时间[默认:30]"
msgid "Max fail"
msgstr "最大失败次数"
msgid "Maximum allowed number of failures. [default: 3]"
msgstr "最大允许认证失败次数 [默认:3]"
msgid "Disable auto reauth"
msgstr "禁止自动重连"
msgid "Disable auto reauth after offline. [default: True]"
msgstr "认证掉线后不允许自动重连 [默认:是]"
msgid "False"
msgstr "否"
msgid "True"
msgstr "是"
msgid "Daemon mode"
msgstr "运行模式"
msgid "Proxy LAN's name"
msgstr "代理LAN口名称"
msgid "Name of LAN interface when use proxy auth. [default: None]"
msgstr "代理认证时的 LAN 网络界面名 [默认:无]"
msgid "Auth times"
msgstr "认证次数"
msgid "Number of times required for auth. [default: 1]"
msgstr "需要认证的次数 [默认:1]"
msgid "Max timeout"
msgstr "最大超时重试"
msgid "Maximum retry time after timeout. [default: 3]"
msgstr "最大超时重试的次数 [默认:3]"
msgid "PID file"
msgstr "PID文件"
msgid "Path of PID file. (Set 'None' to disable) [default: /var/run/minieap.pid]"
msgstr "PID 文件路径,设为none可禁用 [默认:/var/run/minieap.pid]"
msgid "Network Module"
msgstr "网络操作模块"
msgid "Network module for send and recv packages (openwrt support sockraw only)"
msgstr "选择此网络操作模块(openwrt只支持sockraw)"
msgid "Ping intval"
msgstr "Ping间隔"
msgid "Interval of each ping. (in second) [default: 30]"
msgstr "Ping Ping主机的间隔(秒) [默认:30]"
msgid "Offline command"
msgstr "掉线执行命令"
msgid "Run Command when ping failed. [default: minieap -k 1]"
msgstr "Ping 检测到掉线后执行的命令 [默认: minieap -k 1]"
-18
View File
@@ -1,18 +0,0 @@
config minieap
option pinghost '0.0.0.0'
option pingintval '30'
option pingcommand 'minieap -k 1'
option stage_timeout '5'
option wait_after_fail '30'
option max_fail '3'
option no_auto_reauth '1'
option auth_round '1'
option max_retries '3'
option pid_file '/var/run/minieap.pid'
option if_impl 'sockraw'
option heartbeat '60'
option eap_bcast_addr '0'
option dhcp_type '3'
option service 'internet'
option version_str 'RG-SU For Linux V1.0'
option max_dhcp_count '3'
-70
View File
@@ -1,70 +0,0 @@
#!/bin/sh /etc/rc.common
START=93
run_minieap()
{
kill $(cat /var/log/minieap-ping.pid 2>/dev/null) 2>/dev/null
local enable
local username
local password
local nic
local pinghost
config_get_bool enable $1 enable
config_get username $1 username
config_get password $1 password
config_get nic $1 nic
config_get pinghost $1 pinghost
if [ $enable ] && [ $username ] && [ $password ] && [ $nic ]; then
if [ $pinghost ]; then
/bin/ash -c "/usr/sbin/minieap-ping &"
fi
/bin/ash -c "minieap -b3"
else
/bin/ash -c "minieap -k"
fi
}
restart_minieap()
{
kill $(cat /var/log/minieap-ping.pid 2>/dev/null) 2>/dev/null
local enable
local username
local password
local nic
local pinghost
config_get_bool enable $1 enable
config_get username $1 username
config_get password $1 password
config_get nic $1 nic
config_get pinghost $1 pinghost
if [ $enable ] && [ $username ] && [ $password ] && [ $nic ]; then
if [ $pinghost ]; then
/bin/ash -c "/usr/sbin/minieap-ping &"
fi
/bin/ash -c "minieap -k 1"
else
/bin/ash -c "minieap -k"
fi
}
start()
{
config_load minieap
config_foreach run_minieap minieap
}
stop()
{
kill $(cat /var/log/minieap-ping.pid 2>/dev/null) 2>/dev/null
/bin/ash -c "minieap -k"
}
restart()
{
config_load minieap
config_foreach restart_minieap minieap
}
@@ -1,19 +0,0 @@
#!/bin/sh
[ ! -f "/usr/share/ucitrack/luci-app-minieap.json" ] && {
cat > /usr/share/ucitrack/luci-app-minieap.json << EEOF
{
"config": "minieap",
"init": "minieap"
}
EEOF
}
uci -q batch <<-EOF >/dev/null
delete ucitrack.@minieap[-1]
add ucitrack minieap
set ucitrack.@minieap[-1].init=minieap
commit ucitrack
EOF
rm -rf /tmp/luci-*
exit 0
@@ -1,13 +0,0 @@
#!/bin/sh
default_config='''daemonize=3
'''
echo $default_config
config_keys=$(uci show minieap | cut -d "." -f3- | awk -F "=" '{if ($0 != "") print $1}')
for key in $config_keys
do
if [[ "$key" != "pinghost" ]] && [[ "$key" != "pingintval" ]]; then
echo ${key//_/-}=$(uci get minieap.@minieap[0].$key)
fi
done
@@ -1,24 +0,0 @@
#!/bin/sh
kill $(cat /var/log/minieap-ping.pid 2>/dev/null) 2>/dev/null
echo $$ > /var/log/minieap-ping.pid
ping_host=$(uci get minieap.@minieap[0].pinghost)
ping_intval=$(uci get minieap.@minieap[0].pingintval)
ping_command=$(uci get minieap.@minieap[0].pingcommand)
ipint=$(echo $ping_host | awk -F "." '{print $1*2**8**3 + $2*2**8**2 + $3*2**8 + $4}')
if [[ $ipint -le 0 ]] || [[ $ipint -ge 4294967295 ]]; then
exit
fi
if [ ! -z $ping_host ]; then
while true
do
ping -c1 -w1 $ping_host > /dev/null 2>&1
if [ $? -ne 0 ]; then
$ping_command
fi
sleep $ping_intval
done
fi
@@ -1,11 +0,0 @@
{
"luci-app-minieap": {
"description": "Grant UCI access for luci-app-minieap",
"read": {
"uci": [ "minieap" ]
},
"write": {
"uci": [ "minieap" ]
}
}
}
@@ -1,4 +0,0 @@
{
"config": "minieap",
"init": "minieap"
}
+3 -3
View File
@@ -8,11 +8,11 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for MWAN3 Helper
LUCI_DEPENDS:=+luci-app-mwan3 +pdnsd-alt +dnsmasq-full +ipset
LUCI_PKGARCH:=all
PKG_NAME:=luci-app-mwan3helper
PKG_VERSION:=1
PKG_RELEASE:=1
PKG_RELEASE:=2
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
@@ -1,4 +1,3 @@
-- Licensed to the public under the GNU General Public License v3.
module("luci.controller.mwan3helper", package.seeall)
@@ -8,21 +7,15 @@ function index()
return
end
local page = entry({"admin", "services", "mwan3helper"},alias("admin", "services", "mwan3helper", "client"),_("MWAN3 Helper"), 300)
page.dependent = true
page.acl_depends = { "luci-app-mwan3helper" }
entry({"admin", "services", "mwan3helper", "client"},cbi("mwan3helper/client"),_("Settings"), 10).leaf = true
entry({"admin", "services", "mwan3helper", "lists"},cbi("mwan3helper/list"),_("IPSet Lists"), 20).leaf = true
entry({"admin","services","mwan3helper","status"},call("act_status")).leaf=true
entry({"admin", "services", "mwan3helper"}, alias("admin", "services", "mwan3helper", "client"), _("MWAN3 Helper"), 300).dependent = true
entry({"admin", "services", "mwan3helper", "client"}, cbi("mwan3helper/client"), _("Settings"), 10).leaf = true
entry({"admin", "services", "mwan3helper", "lists"}, cbi("mwan3helper/list"), _("IPSet Lists"), 20).leaf = true
entry({"admin", "services", "mwan3helper", "status"}, call("act_status")).leaf = true
end
function act_status()
local e={}
e.running=luci.sys.call("pgrep mwan3dns >/dev/null")==0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
local e = {}
e.running = luci.sys.call("pgrep mwan3dns >/dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
@@ -1,5 +1,3 @@
m = Map("mwan3helper")
m.title = translate("MWAN3 Helper")
m.description = translate("MWAN3 Helper generate IPSets")
@@ -11,8 +9,8 @@ s.addremove = false
s.anonymous = true
o = s:option(Flag, "enabled", translate("Enable GFW IPSet"))
o.rmempty = false
o.description = translate("启用 DNS 防污染并打开GFW IPSet(与SSR的GFW列表模式不能同时开启)")
o.rmempty = false
o = s:option(ListValue, "dns", translate("Anti-pollution DNS Server"))
o:value("208.67.222.222:443", translate("OpenDNS (208.67.222.222)"))
@@ -1,5 +1,3 @@
m = Map("mwan3helper")
m.title = translate("MWAN3 IPSets")
@@ -19,4 +19,4 @@ XHR.poll(3, '<%=url([[admin]], [[services]], [[mwan3helper]], [[status]])%>', nu
<p id="mwan3helper_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>
</fieldset>
-1
View File
@@ -1 +0,0 @@
zh_Hans
@@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"Language: zh_Hans\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+1
View File
@@ -0,0 +1 @@
zh-cn
@@ -19,19 +19,19 @@ start_pdnsd() {
cat > /var/etc/mwan3dns.conf <<EOF
global {
perm_cache=1024; # dns缓存大小,单位KB,建议不要写的太大
cache_dir="/var/mwan3dns"; # 缓存文件的位置
perm_cache=1024; # dns缓存大小,单位KB,建议不要写的太大
cache_dir="/var/mwan3dns"; # 缓存文件的位置
pid_file = /var/run/mwan3dns.pid;
server_ip = 0.0.0.0; # pdnsd监听的网卡,0.0.0.0是全部网卡
server_port=53000; # pdnsd监听的端口,不要和别的服务冲突即可
server_ip = 0.0.0.0; # pdnsd监听的网卡,0.0.0.0是全部网卡
server_port=53000; # pdnsd监听的端口,不要和别的服务冲突即可
status_ctl = on;
paranoid=on; # 二次请求模式,如果请求主DNS服务器返回的是垃圾地址,就向备用服务器请求
paranoid=on; # 二次请求模式,如果请求主DNS服务器返回的是垃圾地址,就向备用服务器请求
query_method=udp_only;
neg_domain_pol = off;
par_queries = 400; # 最多同时请求数
min_ttl = 1h; # DNS结果最短缓存时间
max_ttl = 1w; # DNS结果最长缓存时间
timeout = 10; # DNS请求超时时间,单位秒
par_queries = 400; # 最多同时请求数
min_ttl = 1h; # DNS结果最短缓存时间
max_ttl = 1w; # DNS结果最长缓存时间
timeout = 10; # DNS请求超时时间,单位秒
}
server {
@@ -39,7 +39,7 @@ server {
ip = $DNS_SERVER;
port = 53;
timeout = 5;
reject = 74.125.127.102, # 以下是脏IP,也就是DNS污染一般会返回的结果,如果收到如下DNS结果会触发二次请求(TCP协议一般不会碰到脏IP)
reject = 74.125.127.102, # 以下是脏IP,也就是DNS污染一般会返回的结果,如果收到如下DNS结果会触发二次请求(TCP协议一般不会碰到脏IP)
74.125.155.102,
74.125.39.102,
74.125.39.113,
@@ -102,9 +102,9 @@ server {
}
server {
label = "special"; # 这个随便写
ip = 208.67.222.222,208.67.220.220; # 这里为备用DNS服务器的 ip 地址
port = 443; # 推荐使用53以外的端口(DNS服务器必须支持)
label = "special"; # 这个随便写
ip = 208.67.222.222,208.67.220.220; # 这里为备用DNS服务器的 ip 地址
port = 443; # 推荐使用53以外的端口(DNS服务器必须支持)
proxy_only = on;
timeout = 5;
}
@@ -164,6 +164,3 @@ stop(){
rm -f /tmp/dnsmasq.d/dnsmasq-mwan3.conf
/etc/init.d/dnsmasq restart
}
-14
View File
@@ -1,14 +0,0 @@
--Copyright (C) 2019 mleaf <mleaf90@gmail.com>
--微信公众号【WiFi物联网】
module("luci.controller.mwol", package.seeall)
function index()
if not nixio.fs.access("/etc/config/mwol") then
return
end
local page = entry({"admin", "services", "mwol"}, cbi("mwol"), _("Mwol"))
page.dependent = true
page.acl_depends = { "luci-app-mwol" }
end
-141
View File
@@ -1,141 +0,0 @@
--Copyright (C) 2019 mleaf <mleaf90@gmail.com>
--微信公众号【WiFi物联网】
local NXFS = require "nixio.fs"
local SYS = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local Status, subTopic, pubTopic
local m, s
local e, mwol
local encryption
local sys = require "luci.sys"
local mac = luci.sys.exec("uci -q get mwol.mwol_conf.id")
m = Map("mwol", translate("Mqtt wake on lan"))
m.description = translate("请关注微信公众号【WiFi物联网】获取更多信息: \<a href=\"http://www.mleaf.org/downloads/logo/201911171573997716658567.jpg\" target=\"_blank\">【WiFi物联网】</a>")
if SYS.call("pidof mwol >/dev/null") == 0 then
Status = translate("<strong><font color=\"green\">Mwol正在运行...</font></strong>")
else
Status = translate("<strong><font color=\"red\">Mwol未运行...</font></strong>")
end
subTopic = string.format("<strong><font color=\"red\">Mwol订阅消息主题: /mwol/pub/%s</font></strong>", mac)
pubTopic = string.format("<strong><font color=\"red\">Mwol发布消息主题: /mwol/sub/%s</font></strong>", mac)
--
-- LoRa Gateway config for gateway_conf
--
mwol = m:section(TypedSection, "mwol")
--mwol.addremove = false
mwol.anonymous = true
mwol.description = translate(string.format("%s<br /><br />%s<br><br />%s", Status, subTopic, pubTopic))
mwol:tab("general", translate("General Settings"))
mwol:tab("encryptionSettings", translate("Encryption Settings"))
mwol:tab("ssl", translate("SSL Settings"))
--
-- MQTT general
--
e = mwol:taboption("general", Flag, "enable")
e.title = translate("Enable")
e.default = 0
e.rmempty = false
e = mwol:taboption("general", Value, "hostname")
e.title = translate("MQTT Server")
e = mwol:taboption("general", Value, "port")
e.title = translate("MQTT Port")
host = mwol:taboption("general", Value, "presetmac", translate("Host to wake up"))
host.description = translate("Choose the host to wake up or enter a custom MAC address to use")
host.title = translate("Preset Mac")
sys.net.mac_hints(function(mac, name)
host:value(mac, "%s (%s)" %{ mac, name })
end)
e = mwol:taboption("general", Value, "id")
e.default = mac
e.rmempty = false;
e.title = translate("MQTT Topic Id")
--
-- MQTT Using encryption
--
encryption_enable = mwol:taboption("encryptionSettings", ListValue, "encryptionenable", translate("Enable"))
encryption_enable.optional = false;
encryption_enable.rmempty = false;
encryption_enable.default = 0
encryption_enable.datatype = "uinteger"
encryption_enable:value(1, translate("True"))
encryption_enable:value(0, translate("False"))
--
-- MQTT username
--
encryption_username = mwol:taboption("encryptionSettings", Value, "username", translate("MQTT UserName"))
encryption_username.optional = true;
encryption_username.rmempty = true;
encryption_username.default = "mleaf"
encryption_username.datatype = "string"
encryption_username:depends("encryptionenable", "1")
--
-- MQTT password
--
encryption_password = mwol:taboption("encryptionSettings", Value, "password", translate("MQTT Password"))
encryption_password.optional = true;
encryption_password.rmempty = true;
encryption_password.default = "www.mleaf.org"
encryption_password.datatype = "string"
encryption_password:depends("encryptionenable", "1")
--
-- MQTT Using SSL
--
ssl_enable = mwol:taboption("ssl", ListValue, "sslenable", translate("Enable"))
ssl_enable.optional = false;
ssl_enable.rmempty = false;
ssl_enable.default = 0
ssl_enable.datatype = "uinteger"
ssl_enable:value(1, translate("True"))
ssl_enable:value(0, translate("False"))
--
-- MQTT cafile
--
cafile = mwol:taboption("ssl", Value, "cafile", translate("ca"))
cafile.description = translate("Edit the ca file path.")
cafile.optional = true;
cafile.rmempty = true;
cafile.default = false
cafile.datatype = "string"
cafile:depends("sslenable", "1")
--
-- MQTT crtfile
--
crtfile = mwol:taboption("ssl", Value, "crtfile", translate("crt"))
crtfile.description = translate("Edit the crt file path.")
crtfile.optional = true;
crtfile.rmempty = true;
crtfile.default = false
crtfile.datatype = "string"
crtfile:depends("sslenable", "1")
--
-- MQTT keyfile
--
keyfile = mwol:taboption("ssl", Value, "keyfile", translate("key"))
keyfile.description = translate("Edit the key file path.")
keyfile.optional = true;
keyfile.rmempty = true;
keyfile.default = false
keyfile.datatype = "string"
keyfile:depends("sslenable", "1")
return m
-1
View File
@@ -1 +0,0 @@
zh_Hans
-54
View File
@@ -1,54 +0,0 @@
msgid "Mwol Plus is Running"
msgstr "Mwol正在运行"
msgid "Mwol Plus is Not Running"
msgstr "Mwol未运行"
msgid "Mwol Sub Topic:"
msgstr "Mwol订阅消息主题:"
msgid "Mwol Pub Topic:"
msgstr "Mwol发布消息主题:"
msgid "General Settings"
msgstr "通用设置"
msgid "Encryption Settings"
msgstr "加密设定"
msgid "SSL Settings"
msgstr "SSL证书设置"
msgid "Enable"
msgstr "开启"
msgid "MQTT Server"
msgstr "MQTT服务器"
msgid "MQTT Port"
msgstr "MQTT端口"
msgid "Preset Mac"
msgstr "预设MAC地址"
msgid "Choose the host to wake up or enter a custom MAC address to use"
msgstr "选择一个需要唤醒的主机或自定义唤醒主机的mac地址"
msgid "MQTT Topic Id"
msgstr "MQTT主题ID"
msgid "MQTT UserName"
msgstr "MQTT用户名"
msgid "MQTT Password"
msgstr "MQTT密码"
msgid "Edit the ca file path."
msgstr "编辑CA路径。"
msgid "Edit the crt file path."
msgstr "编辑CRT路径。"
msgid "Edit the key file path."
msgstr "编辑KEY路径。"
@@ -1,19 +0,0 @@
#!/bin/sh
[ ! -f "/usr/share/ucitrack/luci-app-mwol.json" ] && {
cat > /usr/share/ucitrack/luci-app-mwol.json << EEOF
{
"config": "mwol",
"init": "mwol"
}
EEOF
}
uci -q batch <<-EOF >/dev/null
delete ucitrack.@mwol[-1]
add ucitrack mwol
set ucitrack.@mwol[-1].init=mwol
commit ucitrack
EOF
rm -f /tmp/luci-indexcache
exit 0
@@ -1,11 +0,0 @@
{
"luci-app-mwol": {
"description": "Grant UCI access for luci-app-mwol",
"read": {
"uci": [ "mwol" ]
},
"write": {
"uci": [ "mwol" ]
}
}
}
@@ -1,16 +1,17 @@
#
# Copyright (C) 2019 mleaf <mleaf90@gmail.com>
# 微信公众号【WiFi物联网】
# Copyright (C) 2008-2014 The LuCI Team <luci@lists.subsignal.org>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI Support for Mwol
LUCI_DEPENDS:=+mwol
LUCI_TITLE:=Qos over Nftables
LUCI_DEPENDS:=+nft-qos
LUCI_PKGARCH:=all
PKG_VERSION:=1.0
PKG_NAME:=luci-app-nft-qos
PKG_VERSION:=1
PKG_RELEASE:=1
include $(TOPDIR)/feeds/luci/luci.mk
@@ -0,0 +1,52 @@
-- Copyright 2018 Rosy Song <rosysong@rosinson.com>
-- Licensed to the public under the Apache License 2.0.
module("luci.controller.nft-qos", package.seeall)
function index()
if not nixio.fs.access("/etc/config/nft-qos") then
return
end
entry({"admin", "status", "realtime", "rate"}, template("nft-qos/rate"), _("Rate"), 5).leaf = true
entry({"admin", "status", "realtime", "rate_status"}, call("action_rate")).leaf = true
entry({"admin", "services", "nft-qos"}, cbi("nft-qos/nft-qos"), _("Qos over Nftables"), 60)
end
function _action_rate(rv, n)
local c = nixio.fs.access("/proc/net/ipv6_route") and
io.popen("nft list chain inet nft-qos-monitor " .. n .. " 2>/dev/null") or
io.popen("nft list chain ip nft-qos-monitor " .. n .. " 2>/dev/null")
if c then
for l in c:lines() do
local _, i, p, b = l:match(
'^%s+ip ([^%s]+) ([^%s]+) counter packets (%d+) bytes (%d+)'
)
if i and p and b then
-- handle expression
rv[#rv + 1] = {
rule = {
family = "inet",
table = "nft-qos-monitor",
chain = n,
handle = 0,
expr = {
{ match = { right = i } },
{ counter = { packets = p, bytes = b } }
}
}
}
end
end
c:close()
end
end
function action_rate()
luci.http.prepare_content("application/json")
local data = { nftables = {} }
_action_rate(data.nftables, "upload")
_action_rate(data.nftables, "download")
luci.http.write_json(data)
end
@@ -0,0 +1,229 @@
-- Copyright 2018 Rosy Song <rosysong@rosinson.com>
-- Licensed to the public under the Apache License 2.0.
local uci = require("luci.model.uci").cursor()
local wa = require("luci.tools.webadmin")
local fs = require("nixio.fs")
local ipc = require("luci.ip")
local def_rate_dl = uci:get("nft-qos", "default", "static_rate_dl")
local def_rate_ul = uci:get("nft-qos", "default", "static_rate_ul")
local def_unit_dl = uci:get("nft-qos", "default", "static_unit_dl")
local def_unit_ul = uci:get("nft-qos", "default", "static_unit_ul")
local def_up = uci:get("nft-qos", "default", "dynamic_bw_up")
local def_down = uci:get("nft-qos", "default", "dynamic_bw_down")
local limit_enable = uci:get("nft-qos", "default", "limit_enable")
local limit_type = uci:get("nft-qos", "default", "limit_type")
local enable_priority = uci:get("nft-qos", "default", "priority_enable")
local has_ipv6 = fs.access("/proc/net/ipv6_route")
m = Map("nft-qos", translate("Qos over Nftables"))
--
-- Taboptions
--
s = m:section(TypedSection, "default", translate("NFT-QoS Settings"))
s.addremove = false
s.anonymous = true
s:tab("limit", "Limit Rate")
s:tab("priority", "Traffic Priority")
--
-- Static
--
o = s:taboption("limit", Flag, "limit_enable", translate("Limit Enable"), translate("Enable Limit Rate Feature"))
o.default = limit_enable or o.enabled
o.rmempty = false
o = s:taboption("limit", ListValue, "limit_type", translate("Limit Type"), translate("Type of Limit Rate"))
o.default = limit_static or "static"
o:depends("limit_enable","1")
o:value("static", "Static")
o:value("dynamic", "Dynamic")
o = s:taboption("limit", Value, "static_rate_dl", translate("Default Download Rate"), translate("Default value for download rate"))
o.datatype = "uinteger"
o.default = def_rate_dl or '50'
o:depends("limit_type","static")
o = s:taboption("limit", ListValue, "static_unit_dl", translate("Default Download Unit"), translate("Default unit for download rate"))
o.default = def_unit_dl or "kbytes"
o:depends("limit_type","static")
o:value("bytes", "Bytes/s")
o:value("kbytes", "KBytes/s")
o:value("mbytes", "MBytes/s")
o = s:taboption("limit", Value, "static_rate_ul", translate("Default Upload Rate"), translate("Default value for upload rate"))
o.datatype = "uinteger"
o.default = def_rate_ul or '50'
o:depends("limit_type","static")
o = s:taboption("limit", ListValue, "static_unit_ul", translate("Default Upload Unit"), translate("Default unit for upload rate"))
o.default = def_unit_ul or "kbytes"
o:depends("limit_type","static")
o:value("bytes", "Bytes/s")
o:value("kbytes", "KBytes/s")
o:value("mbytes", "MBytes/s")
--
-- Dynamic
--
o = s:taboption("limit", Value, "dynamic_bw_down", translate("Download Bandwidth (Mbps)"), translate("Default value for download bandwidth"))
o.default = def_up or '100'
o.datatype = "uinteger"
o:depends("limit_type","dynamic")
o = s:taboption("limit", Value, "dynamic_bw_up", translate("Upload Bandwidth (Mbps)"), translate("Default value for upload bandwidth"))
o.default = def_down or '100'
o.datatype = "uinteger"
o:depends("limit_type","dynamic")
o = s:taboption("limit", Value, "dynamic_cidr", translate("Target Network (IPv4/MASK)"), translate("Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc"))
o.datatype = "cidr4"
ipc.routes({ family = 4, type = 1 }, function(rt) o.default = rt.dest end)
o:depends("limit_type","dynamic")
if has_ipv6 then
o = s:taboption("limit", Value, "dynamic_cidr6", translate("Target Network6 (IPv6/MASK)"), translate("Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc"))
o.datatype = "cidr6"
o:depends("limit_type","dynamic")
end
o = s:taboption("limit", DynamicList, "limit_whitelist", translate("White List for Limit Rate"))
o.datatype = "ipaddr"
o:depends("limit_enable","1")
--
-- Priority
--
o = s:taboption("priority", Flag, "priority_enable", translate("Enable Traffic Priority"), translate("Enable this feature"))
o.default = enable_priority or o.enabled
o.rmempty = false
o = s:taboption("priority", ListValue, "priority_netdev", translate("Default Network Interface"), translate("Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc"))
o:depends("priority_enable", "1")
wa.cbi_add_networks(o)
--
-- Static Limit Rate - Download Rate
--
if limit_enable == "1" and limit_type == "static" then
x = m:section(TypedSection, "download", translate("Static QoS-Download Rate"))
x.anonymous = true
x.addremove = true
x.template = "cbi/tblsection"
o = x:option(Value, "hostname", translate("Hostname"))
o.datatype = "hostname"
o.default = 'undefined'
if has_ipv6 then
o = x:option(Value, "ipaddr", translate("IP Address(V4 / V6)"))
else
o = x:option(Value, "ipaddr", translate("IP Address(V4 Only)"))
end
o.datatype = "ipaddr"
if nixio.fs.access("/tmp/dhcp.leases") or nixio.fs.access("/var/dhcp6.leases") then
o.titleref = luci.dispatcher.build_url("admin", "status", "overview")
end
o = x:option(Value, "macaddr", translate("MAC (optional)"))
o.rmempty = true
o.datatype = "macaddr"
o = x:option(Value, "rate", translate("Rate"))
o.default = def_rate_dl or '50'
o.size = 4
o.datatype = "uinteger"
o = x:option(ListValue, "unit", translate("Unit"))
o.default = def_unit_dl or "kbytes"
o:value("bytes", "Bytes/s")
o:value("kbytes", "KBytes/s")
o:value("mbytes", "MBytes/s")
--
-- Static Limit Rate - Upload Rate
--
y = m:section(TypedSection, "upload", translate("Static QoS-Upload Rate"))
y.anonymous = true
y.addremove = true
y.template = "cbi/tblsection"
o = y:option(Value, "hostname", translate("Hostname"))
o.datatype = "hostname"
o.default = 'undefined'
if has_ipv6 then
o = y:option(Value, "ipaddr", translate("IP Address(V4 / V6)"))
else
o = y:option(Value, "ipaddr", translate("IP Address(V4 Only)"))
end
o.datatype = "ipaddr"
if nixio.fs.access("/tmp/dhcp.leases") or nixio.fs.access("/var/dhcp6.leases") then
o.titleref = luci.dispatcher.build_url("admin", "status", "overview")
end
o = y:option(Value, "macaddr", translate("MAC (optional)"))
o.rmempty = true
o.datatype = "macaddr"
o = y:option(Value, "rate", translate("Rate"))
o.default = def_rate_ul or '50'
o.size = 4
o.datatype = "uinteger"
o = y:option(ListValue, "unit", translate("Unit"))
o.default = def_unit_ul or "kbytes"
o:value("bytes", "Bytes/s")
o:value("kbytes", "KBytes/s")
o:value("mbytes", "MBytes/s")
end
--
-- Traffic Priority Settings
--
if enable_priority == "1" then
s = m:section(TypedSection, "priority", translate("Traffic Priority Settings"))
s.anonymous = true
s.addremove = true
s.template = "cbi/tblsection"
o = s:option(ListValue, "protocol", translate("Protocol"))
o.default = "tcp"
o:value("tcp", "TCP")
o:value("udp", "UDP")
o:value("udplite", "UDP-Lite")
o:value("sctp", "SCTP")
o:value("dccp", "DCCP")
o = s:option(ListValue, "priority", translate("Priority"))
o.default = "1"
o:value("-400", "1")
o:value("-300", "2")
o:value("-225", "3")
o:value("-200", "4")
o:value("-150", "5")
o:value("-100", "6")
o:value("0", "7")
o:value("50", "8")
o:value("100", "9")
o:value("225", "10")
o:value("300", "11")
o = s:option(Value, "service", translate("Service"), translate("e.g. https, 23, (separator is comma)"))
o.default = '?'
o = s:option(Value, "comment", translate("Comment"))
o.default = '?'
end
return m
@@ -0,0 +1,187 @@
<%#
Copyright 2018 Rosy Song <rosysong@rosinson.com>
Licensed to the public under the Apache License 2.0.
-%>
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
var RC = { };
var em = 0;
var ec = 1;
var rate_table_dl;
var rate_table_ul;
function init_bytes(rl, ra) {
var bytes_pre;
var obj = { };
obj.chain = rl.chain;
obj.ipaddr = rl.expr[em].match.right;
obj.bytes = rl.expr[ec].counter.bytes;
obj.packets = rl.expr[ec].counter.packets;
obj.rate = 0;
if (RC[obj.chain] && RC[obj.chain][obj.ipaddr])
bytes_pre = RC[obj.chain][obj.ipaddr];
else
bytes_pre = 0;
obj.rate = (bytes_pre > 0) ? (obj.bytes - bytes_pre) / 3: 0;
if (!RC[obj.chain])
RC[obj.chain] = { };
RC[obj.chain][obj.ipaddr] = obj.bytes;
if (!ra[obj.chain])
ra[obj.chain] = [ ];
ra[obj.chain].push(obj);
} /* function init_bytes(rl, ra) */
function bytes_label(bytes) {
var uby = '<%:kB%>';
var kby = (bytes / 1024);
if (kby > 1024) {
uby = '<%:MB%>';
kby = (kby / 1024);
}
return String.format("%f %s", kby.toFixed(2), uby);
}
function print_table(tbl, rs, ra) {
ra.sort(function(a, b) { return b.rate - a.rate });
for (var i = 0; i < ra.length; i++) {
rs.push([
ra[i].ipaddr,
bytes_label(ra[i].rate) + '/s',
bytes_label(ra[i].bytes),
'%s Pkts.'.format(ra[i].packets),
]);
}
/* BEGIN: Workaround as "cbi_update_table" isn't working */
rs.forEach((element, i) => {
var r = document.createElement("TR");
r.innerHTML = `
<tr>
<td style="text-align: center;">${element[0]}</th>
<td style="text-align: center;">${element[1]}</td>
<td style="text-align: center;">${element[2]}</td>
<td style="text-align: center;">${element[3]}</td>
</tr>
`;
if (i%2){
r.classList.add('tr', 'cbi-rowstyle-2');
} else {
r.classList.add('tr', 'cbi-rowstyle-1');
}
tbl.appendChild(r)
/* END: Workaround as "cbi_update_table" isn't working */
});
} /* function print_table(tbl, ra) */
/* wait for SVG */
window.setTimeout(
function() {
if (!RC)
{
window.setTimeout(arguments.callee, 1000);
}
else
{
rate_table_dl = document.getElementById('rate_table_dl');
rate_table_ul = document.getElementById('rate_table_ul');
/* render datasets, start update interval */
XHR.poll(3, '<%=build_url("admin/status/realtime/rate_status")%>', null,
function(x, json)
{
var RA = {};
var rows_dl = [];
var rows_ul = [];
var rules = json.nftables;
for (var i = 0; i < rules.length; i++)
{
if (!rules[i].rule)
continue;
if (rules[i].rule.table != 'nft-qos-monitor')
continue;
var rl = rules[i].rule;
switch (rl.chain)
{
case 'download':
case 'upload': init_bytes(rl, RA); break;
}
} /* for (var i = 0; i < rules.length; i++) */
/* display the result */
if (RA.download) {
while (rate_table_dl.firstElementChild !== rate_table_dl.lastElementChild)
rate_table_dl.removeChild(rate_table_dl.lastElementChild);
print_table(rate_table_dl, rows_dl, RA.download);
}
if (RA.upload) {
while (rate_table_ul.firstElementChild !== rate_table_ul.lastElementChild)
rate_table_ul.removeChild(rate_table_ul.lastElementChild);
print_table(rate_table_ul, rows_ul, RA.upload);
}
} /* function(x, json) */
); /* XHR.poll() */
XHR.run();
}
}, 1000
);
//]]></script>
<h2 name="content"><%:Realtime Rate%></h2>
<div class="cbi-map-descr"><%:This page gives an overview over currently download/upload rate.%></div>
<fieldset class="cbi-section" id="cbi-table-table">
<legend><%:Realtime Download Rate%></legend>
<div class="cbi-section-node">
<div class="table" id="rate_table_dl">
<div class="tr table-titles">
<div class="th col-2 hide-xs"><%:IP Address%></div>
<div class="th col-2"><%:Download Rate%></div>
<div class="th col-7"><%:Bytes Total%></div>
<div class="th col-7"><%:Packets Total%></div>
</div>
<div class="tr placeholder">
<div class="td">
<em><%:Collecting data...%></em>
</div>
</div>
</div>
</div>
</fieldset>
<fieldset class="cbi-section" id="cbi-table-table">
<legend><%:Realtime Upload Rate%></legend>
<div class="cbi-section-node">
<div class="table" id="rate_table_ul">
<div class="tr table-titles">
<div class="th col-2 hide-xs"><%:IP Address%></div>
<div class="th col-2"><%:Upload Rate%></div>
<div class="th col-7"><%:Bytes Total%></div>
<div class="th col-7"><%:Packets Total%></div>
</div>
<div class="tr placeholder">
<div class="td">
<em><%:Collecting data...%></em>
</div>
</div>
</div>
</div>
</fieldset>
<%+footer%>
Loaded 100 of 207 files, more files were not shown because too many files have changed in this diff. Show more