mirror of
https://github.com/kenzok8/small-package
synced 2025-09-18 18:51:16 +08:00
update-12.04
This commit is contained in:
@ -47,7 +47,7 @@ config CDNSPEEDTEST_COMPRESS_GOPROXY
|
||||
config CDNSPEEDTEST_COMPRESS_UPX
|
||||
bool "Compress executable files with UPX"
|
||||
depends on !mips64
|
||||
default y if mips||mipsel
|
||||
default n
|
||||
endef
|
||||
|
||||
ifeq ($(CONFIG_CDNSPEEDTEST_COMPRESS_GOPROXY),y)
|
||||
|
@ -11,9 +11,9 @@ PKG_ARCH_DDNSTO:=$(ARCH)
|
||||
|
||||
PKG_NAME:=ddnsto
|
||||
PKG_VERSION:=0.3.0
|
||||
PKG_RELEASE:=1
|
||||
PKG_RELEASE:=2
|
||||
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://firmware.koolshare.cn/binary/ddnsto/
|
||||
PKG_SOURCE_URL:=http://fw.koolcenter.com/binary/ddnsto/
|
||||
PKG_HASH:=skip
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION)
|
||||
@ -40,6 +40,13 @@ define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/ddnsto
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
[ -f /etc/uci-defaults/ddnsto ] && /etc/uci-defaults/ddnsto && rm -f /etc/uci-defaults/ddnsto
|
||||
fi
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
|
@ -5,14 +5,14 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=libcron
|
||||
PKG_VERSION:=1.3.0
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/PerMalmberg/libcron.git
|
||||
PKG_SOURCE_DATE:=2020-12-04
|
||||
PKG_SOURCE_VERSION:=b0046755bda166dde253e33f68a5b0a1c3ed387e
|
||||
PKG_SOURCE_DATE:=2021-11-22
|
||||
PKG_SOURCE_VERSION:=d4679b7c3cd7b03bf3865dc1709f1d1133fb7ee1
|
||||
PKG_MIRROR_HASH:=skip
|
||||
PKG_VERSION:=1.3.0-$(call version_abbrev,$(PKG_SOURCE_VERSION))
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
@ -32,15 +32,8 @@ define Package/libcron
|
||||
endef
|
||||
|
||||
define Package/libcron/description
|
||||
Libcron offers an easy to use API to add callbacks with corresponding cron-formatted strings.
|
||||
endef
|
||||
|
||||
define Build/Install
|
||||
$(INSTALL_DIR) $(PKG_INSTALL_DIR)/usr/lib/
|
||||
$(CP) $(PKG_BUILD_DIR)/libcron/out/Release/liblibcron.a $(PKG_INSTALL_DIR)/usr/lib/
|
||||
$(INSTALL_DIR) $(PKG_INSTALL_DIR)/usr/include/libcron/
|
||||
$(CP) $(PKG_BUILD_DIR)/libcron/include/* $(PKG_INSTALL_DIR)/usr/include/
|
||||
$(CP) $(PKG_BUILD_DIR)/libcron/externals/date/include/* $(PKG_INSTALL_DIR)/usr/include/
|
||||
Libcron offers an easy to use API to add callbacks with corresponding
|
||||
cron-formatted strings.
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,libcron))
|
||||
|
65
linkease/Makefile
Normal file
65
linkease/Makefile
Normal file
@ -0,0 +1,65 @@
|
||||
#
|
||||
# Copyright (C) 2015-2016 OpenWrt.org
|
||||
# Copyright (C) 2020 jjm2473@gmail.com
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_ARCH_LINKEASE:=$(ARCH)
|
||||
|
||||
PKG_NAME:=linkease
|
||||
PKG_VERSION:=0.3.66
|
||||
PKG_RELEASE:=2
|
||||
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://fw.koolcenter.com/binary/LinkEase/LinuxStorage/
|
||||
PKG_HASH:=skip
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION)
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=Web Servers/Proxies
|
||||
TITLE:=LinkEase - the file cloud
|
||||
DEPENDS:=
|
||||
URL:=https://www.ddnsto.com/linkease/
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
LinkEase is a file cloud
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/linkease
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
[ -f /etc/uci-defaults/linkease ] && /etc/uci-defaults/linkease && rm -f /etc/uci-defaults/linkease
|
||||
fi
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin/linkease-plugins $(1)/etc/config $(1)/etc/init.d $(1)/etc/uci-defaults
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/linkease.$(PKG_ARCH_LINKEASE) $(1)/usr/sbin/linkease
|
||||
$(INSTALL_BIN) ./files/aria2.sh $(1)/usr/sbin/linkease-plugins/aria2.sh
|
||||
$(INSTALL_CONF) ./files/linkease.config $(1)/etc/config/linkease
|
||||
$(INSTALL_BIN) ./files/linkease.init $(1)/etc/init.d/linkease
|
||||
$(INSTALL_BIN) ./files/linkease.uci-default $(1)/etc/uci-defaults/linkease
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
134
linkease/files/aria2.sh
Executable file
134
linkease/files/aria2.sh
Executable file
@ -0,0 +1,134 @@
|
||||
#!/bin/bash
|
||||
|
||||
sh_ver="1.0.0"
|
||||
export PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/sbin:/bin
|
||||
aria2_conf_dir=/var/etc/aria2/
|
||||
#替换成你设备aria2.conf路径
|
||||
aria2_conf=${aria2_conf_dir}/aria2.conf.main
|
||||
#替换成你设备的aria2c路径
|
||||
aria2c=/usr/bin/aria2c
|
||||
Green_font_prefix="\033[32m"
|
||||
Red_font_prefix="\033[31m"
|
||||
Green_background_prefix="\033[42;37m"
|
||||
Red_background_prefix="\033[41;37m"
|
||||
Font_color_suffix="\033[0m"
|
||||
Info="[${Green_font_prefix}信息${Font_color_suffix}]"
|
||||
Error="[${Red_font_prefix}错误${Font_color_suffix}]"
|
||||
Tip="[${Green_font_prefix}注意${Font_color_suffix}]"
|
||||
error_code=11
|
||||
success_code=0
|
||||
|
||||
return_error(){
|
||||
echo 'Content-Type:application/json;charset=utf-8'
|
||||
echo
|
||||
echo "{
|
||||
"\"success\"":$error_code,
|
||||
"\"error\"":"\"$1\"",
|
||||
"\"result"\":null
|
||||
}"
|
||||
exit 1
|
||||
}
|
||||
return_ok(){
|
||||
echo 'Content-Type:application/json;charset=utf-8'
|
||||
echo
|
||||
echo "{
|
||||
"\"success\"":$success_code,
|
||||
"\"error\"":"\"$1\"",
|
||||
"\"result"\":null
|
||||
}"
|
||||
exit 0
|
||||
}
|
||||
return_result(){
|
||||
echo 'Content-Type:application/json;charset=utf-8'
|
||||
echo
|
||||
echo "{
|
||||
"\"success\"":$success_code,
|
||||
"\"error\"":"\"\"",
|
||||
"\"result"\":$1
|
||||
}"
|
||||
exit 0
|
||||
}
|
||||
|
||||
#进程中是否运行aria2
|
||||
check_pid() {
|
||||
PID=$(ps -ef | grep "aria2c" | grep -v grep | grep -v "aria2.sh" | grep -v "init.d" | grep -v "service" | awk '{print $2}')
|
||||
}
|
||||
|
||||
#aria2是否正在运行
|
||||
aria2_work_status(){
|
||||
check_pid
|
||||
# [[ ! -z ${PID} ]] && echo -e "${Error} Aria2 正在运行,请检查 !" && exit 1
|
||||
[[ ! -z ${PID} ]] && return_ok "Aria2正在运行"
|
||||
return_error "Aria2未运行"
|
||||
}
|
||||
|
||||
#检测设备是否安装aria2
|
||||
check_installed_status() {
|
||||
[[ ! -e ${aria2c} ]] && return_error "Aria2 没有安装,请检查 !"
|
||||
[[ ! -e ${aria2_conf} ]] && return_error "Aria2 配置文件不存在,请检查 !"
|
||||
# return_ok "Aria2已安装"
|
||||
}
|
||||
#读取aria2配置信息
|
||||
read_config() {
|
||||
check_installed_status
|
||||
if [[ ! -e ${aria2_conf} ]]; then
|
||||
return_error "Aria2 配置文件不存在,请检查 !"
|
||||
else
|
||||
conf_text=$(cat ${aria2_conf} | grep -v '#')
|
||||
aria2_dir=$(echo -e "${conf_text}" | grep "^dir=" | awk -F "=" '{print $NF}')
|
||||
aria2_port=$(echo -e "${conf_text}" | grep "^rpc-listen-port=" | awk -F "=" '{print $NF}')
|
||||
aria2_passwd=$(echo -e "${conf_text}" | grep "^rpc-secret=" | awk -F "=" '{print $NF}')
|
||||
aria2_bt_port=$(echo -e "${conf_text}" | grep "^listen-port=" | awk -F "=" '{print $NF}')
|
||||
aria2_dht_port=$(echo -e "${conf_text}" | grep "^dht-listen-port=" | awk -F "=" '{print $NF}')
|
||||
|
||||
return_result "{
|
||||
"\"dir"\":"\"$aria2_dir"\",
|
||||
"\"rpc-listen-port"\":"\"$aria2_port"\",
|
||||
"\"rpc-secret"\":"\"$aria2_passwd"\",
|
||||
"\"listen-port"\":"\"$aria2_bt_port"\",
|
||||
"\"dht-listen-port"\":"\"$aria2_dht_port"\"}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#"Content-Type:text/html;charset=utf-8"
|
||||
#echo
|
||||
|
||||
#SERVER_SOFTWARE = $SERVER_SOFTWARE #服务器软件
|
||||
#SERVER_NAME = $SERVER_NAME #服务器主机名
|
||||
#GATEWAY_INTERFACE = $GATEWAY_INTERFACE #CGI版本
|
||||
#SERVER_PROTOCOL = $SERVER_PROTOCOL #通信使用的协议
|
||||
#SERVER_PORT = $SERVER_PORT #服务器的端口号
|
||||
#REQUEST_METHOD = $REQUEST_METHOD #请求方法(GET/POST/PUT/DELETE..)
|
||||
#HTTP_ACCEPT = $HTTP_ACCEPT #HTTP定义的浏览器能够接受的数据类型
|
||||
#SCRIPT_NAME = $SCRIPT_NAME #当前运行的脚本名称(包含路径)
|
||||
#QUERY_STRING = $QUERY_STRING #地址栏中传的数据(get方式)
|
||||
#REMOTE_ADDR = $REMOTE_ADDR #客户端的ip
|
||||
|
||||
#根据url QUERY调不同方法
|
||||
query(){
|
||||
aria2Query=${QUERY_STRING}
|
||||
parse(){
|
||||
echo $1 | sed 's/.*'$2'=\([[:alnum:]]*\).*/\1/'
|
||||
}
|
||||
value=$(parse $aria2Query "action")
|
||||
|
||||
if [ ! -z = "$value" ]
|
||||
then
|
||||
if [ "$value" = "status" ]
|
||||
then
|
||||
check_installed_status
|
||||
elif [ "$value" = "readConfig" ]
|
||||
then
|
||||
read_config
|
||||
elif [ "$value" = "workStatus" ]
|
||||
then
|
||||
aria2_work_status
|
||||
else
|
||||
echo
|
||||
fi
|
||||
else
|
||||
return_error "action不能为空"
|
||||
fi
|
||||
}
|
||||
query
|
3
linkease/files/linkease.config
Normal file
3
linkease/files/linkease.config
Normal file
@ -0,0 +1,3 @@
|
||||
config linkease
|
||||
option 'port' '8897'
|
||||
option 'enabled' '1'
|
23
linkease/files/linkease.init
Executable file
23
linkease/files/linkease.init
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
USE_PROCD=1
|
||||
|
||||
get_config() {
|
||||
config_get_bool enabled $1 enabled 1
|
||||
config_get_bool logger $1 logger
|
||||
config_get port $1 port 8897
|
||||
}
|
||||
|
||||
start_service() {
|
||||
config_load linkease
|
||||
config_foreach get_config linkease
|
||||
[ $enabled != 1 ] && return 1
|
||||
|
||||
procd_open_instance
|
||||
procd_set_param command /usr/sbin/linkease
|
||||
[ -n "$port" ] && procd_append_param command --deviceAddr ":$port"
|
||||
[ "$logger" == 1 ] && procd_set_param stderr 1
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
22
linkease/files/linkease.uci-default
Executable file
22
linkease/files/linkease.uci-default
Executable file
@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@linkease[-1]
|
||||
add ucitrack linkease
|
||||
set ucitrack.@linkease[-1].init=linkease
|
||||
commit ucitrack
|
||||
|
||||
delete firewall.linkease
|
||||
set firewall.linkease=rule
|
||||
set firewall.linkease.name="linkease"
|
||||
set firewall.linkease.target="ACCEPT"
|
||||
set firewall.linkease.src="wan"
|
||||
set firewall.linkease.proto="tcp"
|
||||
set firewall.linkease.dest_port="8897"
|
||||
commit firewall
|
||||
EOF
|
||||
|
||||
/etc/init.d/linkease enable
|
||||
/etc/init.d/linkease start
|
||||
|
||||
exit 0
|
14
luci-app-advancedsetting/Makefile
Normal file
14
luci-app-advancedsetting/Makefile
Normal file
@ -0,0 +1,14 @@
|
||||
#
|
||||
#-- Copyright (C) 2018 dz <dingzhong110@gmail.com>
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI Support for advancedsetting
|
||||
LUCI_DEPENDS:=
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
@ -0,0 +1,14 @@
|
||||
#-- Copyright (C) 2018 dz <dingzhong110@gmail.com>
|
||||
|
||||
module("luci.controller.advancedsetting", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/advancedsetting") then
|
||||
return
|
||||
end
|
||||
|
||||
local page
|
||||
page = entry({"admin", "system", "advancedsetting"}, cbi("advancedsetting"), _("Advanced Setting"), 60)
|
||||
page.dependent = true
|
||||
page.acl_depends = { "luci-app-advancedsetting" }
|
||||
end
|
@ -0,0 +1,75 @@
|
||||
#-- Copyright (C) 2018 dz <dingzhong110@gmail.com>
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
m = Map("advancedsetting", translate("Advanced Setting"), translate("Direct editing of built-in Script Documents for various services, unless you know what you are doing, do not easily modify these configuration documents"))
|
||||
s = m:section(TypedSection, "advancedsetting")
|
||||
s.anonymous=true
|
||||
--dnsmasq
|
||||
if nixio.fs.access("/etc/dnsmasq.conf") then
|
||||
s:tab("config1", translate("dnsmasq"),translate("This page is the document content for configuring /etc/dnsmasq.conf. Restart takes effect after application is saved"))
|
||||
conf = s:taboption("config1", Value, "editconf1", nil, translate("Each line of the opening numeric symbol (#) or semicolon (;) is considered a comment; delete (;) and enable the specified option."))
|
||||
conf.template = "cbi/tvalue"
|
||||
conf.rows = 20
|
||||
conf.wrap = "off"
|
||||
function conf.cfgvalue(self, section)
|
||||
return fs.readfile("/etc/dnsmasq.conf") or ""
|
||||
end
|
||||
function conf.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
fs.writefile("/tmp/dnsmasq.conf", value)
|
||||
if (luci.sys.call("cmp -s /tmp/dnsmasq.conf /etc/dnsmasq.conf") == 1) then
|
||||
fs.writefile("/etc/dnsmasq.conf", value)
|
||||
luci.sys.call("/etc/init.d/dnsmasq restart >/dev/null")
|
||||
end
|
||||
fs.remove("/tmp/dnsmasq.conf")
|
||||
end
|
||||
end
|
||||
end
|
||||
--network
|
||||
if nixio.fs.access("/etc/config/network") then
|
||||
s:tab("config2", translate("network"),translate("This page is the document content for configuring /etc/config/network. Restart takes effect after application is saved"))
|
||||
conf = s:taboption("config2", Value, "editconf2", nil, translate("Each line of the opening numeric symbol (#) or semicolon (;) is considered a comment; delete (;) and enable the specified option."))
|
||||
conf.template = "cbi/tvalue"
|
||||
conf.rows = 20
|
||||
conf.wrap = "off"
|
||||
function conf.cfgvalue(self, section)
|
||||
return fs.readfile("/etc/config/network") or ""
|
||||
end
|
||||
function conf.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
fs.writefile("/tmp/netwok", value)
|
||||
if (luci.sys.call("cmp -s /tmp/network /etc/config/network") == 1) then
|
||||
fs.writefile("/etc/config/network", value)
|
||||
luci.sys.call("/etc/init.d/network restart >/dev/null")
|
||||
end
|
||||
fs.remove("/tmp/network")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--hosts
|
||||
if nixio.fs.access("/etc/hosts") then
|
||||
s:tab("config3", translate("hosts"),translate("This page is the document content for configuring /etc/hosts. Restart takes effect after application is saved"))
|
||||
conf = s:taboption("config3", Value, "editconf3", nil, translate("Each line of the opening numeric symbol (#) or semicolon (;) is considered a comment; delete (;) and enable the specified option."))
|
||||
conf.template = "cbi/tvalue"
|
||||
conf.rows = 20
|
||||
conf.wrap = "off"
|
||||
function conf.cfgvalue(self, section)
|
||||
return fs.readfile("/etc/hosts") or ""
|
||||
end
|
||||
function conf.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
fs.writefile("/tmp/etc/hosts", value)
|
||||
if (luci.sys.call("cmp -s /tmp/etc/hosts /etc/hosts") == 1) then
|
||||
fs.writefile("/etc/hosts", value)
|
||||
luci.sys.call("/etc/init.d/dnsmasq restart >/dev/null")
|
||||
end
|
||||
fs.remove("/tmp/etc/hosts")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return m
|
1
luci-app-advancedsetting/po/zh-cn
Symbolic link
1
luci-app-advancedsetting/po/zh-cn
Symbolic link
@ -0,0 +1 @@
|
||||
zh_Hans
|
21
luci-app-advancedsetting/po/zh_Hans/advancedsetting.po
Normal file
21
luci-app-advancedsetting/po/zh_Hans/advancedsetting.po
Normal file
@ -0,0 +1,21 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
msgid "Advanced Setting"
|
||||
msgstr "高级设置"
|
||||
|
||||
msgid "Direct editing of built-in Script Documents for various services, unless you know what you are doing, do not easily modify these configuration documents"
|
||||
msgstr "各类服务内置脚本文档的直接编辑,除非你知道自己在干什么,否则请不要轻易修改这些配置文档"
|
||||
|
||||
msgid "This page is the document content for configuring /etc/dnsmasq.conf. Restart takes effect after application is saved"
|
||||
msgstr "本页是配置/etc/dnsmasq.conf的文档内容。应用保存后重启生效"
|
||||
|
||||
msgid "Each line of the opening numeric symbol (#) or semicolon (;) is considered a comment; delete (;) and enable the specified option."
|
||||
msgstr "开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"
|
||||
|
||||
msgid "This page is the document content for configuring /etc/config/network. Restart takes effect after application is saved"
|
||||
msgstr "本页是配置/etc/config/network的文档内容。"
|
||||
|
||||
msgid "This page is the document content for configuring /etc/hosts. Restart takes effect after application is saved"
|
||||
msgstr "本页是配置/etc/hosts的文档内容。"
|
||||
|
1
luci-app-advancedsetting/root/etc/config/advancedsetting
Normal file
1
luci-app-advancedsetting/root/etc/config/advancedsetting
Normal file
@ -0,0 +1 @@
|
||||
config advancedsetting
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-advancedsetting": {
|
||||
"description": "Grant UCI access for luci-app-advancedsetting",
|
||||
"read": {
|
||||
"uci": [ "advancedsetting" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "advancedsetting" ]
|
||||
}
|
||||
}
|
||||
}
|
17
luci-app-easyupdate/Makefile
Normal file
17
luci-app-easyupdate/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for EasyUpdate From sundaqiang
|
||||
LUCI_DEPENDS:=+bash
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=20211125
|
||||
PKG_MAINTAINER:=sundaqiang
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
61
luci-app-easyupdate/README.md
Normal file
61
luci-app-easyupdate/README.md
Normal file
@ -0,0 +1,61 @@
|
||||
|
||||
# luci-app-easyupdate<74><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7B8>£<EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>P3TERX/Actions-OpenWrt<72>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD><CCBC><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
### ʹ<>÷<EFBFBD><C3B7><EFBFBD>
|
||||
|
||||
#### <20><><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
```yaml
|
||||
- name: Install feeds
|
||||
run: cd openwrt && ./scripts/feeds install -a -f
|
||||
```
|
||||
#### <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>²<EFBFBD><C2B2><EFBFBD>
|
||||
```yaml
|
||||
- name: Openwrt AutoUpdate
|
||||
run: |
|
||||
TEMP=$(date +"OpenWrt_%Y%m%d_%H%M%S_")$(git rev-parse --short HEAD)
|
||||
echo "RELEASE_TAG=$TEMP" >> $GITHUB_ENV
|
||||
#required>>add "DISTRIB_GITHUB" to "zzz-default-settings"
|
||||
sed -i "/DISTRIB_DESCRIPTION=/a\sed -i '/DISTRIB_GITHUB/d' /etc/openwrt_release" openwrt/package/lean/default-settings/files/zzz-default-settings
|
||||
sed -i "/DISTRIB_GITHUB/a\echo \"DISTRIB_GITHUB=\'https://github.com/${{github.repository}}\'\" >> /etc/openwrt_release" openwrt/package/lean/default-settings/files/zzz-default-settings
|
||||
#required>>add "DISTRIB_VERSIONS" to "zzz-default-settings"
|
||||
sed -i "/DISTRIB_DESCRIPTION=/a\sed -i '/DISTRIB_VERSIONS/d' /etc/openwrt_release" openwrt/package/lean/default-settings/files/zzz-default-settings
|
||||
sed -i "/DISTRIB_VERSIONS/a\echo \"DISTRIB_VERSIONS=\'${TEMP:8}\'\" >> /etc/openwrt_release" openwrt/package/lean/default-settings/files/zzz-default-settings
|
||||
#nonessential>>add "github.actor" to "DISTRIB_DESCRIPTION" in "zzz-default-settings"
|
||||
sed -i "s/OpenWrt /${{github.actor}} compiled (${TEMP:8}) \/ OpenWrt /g" openwrt/package/lean/default-settings/files/zzz-default-settings
|
||||
```
|
||||
|
||||
#### <20><><EFBFBD><EFBFBD><EFBFBD>²<EFBFBD><C2B2><EFBFBD><EFBFBD><EFBFBD>`tag_name`<60><>ֵ`${{ steps.tag.outputs.release_tag }}`
|
||||
```yaml
|
||||
- name: Upload firmware to release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: steps.tag.outputs.status == 'success' && !cancelled()
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ steps.tag.outputs.release_tag }}
|
||||
body_path: release.txt
|
||||
files: ${{ env.FIRMWARE }}/*
|
||||
```
|
||||
|
||||
#### <20><><EFBFBD><EFBFBD>Ϊ`${{ env.RELEASE_TAG }}`
|
||||
```yaml
|
||||
- name: Upload firmware to release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: steps.tag.outputs.status == 'success' && !cancelled()
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ env.RELEASE_TAG }}
|
||||
body_path: release.txt
|
||||
files: ${{ env.FIRMWARE }}/*
|
||||
```
|
||||
|
||||
#### Ҳ<><D2B2><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD>ĺõ<C4BA>actions
|
||||
[Actions-OpenWrt](https://github.com/sundaqiang/Actions-OpenWrt)
|
||||
|
||||
### Ч<><D0A7>չʾ
|
||||
![easyupdate][1]
|
||||
|
||||
[1]: https://raw.githubusercontent.com/sundaqiang/openwrt-packages/master/img/easyupdate.png
|
116
luci-app-easyupdate/luasrc/controller/easyupdate.lua
Normal file
116
luci-app-easyupdate/luasrc/controller/easyupdate.lua
Normal file
@ -0,0 +1,116 @@
|
||||
module("luci.controller.easyupdate",package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/easyupdate") then
|
||||
return
|
||||
end
|
||||
local c=luci.model.uci.cursor()
|
||||
local r=0
|
||||
if not c:get("easyupdate", "main", "proxy") then
|
||||
r=1
|
||||
c:set("easyupdate", "main", "proxy", "1")
|
||||
end
|
||||
if not c:get("easyupdate", "main", "keepconfig") then
|
||||
r=1
|
||||
c:set("easyupdate", "main", "keepconfig", "1")
|
||||
end
|
||||
if not c:get("easyupdate", "main", "github") then
|
||||
r=1
|
||||
local pcall, dofile, _G = pcall, dofile, _G
|
||||
pcall(dofile, "/etc/openwrt_release")
|
||||
c:set("easyupdate", "main", "github", _G.DISTRIB_GITHUB)
|
||||
end
|
||||
if r then
|
||||
c:commit("easyupdate")
|
||||
end
|
||||
entry({"admin", "services", "easyupdate"}, cbi("easyupdate"),_("EasyUpdate"), 99).dependent = true
|
||||
entry({"admin", "services", "easyupdate", "getver"}, call("getver")).leaf = true
|
||||
entry({"admin", "services", "easyupdate", "download"}, call("download")).leaf = true
|
||||
entry({"admin", "services", "easyupdate", "getlog"}, call("getlog")).leaf = true
|
||||
entry({"admin", "services", "easyupdate", "flash"}, call("flash")).leaf = true
|
||||
end
|
||||
|
||||
function Split(str, delim, maxNb)
|
||||
-- Eliminate bad cases...
|
||||
if string.find(str, delim) == nil then
|
||||
return { str }
|
||||
end
|
||||
if maxNb == nil or maxNb < 1 then
|
||||
maxNb = 0 -- No limit
|
||||
end
|
||||
local result = {}
|
||||
local pat = "(.-)" .. delim .. "()"
|
||||
local nb = 0
|
||||
local lastPos
|
||||
for part, pos in string.gfind(str, pat) do
|
||||
nb = nb + 1
|
||||
result[nb] = part
|
||||
lastPos = pos
|
||||
if nb == maxNb then break end
|
||||
end
|
||||
-- Handle the last field
|
||||
if nb ~= maxNb then
|
||||
result[nb + 1] = string.sub(str, lastPos)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function getver()
|
||||
local e={}
|
||||
local c=luci.model.uci.cursor()
|
||||
local l=Split(c:get("easyupdate", "main", "github"), "/")
|
||||
e.newver=luci.sys.exec("uclient-fetch -qO- 'https://api.github.com/repos/" .. l[4] .. "/" .. l[5] .. "/releases/latest' | jsonfilter -e '@.tag_name'")
|
||||
e.newver=e.newver:sub(e.newver:find('_')+1,-2)
|
||||
e.newverint=os.time({day=e.newver:sub(7,8), month=e.newver:sub(5,6), year=e.newver:sub(1,4), hour=e.newver:sub(10,11), min=e.newver:sub(12,13), sec=e.newver:sub(14,15)})
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function download()
|
||||
local e={}
|
||||
local c=luci.model.uci.cursor()
|
||||
local l=Split(c:get("easyupdate", "main", "github"), "/")
|
||||
local sedd
|
||||
if nixio.fs.access("/sys/firmware/efi") then
|
||||
sedd="combined-efi.img.gz"
|
||||
else
|
||||
sedd="combined.img.gz"
|
||||
end
|
||||
local url=luci.sys.exec("uclient-fetch -qO- 'https://api.github.com/repos/" .. l[4] .. "/" .. l[5] .. "/releases/latest' | jsonfilter -e '@.assets[*].browser_download_url' | sed -n '/" .. sedd .. "/p'")
|
||||
url=url:gsub("\n","")
|
||||
local u=c:get("easyupdate", "main", "proxy")
|
||||
if u then
|
||||
u="https://ghproxy.com/"
|
||||
else
|
||||
u=""
|
||||
end
|
||||
local l=Split(url, "/")
|
||||
luci.sys.exec("uclient-fetch -O '/tmp/" .. l[9] .. "' '" .. u .. url .. "' > /tmp/easyupdate.log 2>&1 &")
|
||||
e.code=1
|
||||
e.data=l[9]
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function getlog()
|
||||
local e = {}
|
||||
e.data=nixio.fs.readfile ("/tmp/easyupdate.log")
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function flash()
|
||||
local e={}
|
||||
local f = luci.http.formvalue('file')
|
||||
local c=luci.model.uci.cursor()
|
||||
local k=c:get("easyupdate", "main", "keepconfig")
|
||||
if k then
|
||||
k=""
|
||||
else
|
||||
k="-n"
|
||||
end
|
||||
luci.sys.exec("sysupgrade " .. k .. " '/tmp/" .. f .. "' > /tmp/easyupdate.log 2>&1 &")
|
||||
e.code=1
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
57
luci-app-easyupdate/luasrc/model/cbi/easyupdate.lua
Normal file
57
luci-app-easyupdate/luasrc/model/cbi/easyupdate.lua
Normal file
@ -0,0 +1,57 @@
|
||||
local pcall, dofile, _G = pcall, dofile, _G
|
||||
pcall(dofile, "/etc/openwrt_release")
|
||||
|
||||
m=Map("easyupdate",translate("EasyUpdate"),translate("EasyUpdate LUCI supports scheduled upgrade & one-click firmware upgrade") .. [[<br /><br /><a href="https://github.com/sundaqiang/openwrt-packages" target="_blank">Powered by sundaqiang</a>]])
|
||||
|
||||
s=m:section(TypedSection,"easyupdate")
|
||||
s.anonymous=true
|
||||
|
||||
e=s:option(Flag, "enable", translate("Enable"),translate("When selected, firmware upgrade will be automatically at the specified time."))
|
||||
e.default=0
|
||||
e.optional=false
|
||||
|
||||
p=s:option(Flag, "proxy", translate("Use China Mirror"),translate("When selected, will use the China mirror when accessing Github."))
|
||||
p.default=1
|
||||
p.optional=false
|
||||
|
||||
k= s:option(Flag, "keepconfig", translate("KEEP CONFIG"),translate("When selected, configuration is retained when firmware upgrade."))
|
||||
k.default=1
|
||||
k.optional=false
|
||||
|
||||
f=s:option(Flag, "forceflash", translate("Preference Force Flashing"),translate("When selected, Preference Force Flashing while firmware upgrading."))
|
||||
f.default=0
|
||||
f.optional=false
|
||||
|
||||
w=s:option(ListValue,"week",translate("Update Time"),translate("Advised to set the automatic update time to idle time."))
|
||||
w:value(7,translate("Everyday"))
|
||||
w:value(1,translate("Monday"))
|
||||
w:value(2,translate("Tuesday"))
|
||||
w:value(3,translate("Wednesday"))
|
||||
w:value(4,translate("Thursday"))
|
||||
w:value(5,translate("Friday"))
|
||||
w:value(6,translate("Saturday"))
|
||||
w:value(0,translate("Sunday"))
|
||||
w.default=0
|
||||
w:depends("enable", "1")
|
||||
|
||||
h=s:option(Value,"hour",translate("Hour"))
|
||||
h.datatype="range(0,23)"
|
||||
h.rmempty=true
|
||||
h.default=0
|
||||
h:depends("enable", "1")
|
||||
|
||||
n=s:option(Value,"minute",translate("Minute"))
|
||||
n.datatype="range(0,59)"
|
||||
n.rmempty=true
|
||||
n.default=30
|
||||
n:depends("enable", "1")
|
||||
|
||||
g=s:option(Value,"github",translate("Github Url"),translate("Your Github project address "))
|
||||
g.default=''
|
||||
g.rmempty=false
|
||||
|
||||
b=s:option(Button,"",translate("Firmware Upgrade"))
|
||||
b.template="easyupdate/button"
|
||||
b.versions=_G.DISTRIB_VERSIONS
|
||||
|
||||
return m
|
168
luci-app-easyupdate/luasrc/view/easyupdate/button.htm
Normal file
168
luci-app-easyupdate/luasrc/view/easyupdate/button.htm
Normal file
@ -0,0 +1,168 @@
|
||||
<%+cbi/valueheader%>
|
||||
<input class="cbi-button cbi-input-reload" id="update" type="button" value="<%:Collecting data...%>" size="0" disabled onclick="check_version()">
|
||||
<br>
|
||||
<div class="cbi-value-description">
|
||||
<span class="cbi-value-helpicon"><img src="/luci-static/resources/cbi/help.gif" alt="帮助"></span>
|
||||
<span>
|
||||
<%:Local Firmware Version%>:<%=self.versions%>
|
||||
</span>
|
||||
<br>
|
||||
<span class="cbi-value-helpicon"><img src="/luci-static/resources/cbi/help.gif" alt="帮助"></span>
|
||||
<span id="cloudver">
|
||||
<%:Cloud Firmware Version%>:<%:Collecting data...%>
|
||||
</span>
|
||||
</div>
|
||||
<%+cbi/valuefooter%>
|
||||
<style type="text/css">
|
||||
#update_apply_overlay {
|
||||
white-space: pre-line;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
display: none;
|
||||
z-index: 20000;
|
||||
}
|
||||
|
||||
#update_apply_overlay .alert-message {
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
top: 10%;
|
||||
width: 60%;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
min-height: 10%;
|
||||
align-items: center;
|
||||
max-height: 80%;
|
||||
}
|
||||
|
||||
#update_apply_overlay .alert-message > h4,
|
||||
#update_apply_overlay .alert-message > p,
|
||||
#update_apply_overlay .alert-message > div {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
#update_apply_overlay .alert-message > img {
|
||||
margin-right: 1em;
|
||||
flex-basis: 32px;
|
||||
}
|
||||
|
||||
body.apply-overlay-active {
|
||||
overflow: hidden;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
body.apply-overlay-active #update_apply_overlay {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function update_status_message(type, content) {
|
||||
document.getElementById('update_apply_overlay') || document.body.insertAdjacentHTML("beforeend",'<div id="update_apply_overlay"><div class="alert-message"></div></div>')
|
||||
var overlay = document.getElementById('update_apply_overlay')
|
||||
message = overlay.querySelector('.alert-message');
|
||||
if (message && type) {
|
||||
if (!message.classList.contains(type)) {
|
||||
message.classList.remove('notice');
|
||||
message.classList.remove('warning');
|
||||
message.classList.add(type);
|
||||
}
|
||||
if (content)
|
||||
message.innerHTML = content;
|
||||
message.scrollTop = message.scrollHeight;
|
||||
document.body.classList.add('apply-overlay-active');
|
||||
document.body.scrollTop = document.documentElement.scrollTop = 0;
|
||||
}
|
||||
else {
|
||||
document.body.classList.remove('apply-overlay-active');
|
||||
}
|
||||
}
|
||||
function getver() {
|
||||
XHR.get('<%=url([[admin]], [[services]], [[easyupdate]], [[getver]])%>', null,
|
||||
function(x, data) {
|
||||
const tb = document.getElementById('cloudver');
|
||||
const up = document.getElementById('update');
|
||||
if (data && tb) {
|
||||
if (data.newver) {
|
||||
tb.innerHTML = '<%:Cloud Firmware Version%>:' + data.newver;
|
||||
nowverint=<%=os.time({day=self.versions:sub(7,8), month=self.versions:sub(5,6), year=self.versions:sub(1,4), hour=self.versions:sub(10,11), min=self.versions:sub(12,13), sec=self.versions:sub(14,15)})%>
|
||||
if (data.newverint > nowverint){
|
||||
up.value = '<%:Download Firmware%>'
|
||||
up.disabled = false
|
||||
up.setAttribute('newver', data.newver);
|
||||
}else{
|
||||
up.value = '<%:Is the latest%>'
|
||||
up.disabled = true
|
||||
}
|
||||
}else{
|
||||
tb.innerHTML = '<%:Cloud Firmware Version%>:<%:Collecting data...%>';
|
||||
up.value = '<%:Retry Firmware Check%>'
|
||||
up.disabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
getver()
|
||||
function check_version() {
|
||||
const tb = document.getElementById('update');
|
||||
const flash= tb.getAttribute("flash")
|
||||
if (flash){
|
||||
XHR.get('<%=url([[admin]], [[services]], [[easyupdate]], [[flash]])%>', {file: tb.getAttribute("file")}, (x, r) => {
|
||||
if (r.code == 1) {
|
||||
XHR.poll(1, '<%=url([[admin]], [[services]], [[easyupdate]], [[getlog]])%>', null,(x, r) => {
|
||||
update_status_message('notice', r.data);
|
||||
if (r.data.indexOf("Commencing upgrade") > -1 ){
|
||||
XHR.halt()
|
||||
setTimeout(() => {
|
||||
location.replace(document.location.origin)
|
||||
},180000);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
tb.disabled = false;
|
||||
tb.value = '<%:Retry Firmware Upgrade%>';
|
||||
}
|
||||
});
|
||||
return
|
||||
}
|
||||
const newver= tb.getAttribute("newver")
|
||||
if (newver){
|
||||
tb.disabled = true;
|
||||
XHR.get('<%=url([[admin]], [[services]], [[easyupdate]], [[download]])%>', null, (x, r) => {
|
||||
if (r.code == 1) {
|
||||
tb.setAttribute('file', r.data);
|
||||
XHR.poll(1, '<%=url([[admin]], [[services]], [[easyupdate]], [[getlog]])%>', null,(x, r) => {
|
||||
if (r.data.indexOf(" error") > -1 || r.data.indexOf("Connection reset") > -1){
|
||||
XHR.halt()
|
||||
update_status_message('warning', r.data);
|
||||
document.getElementById('update_apply_overlay').addEventListener("click", (e)=>{
|
||||
update_status_message()
|
||||
})
|
||||
}else{
|
||||
if (r.data.indexOf("Download completed") > -1 ){
|
||||
XHR.halt()
|
||||
setTimeout(() => {
|
||||
update_status_message();
|
||||
tb.value = '<%:Firmware Upgrade%>'
|
||||
tb.setAttribute('flash', 1);
|
||||
},3000);
|
||||
}else{
|
||||
update_status_message('notice', r.data);
|
||||
}
|
||||
}
|
||||
tb.disabled = false;
|
||||
})
|
||||
} else {
|
||||
tb.disabled = false;
|
||||
tb.value = '<%:Retry Firmware Download%>';
|
||||
}
|
||||
});
|
||||
}else{
|
||||
getver()
|
||||
}
|
||||
}
|
||||
</script>
|
68
luci-app-easyupdate/po/zh-cn/easyupdate.po
Normal file
68
luci-app-easyupdate/po/zh-cn/easyupdate.po
Normal file
@ -0,0 +1,68 @@
|
||||
msgid "EasyUpdate"
|
||||
msgstr "简易更新"
|
||||
|
||||
msgid "EasyUpdate LUCI supports scheduled upgrade & one-click firmware upgrade"
|
||||
msgstr "EasyUpdate 支持LUCI定时升级和一键式固件升级"
|
||||
|
||||
msgid "When selected, firmware upgrade will be automatically at the specified time."
|
||||
msgstr "选中后,系统将在指定的时间自动升级固件。"
|
||||
|
||||
msgid "When selected, will use the China mirror when accessing Github."
|
||||
msgstr "选中后,将在访问Github时使用中国镜像。"
|
||||
|
||||
msgid "KEEP CONFIG"
|
||||
msgstr "保留配置"
|
||||
|
||||
msgid "When selected, configuration is retained when firmware upgrade."
|
||||
msgstr "选中后,固件升级时配置将保留。"
|
||||
|
||||
msgid "Preference Force Flashing"
|
||||
msgstr "强制刷入"
|
||||
|
||||
msgid "When selected, Preference Force Flashing while firmware upgrading."
|
||||
msgstr "选中时,升级固件时将强制刷入。"
|
||||
|
||||
msgid "Update Time"
|
||||
msgstr "更新时机"
|
||||
|
||||
msgid "Advised to set the automatic update time to idle time."
|
||||
msgstr "建议将自动更新时间设置为空闲时间。"
|
||||
|
||||
msgid "Everyday"
|
||||
msgstr "每天"
|
||||
|
||||
msgid "Hour"
|
||||
msgstr "小时"
|
||||
|
||||
msgid "Minute"
|
||||
msgstr "分钟"
|
||||
|
||||
msgid "Github Url"
|
||||
msgstr "Github网址"
|
||||
|
||||
msgid "Your Github project address"
|
||||
msgstr "你的Github项目地址"
|
||||
|
||||
msgid "Firmware Upgrade"
|
||||
msgstr "固件升级"
|
||||
|
||||
msgid "Local Firmware Version"
|
||||
msgstr "本地的固件版本"
|
||||
|
||||
msgid "Cloud Firmware Version"
|
||||
msgstr "云端的固件版本"
|
||||
|
||||
msgid "Download Firmware"
|
||||
msgstr "下载固件"
|
||||
|
||||
msgid "Is the latest"
|
||||
msgstr "已是最新"
|
||||
|
||||
msgid "Retry Firmware Check"
|
||||
msgstr "重试固件检查"
|
||||
|
||||
msgid "Retry Firmware Upgrade"
|
||||
msgstr "重试固件升级"
|
||||
|
||||
msgid "Retry Firmware Download"
|
||||
msgstr "重试固件下载"
|
2
luci-app-easyupdate/root/etc/config/easyupdate
Normal file
2
luci-app-easyupdate/root/etc/config/easyupdate
Normal file
@ -0,0 +1,2 @@
|
||||
config easyupdate 'main'
|
||||
option enable '0'
|
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@easyupdate[-1]
|
||||
add ucitrack easyupdate
|
||||
set ucitrack.@easyupdate[-1].init=easyupdate
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-easyupdate": {
|
||||
"description": "Grant UCI access for luci-app-easyupdate",
|
||||
"read": {
|
||||
"uci": [ "easyupdate" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "easyupdate" ]
|
||||
}
|
||||
}
|
||||
}
|
18
luci-app-mosdns/Makefile
Normal file
18
luci-app-mosdns/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-mosdns
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=4
|
||||
|
||||
LUCI_TITLE:=LuCI Support for mosdns
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+mosdns
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/mosdns/config.yaml
|
||||
/etc/config/mosdns
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
20
luci-app-mosdns/luasrc/controller/mosdns.lua
Normal file
20
luci-app-mosdns/luasrc/controller/mosdns.lua
Normal file
@ -0,0 +1,20 @@
|
||||
module("luci.controller.mosdns", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/mosdns") then
|
||||
return
|
||||
end
|
||||
|
||||
entry({"admin", "services", "mosdns"}, alias("admin", "services", "mosdns", "basic"), _("MosDNS"), 30).dependent = true
|
||||
entry({"admin", "services", "mosdns", "basic"}, cbi("mosdns/basic"), _("Basic Setting"), 1).leaf = true
|
||||
entry({"admin", "services", "mosdns", "update"}, cbi("mosdns/update"), _("Geodata Update"), 2).leaf = true
|
||||
entry({"admin", "services", "mosdns", "config"}, cbi("mosdns/config"), _("Manual Configuration"), 3).leaf = true
|
||||
entry({"admin", "services", "mosdns", "status"}, call("act_status")).leaf = true
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e = {}
|
||||
e.running = luci.sys.call("pgrep -f mosdns >/dev/null") == 0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
21
luci-app-mosdns/luasrc/model/cbi/mosdns/basic.lua
Normal file
21
luci-app-mosdns/luasrc/model/cbi/mosdns/basic.lua
Normal file
@ -0,0 +1,21 @@
|
||||
m = Map("mosdns")
|
||||
m.title = translate("MosDNS")
|
||||
m.description = translate("MosDNS is a 'programmable' DNS forwarder.")
|
||||
|
||||
m:section(SimpleSection).template = "mosdns/mosdns_status"
|
||||
|
||||
s = m:section(TypedSection, "mosdns")
|
||||
s.addremove = false
|
||||
s.anonymous = true
|
||||
|
||||
enable = s:option(Flag, "enabled", translate("Enable"))
|
||||
enable.rmempty = false
|
||||
|
||||
redirect = s:option(Flag, "redirect", translate("Enable DNS Redirect"))
|
||||
redirect.rmempty = false
|
||||
|
||||
autoconf = s:option(Flag, "autoconf", translate("Enable AutoConfiguration"))
|
||||
autoconf.description = translate("Turning it on will make the necessary adjustments to other plug-in settings.")
|
||||
autoconf.rmempty = false
|
||||
|
||||
return m
|
21
luci-app-mosdns/luasrc/model/cbi/mosdns/config.lua
Normal file
21
luci-app-mosdns/luasrc/model/cbi/mosdns/config.lua
Normal file
@ -0,0 +1,21 @@
|
||||
m = Map("mosdns")
|
||||
|
||||
s = m:section(TypedSection, "mosdns")
|
||||
s.addremove = false
|
||||
s.anonymous = true
|
||||
|
||||
config = s:option(TextValue, "manual-config")
|
||||
config.description = translate("View the YAML Configuration file used by this MosDNS. You can edit it as you own need; Beware the listening port 5335 was hardcoded into the init script, do not change that.")
|
||||
config.template = "cbi/tvalue"
|
||||
config.rows = 25
|
||||
|
||||
function config.cfgvalue(self, section)
|
||||
return nixio.fs.readfile("/etc/mosdns/config.yaml")
|
||||
end
|
||||
|
||||
function config.write(self, section, value)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
nixio.fs.writefile("/etc/mosdns/config.yaml", value)
|
||||
end
|
||||
|
||||
return m
|
41
luci-app-mosdns/luasrc/model/cbi/mosdns/update.lua
Normal file
41
luci-app-mosdns/luasrc/model/cbi/mosdns/update.lua
Normal file
@ -0,0 +1,41 @@
|
||||
m = Map("mosdns")
|
||||
m.title = translate("MosDNS")
|
||||
m.description = translate("MosDNS is a 'programmable' DNS forwarder.")
|
||||
|
||||
m:section(SimpleSection).template = "mosdns/mosdns_status"
|
||||
|
||||
s = m:section(TypedSection, "mosdns")
|
||||
s.addremove = false
|
||||
s.anonymous = true
|
||||
|
||||
enable = s:option(Flag, "geo_auto_update", translate("Enable Auto Database Update"))
|
||||
enable.rmempty = false
|
||||
|
||||
enable = s:option(Flag, "syncconfig", translate("Enable Config Update"))
|
||||
enable.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "geo_update_week_time", translate("Update Cycle"))
|
||||
o:value("all", translate("Every Day"))
|
||||
o:value("1", translate("Every Monday"))
|
||||
o:value("2", translate("Every Tuesday"))
|
||||
o:value("3", translate("Every Wednesday"))
|
||||
o:value("4", translate("Every Thursday"))
|
||||
o:value("5", translate("Every Friday"))
|
||||
o:value("6", translate("Every Saturday"))
|
||||
o:value("7", translate("Every Sunday"))
|
||||
o.default = "all"
|
||||
|
||||
update_time = s:option(ListValue, "geo_update_day_time", translate("Update Time (Every Day)"))
|
||||
for t = 0, 23 do
|
||||
update_time:value(t, t..":00")
|
||||
end
|
||||
update_time.default = 0
|
||||
|
||||
data_update = s:option(Button, "geo_update_database", translate("Database Update"))
|
||||
data_update.inputtitle = translate("Check And Update")
|
||||
data_update.inputstyle = "reload"
|
||||
data_update.write = function()
|
||||
luci.sys.exec("/etc/mosdns/mosupdater.sh >/dev/null 2>&1 &")
|
||||
end
|
||||
|
||||
return m
|
28
luci-app-mosdns/luasrc/view/mosdns/mosdns_status.htm
Normal file
28
luci-app-mosdns/luasrc/view/mosdns/mosdns_status.htm
Normal file
@ -0,0 +1,28 @@
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[mosdns]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('mosdns_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
var links = '<em><b><font color=green>MosDNS <%:RUNNING%></font></b></em>';
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<em><b><font color=red>MosDNS <%:NOT RUNNING%></font></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<style>
|
||||
.mar-10 {
|
||||
margin-left: 50px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="mosdns_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
77
luci-app-mosdns/po/zh-cn/mosdns.po
Normal file
77
luci-app-mosdns/po/zh-cn/mosdns.po
Normal file
@ -0,0 +1,77 @@
|
||||
msgid "Basic Setting"
|
||||
msgstr "基本设置"
|
||||
|
||||
msgid "Manual Configuration"
|
||||
msgstr "手动配置"
|
||||
|
||||
msgid "MosDNS is a 'programmable' DNS forwarder."
|
||||
msgstr "MosDNS 是一个插件化的 DNS 转发/分流器。"
|
||||
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "Collecting data..."
|
||||
msgstr "获取数据中..."
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Enable DNS Redirect"
|
||||
msgstr "启用 DNS 重定向"
|
||||
|
||||
msgid "View the YAML Configuration file used by this MosDNS. You can edit it as you own need; Beware the listening port 5335 was hardcoded into the init script, do not change that."
|
||||
msgstr "查看 MosDNS 所使用的 YAML 配置文件。你可以根据自己的需要进行编辑;但请注意,监听端口5335是硬编码在启动脚本中的,不要更改!"
|
||||
|
||||
msgid "Geodata Update"
|
||||
msgstr "数据库更新"
|
||||
|
||||
msgid "Update Time (Every Day)"
|
||||
msgstr "更新时间(每天)"
|
||||
|
||||
msgid "Update Cycle"
|
||||
msgstr "更新周期"
|
||||
|
||||
msgid "Every Day"
|
||||
msgstr "每天"
|
||||
|
||||
msgid "Every Monday"
|
||||
msgstr "每周一"
|
||||
|
||||
msgid "Every Tuesday"
|
||||
msgstr "每周二"
|
||||
|
||||
msgid "Every Wednesday"
|
||||
msgstr "每周三"
|
||||
|
||||
msgid "Every Thursday"
|
||||
msgstr "每周四"
|
||||
|
||||
msgid "Every Friday"
|
||||
msgstr "每周五"
|
||||
|
||||
msgid "Every Saturday"
|
||||
msgstr "每周六"
|
||||
|
||||
msgid "Every Sunday"
|
||||
msgstr "每周日"
|
||||
|
||||
msgid "Database Update"
|
||||
msgstr "数据库更新"
|
||||
|
||||
msgid "Check And Update"
|
||||
msgstr "检查并更新"
|
||||
|
||||
msgid "Enable Auto Database Update"
|
||||
msgstr "启用数据库自动更新"
|
||||
|
||||
msgid "Enable Config Update"
|
||||
msgstr "启用配置文件同步"
|
||||
|
||||
msgid "Enable AutoConfiguration"
|
||||
msgstr "启用自动化配置"
|
||||
|
||||
msgid "Turning it on will make the necessary adjustments to other plug-in settings."
|
||||
msgstr "开启这个选项会允许本插件对其他插件的设置进行必要的设置,目前仅支持 SSRP VSSR PASSWALL。"
|
1
luci-app-mosdns/po/zh_Hans
Symbolic link
1
luci-app-mosdns/po/zh_Hans
Symbolic link
@ -0,0 +1 @@
|
||||
zh-cn
|
10
luci-app-mosdns/root/etc/config/mosdns
Normal file
10
luci-app-mosdns/root/etc/config/mosdns
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
config mosdns 'mosdns'
|
||||
option not_first_start '0'
|
||||
option enabled '0'
|
||||
option geo_auto_update '0'
|
||||
option geo_update_week_time 'all'
|
||||
option geo_update_day_time '2'
|
||||
option redirect '1'
|
||||
option autoconf '1'
|
||||
option syncconfig '1'
|
162
luci-app-mosdns/root/etc/init.d/mosdns
Executable file
162
luci-app-mosdns/root/etc/init.d/mosdns
Executable file
@ -0,0 +1,162 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2020 IrineSistiana
|
||||
|
||||
START=91
|
||||
USE_PROCD=1
|
||||
|
||||
##### ONLY CHANGE THIS BLOCK ######
|
||||
PROG=/usr/bin/mosdns # where is mosdns
|
||||
RES_DIR=/etc/mosdns/ # resource dir / working dir / the dir where you store ip/domain lists
|
||||
CONF=./config.yaml # where is the config file, it can be a relative path to $RES_DIR
|
||||
CRON_FILE=/etc/crontabs/root
|
||||
##### ONLY CHANGE THIS BLOCK ######
|
||||
|
||||
inital_conf() {
|
||||
config_load "mosdns"
|
||||
config_get "enabled" "mosdns" "enabled" "0"
|
||||
}
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "mosdns"
|
||||
}
|
||||
|
||||
restore_setting() {
|
||||
redirect=$(uci -q get mosdns.mosdns.redirect)
|
||||
if [ $redirect -eq 1 ]; then
|
||||
sed -i "/list server/d" /etc/config/dhcp
|
||||
sed -i "/dhcp_option/d" /etc/config/dhcp
|
||||
uci set dhcp.@dnsmasq[0].noresolv='0'
|
||||
uci del dhcp.@dnsmasq[0].cachesize
|
||||
uci set dhcp.@dnsmasq[0].filter_aaaa='1'
|
||||
uci commit dhcp
|
||||
fi
|
||||
autoconf="$(uci -q get mosdns.mosdns.autoconf)"
|
||||
if [ $autoconf -eq 1 ]; then
|
||||
uci set shadowsocksr.@global[0].pdnsd_enable='1'
|
||||
uci set shadowsocksr.@global[0].tunnel_forward='8.8.4.4:53'
|
||||
uci commit shadowsocksr
|
||||
uci set passwall.@global[0].dns_mode='pdnsd'
|
||||
uci set passwall.@global[0].dns_forward='8.8.8.8'
|
||||
uci set passwall.@global[0].dns_cache='1'
|
||||
uci commit passwall
|
||||
uci set vssr.@global[0].pdnsd_enable='1'
|
||||
uci commit vssr
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_setting() {
|
||||
redirect=$(uci -q get mosdns.mosdns.redirect)
|
||||
if [ $redirect -eq 1 ]; then
|
||||
sed -i "/list server/d" /etc/config/dhcp
|
||||
uci add_list dhcp.@dnsmasq[0].server='127.0.0.1#5335'
|
||||
uci set dhcp.@dnsmasq[0].rebind_protection='0'
|
||||
lanip="$(uci get network.lan.ipaddr)"
|
||||
sed -i "/dhcp_option/d" /etc/config/dhcp
|
||||
sed -i "/dhcpv6/a\\\tlist dhcp_option '6,$lanip'" /etc/config/dhcp
|
||||
uci set dhcp.@dnsmasq[0].noresolv="1"
|
||||
uci set dhcp.@dnsmasq[0].cachesize='0'
|
||||
uci set dhcp.@dnsmasq[0].filter_aaaa='0'
|
||||
uci commit dhcp
|
||||
fi
|
||||
autoconf="$(uci -q get mosdns.mosdns.autoconf)"
|
||||
if [ $autoconf -eq 1 ]; then
|
||||
uci set shadowsocksr.@global[0].pdnsd_enable='0'
|
||||
uci del shadowsocksr.@global[0].tunnel_forward
|
||||
uci commit shadowsocksr
|
||||
uci set passwall.@global[0].dns_mode='nonuse'
|
||||
uci del passwall.@global[0].dns_forward
|
||||
uci del passwall.@global[0].dns_cache
|
||||
uci commit passwall
|
||||
uci set vssr.@global[0].pdnsd_enable='0'
|
||||
uci commit vssr
|
||||
fi
|
||||
}
|
||||
|
||||
restart_others() {
|
||||
/etc/init.d/network reload
|
||||
/etc/init.d/dnsmasq reload
|
||||
|
||||
ssrp="$(uci get shadowsocksr.@global[0].global_server)"
|
||||
count1="$(ps | grep ssrplus | grep -v 'grep' | wc -l)"
|
||||
if [ $ssrp != "nil" ] && [ $count1 -ne 0 ]; then
|
||||
/etc/init.d/shadowsocksr restart
|
||||
fi
|
||||
|
||||
pw="$(uci get passwall.@global[0].enabled)"
|
||||
count2="$(ps | grep passwall | grep -v 'grep' | wc -l)"
|
||||
if [ $pw -eq 1 ] && [ $count2 -ne 0 ]; then
|
||||
/etc/init.d/passwall restart
|
||||
fi
|
||||
|
||||
vssr="$(uci get vssr.@global[0].global_server)"
|
||||
count3="$(ps | grep vssr | grep -v 'grep' | wc -l)"
|
||||
if [ $vssr != "nil" ] && [ $count3 -ne 0 ]; then
|
||||
/etc/init.d/vssr restart
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
sleep 2s
|
||||
echo "MosDNS is restarted!"
|
||||
start
|
||||
}
|
||||
|
||||
setcron() {
|
||||
chmod 755 /etc/mosdns/mosupdater.sh
|
||||
[ "$(tail -n1 /etc/crontabs/root | wc -l)" -eq 0 ] && [ -n "$(cat /etc/crontabs/root 2>/dev/null)" ] && echo >>/etc/crontabs/root
|
||||
[ -z "$(grep "mosupdater.sh" "$CRON_FILE" 2>/dev/null)" ] && {
|
||||
[ "$(uci -q get mosdns.mosdns.geo_auto_update)" -eq 1 ] && echo "0 $(uci -q get mosdns.mosdns.geo_update_day_time) * * $(uci -q get mosdns.mosdns.geo_update_week_time) /etc/mosdns/mosupdater.sh" >>$CRON_FILE
|
||||
}
|
||||
crontab $CRON_FILE
|
||||
}
|
||||
|
||||
delcron() {
|
||||
sed -i '/mosupdater.sh/d' $CRON_FILE 2>/dev/null
|
||||
/etc/init.d/cron restart
|
||||
}
|
||||
|
||||
start_service() {
|
||||
|
||||
# Reading config
|
||||
inital_conf
|
||||
if [ "$enabled" -eq 0 ]; then
|
||||
firstblood=$(uci -q get mosdns.mosdns.not_first_start)
|
||||
[ "${firstblood}" = "0" ] && restore_setting
|
||||
[ "${firstblood}" = "0" ] && restart_others
|
||||
uci set mosdns.mosdns.not_first_start='1'
|
||||
uci commit mosdns
|
||||
echo "MosDNS has turned off"
|
||||
return 1
|
||||
fi
|
||||
delcron
|
||||
setcron
|
||||
procd_open_instance mosdns
|
||||
procd_set_param command $PROG -dir $RES_DIR -c $CONF
|
||||
procd_set_param user root
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}"
|
||||
procd_close_instance mosdns
|
||||
|
||||
prepare_setting
|
||||
restart_others
|
||||
|
||||
echo "MosDNS turn on"
|
||||
echo "enabled="$enabled""
|
||||
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
|
||||
killall -q mosdns
|
||||
echo "MosDNS turn off"
|
||||
echo "enabled="$enabled""
|
||||
|
||||
config_load "mosdns"
|
||||
enabled=$(uci -q get mosdns.mosdns.enabled)
|
||||
[ "${enabled}" = "0" ] && restore_setting
|
||||
restart_others
|
||||
delcron
|
||||
|
||||
}
|
95
luci-app-mosdns/root/etc/mosdns/config.yaml
Normal file
95
luci-app-mosdns/root/etc/mosdns/config.yaml
Normal file
@ -0,0 +1,95 @@
|
||||
log:
|
||||
level: error
|
||||
file: ''
|
||||
|
||||
plugin:
|
||||
- tag: main_server
|
||||
type: server
|
||||
args:
|
||||
entry:
|
||||
- _no_ecs
|
||||
- lazy_cache
|
||||
- main_sequence
|
||||
server:
|
||||
- protocol: udp
|
||||
addr: '127.0.0.1:5335'
|
||||
- protocol: tcp
|
||||
addr: '127.0.0.1:5335'
|
||||
|
||||
- tag: main_sequence
|
||||
type: sequence
|
||||
args:
|
||||
exec:
|
||||
- if:
|
||||
- query_is_local_domain
|
||||
- '!_query_is_common'
|
||||
exec:
|
||||
- forward_local
|
||||
- _end
|
||||
- if:
|
||||
- query_is_non_local_domain
|
||||
exec:
|
||||
- if:
|
||||
- _qtype_AAAA
|
||||
exec:
|
||||
- _block_with_empty_response
|
||||
- _end
|
||||
- forward_remote
|
||||
- _end
|
||||
- primary:
|
||||
- forward_local
|
||||
- if:
|
||||
- '!response_has_local_ip'
|
||||
exec:
|
||||
- _drop_response
|
||||
secondary:
|
||||
- if:
|
||||
- _qtype_AAAA
|
||||
exec:
|
||||
- _block_with_empty_response
|
||||
- _end
|
||||
- forward_remote
|
||||
fast_fallback: 150
|
||||
always_standby: true
|
||||
|
||||
- tag: forward_local
|
||||
type: fast_forward
|
||||
args:
|
||||
upstream:
|
||||
- addr: 119.29.29.29
|
||||
- addr: 101.226.4.6
|
||||
|
||||
- tag: forward_remote
|
||||
type: fast_forward
|
||||
args:
|
||||
upstream:
|
||||
- addr: 'tls://8.8.4.4'
|
||||
idle_timeout: 60
|
||||
max_conns: 10
|
||||
- addr: 'tls://101.101.101.101'
|
||||
idle_timeout: 20
|
||||
max_conns: 10
|
||||
|
||||
- tag: lazy_cache
|
||||
type: cache
|
||||
args:
|
||||
size: 512000
|
||||
lazy_cache_ttl: 31536000
|
||||
|
||||
- tag: query_is_local_domain
|
||||
type: query_matcher
|
||||
args:
|
||||
domain:
|
||||
- 'ext:./geosite.dat:cn'
|
||||
|
||||
- tag: query_is_non_local_domain
|
||||
type: query_matcher
|
||||
args:
|
||||
domain:
|
||||
- 'ext:./geosite.dat:geolocation-!cn'
|
||||
|
||||
- tag: response_has_local_ip
|
||||
type: response_matcher
|
||||
args:
|
||||
ip:
|
||||
- 'ext:./geoip.dat:cn'
|
BIN
luci-app-mosdns/root/etc/mosdns/geoip.dat
Normal file
BIN
luci-app-mosdns/root/etc/mosdns/geoip.dat
Normal file
Binary file not shown.
10532
luci-app-mosdns/root/etc/mosdns/geosite.dat
Normal file
10532
luci-app-mosdns/root/etc/mosdns/geosite.dat
Normal file
File diff suppressed because one or more lines are too long
16
luci-app-mosdns/root/etc/mosdns/mosupdater.sh
Executable file
16
luci-app-mosdns/root/etc/mosdns/mosupdater.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash -e
|
||||
set -o pipefail
|
||||
rm -rf /tmp/mosdns
|
||||
mkdir /tmp/mosdns
|
||||
wget https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/geoip-only-cn-private.dat -nv -O /tmp/mosdns/geoip.dat
|
||||
wget https://cdn.jsdelivr.net/gh/Loyalsoldier/domain-list-custom@release/geosite.dat -nv -O /tmp/mosdns/geosite.dat
|
||||
find /tmp/mosdns/* -size -20k -exec rm {} \;
|
||||
syncconfig=$(uci -q get mosdns.mosdns.syncconfig)
|
||||
if [ $syncconfig -eq 1 ]; then
|
||||
wget https://cdn.jsdelivr.net/gh/QiuSimons/openwrt-mos@master/luci-app-mosdns/root/etc/mosdns/config.yaml -nv -O /tmp/mosdns/config.yaml
|
||||
find /tmp/mosdns/* -size -2k -exec rm {} \;
|
||||
fi
|
||||
chmod -R 755 /tmp/mosdns
|
||||
cp -rf /tmp/mosdns/* /etc/mosdns
|
||||
rm -rf /tmp/mosdns
|
||||
exit 0
|
11
luci-app-mosdns/root/etc/uci-defaults/luci-mosdns
Executable file
11
luci-app-mosdns/root/etc/uci-defaults/luci-mosdns
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@mosdns[-1]
|
||||
add ucitrack mosdns
|
||||
set ucitrack.@mosdns[-1].init=mosdns
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-*
|
||||
exit 0
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-mosdns": {
|
||||
"description": "Grant UCI access for luci-app-mosdns",
|
||||
"read": {
|
||||
"uci": [ "mosdns" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "mosdns" ]
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-netspeedtest
|
||||
PKG_VERSION:=1.6
|
||||
PKG_RELEASE:=20210415
|
||||
PKG_RELEASE:=20210511
|
||||
PKG_LICENSE:=GPLv2
|
||||
PKG_MAINTAINER:=sirpdboy
|
||||
|
||||
@ -23,9 +23,6 @@ define Package/$(PKG_NAME)
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
LuCI support Network speed test intranet and Extranet
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
@ -40,7 +37,7 @@ define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/
|
||||
cp -pR ./root/* $(1)/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
|
||||
po2lmo ./po/zh-cn/netspeedtest.po $(1)/usr/lib/lua/luci/i18n/netspeedtest.lmo
|
||||
po2lmo ./po/zh-cn/netspeedtest.po $(1)/usr/lib/lua/luci/i18n/netspeedtest.zh-cn.lmo
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
|
@ -1,2 +1,123 @@
|
||||
[](#解决-github-网页上图片显示失败的问题) [](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ)
|
||||
<a href="#readme">
|
||||
<img src="https://img.vim-cn.com/a1/8713845a4aa922ac96619b0d2fb3d6919d37fc.png" alt="图飞了😂" title="NetSpeedTest" align="right" height="180" />
|
||||
</a>
|
||||
|
||||
欢迎来到sirpdboy的源码仓库!
|
||||
=
|
||||
Welcome to sirpdboy's git source of packages
|
||||
-
|
||||
[luci-app-NetSpeedTest — 网络速度测试1.5完整版](https://github.com/sirpdboy/NetSpeedTest)
|
||||
======================
|
||||
|
||||
[](#readme) [](#写在前面-) [](#编译说明-) [](#说明-) [](#捐助-)
|
||||
|
||||
请 **认真阅读完毕** 本页面,本页面包含注意事项和如何使用。
|
||||
|
||||
a new netspeedtest luci app bese luci-app-netspeedtest
|
||||
-
|
||||
|
||||
## 写在前面:[](#写在前面-)
|
||||
|
||||
一直在找OPENWRT上测试速度的插件,苦寻不到,于是有了它!
|
||||
此插件可进行内外和外网网络速度测试。
|
||||
|
||||
1.内网测速基于iperf3 插件,服务端路由器如果没有安装请先安装此ipk插件。
|
||||
|
||||
2.测速的终端使用机器必须和测速服务器在同一个局域网络中!
|
||||
|
||||
3.客户端使用步骤:
|
||||
启动测速服务器端-->下载测试客户端-->运行测速客户端-->输入服务端IP地址-->查看结果。
|
||||
|
||||
5.客户端运行,国内端下载中有“iperf3测速客户端”,运行它输入服务器IP即可。
|
||||
国外原版,需要手动进入 CMD命令模式,再输入命令:iperf3.exe -c 服务器IP
|
||||
|
||||
6.网络测速iperf3客户端下载地址:https://sipdboy.lanzoui.com/b01c3esih 密码:cpd6
|
||||
|
||||
8.外网测速使用speedtest.net测速内核,需要依赖speedtest,另外感谢superspeed和user1121114685因为借用了你们的灵感!
|
||||
|
||||
9.外网测速最后测试阶段感谢佐大:佐须之男 测试查问题!
|
||||
|
||||
10.新插件难免有bug 请不要大惊小怪。欢迎提交bug。
|
||||
|
||||
11.安装需要依赖: python3 iperf3 。
|
||||
|
||||
## 编译说明 [](#编译说明-)
|
||||
|
||||
将NetSpeedTest 主题添加至 LEDE/OpenWRT 源码的方法。
|
||||
|
||||
## 下载源码方法一:
|
||||
编辑源码文件夹根目录feeds.conf.default并加入如下内容:
|
||||
|
||||
```Brach
|
||||
# feeds获取源码:
|
||||
src-git netspeedtest https://github.com/sirpdboy/netspeedtest
|
||||
```
|
||||
```Brach
|
||||
# 更新feeds,并安装主题:
|
||||
scripts/feeds update netspeedtest
|
||||
scripts/feeds install luci-app-netspeedtest
|
||||
```
|
||||
|
||||
## 下载源码方法二:
|
||||
```Brach
|
||||
# 下载源码
|
||||
|
||||
git clone https://github.com/sirpdboy/netspeedtest package/netspeedtest
|
||||
|
||||
make menuconfig
|
||||
```
|
||||
## 配置菜单
|
||||
```Brach
|
||||
make menuconfig
|
||||
# 找到 LuCI -> Applications, 选择 luci-app-netspeedtest, 保存后退出。
|
||||
```
|
||||
## 编译
|
||||
```Brach
|
||||
# 编译固件
|
||||
make package/netspeedtest/luci-app-netspeedtest/{clean,compile} V=s
|
||||
```
|
||||
|
||||
## 说明 [](#说明-)
|
||||
|
||||
源码来源:https://github.com/sirpdboy/netspeedtest/luci-app-netspeedtest
|
||||
|
||||
|
||||
你可以随意使用其中的源码,但请注明出处。
|
||||
============================
|
||||
|
||||
# My other project
|
||||
网络速度测试 :https://github.com/sirpdboy/netspeedtest
|
||||
|
||||
定时关机重启 : https://github.com/sirpdboy/luci-app-autopoweroff
|
||||
|
||||
关机功能插件 : https://github.com/sirpdboy/luci-app-poweroffdevice
|
||||
|
||||
opentopd主题 : https://github.com/sirpdboy/luci-theme-opentopd
|
||||
|
||||
opentoks 主题: https://github.com/sirpdboy/luci-theme-opentoks [仿KOOLSAHRE主题]
|
||||
|
||||
btmob 主题: https://github.com/sirpdboy/luci-theme-btmob
|
||||
|
||||
系统高级设置 : https://github.com/sirpdboy/luci-app-advanced
|
||||
|
||||
## 捐助 [](#捐助-)
|
||||
|
||||
**如果你觉得此项目对你有帮助,请捐助我们,以使项目能持续发展,更加完善。··请作者喝杯咖啡~~~**
|
||||
|
||||
**你们的支持就是我的动力!**
|
||||
|
||||
### 捐助方式
|
||||
|
||||
| <img src="https://img.shields.io/badge/-支付宝-F5F5F5.svg" href="#赞助支持本项目-" height="25" alt="图飞了😂"/> | <img src="https://img.shields.io/badge/-微信-F5F5F5.svg" height="25" alt="图飞了😂" href="#赞助支持本项目-"/> |
|
||||
| :-----------------: | :-------------: |
|
||||
|<img src="https://img.vim-cn.com/fd/8e2793362ac3510094961b04407beec569b2b4.png" width="150" height="150" alt="图飞了😂" href="#赞助支持本项目-"/>|<img src="https://img.vim-cn.com/c7/675730a88accebf37a97d9e84e33529322b6e9.png" width="150" height="150" alt="图飞了😂" href="#赞助支持本项目-"/>|
|
||||
|
||||
<a href="#readme">
|
||||
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="图飞了😂" title="返回顶部" align="right"/>
|
||||
</a>
|
||||
|
||||
###### [解决 Github 网页上图片显示失败的问题](https://blog.csdn.net/qq_38232598/article/details/91346392)
|
||||
|
||||
[](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ)
|
||||
|
||||
#### 原作者sirpdboy 修复了编译错误
|
||||
|
@ -1 +0,0 @@
|
||||
zh-cn
|
1
luci-app-netspeedtest/po/zh_Hans
Normal file
1
luci-app-netspeedtest/po/zh_Hans
Normal file
@ -0,0 +1 @@
|
||||
zh-cn
|
17
luci-app-nginx-manager/Makefile
Normal file
17
luci-app-nginx-manager/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for NginxManager From sundaqiang
|
||||
LUCI_DEPENDS:=+luci-nginx +luci-ssl-nginx +luci-ssl-openssl
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=20211030
|
||||
PKG_MAINTAINER:=sundaqiang
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
18
luci-app-nginx-manager/README.md
Normal file
18
luci-app-nginx-manager/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
# luci-app-nginx-manager<65><72>Nginx<6E><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD>openwrt<EFBFBD><EFBFBD>nginx
|
||||
|
||||
### ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
1. <20><><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϵ<EFBFBD>uhttpd<70><64>Ϊ·<CEAA>ɺ<EFBFBD>̨<EFBFBD><CCA8>web<65><62><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+luci-nginx +luci-ssl-nginx +luci-ssl-openssl<73><6C><EFBFBD><EFBFBD><EFBFBD>һῪ<D2BB><E1BFAA>·<EFBFBD>ɺ<EFBFBD>̨<EFBFBD><CCA8>https<70><73><EFBFBD><EFBFBD>
|
||||
3. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϵ<EFBFBD>uhttpd<70><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE>uhttpd<70><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫɾ<D2AA><C9BE>uhttpd<70><64><EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><DAB1><EFBFBD>ǰ<EFBFBD>ڸ<EFBFBD>Ŀ¼ִ<C2BC><D6B4><EFBFBD><EFBFBD><EFBFBD>²<EFBFBD><C2B2><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
```bash
|
||||
sed -i 's/+uhttpd +uhttpd-mod-ubus //g' feeds/luci/collections/luci/Makefile
|
||||
```
|
||||
|
||||
### Ч<><D0A7>չʾ
|
||||
![nginx-manager][1]
|
||||
|
||||
[1]: https://raw.githubusercontent.com/sundaqiang/openwrt-packages/master/img/nginx-manager.png
|
39
luci-app-nginx-manager/luasrc/controller/nginx-manager.lua
Normal file
39
luci-app-nginx-manager/luasrc/controller/nginx-manager.lua
Normal file
@ -0,0 +1,39 @@
|
||||
module("luci.controller.nginx-manager", package.seeall)
|
||||
|
||||
function index()
|
||||
nixio.fs.rename ("/etc/nginx/uci.conf", "/etc/nginx/ucibak.conf")
|
||||
if not nixio.fs.access("/etc/nginx/nginx.conf") then
|
||||
nixio.fs.copyr("/var/lib/nginx/uci.conf", "/etc/nginx/nginx.conf")
|
||||
luci.sys.call("/etc/init.d/nginx restart")
|
||||
end
|
||||
file=nixio.fs.readfile("/etc/uwsgi/vassals/luci-webui.ini")
|
||||
if tonumber(file:match("limit%pas[%p%s]+(%d+)")) < 5000 then
|
||||
file=file:gsub("limit%pas[%p%s]+(%d+)","limit-as = 5000")
|
||||
nixio.fs.writefile("/etc/uwsgi/vassals/luci-webui.ini", file)
|
||||
luci.sys.call("/etc/init.d/uwsgi restart")
|
||||
end
|
||||
nixio.fs.writefile("/etc/config/nginx-manager", "")
|
||||
x = luci.model.uci.cursor()
|
||||
x:set("nginx-manager", "main", "nginx")
|
||||
x:set("nginx-manager", "main", "name", "main")
|
||||
x:set("nginx-manager", "main", "filepath", "/etc/nginx/nginx.conf")
|
||||
for path in nixio.fs.dir("/etc/nginx/conf.d") do
|
||||
if path:find(".conf$") ~= nil then
|
||||
name = path:gsub(".conf", "")
|
||||
x:set("nginx-manager", name, "nginx")
|
||||
x:set("nginx-manager", name, "name", name)
|
||||
x:set("nginx-manager", name, "filepath", "/etc/nginx/conf.d/" .. path)
|
||||
end
|
||||
end
|
||||
x:commit("nginx-manager")
|
||||
entry({"admin", "services", "nginx-manager"}, cbi("nginx-manager"), _("Nginx Manager"), 95).dependent = true
|
||||
entry({"admin", "services", "nginx-manager", "setstatus"}, call("setstatus")).leaf = true
|
||||
end
|
||||
|
||||
function setstatus()
|
||||
local e = {}
|
||||
local mode = luci.http.formvalue('mode')
|
||||
e.code=luci.sys.call("/etc/init.d/nginx " .. mode)
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
43
luci-app-nginx-manager/luasrc/model/cbi/nginx-manager.lua
Normal file
43
luci-app-nginx-manager/luasrc/model/cbi/nginx-manager.lua
Normal file
@ -0,0 +1,43 @@
|
||||
local fs = require "nixio.fs"
|
||||
local m = Map("nginx-manager",translate("Nginx Manager"), translate("A simple Nginx manager") .. [[<br /><br /><a href="https://github.com/sundaqiang/openwrt-packages" target="_blank">Powered by sundaqiang</a>]])
|
||||
s = m:section(TypedSection, "nginx", translate("Web site list"))
|
||||
s.template = "nginx-manager/index"
|
||||
s.addremove = true
|
||||
s.anonymous = false
|
||||
s:tab("general", translate("General Info"))
|
||||
s:tab("server", translate("Configuration File"))
|
||||
s:taboption("general", DummyValue, "name", translate("name"))
|
||||
s:taboption("general", DummyValue, "filepath", translate("File Path"))
|
||||
file=s:taboption("server", TextValue, "")
|
||||
file.template = "cbi/tvalue"
|
||||
file.rows = 25
|
||||
file.wrap = "off"
|
||||
file.rmempty = true
|
||||
|
||||
function s.create(self,section)
|
||||
path="/etc/nginx/conf.d/" .. section .. ".conf"
|
||||
fs.copyr("/etc/nginx/conf.d/templates", path)
|
||||
TypedSection.create(self,section)
|
||||
self.map:set(section, "name", section)
|
||||
self.map:set(section, "filepath", path)
|
||||
return true
|
||||
end
|
||||
function s.remove(self,section)
|
||||
path="/etc/nginx/conf.d/" .. section .. ".conf"
|
||||
fs.remove(path)
|
||||
TypedSection.remove(self,section)
|
||||
end
|
||||
function sync_value_to_file(value, file)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
local old_value = fs.readfile(file)
|
||||
if value ~= old_value then
|
||||
fs.writefile(file, value)
|
||||
end
|
||||
end
|
||||
function file.cfgvalue(self,section)
|
||||
return fs.readfile(self.map:get(section, "filepath")) or ""
|
||||
end
|
||||
function file.write(self, section, value)
|
||||
sync_value_to_file(value, self.map:get(section, "filepath"))
|
||||
end
|
||||
return m
|
65
luci-app-nginx-manager/luasrc/view/nginx-manager/index.htm
Normal file
65
luci-app-nginx-manager/luasrc/view/nginx-manager/index.htm
Normal file
@ -0,0 +1,65 @@
|
||||
<fieldset class="cbi-section" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
|
||||
<% if self.title and #self.title > 0 then -%>
|
||||
<legend><%=self.title%></legend>
|
||||
<%- end %>
|
||||
<% if self.description and #self.description > 0 then -%>
|
||||
<div class="cbi-section-descr"><%=self.description%></div>
|
||||
<%- end %>
|
||||
<div class="cbi-value" style="border-bottom: 1px solid #ddd;border-radius: 0px">
|
||||
<label class="cbi-value-title"><%= translate("Restart the nginx") %></label>
|
||||
<div class="cbi-value-field" style="padding:unset">
|
||||
<input class="btn cbi-button cbi-button-reload" id="restart" type="button" size="0" onclick="check_status('restart')" value="<%:Restart%>" />
|
||||
</div>
|
||||
<label class="cbi-value-title"><%= translate("Reload the nginx") %></label>
|
||||
<div class="cbi-value-field" style="padding:unset">
|
||||
<input class="btn cbi-button cbi-button-reload" id="reload" type="button" size="0" onclick="check_status('reload')" value="<%:Reload%>" />
|
||||
</div>
|
||||
</div>
|
||||
<% local isempty = true for i, k in ipairs(self:cfgsections()) do -%>
|
||||
<%- section = k; isempty = false -%>
|
||||
|
||||
<% if not self.anonymous then -%>
|
||||
<div class="cbi-section-remove" style="display: flex;flex-flow: row nowrap;justify-content: space-between">
|
||||
<span style="font-size:1.15rem;color:#32325d;font-weight:bold;letter-spacing:0.1rem;padding:1rem 1.5rem;"><%=section:upper()%></span>
|
||||
<input type="submit" name="cbi.rts.<%=self.config%>.<%=k%>" onclick="this.form.cbi_state='del-section'; return true" value="<%:Delete%>" class="cbi-button" />
|
||||
</div>
|
||||
<%- end %>
|
||||
|
||||
<%+cbi/tabmenu%>
|
||||
|
||||
<fieldset class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>" style="border-bottom: 1px solid #ddd;border-radius: 0px">
|
||||
<%+cbi/ucisection%>
|
||||
</fieldset>
|
||||
<%- end %>
|
||||
|
||||
<% if isempty then -%>
|
||||
<em><%:This section contains no values yet%><br /><br /></em>
|
||||
<%- end %>
|
||||
|
||||
<% if self.addremove then -%>
|
||||
<% if self.template_addremove then include(self.template_addremove) else -%>
|
||||
<div class="cbi-section-create">
|
||||
<% if self.anonymous then -%>
|
||||
<input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" />
|
||||
<%- else -%>
|
||||
<% if self.invalid_cts then -%><div class="cbi-section-error"><% end %>
|
||||
<input type="text" class="cbi-section-create-name" id="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" data-type="uciname" data-optional="true" />
|
||||
<input type="submit" class="cbi-button cbi-button-add" onclick="this.form.cbi_state='add-section'; return true" value="<%:Add%>" />
|
||||
<% if self.invalid_cts then -%>
|
||||
<br /><%:Invalid%></div>
|
||||
<%- end %>
|
||||
<%- end %>
|
||||
</div>
|
||||
<%- end %>
|
||||
<%- end %>
|
||||
</fieldset>
|
||||
<style>.cbi-value-field {padding: 11.2px;}.cbi-tabmenu {border-bottom: unset !important;}</style>
|
||||
<script type="text/javascript">
|
||||
function check_status(mode) {
|
||||
const tb = document.getElementById(mode);
|
||||
tb.disabled = true;
|
||||
XHR.get('<%=url([[admin]], [[services]], [[nginx-manager]], [[setstatus]])%>', {mode: mode}, (x, r) => {
|
||||
tb.disabled = false;
|
||||
});
|
||||
}
|
||||
</script>
|
26
luci-app-nginx-manager/po/zh-cn/nginx-manager.po
Normal file
26
luci-app-nginx-manager/po/zh-cn/nginx-manager.po
Normal file
@ -0,0 +1,26 @@
|
||||
msgid "Nginx Manager"
|
||||
msgstr "Nginx管理器"
|
||||
|
||||
msgid "A simple Nginx manager"
|
||||
msgstr "一个简易的Nginx管理器"
|
||||
|
||||
msgid "Web site list"
|
||||
msgstr "网站列表"
|
||||
|
||||
msgid "Restart the nginx"
|
||||
msgstr "重新启动Nginx"
|
||||
|
||||
msgid "Reload the nginx"
|
||||
msgstr "重新加载Nginx"
|
||||
|
||||
msgid "Reload"
|
||||
msgstr "重新加载"
|
||||
|
||||
msgid "Configuration File"
|
||||
msgstr "配置文件"
|
||||
|
||||
msgid "General Info"
|
||||
msgstr "基础信息"
|
||||
|
||||
msgid "File Path"
|
||||
msgstr "文件路径"
|
1
luci-app-nginx-manager/po/zh_Hans
Symbolic link
1
luci-app-nginx-manager/po/zh_Hans
Symbolic link
@ -0,0 +1 @@
|
||||
zh-cn
|
17
luci-app-nginx-manager/root/etc/nginx/conf.d/templates
Normal file
17
luci-app-nginx-manager/root/etc/nginx/conf.d/templates
Normal file
@ -0,0 +1,17 @@
|
||||
server {
|
||||
listen 8080; #bind prot 绑定的端口
|
||||
root /www; #directory 网站路径
|
||||
ssl_session_timeout 5m;
|
||||
gzip on;
|
||||
gzip_types text/plain application/json application/javascript application/x-javascript text/css application/xml text/javascript;
|
||||
gzip_proxied any;
|
||||
gzip_vary on;
|
||||
gzip_comp_level 6;
|
||||
gzip_buffers 16 8k;
|
||||
gzip_http_version 1.0;
|
||||
|
||||
location / {
|
||||
index index.html index.htm; #默认文件
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@nginx-manager[-1]
|
||||
add ucitrack nginx-manager
|
||||
set ucitrack.@nginx-manage[-1].init=nginx
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-nginx-manager": {
|
||||
"description": "Grant UCI access for luci-app-nginx-manager",
|
||||
"read": {
|
||||
"uci": [ "nginx-manager" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "nginx-manager" ]
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -142,6 +142,12 @@ local status = api.uci_get_type("global_other", "status", "")
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"></label>
|
||||
<div class="cbi-value-field">
|
||||
<iframe src="https://ip.skk.moe/simple" style="width: 100%; border: 0"></iframe></div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
|
||||
|
16
luci-app-supervisord/Makefile
Normal file
16
luci-app-supervisord/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for NginxManager From sundaqiang
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=20211102
|
||||
PKG_MAINTAINER:=sundaqiang
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
27
luci-app-supervisord/README.md
Normal file
27
luci-app-supervisord/README.md
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
# luci-app-supervisord<72><64><EFBFBD><EFBFBD><EFBFBD>̹<EFBFBD><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Luci<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> [supervisord](https://github.com/ochinchina/supervisord)
|
||||
|
||||
### <20><><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>̹<EFBFBD><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>pm2
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>Dz<EFBFBD><C7B2>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>ij<EFBFBD>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٵ<EFBFBD><D9B5><EFBFBD>ʵ<EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- nodejs<6A><73>python<6F>ij<EFBFBD><C4B3><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD><CCBC>Ѿ<EFBFBD><D1BE>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>nodejs<6A><73>python
|
||||
- <20><><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD>Ҫֱ<D2AA>ӵ㰴ť<E3B0B4><C5A5><EFBFBD>¡<EFBFBD><C2A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>Ŀ<EFBFBD><C4BF><EFBFBD>ض<EFBFBD><D8B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>˵<EFBFBD><CBB5>:
|
||||
|
||||
```ini
|
||||
;<3B><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>||<7C>ָ<D6B8><EEA3AC><EFBFBD><EFBFBD>
|
||||
;backupfile=/usr/bin/xxxxx||/etc/yyyyy
|
||||
backupfile=
|
||||
|
||||
;<3B><>ȡ<EFBFBD>汾<EFBFBD><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EEA3AC><EFBFBD><EFBFBD>
|
||||
;getversions=xxxxx version
|
||||
getversions=
|
||||
```
|
||||
### Ч<><D0A7>չʾ
|
||||
![supervisord-1][1]
|
||||
![supervisord-2][2]
|
||||
|
||||
[1]: https://raw.githubusercontent.com/sundaqiang/openwrt-packages/master/img/supervisord-1.png
|
||||
[2]: https://raw.githubusercontent.com/sundaqiang/openwrt-packages/master/img/supervisord-2.png
|
234
luci-app-supervisord/luasrc/controller/supervisord.lua
Normal file
234
luci-app-supervisord/luasrc/controller/supervisord.lua
Normal file
@ -0,0 +1,234 @@
|
||||
module("luci.controller.supervisord", package.seeall)
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/supervisord") then return end
|
||||
entry({"admin", "services", "supervisord"}, cbi("supervisord"), _("Supervisord"), 95).dependent = true
|
||||
entry({"admin", "services", "supervisord", "status"}, call("status")).leaf = true
|
||||
entry({"admin", "services", "supervisord", "getver"}, call("getver")).leaf = true
|
||||
entry({"admin", "services", "supervisord", "update"}, call("update")).leaf = true
|
||||
entry({"admin", "services", "supervisord", "gettask"}, call("gettask")).leaf = true
|
||||
entry({"admin", "services", "supervisord", "starttask"}, call("starttask")).leaf = true
|
||||
entry({"admin", "services", "supervisord", "restarttask"}, call("restarttask")).leaf = true
|
||||
entry({"admin", "services", "supervisord", "stoptask"}, call("stoptask")).leaf = true
|
||||
entry({"admin", "services", "supervisord", "removetask"}, call("removetask")).leaf = true
|
||||
entry({"admin", "services", "supervisord", "addtask"}, call("addtask")).leaf = true
|
||||
entry({"admin", "services", "supervisord", "savetask"}, call("savetask")).leaf = true
|
||||
entry({"admin", "services", "supervisord", "getlog"}, call("getlog")).leaf = true
|
||||
end
|
||||
|
||||
function Split(str, delim, maxNb)
|
||||
-- Eliminate bad cases...
|
||||
if string.find(str, delim) == nil then
|
||||
return { str }
|
||||
end
|
||||
if maxNb == nil or maxNb < 1 then
|
||||
maxNb = 0 -- No limit
|
||||
end
|
||||
local result = {}
|
||||
local pat = "(.-)" .. delim .. "()"
|
||||
local nb = 0
|
||||
local lastPos
|
||||
for part, pos in string.gfind(str, pat) do
|
||||
nb = nb + 1
|
||||
result[nb] = part
|
||||
lastPos = pos
|
||||
if nb == maxNb then break end
|
||||
end
|
||||
-- Handle the last field
|
||||
if nb ~= maxNb then
|
||||
result[nb + 1] = string.sub(str, lastPos)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function status()
|
||||
local e = {}
|
||||
e.running = luci.sys.call("ps | grep supervisord | grep -v grep >/dev/null") == 0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function getver()
|
||||
local e = {}
|
||||
local c=luci.model.uci.cursor()
|
||||
local d=c:get("supervisord", "main", "filepath")
|
||||
e.nowver=luci.sys.exec(d .. " version")
|
||||
e.newver=luci.sys.exec("uclient-fetch -qO- 'https://api.github.com/repos/ochinchina/supervisord/releases/latest' | jsonfilter -e '@.tag_name'")
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function update()
|
||||
local e = {}
|
||||
local c=luci.model.uci.cursor()
|
||||
local d=c:get("supervisord", "main", "filepath")
|
||||
local version = luci.http.formvalue('version')
|
||||
local arch = nixio.uname().machine or ""
|
||||
version = version:gsub("\n", "")
|
||||
if nixio.fs.access("/usr/lib/os-release") then
|
||||
LEDE_BOARD = luci.sys.exec("echo -n $(grep 'LEDE_BOARD' /usr/lib/os-release | awk -F '[\\042\\047]' '{print $2}')")
|
||||
end
|
||||
if nixio.fs.access("/etc/openwrt_release") then
|
||||
DISTRIB_TARGET = luci.sys.exec("echo -n $(grep 'DISTRIB_TARGET' /etc/openwrt_release | awk -F '[\\042\\047]' '{print $2}')")
|
||||
end
|
||||
arch=luci.util.trim(arch)
|
||||
if arch == "x86_64" then
|
||||
arch = "64-bit"
|
||||
end
|
||||
filename = "supervisord_" .. version:gsub("v", "") .. "_Linux_" .. arch .. ".tar.gz"
|
||||
nixio.fs.remove("/tmp/" .. filename)
|
||||
u=c:get("supervisord", "main", "usechinamirror")
|
||||
if u then
|
||||
u="https://ghproxy.com/"
|
||||
else
|
||||
u=""
|
||||
end
|
||||
e.error=luci.sys.call("uclient-fetch -qO- -O '/tmp/" .. filename .. "' '" .. u .. "https://github.com/ochinchina/supervisord/releases/download/" .. version .. "/" .. filename .. "'")
|
||||
if e.error == 0 then
|
||||
e.error=luci.sys.exec("tar -xzvf '/tmp/" .. filename .. "' -C /tmp")
|
||||
if e.error then
|
||||
e.error=nixio.fs.mover("/tmp/" .. filename:gsub(".tar.gz", "") .. "/supervisord", d)
|
||||
if e.error then
|
||||
e.error=0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
else
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
else
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
end
|
||||
|
||||
function gettask()
|
||||
local e = {}
|
||||
local name = luci.http.formvalue('name')
|
||||
local data = luci.sys.exec("supervisord ctl status " .. name)
|
||||
e.status=string.gsub(string.sub(data, 34, 50), " ", "")
|
||||
e.description=string.sub(data, 51)
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function starttask()
|
||||
local e = {}
|
||||
local name = luci.http.formvalue('name')
|
||||
local data = luci.sys.exec("supervisord ctl start " .. name)
|
||||
if string.find(data,"started") ~= nil then
|
||||
e.code=1
|
||||
else
|
||||
e.code=0
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function restarttask()
|
||||
local e = {}
|
||||
local name = luci.http.formvalue('name')
|
||||
local data = luci.sys.exec("supervisord ctl stop " .. name .. " && supervisord ctl start " .. name)
|
||||
if string.find(data,"started") ~= nil then
|
||||
e.code=1
|
||||
else
|
||||
e.code=0
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function stoptask()
|
||||
local e = {}
|
||||
local name = luci.http.formvalue('name')
|
||||
local data = luci.sys.exec("supervisord ctl stop " .. name)
|
||||
if string.find(data,"stopped") ~= nil then
|
||||
e.code=1
|
||||
else
|
||||
e.code=0
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function removetask()
|
||||
local e = {}
|
||||
local name = luci.http.formvalue('name')
|
||||
e.code=nixio.fs.remove('/etc/supervisord/program/' .. name .. '.ini')
|
||||
if e.code then
|
||||
luci.sys.call("supervisord ctl reload")
|
||||
e.code=1
|
||||
else
|
||||
e.code=0
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function addtask()
|
||||
local e = {}
|
||||
local name = luci.http.formvalue('name')
|
||||
if nixio.fs.access('/etc/supervisord/program/' .. name .. '.ini') then
|
||||
e.code=2
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
return
|
||||
end
|
||||
file=nixio.fs.readfile("/etc/supervisord/program/templates")
|
||||
file=file:gsub("demo", name)
|
||||
e.code=nixio.fs.writefile('/etc/supervisord/program/' .. name .. '.ini', file)
|
||||
if e.code then
|
||||
luci.sys.call("supervisord ctl reload")
|
||||
e.code=1
|
||||
e.data=file
|
||||
else
|
||||
e.code=0
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function savetask()
|
||||
local e = {}
|
||||
local name = luci.http.formvalue('name')
|
||||
local data = luci.http.formvalue('data')
|
||||
data = data:gsub("\r\n?", "\n")
|
||||
file = '/etc/supervisord/program/' .. name .. '.ini'
|
||||
e.code=nixio.fs.writefile (file, data)
|
||||
if e.code then
|
||||
sysupgrade=nixio.fs.readfile("/etc/sysupgrade.conf")
|
||||
if not sysupgrade:find(file) then
|
||||
sysupgrade=sysupgrade .. '\n' .. file
|
||||
end
|
||||
backupfile=data:match("backupfile=([%a%d%p]+)")
|
||||
backupfile=Split(backupfile, "||")
|
||||
for k, v in ipairs(backupfile) do
|
||||
if not sysupgrade:find(v:gsub("%p", "%%%1")) then
|
||||
sysupgrade=sysupgrade .. '\n' .. v
|
||||
end
|
||||
end
|
||||
nixio.fs.writefile ("/etc/sysupgrade.conf", sysupgrade)
|
||||
luci.sys.call("supervisord ctl reload")
|
||||
e.code=1
|
||||
else
|
||||
e.code=0
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function getlog()
|
||||
local e = {}
|
||||
local name = luci.http.formvalue('name')
|
||||
if name=="main" then
|
||||
local data = nixio.fs.readfile ('/etc/supervisord/supervisord.conf')
|
||||
data = string.match(data, "logfile=([%a%d%p]+)")
|
||||
e.data=nixio.fs.readfile (data)
|
||||
else
|
||||
local data = nixio.fs.readfile ('/etc/supervisord/program/' .. name .. '.ini')
|
||||
data = string.match(data, "stdout_logfile=([%a%d%p]+)")
|
||||
e.data=nixio.fs.readfile (data)
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
70
luci-app-supervisord/luasrc/model/cbi/supervisord.lua
Normal file
70
luci-app-supervisord/luasrc/model/cbi/supervisord.lua
Normal file
@ -0,0 +1,70 @@
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
|
||||
local m = Map("supervisord",translate("Supervisord"), translate("A golang development process management") .. [[<br /><br /><a href="https://github.com/sundaqiang/openwrt-packages" target="_blank">Powered by sundaqiang</a>]])
|
||||
m:section(SimpleSection).template = "supervisord/index"
|
||||
|
||||
s = m:section(TypedSection, "supervisord")
|
||||
s.addremove = false
|
||||
s.anonymous = true
|
||||
s:tab("general", translate("General Settings"))
|
||||
s:tab("advanced", translate("Configuration File"))
|
||||
s:tab("list", translate("Task List"))
|
||||
s:tab("log", translate("Log List"))
|
||||
|
||||
f = s:taboption("general", Flag, "enabled", translate("Enabled"))
|
||||
f.rmempty = false
|
||||
v = s:taboption("general", Value, "filepath", translate("File Path"))
|
||||
v.rmempty = false
|
||||
v = s:taboption("general", Flag, "usechinamirror", translate("Use China Mirror"))
|
||||
v.rmempty = false
|
||||
b = s:taboption("general", Button, "")
|
||||
b.template = "supervisord/version"
|
||||
|
||||
file=s:taboption("advanced", TextValue, "")
|
||||
file.template = "cbi/tvalue"
|
||||
file.rows = 15
|
||||
file.wrap = "off"
|
||||
file.rmempty = false
|
||||
|
||||
l=s:taboption("list", DummyValue, "")
|
||||
l.template = "supervisord/list"
|
||||
l.list={}
|
||||
index=1
|
||||
for filelist in fs.dir("/etc/supervisord/program") do
|
||||
if filelist:find(".ini$") ~= nil then
|
||||
name=fs.readfile("/etc/supervisord/program/" .. filelist)
|
||||
l.list[index]={}
|
||||
l.list[index][1]=name:match("program:(%a+)")
|
||||
l.list[index][2]="/etc/supervisord/program/" .. filelist
|
||||
local cmd=name:match("directory=([%a%d%p ]+)") .. "/" .. name:match("getversions=([%a%d%p ]+)")
|
||||
l.list[index][3]=sys.exec(cmd)
|
||||
index=index+1
|
||||
end
|
||||
end
|
||||
|
||||
g=s:taboption("log", DummyValue, "")
|
||||
g.template = "supervisord/log"
|
||||
g.list=l.list
|
||||
|
||||
function s.create(self,section)
|
||||
return TypedSection.create(self,section)
|
||||
end
|
||||
function s.remove(self,section)
|
||||
return TypedSection.remove(self,section)
|
||||
end
|
||||
function sync_value_to_file(self, section, value, file)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
local old_value = fs.readfile(file)
|
||||
if value ~= old_value then
|
||||
fs.writefile(file, value)
|
||||
self.map:set(section, "amend", "1")
|
||||
end
|
||||
end
|
||||
function file.cfgvalue(self,section)
|
||||
return fs.readfile("/etc/supervisord/supervisord.conf") or ""
|
||||
end
|
||||
function file.write(self, section, value)
|
||||
sync_value_to_file(self, section, value, "/etc/supervisord/supervisord.conf")
|
||||
end
|
||||
return m
|
21
luci-app-supervisord/luasrc/view/supervisord/index.htm
Normal file
21
luci-app-supervisord/luasrc/view/supervisord/index.htm
Normal file
@ -0,0 +1,21 @@
|
||||
<script type="text/javascript">
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[supervisord]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
var links = '<em><b><font color=green>Supervisord <%:RUNNING%></font></b></em>';
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<em><b><font color=red>Supervisord <%:NOT RUNNING%></font></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<style></style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
163
luci-app-supervisord/luasrc/view/supervisord/list.htm
Normal file
163
luci-app-supervisord/luasrc/view/supervisord/list.htm
Normal file
@ -0,0 +1,163 @@
|
||||
<%local fs = require "nixio.fs"%>
|
||||
<%+cbi/valueheader%>
|
||||
<div class="cbi-section-node">
|
||||
<table class="cbi-section-table" id="task-list">
|
||||
<tbody>
|
||||
<tr class="cbi-section-table-titles">
|
||||
<th class="cbi-section-table-cell" style="width:120px!important"><%:Name%></th>
|
||||
<th class="cbi-section-table-cell" style="width:120px!important"><%:Versions%></th>
|
||||
<th class="cbi-section-table-cell" style="width:100px!important"><%:Status%></th>
|
||||
<th class="cbi-section-table-cell" style="width:300px!important"><%:Description%></th>
|
||||
<th class="cbi-section-table-cell"><%:Configuration File%></th>
|
||||
<th class="cbi-section-table-cell" style="width:355px!important"><%:Action%></th>
|
||||
</tr>
|
||||
<% for _,item in pairs(self.list) do %>
|
||||
<tr class="cbi-section-table-row" id="<%=item[2]:gsub('/etc/supervisord/program/', ""):gsub('.ini', "")%>-main">
|
||||
<td class="cbi-value-field">
|
||||
<%=item[1]%>
|
||||
</td>
|
||||
<td class="cbi-value-field">
|
||||
<%=item[3]%>
|
||||
</td>
|
||||
<td class="cbi-value-field" id="<%=item[1]%>-status">
|
||||
</td>
|
||||
<td class="cbi-value-field" id="<%=item[1]%>-description">
|
||||
</td>
|
||||
<td class="cbi-value-field">
|
||||
<textarea class="cbi-input-textarea" id="<%=item[1]%>-text" rows="15" wrap="off"><%=fs.readfile(item[2])%></textarea>
|
||||
</td>
|
||||
<td class="cbi-value-field">
|
||||
<input class="cbi-button cbi-input-apply" style="font-size: 100%;background-color: green!important;" type="button" id="<%=item[1]%>-start" disabled
|
||||
onclick="actions('starttask','<%=item[1]%>')" value="<%:Start%>" size="0">
|
||||
<input class="cbi-button cbi-input-remove" style="font-size: 100%;background-color: #333333!important;" type="button" id="<%=item[1]%>-stop" disabled
|
||||
onclick="actions('stoptask','<%=item[1]%>')" value="<%:Stop%>" size="0">
|
||||
<input class="cbi-button cbi-input-apply" style="font-size: 100%;" type="button"
|
||||
onclick="actions('restarttask','<%=item[1]%>')" value="<%:Reboot%>" size="0">
|
||||
<input class="cbi-button cbi-input-remove" style="font-size: 100%;" type="button"
|
||||
onclick="actions('savetask','<%=item[2]:gsub('/etc/supervisord/program/', ''):gsub('.ini', '')%>')" value="<%:Save%>" size="0">
|
||||
<input class="cbi-button cbi-button-remove" style="font-size: 100%;" type="button"
|
||||
onclick="actions('removetask','<%=item[2]:gsub('/etc/supervisord/program/', ''):gsub('.ini', '')%>')" value="<%:Delete%>" size="0">
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="cbi-section-create">
|
||||
<input type="text" class="cbi-section-create-name" id="addtext" value="" maxlength="20" size="0">
|
||||
<input class="cbi-button cbi-button-add" onclick="addtask()" type="button" value="<%:Add%>" size="0">
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
<% for _,item in pairs(self.list) do -%>
|
||||
XHR.poll(5, '<%=url([[admin]], [[services]], [[supervisord]], [[gettask]])%>', {name: '<%=item[1]%>'},
|
||||
function(x, data) {
|
||||
const st = document.getElementById('<%=item[1]%>-status');
|
||||
const des = document.getElementById('<%=item[1]%>-description');
|
||||
if (data) {
|
||||
st.innerHTML = data.status;
|
||||
if (data.status == "Exited" || data.status == "Backoff"){
|
||||
st.style.color="red"
|
||||
document.getElementById('<%=item[1]%>-start').disabled = false;
|
||||
document.getElementById('<%=item[1]%>-stop').disabled = true;
|
||||
}else{
|
||||
|
||||
st.style.color="green"
|
||||
document.getElementById('<%=item[1]%>-start').disabled = true;
|
||||
document.getElementById('<%=item[1]%>-stop').disabled = false;
|
||||
}
|
||||
des.innerHTML = data.description;
|
||||
}
|
||||
}
|
||||
)
|
||||
<% end %>
|
||||
|
||||
function addtask(){
|
||||
const name = document.getElementById("addtext").value
|
||||
const isletter = /^[a-zA-Z]+$/.test(name);
|
||||
if (!isletter) {
|
||||
alert("<%:Only letters can be used for names!%>")
|
||||
return
|
||||
}
|
||||
if (name.length > 20) {
|
||||
alert("<%:Cannot exceed 20 characters!%>")
|
||||
return
|
||||
}
|
||||
XHR.get('<%=url([[admin]], [[services]], [[supervisord]], [[addtask]])%>', {name: name},
|
||||
function(x, data) {
|
||||
if (data.code == 0) {
|
||||
alert("<%:Creation failed. Please try again!%>")
|
||||
return
|
||||
}else if (data.code == 1){
|
||||
const currentRows = document.getElementById("task-list").rows.length;
|
||||
const insertTr = document.getElementById("task-list").insertRow(currentRows);
|
||||
insertTr.className = 'cbi-section-table-row';
|
||||
insertTr.id = name + '-main';
|
||||
insertTr.innerHTML = "<td class='cbi-value-field'>"+name+"</td><td class='cbi-value-field' id='"+name+"-status'></td><td class='cbi-value-field' id='"+name+"-description'></td><td class='cbi-value-field'><textarea class='cbi-input-textarea' id='"+name+"-text' rows='15' wrap='off'>"+data.data+"</textarea></td><td class='cbi-value-field'><input class='cbi-button cbi-input-apply' style='font-size: 100%;background-color: green!important;' type='button' id='"+name+"-start' disabled onclick='actions("starttask",""+name+"")' value='<%:Start%>' size='0'><input class='cbi-button cbi-input-remove' style='font-size: 100%;background-color: #333333!important;' type='button' id='"+name+"-stop' disabled onclick='actions("stoptask",""+name+"")' value='<%:Stop%>' size='0'><input class='cbi-button cbi-input-apply' style='font-size: 100%;' type='button' onclick='actions("restarttask",""+name+"")' value='<%:Reboot%>' size='0'><input class='cbi-button cbi-input-remove' style='font-size: 100%;' type='button' onclick='actions("savetask",""+name+"")' value='<%:Save%>' size='0'><input class='cbi-button cbi-button-remove' style='font-size: 100%;' type='button' onclick='actions("removetask",""+name+"")' value='<%:Delete%>' size='0'></td>";
|
||||
document.getElementById("addtext").value="";
|
||||
XHR.poll(5, '<%=url([[admin]], [[services]], [[supervisord]], [[gettask]])%>', {name: name},
|
||||
function(x, data) {
|
||||
const st = document.getElementById(name + '-status');
|
||||
const des = document.getElementById(name + '-description');
|
||||
if (data) {
|
||||
st.innerHTML = data.status;
|
||||
if (data.status == "Exited" || data.status == "Backoff"){
|
||||
st.style.color="red"
|
||||
document.getElementById(name + '-start').disabled = false;
|
||||
document.getElementById(name + '-stop').disabled = true;
|
||||
}else{
|
||||
st.style.color="green"
|
||||
document.getElementById(name + '-start').disabled = true;
|
||||
document.getElementById(name + '-stop').disabled = false;
|
||||
}
|
||||
des.innerHTML = data.description;
|
||||
}
|
||||
}
|
||||
)
|
||||
}else if (data.code == 2){
|
||||
alert("<%:A task with this name already exists!%>")
|
||||
return
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
function actions(mode,name){
|
||||
if (mode=="savetask"){
|
||||
const x = new XHR()
|
||||
x.post('<%=url([[admin]], [[services]], [[supervisord]], [[savetask]])%>', {name: name, data: $('#' + name + '-text').val()},
|
||||
function(x) {
|
||||
if (JSON.parse(x.response).code) {
|
||||
alert("<%:Save success!%>")
|
||||
}else{
|
||||
alert("<%:Save failed!%>")
|
||||
}
|
||||
}
|
||||
)
|
||||
}else{
|
||||
if (mode=="removetask") {
|
||||
const ret=confirm("<%:Are you sure you want to delete this task?%>")
|
||||
if (!ret) return
|
||||
}
|
||||
XHR.get('<%=url([[admin]], [[services]], [[supervisord]], [[mode]])%>'.replace("mode",mode), {name: name},
|
||||
function(x, data) {
|
||||
if (data.code) {
|
||||
if (mode == "starttask"){
|
||||
document.getElementById(name + '-start').disabled = true;
|
||||
document.getElementById(name + '-stop').disabled = false;
|
||||
}
|
||||
if (mode == "stoptask"){
|
||||
document.getElementById(name + '-start').disabled = false;
|
||||
document.getElementById(name + '-stop').disabled = true;
|
||||
}
|
||||
if (mode == "removetask"){
|
||||
document.getElementById(name + '-main').remove();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<%+cbi/valuefooter%>
|
35
luci-app-supervisord/luasrc/view/supervisord/log.htm
Normal file
35
luci-app-supervisord/luasrc/view/supervisord/log.htm
Normal file
@ -0,0 +1,35 @@
|
||||
<%local fs = require "nixio.fs"%>
|
||||
<%+cbi/valueheader%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">
|
||||
<p style="color: red">日记列表</p>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<select class="cbi-input-select" size="1">
|
||||
<option value="main">supervisord</option>
|
||||
<% for _,item in pairs(self.list) do %>
|
||||
<option value="<%=item[2]:gsub('/etc/supervisord/program/', ''):gsub('.ini', '')%>">
|
||||
<%=item[2]:gsub('/etc/supervisord/program/', ''):gsub('.ini', '')%>
|
||||
</option>
|
||||
<% end %>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<textarea class="cbi-input-textarea" id="log-text" rows="30" wrap="off" readonly></textarea>
|
||||
<script type="text/javascript">
|
||||
getlog('main')
|
||||
$(".cbi-input-select").change(function (e) {
|
||||
getlog($(this).val())
|
||||
});
|
||||
|
||||
function getlog(name) {
|
||||
XHR.get('<%=url([[admin]], [[services]], [[supervisord]], [[getlog]])%>', {name: name},
|
||||
function (x, data) {
|
||||
if (data.data) {
|
||||
document.getElementById("log-text").value = data.data;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
</script>
|
||||
<%+cbi/valuefooter%>
|
56
luci-app-supervisord/luasrc/view/supervisord/version.htm
Normal file
56
luci-app-supervisord/luasrc/view/supervisord/version.htm
Normal file
@ -0,0 +1,56 @@
|
||||
<%+cbi/valueheader%>
|
||||
<label class="cbi-value-title"><%= translate("Update the core") %></label>
|
||||
<div class="cbi-value-field">
|
||||
<input class="btn cbi-button cbi-button-reload" id="update" type="button" size="0" onclick="check_version()" value="<%:Collecting data...%>" />
|
||||
<div class="cbi-value-description">
|
||||
<span class="cbi-value-helpicon"><img src="/luci-static/resources/cbi/help.gif" alt="帮助"></span>
|
||||
<%:If repeated failures occur, you can download the binaries for the corresponding schemas at the following url.%>
|
||||
</br>
|
||||
<%:https://github.com/ochinchina/supervisord/releases%>
|
||||
</br>
|
||||
<%:Unpack the package and place it in the top path.%>
|
||||
</br>
|
||||
<%:The author binary version number may not have changed.%>
|
||||
</br>
|
||||
<%:If you successfully update, the refresh page is still lower than the latest version.%>
|
||||
</br>
|
||||
<%:This is normal.%>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
function getver() {
|
||||
XHR.get('<%=url([[admin]], [[services]], [[supervisord]], [[getver]])%>', null,
|
||||
function(x, data) {
|
||||
const tb = document.getElementById('update');
|
||||
if (data && tb) {
|
||||
if (data.newver) {
|
||||
tb.value = '<%:Local version is %>' + data.nowver + '<%:, New version is %>' + data.newver;
|
||||
tb.setAttribute('newver', data.newver);
|
||||
}else{
|
||||
tb.value = '<%:The check failed. Please try again%>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
getver()
|
||||
function check_version() {
|
||||
const tb = document.getElementById('update');
|
||||
const newver= tb.getAttribute("newver")
|
||||
if (newver){
|
||||
tb.disabled = true;
|
||||
XHR.get('<%=url([[admin]], [[services]], [[supervisord]], [[update]])%>', {version: newver}, (x, r) => {
|
||||
if (r.error == 0) {
|
||||
tb.disabled = false;
|
||||
tb.value = '<%:Local version is %>' + newver + '<%:, New version is %>' + newver;
|
||||
} else {
|
||||
tb.disabled = false;
|
||||
tb.value = '<%:The update failed. Please try again%>';
|
||||
}
|
||||
});
|
||||
}else{
|
||||
getver()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<%+cbi/valuefooter%>
|
80
luci-app-supervisord/po/zh-cn/supervisord.po
Normal file
80
luci-app-supervisord/po/zh-cn/supervisord.po
Normal file
@ -0,0 +1,80 @@
|
||||
msgid "Supervisord"
|
||||
msgstr "进程管理器"
|
||||
|
||||
msgid "A golang development process management"
|
||||
msgstr "一款golang开发的进程管理"
|
||||
|
||||
msgid "General Settings"
|
||||
msgstr "基础设置"
|
||||
|
||||
msgid "Configuration File"
|
||||
msgstr "配置文件"
|
||||
|
||||
msgid "Task List"
|
||||
msgstr "任务列表"
|
||||
|
||||
msgid "Log List"
|
||||
msgstr "日志列表"
|
||||
|
||||
msgid "Enabled"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "File Path"
|
||||
msgstr "文件路径"
|
||||
|
||||
msgid "Use China Mirror"
|
||||
msgstr "使用中国镜像"
|
||||
|
||||
msgid "Update the core"
|
||||
msgstr "更新核心"
|
||||
|
||||
msgid "If repeated failures occur, you can download the binaries for the corresponding schemas at the following url."
|
||||
msgstr "如果重复失败,您可以从以下url下载对应模式的二进制文件。"
|
||||
|
||||
msgid "Unpack the package and place it in the top path."
|
||||
msgstr "解压后并将其放置在上方设置的路径中。"
|
||||
|
||||
msgid "The author binary version number may not have changed."
|
||||
msgstr "作者二进制版本号可能没有改变。"
|
||||
|
||||
msgid "If you successfully update, the refresh page is still lower than the latest version."
|
||||
msgstr "如果更新成功,刷新页面仍然低于最新版本。"
|
||||
|
||||
msgid "This is normal."
|
||||
msgstr "这是正常的。"
|
||||
|
||||
msgid "Local version is"
|
||||
msgstr "本地版本是"
|
||||
|
||||
msgid ", New version is"
|
||||
msgstr ",最新版本是"
|
||||
|
||||
msgid "The check failed. Please try again"
|
||||
msgstr "检查失败。请再试一次"
|
||||
|
||||
msgid "The update failed. Please try again"
|
||||
msgstr "更新失败。请再试一次"
|
||||
|
||||
msgid "Versions"
|
||||
msgstr "版本"
|
||||
|
||||
msgid "Only letters can be used for names!"
|
||||
msgstr "只有字母可以用来命名!"
|
||||
|
||||
msgid "Cannot exceed 20 characters!"
|
||||
msgstr "不能超过20个字符!"
|
||||
|
||||
msgid "Creation failed. Please try again!"
|
||||
msgstr "创建失败了。请再试一次!"
|
||||
|
||||
msgid "A task with this name already exists!"
|
||||
msgstr "已经存在此名称的任务!"
|
||||
|
||||
msgid "Save success!"
|
||||
msgstr "保存成功!"
|
||||
|
||||
msgid "Save failed!"
|
||||
msgstr "保存失败!"
|
||||
|
||||
msgid "Are you sure you want to delete this task?"
|
||||
msgstr "您确定要删除该任务吗?"
|
1
luci-app-supervisord/po/zh_Hans
Symbolic link
1
luci-app-supervisord/po/zh_Hans
Symbolic link
@ -0,0 +1 @@
|
||||
zh-cn
|
6
luci-app-supervisord/root/etc/config/supervisord
Normal file
6
luci-app-supervisord/root/etc/config/supervisord
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
config supervisord 'main'
|
||||
option filepath '/usr/bin/supervisord'
|
||||
option enabled '1'
|
||||
option amend '0'
|
||||
|
42
luci-app-supervisord/root/etc/init.d/supervisord
Executable file
42
luci-app-supervisord/root/etc/init.d/supervisord
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2015 OpenWrt.org
|
||||
|
||||
START=90
|
||||
|
||||
get_config() {
|
||||
config_get_bool enabled $1 enabled 0
|
||||
config_get_bool amend $1 amend 0
|
||||
config_get filepath $1 filepath /usr/bin/supervisord
|
||||
}
|
||||
|
||||
start() {
|
||||
config_load supervisord
|
||||
config_foreach get_config supervisord
|
||||
[ $enabled -eq 0 ] && exit 0
|
||||
$filepath -c /etc/supervisord/supervisord.conf -d
|
||||
}
|
||||
|
||||
stop() {
|
||||
config_load supervisord
|
||||
config_foreach get_config supervisord
|
||||
$filepath ctl shutdown
|
||||
}
|
||||
|
||||
reload() {
|
||||
config_load supervisord
|
||||
config_foreach get_config supervisord
|
||||
[ $enabled -eq 0 ] && logger -t supervisord disabled to stop && stop && exit 0
|
||||
status=$(ps | grep supervisord | grep -v grep | grep -v luci | grep -v init | grep -v version | wc -l)
|
||||
[ $status -eq 0 ] && logger -t supervisord unstarted to start && start && exit 0
|
||||
if [ $amend -eq 1 ]; then
|
||||
logger -t supervisord amend to restart
|
||||
stop
|
||||
sleep 1
|
||||
uci set supervisord.main.amend=0
|
||||
uci commit supervisord
|
||||
start
|
||||
else
|
||||
logger -t supervisord fixed to reload
|
||||
$filepath ctl reload
|
||||
fi
|
||||
}
|
60
luci-app-supervisord/root/etc/supervisord/program/templates
Normal file
60
luci-app-supervisord/root/etc/supervisord/program/templates
Normal file
@ -0,0 +1,60 @@
|
||||
;更多参数查看https://github.com/ochinchina/supervisord/
|
||||
|
||||
;程序名称,没事别乱改
|
||||
[program:demo]
|
||||
|
||||
;程序启动命令,必须
|
||||
;command=xxxxx
|
||||
command=
|
||||
|
||||
;执行命令的路径,必须
|
||||
;directory=/usr/bin
|
||||
directory=
|
||||
|
||||
;需要备份文件的完整路径,多个文件以||分割,必须
|
||||
;backupfile=/usr/bin/xxxxx||/etc/yyyyy
|
||||
backupfile=
|
||||
|
||||
;获取版本号命令,必须
|
||||
;getversions=xxxxx version
|
||||
getversions=
|
||||
|
||||
;在supervisord启动的时候也自动启动
|
||||
autostart=true
|
||||
|
||||
;启动10秒后没有异常退出,就表示进程正常启动了,默认为1秒
|
||||
startsecs=10
|
||||
|
||||
;程序退出后自动重启,可选值:[unexpected,true,false]
|
||||
;默认为unexpected,表示进程意外杀死后才重启
|
||||
autorestart=true
|
||||
|
||||
;启动失败自动重试次数,默认是3
|
||||
startretries=3
|
||||
|
||||
;用哪个用户启动进程,默认是root
|
||||
user=root
|
||||
|
||||
;进程启动优先级,默认999,值小的优先启动
|
||||
priority=999
|
||||
|
||||
;把stderr重定向到stdout,默认false
|
||||
redirect_stderr=true
|
||||
|
||||
;stdout日志文件大小,默认1MB
|
||||
stdout_logfile_maxbytes=1MB
|
||||
|
||||
;stdout日志文件备份数,默认是10
|
||||
stdout_logfile_backups=10
|
||||
|
||||
;stdout日志文件,需要注意当指定目录不存在时无法正常启动,所以需手动创建目录
|
||||
stdout_logfile=/var/log/demo.log
|
||||
|
||||
;日志的级别
|
||||
loglevel=info
|
||||
|
||||
;默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程
|
||||
stopasgroup=false
|
||||
|
||||
;默认为false,向进程组发送kill信号,包括子进程
|
||||
killasgroup=false
|
40
luci-app-supervisord/root/etc/supervisord/supervisord.conf
Normal file
40
luci-app-supervisord/root/etc/supervisord/supervisord.conf
Normal file
@ -0,0 +1,40 @@
|
||||
;更多参数查看https://github.com/ochinchina/supervisord/
|
||||
[supervisord]
|
||||
|
||||
;主日志文件;默认路径是$CWD/supervisord.log
|
||||
logfile=/var/log/supervisord.log
|
||||
|
||||
;最大主日志文件尺寸;默认3MB
|
||||
logfile_maxbytes=3MB
|
||||
|
||||
;主日志文件备份的数量;默认10
|
||||
logfile_backups=10
|
||||
|
||||
;日志等级;默认info;其他:debug,warn,trace
|
||||
loglevel=debug
|
||||
|
||||
;supervisord的pid文件;默认supervisord.pid
|
||||
pidfile=/var/run/supervisord.pid
|
||||
|
||||
;如果为true,从前台开始;默认false
|
||||
nodaemon=false
|
||||
|
||||
;最小效用启动文件描述符;默认1024
|
||||
minfds=1024
|
||||
|
||||
;最小效用过程描述符;默认200
|
||||
minprocs=200
|
||||
|
||||
;启用web界面,默认仅本地访问且不设置密码
|
||||
[inet_http_server]
|
||||
port=127.0.0.1:9001
|
||||
;username=admin
|
||||
;password=admin
|
||||
|
||||
;启用命令行操作任务,需启用web界面且未设置密码
|
||||
[supervisorctl]
|
||||
serverurl=http://127.0.0.1:9001
|
||||
|
||||
;加载任务配置文件
|
||||
[include]
|
||||
files = /etc/supervisord/program/*.ini
|
11
luci-app-supervisord/root/etc/uci-defaults/luci-supervisord
Normal file
11
luci-app-supervisord/root/etc/uci-defaults/luci-supervisord
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@supervisord[-1]
|
||||
add ucitrack supervisord
|
||||
set ucitrack.@supervisord[-1].init=supervisord
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-supervisord": {
|
||||
"description": "Grant UCI access for luci-app-supervisord",
|
||||
"read": {
|
||||
"uci": [ "supervisord" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "supervisord" ]
|
||||
}
|
||||
}
|
||||
}
|
17
luci-app-wolplus/Makefile
Normal file
17
luci-app-wolplus/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for wolplus From sundaqiang
|
||||
LUCI_DEPENDS:=+etherwake
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=20201225
|
||||
PKG_MAINTAINER:=sundaqiang
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
9
luci-app-wolplus/README.md
Normal file
9
luci-app-wolplus/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
# luci-app-wolplus<75><73><EFBFBD><EFBFBD><EFBFBD>绽<EFBFBD><E7BBBD>++<2B><>
|
||||
|
||||
һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
### Ч<><D0A7>չʾ
|
||||
![wolplus][1]
|
||||
|
||||
[1]: https://raw.githubusercontent.com/sundaqiang/openwrt-packages/master/img/wolplus.png
|
33
luci-app-wolplus/luasrc/controller/wolplus.lua
Normal file
33
luci-app-wolplus/luasrc/controller/wolplus.lua
Normal file
@ -0,0 +1,33 @@
|
||||
module("luci.controller.wolplus", package.seeall)
|
||||
local t, a
|
||||
local x = luci.model.uci.cursor()
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/wolplus") then return end
|
||||
entry({"admin", "services", "wolplus"}, cbi("wolplus"), _("wolplus"), 95).dependent = true
|
||||
entry( {"admin", "services", "wolplus", "awake"}, post("awake") ).leaf = true
|
||||
end
|
||||
|
||||
function awake(sections)
|
||||
lan = x:get("wolplus",sections,"maceth")
|
||||
mac = x:get("wolplus",sections,"macaddr")
|
||||
local e = {}
|
||||
cmd = "/usr/bin/etherwake -D -i " .. lan .. " -b " .. mac .. " 2>&1"
|
||||
local p = io.popen(cmd)
|
||||
local msg = ""
|
||||
if p then
|
||||
while true do
|
||||
local l = p:read("*l")
|
||||
if l then
|
||||
if #l > 100 then l = l:sub(1, 100) .. "..." end
|
||||
msg = msg .. l
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
p:close()
|
||||
end
|
||||
e["data"] = msg
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
35
luci-app-wolplus/luasrc/model/cbi/wolplus.lua
Normal file
35
luci-app-wolplus/luasrc/model/cbi/wolplus.lua
Normal file
@ -0,0 +1,35 @@
|
||||
local i = require "luci.sys"
|
||||
local t, e
|
||||
t = Map("wolplus", translate("wolplus"), translate("Wake up your LAN device") .. [[<br /><br /><a href="https://github.com/sundaqiang/openwrt-packages" target="_blank">Powered by sundaqiang</a>]])
|
||||
t.template = "wolplus/index"
|
||||
e = t:section(TypedSection, "macclient", translate("macclient"))
|
||||
e.template = "cbi/tblsection"
|
||||
e.anonymous = true
|
||||
e.addremove = true
|
||||
a = e:option(Value, "name", translate("name"))
|
||||
a.optional = false
|
||||
nolimit_mac = e:option(Value, "macaddr", translate("macaddr"))
|
||||
nolimit_mac.rmempty = false
|
||||
i.net.mac_hints(function(e, t) nolimit_mac:value(e, "%s (%s)" % {e, t}) end)
|
||||
nolimit_eth = e:option(Value, "maceth", translate("maceth"))
|
||||
nolimit_eth.rmempty = false
|
||||
for t, e in ipairs(i.net.devices()) do if e ~= "lo" then nolimit_eth:value(e) end end
|
||||
btn = e:option(Button, "_awake",translate("awake"))
|
||||
btn.inputtitle = translate("awake")
|
||||
btn.inputstyle = "apply"
|
||||
btn.disabled = false
|
||||
btn.template = "wolplus/awake"
|
||||
function gen_uuid(format)
|
||||
local uuid = i.exec("echo -n $(cat /proc/sys/kernel/random/uuid)")
|
||||
if format == nil then
|
||||
uuid = string.gsub(uuid, "-", "")
|
||||
end
|
||||
return uuid
|
||||
end
|
||||
function e.create(e, t)
|
||||
local uuid = gen_uuid()
|
||||
t = uuid
|
||||
TypedSection.create(e, t)
|
||||
end
|
||||
|
||||
return t
|
3
luci-app-wolplus/luasrc/view/wolplus/awake.htm
Normal file
3
luci-app-wolplus/luasrc/view/wolplus/awake.htm
Normal file
@ -0,0 +1,3 @@
|
||||
<%+cbi/valueheader%>
|
||||
<input class="cbi-button cbi-input-<%=self.inputstyle or "button" %>" style="font-size: 100%;" type="button" onclick="onclick_awake(this.id)" <%=attr("name", section) .. attr("id", cbid) .. attr("value", self.inputtitle)%> />
|
||||
<%+cbi/valuefooter%>
|
22
luci-app-wolplus/luasrc/view/wolplus/index.htm
Normal file
22
luci-app-wolplus/luasrc/view/wolplus/index.htm
Normal file
@ -0,0 +1,22 @@
|
||||
<% include("cbi/map") %>
|
||||
<script type="text/javascript">
|
||||
function _id2section(id) {
|
||||
var x = id.split(".");
|
||||
return x[2];
|
||||
}
|
||||
function onclick_awake(id) {
|
||||
var section = _id2section(id);
|
||||
var btnXHR = new XHR();
|
||||
btnXHR.post('<%=url([[admin]], [[services]], [[wolplus]], [[awake]])%>/' + section, { token: '<%=token%>' },
|
||||
function(x, data) {
|
||||
if (x.responseText == "_uncommitted_") {
|
||||
txt="<%:Please [Save & Apply] your changes first%>";
|
||||
alert( txt.replace(new RegExp("<%:&%>", "g"), "&") );
|
||||
} else {
|
||||
alert( JSON.parse(x.response).data );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
23
luci-app-wolplus/po/zh-cn/wolplus.po
Normal file
23
luci-app-wolplus/po/zh-cn/wolplus.po
Normal file
@ -0,0 +1,23 @@
|
||||
msgid "wolplus"
|
||||
msgstr "网络唤醒++"
|
||||
|
||||
msgid "Wake up your LAN device"
|
||||
msgstr "唤醒你的局域网设备"
|
||||
|
||||
msgid "macclient"
|
||||
msgstr "设备列表"
|
||||
|
||||
msgid "name"
|
||||
msgstr "名称"
|
||||
|
||||
msgid "macaddr"
|
||||
msgstr "客户端MAC"
|
||||
|
||||
msgid "maceth"
|
||||
msgstr "网络接口"
|
||||
|
||||
msgid "awake"
|
||||
msgstr "唤醒"
|
||||
|
||||
msgid "Please [Save & Apply] your changes first"
|
||||
msgstr "请先保存并应用您的设置"
|
1
luci-app-wolplus/po/zh_Hans
Symbolic link
1
luci-app-wolplus/po/zh_Hans
Symbolic link
@ -0,0 +1 @@
|
||||
zh-cn
|
0
luci-app-wolplus/root/etc/config/wolplus
Normal file
0
luci-app-wolplus/root/etc/config/wolplus
Normal file
11
luci-app-wolplus/root/etc/uci-defaults/luci-app-wolplus
Normal file
11
luci-app-wolplus/root/etc/uci-defaults/luci-app-wolplus
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@wolplus[-1]
|
||||
add ucitrack wolplus
|
||||
set ucitrack.@wolplus[-1].init=wolplus
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-wolplus": {
|
||||
"description": "Grant UCI access for luci-app-wolplus",
|
||||
"read": {
|
||||
"uci": [ "wolplus" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "wolplus" ]
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-wrtbwmon
|
||||
PKG_VERSION:=2.0.8
|
||||
PKG_VERSION:=2.0.9
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
|
@ -1,30 +1,15 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require uci';
|
||||
'require rpc';
|
||||
'require view';
|
||||
|
||||
function renameFile(str, tag) {
|
||||
var dir = dirName(str);
|
||||
var n = str.lastIndexOf('/'), fn = n > -1 ? str.slice(n + 1) : str;
|
||||
var n = fn.lastIndexOf('.'), bn = n > -1 ? fn.slice(0, n) : fn;
|
||||
var n = fn.lastIndexOf('.'), en = n > -1 ? fn.slice(n + 1) : '';
|
||||
return dir + bn + '.' + tag + (en ? '.' + en : '');
|
||||
}
|
||||
|
||||
function dirName(str) {
|
||||
var n = str.lastIndexOf('/');
|
||||
return n > -1 ? str.slice(0, n + 1) : '';
|
||||
}
|
||||
|
||||
return L.view.extend({
|
||||
lastPath: null,
|
||||
|
||||
load: function() {
|
||||
return uci.load('wrtbwmon').then(L.bind(function() {
|
||||
this.lastPath = uci.get_first('wrtbwmon', 'wrtbwmon', 'path') || null;
|
||||
}, this));
|
||||
},
|
||||
var callChangeDatabasePath = rpc.declare({
|
||||
object: 'luci.wrtbwmon',
|
||||
method: 'change_db_path',
|
||||
params: [ 'state' ]
|
||||
});
|
||||
|
||||
return view.extend({
|
||||
render: function() {
|
||||
var m, s, o;
|
||||
|
||||
@ -45,51 +30,9 @@ return L.view.extend({
|
||||
return m.render();
|
||||
},
|
||||
|
||||
changePath: function() {
|
||||
return uci.changes().then(L.bind(function(res) {
|
||||
if (res.wrtbwmon && this.lastPath) {
|
||||
for (var i = 0; i < res.wrtbwmon.length; i++) {
|
||||
if (res.wrtbwmon[i][2] == "path") {
|
||||
var newPath = res.wrtbwmon[i][3];
|
||||
return fs.stat(dirName(newPath)).then(L.bind(function(res) {
|
||||
if (res.type == 'directory') {
|
||||
Promise.all([
|
||||
fs.exec('/bin/cp', ['-fp', this.lastPath, newPath]),
|
||||
fs.exec('/bin/cp', ['-fp', renameFile(this.lastPath, '6'), renameFile(newPath, '6')]),
|
||||
fs.exec('/bin/cp', ['-fp', renameFile(this.lastPath, '46'), renameFile(newPath, '46')])
|
||||
]);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
var err = new Error('Can\'t move files to non-directory path.');
|
||||
err.name = 'NotDirectoryError';
|
||||
throw err;
|
||||
}
|
||||
}, this)).catch(function(err) {
|
||||
throw err;
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}, this));
|
||||
},
|
||||
|
||||
handleSaveApply: function(ev, mode) {
|
||||
return this.handleSave(ev).then(L.bind(this.changePath, this)).then(L.bind(function(data) {
|
||||
L.resolveDefault(L.ui.changes.apply(mode == '0')).then(L.bind(function() {
|
||||
if (data) {
|
||||
Promise.all([
|
||||
fs.exec('/bin/rm', ['-f', this.lastPath]),
|
||||
fs.exec('/bin/rm', ['-f', renameFile(this.lastPath, '6')]),
|
||||
fs.exec('/bin/rm', ['-f', renameFile(this.lastPath, '46')])
|
||||
]);
|
||||
}
|
||||
}, this));
|
||||
}, this)).catch(function(err) {
|
||||
if (confirm(err + '\n\n' + _('This will revert the changes. Are you sure?'))) {
|
||||
L.bind(L.ui.changes.revert, L.ui.changes)();
|
||||
}
|
||||
});
|
||||
return callChangeDatabasePath('before')
|
||||
.then(this.super.bind(this, 'handleSaveApply', arguments))
|
||||
.then(callChangeDatabasePath.bind(this, 'after'));
|
||||
}
|
||||
});
|
||||
|
@ -1,8 +1,9 @@
|
||||
'use strict';
|
||||
'require fs';
|
||||
'require ui';
|
||||
'require view';
|
||||
|
||||
return L.view.extend({
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return fs.trimmed('/etc/wrtbwmon.user').catch(function(err) {
|
||||
ui.addNotification(null, E('p', {}, _('Unable to load the customized hostname file: ' + err.message)));
|
||||
@ -36,7 +37,7 @@ return L.view.extend({
|
||||
return E('div', { 'class': 'cbi-page-actions' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-save',
|
||||
'click': L.ui.createHandlerFn(this, 'handleSave')
|
||||
'click': ui.createHandlerFn(this, 'handleSave')
|
||||
}, [ _('Save') ])
|
||||
]);
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
'use strict';
|
||||
'require dom';
|
||||
'require fs';
|
||||
'require poll';
|
||||
'require rpc';
|
||||
'require uci';
|
||||
'require ui';
|
||||
'require validation';
|
||||
'require view';
|
||||
|
||||
var cachedData = [];
|
||||
var luciConfig = '/etc/luci-wrtbwmon.conf';
|
||||
@ -21,25 +23,41 @@ var callLuciDSLStatus = rpc.declare({
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
var callGetDatabaseRaw = rpc.declare({
|
||||
object: 'luci.wrtbwmon',
|
||||
method: 'get_db_raw',
|
||||
params: [ 'protocol' ]
|
||||
});
|
||||
|
||||
var callGetDatabasePath = rpc.declare({
|
||||
object: 'luci.wrtbwmon',
|
||||
method: 'get_db_path',
|
||||
params: [ 'protocol' ]
|
||||
});
|
||||
|
||||
var callRemoveDatabase = rpc.declare({
|
||||
object: 'luci.wrtbwmon',
|
||||
method: 'remove_db',
|
||||
params: [ 'protocol' ]
|
||||
});
|
||||
|
||||
function $(tid) {
|
||||
return document.getElementById(tid);
|
||||
}
|
||||
|
||||
function clickToResetDatabase(settings) {
|
||||
function clickToResetDatabase(settings, table, updated, updating, ev) {
|
||||
if (confirm(_('This will delete the database file. Are you sure?'))) {
|
||||
getPath().then(function(res) {
|
||||
var db = settings.protocol == 'ipv4' ? res : renameFile(res, '6');
|
||||
fs.exec('/bin/rm', [db]).then(function() {
|
||||
updateData($('traffic'), $('updated'), $('updating'), settings, true);
|
||||
});
|
||||
})
|
||||
return callRemoveDatabase(settings.protocol)
|
||||
.then(function() {
|
||||
updateData(settings, table, updated, updating, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function clickToSaveConfig(keylist, cstrs) {
|
||||
var data = {};
|
||||
|
||||
for(var i = 0; i < keylist.length; i++) {
|
||||
for (var i = 0; i < keylist.length; i++) {
|
||||
data[keylist[i]] = cstrs[keylist[i]].getValue();
|
||||
}
|
||||
|
||||
@ -55,26 +73,25 @@ function clickToSaveConfig(keylist, cstrs) {
|
||||
.then(function() { document.location.reload(); });
|
||||
}
|
||||
|
||||
function clickToSelectInterval(settings, ev) {
|
||||
function clickToSelectInterval(settings, updating, ev) {
|
||||
if (ev.target.value > 0) {
|
||||
settings.interval = parseInt(ev.target.value);
|
||||
if (!L.Request.poll.active()) L.Request.poll.start();
|
||||
if (!poll.active()) poll.start();
|
||||
}
|
||||
else {
|
||||
L.Request.poll.stop();
|
||||
setUpdateMessage($('updating'), -1);
|
||||
poll.stop();
|
||||
setUpdateMessage(updating, -1);
|
||||
}
|
||||
}
|
||||
|
||||
function clickToSelectProtocol(settings, ev) {
|
||||
function clickToSelectProtocol(settings, table, updated, updating, ev) {
|
||||
settings.protocol = ev.target.value;
|
||||
updateData($('traffic'), $('updated'), $('updating'), settings, true);
|
||||
updateData(settings, table, updated, updating, true);
|
||||
}
|
||||
|
||||
function clickToShowMore(settings, ev) {
|
||||
var table = $('traffic');
|
||||
function clickToShowMore(settings, table, ev) {
|
||||
var t = table.querySelector('.tr.table-totals');
|
||||
settings.showMore = ev.target.checked
|
||||
settings.showMore = ev.target.checked
|
||||
|
||||
if (t && t.firstElementChild)
|
||||
t.firstElementChild.textContent = _('TOTAL') + (settings.showMore ? '' : ': ' + (table.childElementCount - 2));
|
||||
@ -99,7 +116,7 @@ function createOption(args, val) {
|
||||
]);
|
||||
|
||||
if (desc && desc != '')
|
||||
L.dom.append(frame.lastChild, E('div', { 'class': 'cbi-value-description' }, desc));
|
||||
dom.append(frame.lastChild, E('div', { 'class': 'cbi-value-description' }, desc));
|
||||
|
||||
return [widget, frame];
|
||||
}
|
||||
@ -153,14 +170,6 @@ function getDSLBandwidth() {
|
||||
});
|
||||
}
|
||||
|
||||
function getPath() {
|
||||
return uci.load('wrtbwmon').then(function() {
|
||||
var res = uci.get_first('wrtbwmon', 'wrtbwmon', 'path') || '/tmp/usage.db';
|
||||
uci.unload('wrtbwmon');
|
||||
return res;
|
||||
});
|
||||
}
|
||||
|
||||
function handleConfig(ev) {
|
||||
ui.showModal(_('Configuration'), [
|
||||
E('p', { 'class': 'spinning' }, _('Loading configuration data...'))
|
||||
@ -181,7 +190,7 @@ function handleConfig(ev) {
|
||||
[ui.Textfield, _('Upstream Bandwidth'), '100', {datatype: 'ufloat'}, 'Mbps'],
|
||||
[ui.Textfield, _('Downstream Bandwidth'), '100', {datatype: 'ufloat'}, 'Mbps'],
|
||||
[ui.DynamicList, _('Hide MAC Addresses'), [], '', {datatype: 'macaddr'}, '']
|
||||
]; // [constructor, lable, default_value(, all_values), options, description]
|
||||
]; // [constructor, label, default_value(, all_values), options, description]
|
||||
|
||||
for (var i = 0; i < keylist.length; i++) {
|
||||
res = createOption(arglist[i], settings[keylist[i]]);
|
||||
@ -248,7 +257,7 @@ function parseDefaultSettings(file) {
|
||||
var keylist = ['protocol', 'interval', 'showMore', 'showZero', 'useBits', 'useMultiple', 'useDSL', 'upstream', 'downstream', 'hideMACs'];
|
||||
var valuelist = ['ipv4', '5', false, true, false, '1000', false, '100', '100', []];
|
||||
|
||||
return fs.read(file).then(function(json) {
|
||||
return fs.read_direct(file).then(function(json) {
|
||||
var settings;
|
||||
try {
|
||||
settings = JSON.parse(json);
|
||||
@ -258,7 +267,7 @@ function parseDefaultSettings(file) {
|
||||
}
|
||||
|
||||
for (var i = 0; i < keylist.length; i++) {
|
||||
if(!(keylist[i] in settings))
|
||||
if (!(keylist[i] in settings))
|
||||
settings[keylist[i]] = valuelist[i];
|
||||
}
|
||||
|
||||
@ -292,10 +301,13 @@ function progressbar(query, v, m, useBits, useMultiple) {
|
||||
}
|
||||
}
|
||||
|
||||
function registerTableEventHandlers(settings, table) {
|
||||
var indicators = $('xhr_poll_status') || $('indicators').getElementsByTagName('span')[0];
|
||||
indicators.addEventListener('click', function() {
|
||||
$('selectInterval').value = L.Request.poll.active() ? settings.interval : -1;
|
||||
function setupThisDOM(settings, table) {
|
||||
document.addEventListener('poll-stop', function() {
|
||||
$('selectInterval').value = -1;
|
||||
});
|
||||
|
||||
document.addEventListener('poll-start', function() {
|
||||
$('selectInterval').value = settings.interval;
|
||||
});
|
||||
|
||||
table.querySelectorAll('.th').forEach(function(e) {
|
||||
@ -304,6 +316,9 @@ function registerTableEventHandlers(settings, table) {
|
||||
setSortedColumn(ev.target);
|
||||
displayTable(table, settings);
|
||||
});
|
||||
|
||||
if (e.classList.contains('showMore'))
|
||||
settings.showMore ? e.classList.remove('hide') : e.classList.add('hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -317,8 +332,8 @@ function renameFile(str, tag) {
|
||||
|
||||
function resolveCustomizedHostName() {
|
||||
return fs.stat(hostNameFile).then(function() {
|
||||
return fs.read(hostNameFile).then(function(rawStr) {
|
||||
var hostNames = [], arr = rawStr.split(/\r?\n|\r/g), row;
|
||||
return fs.read_direct(hostNameFile).then(function(raw) {
|
||||
var hostNames = [], arr = raw.trim().split(/\r?\n/), row;
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
row = arr[i].split(',');
|
||||
if (row.length == 2 && row[0])
|
||||
@ -326,7 +341,8 @@ function resolveCustomizedHostName() {
|
||||
}
|
||||
return hostNames;
|
||||
})
|
||||
}).catch(function() { return []; });
|
||||
})
|
||||
.catch(function() { return []; });
|
||||
}
|
||||
|
||||
function resolveHostNameByMACAddr() {
|
||||
@ -367,7 +383,7 @@ function setSortedColumn(sorting) {
|
||||
}
|
||||
|
||||
function setUpdateMessage(e, sec) {
|
||||
e.innerHTML = sec < 0 ? '' : ' ' + _('Updating again in %s second(s).').format('<b>' + sec + '</b>');
|
||||
e.innerHTML = sec < 0 ? '' : _('Updating again in %s second(s).').format('<b>' + sec + '</b>');
|
||||
}
|
||||
|
||||
function sortTable(col, IPVer, flag, x, y) {
|
||||
@ -384,8 +400,8 @@ function sortTable(col, IPVer, flag, x, y) {
|
||||
: (a = validation.parseIPv6(a) || [0, 0, 0, 0, 0, 0, 0, 0], b = validation.parseIPv6(b) || [0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
}
|
||||
|
||||
if(Array.isArray(a) && Array.isArray(b)) {
|
||||
for(var i = 0; i < a.length; i++) {
|
||||
if (Array.isArray(a) && Array.isArray(b)) {
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
if (a[i] != b[i]) {
|
||||
return (b[i] - a[i]) * flag;
|
||||
}
|
||||
@ -396,34 +412,36 @@ function sortTable(col, IPVer, flag, x, y) {
|
||||
return a == b ? 0 : (a < b ? 1 : -1) * flag;
|
||||
}
|
||||
|
||||
function updateData(table, updated, updating, settings, once) {
|
||||
if (!(L.Poll.tick % settings.interval) || once) {
|
||||
getPath().then(function(res) {
|
||||
function updateData(settings, table, updated, updating, once) {
|
||||
if (!(poll.tick % settings.interval) || once) {
|
||||
callGetDatabasePath()
|
||||
.then(function(res) {
|
||||
var params = settings.protocol == 'ipv4' ? '-4' : '-6';
|
||||
fs.exec('/usr/sbin/wrtbwmon', [params, '-f', res]);
|
||||
return params == '-4' ? res : renameFile(res, '6');
|
||||
}).then(function(data) {
|
||||
Promise.all([
|
||||
fs.exec('/bin/cat', [ data ]),
|
||||
return fs.exec_direct('/usr/sbin/wrtbwmon', [params, '-f', res.file_4])
|
||||
})
|
||||
.then(function() {
|
||||
return Promise.all([
|
||||
callGetDatabaseRaw(settings.protocol),
|
||||
resolveHostNameByMACAddr()
|
||||
]).then(function(res) {
|
||||
//console.time('start');
|
||||
cachedData = parseDatabase(res[0].stdout || '', res[1], settings.showZero, settings.hideMACs);
|
||||
displayTable(table, settings);
|
||||
updated.innerHTML = _('Last updated at %s.').format(formatDate(new Date(document.lastModified)));
|
||||
//console.timeEnd('start');
|
||||
});
|
||||
]);
|
||||
})
|
||||
.then(function(res) {
|
||||
//console.time('start');
|
||||
cachedData = parseDatabase(res[0].data || '', res[1], settings.showZero, settings.hideMACs);
|
||||
displayTable(table, settings);
|
||||
updated.textContent = _('Last updated at %s.').format(formatDate(new Date(document.lastModified)));
|
||||
//console.timeEnd('start');
|
||||
});
|
||||
}
|
||||
updatePerSec(updating, settings.interval);
|
||||
}
|
||||
|
||||
function updatePerSec(e, interval) {
|
||||
var tick = L.Poll.tick;
|
||||
var tick = poll.tick;
|
||||
var sec = tick % interval ? interval - tick % interval : 0;
|
||||
|
||||
setUpdateMessage(e, sec);
|
||||
if(sec == 0) {
|
||||
if (sec == 0) {
|
||||
setTimeout(setUpdateMessage.bind(this, e, interval), 100);
|
||||
}
|
||||
}
|
||||
@ -483,7 +501,7 @@ function updateTable(tb, values, placeholder, settings) {
|
||||
}
|
||||
|
||||
//Append the totals or placeholder row.
|
||||
if(formData.length == 0) {
|
||||
if (formData.length == 0) {
|
||||
newNode = document.createElement('div');
|
||||
newNode.className = 'tr placeholder';
|
||||
childTD = document.createElement('div');
|
||||
@ -525,7 +543,17 @@ function updateTable(tb, values, placeholder, settings) {
|
||||
tb.appendChild(fragment);
|
||||
}
|
||||
|
||||
return L.view.extend({
|
||||
function initOption(options, selected) {
|
||||
var res = [], attr = {};
|
||||
for (var idx in options) {
|
||||
attr.value = idx;
|
||||
attr.selected = idx == selected ? '' : null;
|
||||
res.push(E('option', attr, options[idx]));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
parseDefaultSettings(luciConfig),
|
||||
@ -534,8 +562,29 @@ return L.view.extend({
|
||||
},
|
||||
|
||||
render: function(data) {
|
||||
var settings = data[0];
|
||||
var node = E('div', { 'class': 'cbi-map' }, [
|
||||
var settings = data[0],
|
||||
labelUpdated = E('label'),
|
||||
labelUpdating = E('label'),
|
||||
table = E('div', { 'class': 'table', 'id': 'traffic' }, [
|
||||
E('div', { 'class': 'tr table-titles' }, [
|
||||
E('div', { 'class': 'th', 'id': 'thClient' }, _('Clients')),
|
||||
E('div', { 'class': 'th showMore hide', 'id': 'thMAC' }, _('MAC')),
|
||||
E('div', { 'class': 'th', 'id': 'thDownload' }, _('Download')),
|
||||
E('div', { 'class': 'th', 'id': 'thUpload' }, _('Upload')),
|
||||
E('div', { 'class': 'th', 'id': 'thTotalDown' }, _('Total Down')),
|
||||
E('div', { 'class': 'th', 'id': 'thTotalUp' }, _('Total Up')),
|
||||
E('div', { 'class': 'th sorted', 'id': 'thTotal' }, _('Total')),
|
||||
E('div', { 'class': 'th showMore hide', 'id': 'thFirstSeen' }, _('First Seen')),
|
||||
E('div', { 'class': 'th showMore hide', 'id': 'thLastSeen' }, _('Last Seen'))
|
||||
]),
|
||||
E('div', {'class': 'tr placeholder'}, [
|
||||
E('div', { 'class': 'td' }, E('em', {}, _('Collecting data...')))
|
||||
])
|
||||
]);
|
||||
|
||||
poll.add(updateData.bind(this, settings, table, labelUpdated, labelUpdating, false), 1);
|
||||
setupThisDOM(settings, table);
|
||||
return E('div', { 'class': 'cbi-map' }, [
|
||||
E('h2', {}, _('Usage - Details')),
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('div', { 'id': 'control_panel' }, [
|
||||
@ -543,25 +592,26 @@ return L.view.extend({
|
||||
E('label', {}, _('Protocol:')),
|
||||
E('select', {
|
||||
'id': 'selectProtocol',
|
||||
'change': clickToSelectProtocol.bind(this, settings)
|
||||
}, [
|
||||
E('option', { 'value': 'ipv4' }, 'ipv4'),
|
||||
E('option', { 'value': 'ipv6' }, 'ipv6')
|
||||
])
|
||||
'change': clickToSelectProtocol.bind(this, settings, table, labelUpdated, labelUpdating)
|
||||
}, initOption({
|
||||
'ipv4': 'ipv4',
|
||||
'ipv6': 'ipv6'
|
||||
}, settings.protocol))
|
||||
]),
|
||||
E('div', {}, [
|
||||
E('label', { 'for': 'showMore' }, _('Show More Columns:')),
|
||||
E('input', {
|
||||
'id': 'showMore',
|
||||
'type': 'checkbox',
|
||||
'click': clickToShowMore.bind(this, settings)
|
||||
'click': clickToShowMore.bind(this, settings, table),
|
||||
'checked': settings.showMore ? '' : null
|
||||
}),
|
||||
]),
|
||||
E('div', {}, [
|
||||
E('button', {
|
||||
'class': 'btn cbi-button cbi-button-reset important',
|
||||
'id': 'resetDatabase',
|
||||
'click': clickToResetDatabase.bind(this, settings)
|
||||
'click': clickToResetDatabase.bind(this, settings, table, labelUpdated, labelUpdating)
|
||||
}, _('Reset Database')),
|
||||
' ',
|
||||
E('button', {
|
||||
@ -571,22 +621,19 @@ return L.view.extend({
|
||||
])
|
||||
]),
|
||||
E('div', {}, [
|
||||
E('div', {}, [
|
||||
E('div', { 'id': 'updated' }),
|
||||
E('div', { 'id': 'updating' })
|
||||
]),
|
||||
E('div', {}, [ labelUpdated, labelUpdating ]),
|
||||
E('div', {}, [
|
||||
E('label', { 'for': 'selectInterval' }, _('Auto update every:')),
|
||||
E('select', {
|
||||
'id': 'selectInterval',
|
||||
'change': clickToSelectInterval.bind(this, settings)
|
||||
}, [
|
||||
E('option', { 'value': '-1' }, _('Disabled')),
|
||||
E('option', { 'value': '2' }, _('2 seconds')),
|
||||
E('option', { 'value': '5' }, _('5 seconds')),
|
||||
E('option', { 'value': '10' }, _('10 seconds')),
|
||||
E('option', { 'value': '30' }, _('30 seconds'))
|
||||
])
|
||||
'change': clickToSelectInterval.bind(this, settings, labelUpdating)
|
||||
}, initOption({
|
||||
'-1': _('Disabled'),
|
||||
'2': _('2 seconds'),
|
||||
'5': _('5 seconds'),
|
||||
'10': _('10 seconds'),
|
||||
'30': _('30 seconds')
|
||||
}, settings.interval))
|
||||
])
|
||||
]),
|
||||
E('div', { 'id': 'progressbar_panel', 'class': 'table' }, [
|
||||
@ -609,40 +656,9 @@ return L.view.extend({
|
||||
))
|
||||
]),
|
||||
]),
|
||||
E('div', { 'class': 'table', 'id': 'traffic' }, [
|
||||
E('div', { 'class': 'tr table-titles' }, [
|
||||
E('div', { 'class': 'th', 'id': 'thClient' }, _('Clients')),
|
||||
E('div', { 'class': 'th showMore hide', 'id': 'thMAC' }, _('MAC')),
|
||||
E('div', { 'class': 'th', 'id': 'thDownload' }, _('Download')),
|
||||
E('div', { 'class': 'th', 'id': 'thUpload' }, _('Upload')),
|
||||
E('div', { 'class': 'th', 'id': 'thTotalDown' }, _('Total Down')),
|
||||
E('div', { 'class': 'th', 'id': 'thTotalUp' }, _('Total Up')),
|
||||
E('div', { 'class': 'th sorted', 'id': 'thTotal' }, _('Total')),
|
||||
E('div', { 'class': 'th showMore hide', 'id': 'thFirstSeen' }, _('First Seen')),
|
||||
E('div', { 'class': 'th showMore hide', 'id': 'thLastSeen' }, _('Last Seen'))
|
||||
]),
|
||||
E('div', {'class': 'tr placeholder'}, [
|
||||
E('div', { 'class': 'td' }, E('em', {}, _('Collecting data...')))
|
||||
])
|
||||
])
|
||||
table
|
||||
])
|
||||
]);
|
||||
|
||||
return Promise.all([
|
||||
node.querySelector('[id="traffic"]'),
|
||||
node.querySelector('[id="updated"]'),
|
||||
node.querySelector('[id="updating"]'),
|
||||
node.querySelector('[id="selectInterval"]').value = settings.interval,
|
||||
node.querySelector('[id="selectProtocol"]').value = settings.protocol,
|
||||
node.querySelector('[id="showMore"]').checked = settings.showMore,
|
||||
node.querySelectorAll('.showMore').forEach(function(e) { settings.showMore ? e.classList.remove('hide') : e.classList.add('hide'); })
|
||||
])
|
||||
.then(function(data) {
|
||||
L.Poll.add(updateData.bind(this, data[0], data[1], data[2], settings, false), 1);
|
||||
return data[0];
|
||||
})
|
||||
.then(registerTableEventHandlers.bind(this, settings))
|
||||
.then(function() { return node; });
|
||||
},
|
||||
|
||||
handleSaveApply: null,
|
||||
|
@ -43,9 +43,6 @@ div > label + select {
|
||||
flex: 1 1 35%;
|
||||
text-align: right;
|
||||
}
|
||||
#updated, #updating {
|
||||
display: inline;
|
||||
}
|
||||
#thClient {
|
||||
width: 17%;
|
||||
}
|
||||
|
@ -1,105 +1,105 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:585
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:184
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:634
|
||||
msgid "10 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:583
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:184
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:632
|
||||
msgid "2 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:586
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:184
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:635
|
||||
msgid "30 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:584
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:184
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:633
|
||||
msgid "5 seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:577
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:626
|
||||
msgid "Auto update every:"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:199
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:208
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:497
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:612
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:517
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:570
|
||||
msgid "Clients"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:122
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:623
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:139
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:581
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:46
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:165
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:208
|
||||
#: luasrc/controller/wrtbwmon.lua:16
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:64
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:174
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:217
|
||||
#: root/usr/share/luci/menu.d/luci-app-wrtbwmon.json:25
|
||||
msgid "Configuration"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:568
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:620
|
||||
msgid "Configure Options"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:193
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:202
|
||||
msgid "Configure the default values for luci-app-wrtbwmon."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:39
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:24
|
||||
msgid "Database path"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:176
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:185
|
||||
msgid "Default More Columns"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:174
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:183
|
||||
msgid "Default Protocol"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:184
|
||||
msgid "Default Refresh Interval"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/controller/wrtbwmon.lua:13
|
||||
#: root/usr/share/luci/menu.d/luci-app-wrtbwmon.json:16
|
||||
msgid "Details"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:582
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:184
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:631
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:614
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:572
|
||||
msgid "Download"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:182
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:191
|
||||
msgid "Downstream Bandwidth"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:592
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:641
|
||||
msgid "Downstream:"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:17
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:18
|
||||
msgid "Each line must have the following format:"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:619
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:577
|
||||
msgid "First Seen"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:33
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:18
|
||||
msgid "General settings"
|
||||
msgstr ""
|
||||
|
||||
@ -107,154 +107,150 @@ msgstr ""
|
||||
msgid "Grant access to LuCI app wrtbwmon"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:183
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:192
|
||||
msgid "Hide MAC Addresses"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:179
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:188
|
||||
msgid "IEC - 1024"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:36
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:21
|
||||
msgid "Keep running in the background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:620
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:578
|
||||
msgid "Last Seen"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:411
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:432
|
||||
msgid "Last updated at %s."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:166
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
msgid "Loading configuration data..."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:613
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:571
|
||||
msgid "MAC"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:179
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:188
|
||||
msgid "Multiple of Unit"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:541
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:592
|
||||
msgid "Protocol:"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:563
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:615
|
||||
msgid "Reset Database"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:179
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:188
|
||||
msgid "SI - 1000"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:40
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:205
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:41
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:214
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:47
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:65
|
||||
msgid "Saving configuration data..."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:551
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:602
|
||||
msgid "Show More Columns:"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:177
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:186
|
||||
msgid "Show Zeros"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:80
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:496
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:97
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:516
|
||||
msgid "TOTAL"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:39
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:24
|
||||
msgid ""
|
||||
"This box is used to select the Database path, which is /tmp/usage.db by "
|
||||
"default."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:29
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:49
|
||||
msgid "This will delete the database file. Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:90
|
||||
msgid "This will revert the changes. Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:618
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:576
|
||||
msgid "Total"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:616
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:574
|
||||
msgid "Total Down"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:617
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:575
|
||||
msgid "Total Up"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/controller/wrtbwmon.lua:10
|
||||
#: root/usr/share/luci/menu.d/luci-app-wrtbwmon.json:3
|
||||
msgid "Traffic Status"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:178
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:187
|
||||
msgid "Transfer Speed in Bits"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:8
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:9
|
||||
msgid "Unable to load the customized hostname file:"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:52
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:70
|
||||
msgid "Unable to save %s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:368
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:386
|
||||
msgid "Updating again in %s second(s)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:615
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:573
|
||||
msgid "Upload"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:181
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:190
|
||||
msgid "Upstream Bandwidth"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:601
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:650
|
||||
msgid "Upstream:"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:31
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:16
|
||||
msgid "Usage - Configuration"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:15
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:16
|
||||
msgid "Usage - Custom User File"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:537
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:588
|
||||
msgid "Usage - Details"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:180
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:189
|
||||
msgid "Use DSL Bandwidth"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/controller/wrtbwmon.lua:19
|
||||
#: root/usr/share/luci/menu.d/luci-app-wrtbwmon.json:34
|
||||
msgid "User file"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:174
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:183
|
||||
msgid "ipv4"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:174
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:183
|
||||
msgid "ipv6"
|
||||
msgstr ""
|
||||
|
@ -1,105 +1,105 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:585
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:184
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:634
|
||||
msgid "10 seconds"
|
||||
msgstr "10秒"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:583
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:184
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:632
|
||||
msgid "2 seconds"
|
||||
msgstr "2秒"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:586
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:184
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:635
|
||||
msgid "30 seconds"
|
||||
msgstr "30秒"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:584
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:184
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:633
|
||||
msgid "5 seconds"
|
||||
msgstr "5秒"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:577
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:626
|
||||
msgid "Auto update every:"
|
||||
msgstr "自动刷新:"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:199
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:208
|
||||
msgid "Cancel"
|
||||
msgstr "取消"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:497
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:612
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:517
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:570
|
||||
msgid "Clients"
|
||||
msgstr "客户端"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:122
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:623
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:139
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:581
|
||||
msgid "Collecting data..."
|
||||
msgstr "收集数据中..."
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:46
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:165
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:208
|
||||
#: luasrc/controller/wrtbwmon.lua:16
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:64
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:174
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:217
|
||||
#: root/usr/share/luci/menu.d/luci-app-wrtbwmon.json:25
|
||||
msgid "Configuration"
|
||||
msgstr "配置"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:568
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:620
|
||||
msgid "Configure Options"
|
||||
msgstr "配置选项"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:193
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:202
|
||||
msgid "Configure the default values for luci-app-wrtbwmon."
|
||||
msgstr "配置luci-app-wrtbwmon的默认值。"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:39
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:24
|
||||
msgid "Database path"
|
||||
msgstr "数据路径"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:176
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:185
|
||||
msgid "Default More Columns"
|
||||
msgstr "默认显示更多列"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:174
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:183
|
||||
msgid "Default Protocol"
|
||||
msgstr "默认协议"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:184
|
||||
msgid "Default Refresh Interval"
|
||||
msgstr "默认刷新间隔"
|
||||
|
||||
#: luasrc/controller/wrtbwmon.lua:13
|
||||
#: root/usr/share/luci/menu.d/luci-app-wrtbwmon.json:16
|
||||
msgid "Details"
|
||||
msgstr "流量信息"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:582
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:184
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:631
|
||||
msgid "Disabled"
|
||||
msgstr "禁用"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:614
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:572
|
||||
msgid "Download"
|
||||
msgstr "下载"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:182
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:191
|
||||
msgid "Downstream Bandwidth"
|
||||
msgstr "下行带宽"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:592
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:641
|
||||
msgid "Downstream:"
|
||||
msgstr "下行:"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:17
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:18
|
||||
msgid "Each line must have the following format:"
|
||||
msgstr "每行需要满足以下格式:"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:619
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:577
|
||||
msgid "First Seen"
|
||||
msgstr "初次记录"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:33
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:18
|
||||
msgid "General settings"
|
||||
msgstr "通用设置"
|
||||
|
||||
@ -107,154 +107,153 @@ msgstr "通用设置"
|
||||
msgid "Grant access to LuCI app wrtbwmon"
|
||||
msgstr "授予访问LuCI应用程序wrtbwmon的权限"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:183
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:192
|
||||
msgid "Hide MAC Addresses"
|
||||
msgstr "隐藏MAC地址"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:179
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:188
|
||||
msgid "IEC - 1024"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:36
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:21
|
||||
msgid "Keep running in the background"
|
||||
msgstr "保持后台运行"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:620
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:578
|
||||
msgid "Last Seen"
|
||||
msgstr "最后记录"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:411
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:432
|
||||
msgid "Last updated at %s."
|
||||
msgstr "最后更新于%s。"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:166
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:175
|
||||
msgid "Loading configuration data..."
|
||||
msgstr "载入配置数据..."
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:613
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:571
|
||||
msgid "MAC"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:179
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:188
|
||||
msgid "Multiple of Unit"
|
||||
msgstr "单位之间倍数"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:541
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:592
|
||||
msgid "Protocol:"
|
||||
msgstr "协议:"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:563
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:615
|
||||
msgid "Reset Database"
|
||||
msgstr "重置"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:179
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:188
|
||||
msgid "SI - 1000"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:40
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:205
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:41
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:214
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:47
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:65
|
||||
msgid "Saving configuration data..."
|
||||
msgstr "保存配置数据..."
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:551
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:602
|
||||
msgid "Show More Columns:"
|
||||
msgstr "显示更多列:"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:177
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:186
|
||||
msgid "Show Zeros"
|
||||
msgstr "显示0流量"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:80
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:496
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:97
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:516
|
||||
msgid "TOTAL"
|
||||
msgstr "总共"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:39
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:24
|
||||
msgid ""
|
||||
"This box is used to select the Database path, which is /tmp/usage.db by "
|
||||
"default."
|
||||
msgstr "该选项用于选择数据存储路径,默认路径为/tmp/usage.db。"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:29
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:49
|
||||
msgid "This will delete the database file. Are you sure?"
|
||||
msgstr "该操作将删除数据统计文件,确定执行该操作?"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:90
|
||||
msgid "This will revert the changes. Are you sure?"
|
||||
msgstr "更改将会重置,确定吗?"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:618
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:576
|
||||
msgid "Total"
|
||||
msgstr "总计"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:616
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:574
|
||||
msgid "Total Down"
|
||||
msgstr "总下载"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:617
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:575
|
||||
msgid "Total Up"
|
||||
msgstr "总上传"
|
||||
|
||||
#: luasrc/controller/wrtbwmon.lua:10
|
||||
#: root/usr/share/luci/menu.d/luci-app-wrtbwmon.json:3
|
||||
msgid "Traffic Status"
|
||||
msgstr "流量监控"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:178
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:187
|
||||
msgid "Transfer Speed in Bits"
|
||||
msgstr "以bits显示传输速度"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:8
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:9
|
||||
msgid "Unable to load the customized hostname file:"
|
||||
msgstr "不能载入自定义用户名文件:"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:52
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:70
|
||||
msgid "Unable to save %s: %s"
|
||||
msgstr "不能保存%s: %s"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:368
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:386
|
||||
msgid "Updating again in %s second(s)."
|
||||
msgstr "下次更新将于%s秒之后。"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:615
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:573
|
||||
msgid "Upload"
|
||||
msgstr "上传"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:181
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:190
|
||||
msgid "Upstream Bandwidth"
|
||||
msgstr "上传带宽"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:601
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:650
|
||||
msgid "Upstream:"
|
||||
msgstr "上行"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:31
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/config.js:16
|
||||
msgid "Usage - Configuration"
|
||||
msgstr "文件设置"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:15
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/custom.js:16
|
||||
msgid "Usage - Custom User File"
|
||||
msgstr "用户文件配置"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:537
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:588
|
||||
msgid "Usage - Details"
|
||||
msgstr "流量详情"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:180
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:189
|
||||
msgid "Use DSL Bandwidth"
|
||||
msgstr "使用DSL带宽"
|
||||
|
||||
#: luasrc/controller/wrtbwmon.lua:19
|
||||
#: root/usr/share/luci/menu.d/luci-app-wrtbwmon.json:34
|
||||
msgid "User file"
|
||||
msgstr "用户文件"
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:174
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:183
|
||||
msgid "ipv4"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:174
|
||||
#: htdocs/luci-static/resources/view/wrtbwmon/details.js:183
|
||||
msgid "ipv6"
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "This will revert the changes. Are you sure?"
|
||||
#~ msgstr "更改将会重置,确定吗?"
|
||||
|
124
luci-app-wrtbwmon/root/usr/libexec/rpcd/luci.wrtbwmon
Executable file
124
luci-app-wrtbwmon/root/usr/libexec/rpcd/luci.wrtbwmon
Executable file
@ -0,0 +1,124 @@
|
||||
#!/bin/sh
|
||||
|
||||
. "$IPKG_INSTROOT/usr/share/libubox/jshn.sh"
|
||||
|
||||
renamefile() {
|
||||
local base=$(basename -- "$1")
|
||||
local ext=$([ -z "${base/*.*/}" ] && echo ".${base##*.}" || echo '')
|
||||
local base="${base%.*}"
|
||||
echo "$(dirname $1)/${base}$2$ext" && return
|
||||
}
|
||||
|
||||
_get_db_path() {
|
||||
local db db_4 db_6 db_46
|
||||
db="$(uci -q get wrtbwmon.general.path)"
|
||||
db_4=$(renamefile "${db:-/tmp/usage.db}" "")
|
||||
db_6=$(renamefile "${db:-/tmp/usage.db}" ".6")
|
||||
db_46=$(renamefile "${db:-/tmp/usage.db}" ".46")
|
||||
json_init
|
||||
json_add_string file_4 "$db_4"
|
||||
json_add_string file_6 "$db_6"
|
||||
json_add_string file_46 "$db_46"
|
||||
json_dump
|
||||
json_cleanup
|
||||
}
|
||||
|
||||
_get_db_raw() {
|
||||
json_init
|
||||
json_add_string file "$1"
|
||||
json_add_string data "$(cat "$1")"
|
||||
json_dump
|
||||
json_cleanup
|
||||
}
|
||||
|
||||
_remove_db() {
|
||||
local result
|
||||
rm "$1" && result=1 || result=0
|
||||
json_init
|
||||
json_add_boolean result "$result"
|
||||
json_dump
|
||||
json_cleanup
|
||||
}
|
||||
|
||||
_change_db_path() {
|
||||
json_init
|
||||
json_load "$(_get_db_path)"
|
||||
json_get_var db_4 'file_4'
|
||||
json_get_var db_6 'file_6'
|
||||
json_get_var db_46 'file_46'
|
||||
json_cleanup
|
||||
if [ "$1" = "before" ]; then
|
||||
mv "$db_4" /tmp/usage.db.tmp
|
||||
mv "$db_6" /tmp/usage.6.db.tmp
|
||||
mv "$db_46" /tmp/usage.46.db.tmp
|
||||
elif [ "$1" = "after" ]; then
|
||||
mv -f /tmp/usage.db.tmp "$db_4"
|
||||
mv -f /tmp/usage.6.db.tmp "$db_6"
|
||||
mv -f /tmp/usage.46.db.tmp "$db_46"
|
||||
fi
|
||||
json_init
|
||||
json_add_boolean result $([ "$?" = 0 ] && echo 1 || echo 0 )
|
||||
json_dump
|
||||
json_cleanup
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
list)
|
||||
json_init
|
||||
json_add_object remove_db
|
||||
json_add_string protocol "protocol"
|
||||
json_close_object
|
||||
json_add_object get_db_raw
|
||||
json_add_string protocol "protocol"
|
||||
json_close_object
|
||||
json_add_object get_db_path
|
||||
json_close_object
|
||||
json_add_object change_db_path
|
||||
json_add_string state "state"
|
||||
json_close_object
|
||||
json_dump
|
||||
json_cleanup
|
||||
;;
|
||||
call)
|
||||
case "$2" in
|
||||
remove_db)
|
||||
read -r input
|
||||
json_init
|
||||
json_load "$input"
|
||||
json_get_var protocol 'protocol'
|
||||
json_cleanup
|
||||
json_load "$(_get_db_path)"
|
||||
json_get_var db_s $([ "$protocol" = "ipv4" ] && echo file_4 || echo file_6)
|
||||
json_cleanup
|
||||
_remove_db "$db_s"
|
||||
;;
|
||||
get_db_raw)
|
||||
read -r input
|
||||
json_init
|
||||
json_load "$input"
|
||||
json_get_var protocol 'protocol'
|
||||
json_cleanup
|
||||
json_load "$(_get_db_path)"
|
||||
json_get_var db_s $([ "$protocol" = "ipv4" ] && echo file_4 || echo file_6)
|
||||
json_cleanup
|
||||
_get_db_raw "$db_s"
|
||||
;;
|
||||
get_db_path)
|
||||
read -r input
|
||||
json_init
|
||||
json_load "$input"
|
||||
json_get_var protocol 'protocol'
|
||||
json_cleanup
|
||||
_get_db_path
|
||||
;;
|
||||
change_db_path)
|
||||
read -r input
|
||||
json_init
|
||||
json_load "$input"
|
||||
json_get_var state 'state'
|
||||
json_cleanup
|
||||
_change_db_path "$state"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
@ -2,24 +2,31 @@
|
||||
"luci-app-wrtbwmon": {
|
||||
"description": "Grant access to LuCI app wrtbwmon",
|
||||
"read": {
|
||||
"ubus": {
|
||||
"luci.wrtbwmon": [
|
||||
"get_db_raw",
|
||||
"get_db_path"
|
||||
]
|
||||
},
|
||||
"file": {
|
||||
"/tmp/usage.db": [ "read" ],
|
||||
"/etc/wrtbwmon.user": [ "read" ],
|
||||
"/usr/sbin/wrtbwmon": [ "exec" ],
|
||||
"/bin/cp": [ "exec" ],
|
||||
"/etc/luci-wrtbwmon.conf": [ "read" ]
|
||||
},
|
||||
"uci": [ "wrtbwmon", "luci-app-wrtbwmon" ]
|
||||
"uci": [ "wrtbwmon" ]
|
||||
},
|
||||
"write": {
|
||||
"ubus": {
|
||||
"luci.wrtbwmon": [
|
||||
"remove_db",
|
||||
"change_db_path"
|
||||
]
|
||||
},
|
||||
"file": {
|
||||
"/bin/cat": [ "exec" ],
|
||||
"/bin/rm": [ "exec" ],
|
||||
"/bin/cp": [ "exec" ],
|
||||
"/etc/luci-wrtbwmon.conf": [ "write" ],
|
||||
"/etc/wrtbwmon.user": [ "write" ]
|
||||
},
|
||||
"uci": [ "wrtbwmon", "luci-app-wrtbwmon" ]
|
||||
"uci": [ "wrtbwmon" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
80
mosdns/Makefile
Normal file
80
mosdns/Makefile
Normal file
@ -0,0 +1,80 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#
|
||||
# Copyright (C) 2021 ImmortalWrt.org
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=mosdns
|
||||
PKG_VERSION:=293b018
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/IrineSistiana/mosdns/tar.gz/$(PKG_VERSION)?
|
||||
PKG_HASH:=skip
|
||||
|
||||
PKG_LICENSE:=GPL-3.0
|
||||
PKG_LICENSE_FILE:=LICENSE
|
||||
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_MOSDNS_COMPRESS_GOPROXY \
|
||||
CONFIG_MOSDNS_COMPRESS_UPX
|
||||
|
||||
PKG_BUILD_DEPENDS:=golang/host
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
GO_PKG:=github.com/IrineSistiana/mosdns
|
||||
GO_PKG_LDFLAGS:=-s -w
|
||||
GO_PKG_LDFLAGS_X:=main.version=$(PKG_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
|
||||
|
||||
define Package/mosdns/Default
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=IP Addresses and Names
|
||||
TITLE:=A plug-in DNS forwarder/splitter
|
||||
URL:=https://github.com/IrineSistiana/mosdns
|
||||
endef
|
||||
|
||||
define Package/mosdns
|
||||
$(call Package/mosdns/Default)
|
||||
DEPENDS:=$(GO_ARCH_DEPENDS)
|
||||
endef
|
||||
|
||||
define Package/mosdns/config
|
||||
config MOSDNS_COMPRESS_GOPROXY
|
||||
bool "Compiling with GOPROXY proxy"
|
||||
default n
|
||||
|
||||
config MOSDNS_COMPRESS_UPX
|
||||
bool "Compress executable files with UPX"
|
||||
default y
|
||||
endef
|
||||
|
||||
ifeq ($(CONFIG_MOSDNS_COMPRESS_GOPROXY),y)
|
||||
export GO111MODULE=on
|
||||
export GOPROXY=https://goproxy.baidu.com
|
||||
endif
|
||||
|
||||
define Build/Prepare
|
||||
$(call Build/Prepare/Default)
|
||||
endef
|
||||
|
||||
GO_PKG_TARGET_VARS:=$(filter-out CGO_ENABLED=%,$(GO_PKG_TARGET_VARS)) CGO_ENABLED=0
|
||||
|
||||
define Build/Compile
|
||||
$(call GoPackage/Build/Compile)
|
||||
ifneq ($(CONFIG_MOSDNS_COMPRESS_UPX),)
|
||||
$(STAGING_DIR_HOST)/bin/upx --lzma --best $(GO_PKG_BUILD_BIN_DIR)/mosdns
|
||||
endif
|
||||
endef
|
||||
|
||||
define Package/mosdns/install
|
||||
$(call GoPackage/Package/Install/Bin,$(1))
|
||||
endef
|
||||
|
||||
$(eval $(call GoBinPackage,mosdns))
|
||||
$(eval $(call BuildPackage,mosdns))
|
34
nas-packages-luci/README.md
Normal file
34
nas-packages-luci/README.md
Normal file
@ -0,0 +1,34 @@
|
||||
# nas-packages-luci
|
||||
luci for [nas-packages](https://github.com/linkease/nas-packages)
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 增加feed源
|
||||
|
||||
```shell
|
||||
echo >> feeds.conf.default
|
||||
echo 'src-git nas https://github.com/linkease/nas-packages.git;master' >> feeds.conf.default
|
||||
echo 'src-git nas_luci https://github.com/linkease/nas-packages-luci.git;main' >> feeds.conf.default
|
||||
./scripts/feeds update nas nas_luci
|
||||
./scripts/feeds install -a -p nas
|
||||
./scripts/feeds install -a -p nas_luci
|
||||
```
|
||||
|
||||
### 集成软件包
|
||||
|
||||
```shell
|
||||
make menuconfig
|
||||
```
|
||||
|
||||
选择软件包
|
||||
```plain
|
||||
LuCI --->
|
||||
3. Applications --->
|
||||
<*> luci-app-ddnsto.................................. LuCI support for ddnsto
|
||||
<*> luci-app-linkease.................................. LuCI support for linkease
|
||||
```
|
||||
|
||||
### 构建固件
|
||||
```shell
|
||||
make
|
||||
```
|
@ -6,9 +6,9 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for ddnsto
|
||||
LUCI_DEPENDS:=ddnsto
|
||||
LUCI_DEPENDS:=+ddnsto
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.0.0
|
||||
PKG_VERSION:=1.0.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
@ -7,11 +7,12 @@
|
||||
{
|
||||
if (st.running)
|
||||
{
|
||||
tb.innerHTML = '<br/><%:The DDNS.to service is running.%>';
|
||||
tb.innerHTML = '<br/><em style=\"color:green\"><%:The DDNS.to service is running.%></em>'
|
||||
+ "<br/><br/><input class=\"btn cbi-button cbi-button-apply\" type=\"button\" value=\" <%:Click to open DDNS.to%> \" onclick=\"window.open('https://www.ddnsto.com/app/#/login/')\"/>";
|
||||
}
|
||||
else
|
||||
{
|
||||
tb.innerHTML = '<br/><em><%:The DDNS.to service is not running.%></em>';
|
||||
tb.innerHTML = '<br/><em style=\"color:red\"><%:The DDNS.to service is not running.%></em>';
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user