mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-27 18:41:15 +08:00
🐶 Sync 2026-03-30 14:49:16
This commit is contained in:
parent
f00793a73b
commit
f28e441b8e
@ -1,5 +1,4 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
# Copyright (C) 2024 iv7777 <hongba@rocketmail.com>
|
||||
# Copyright (C) 2025 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
@ -7,15 +6,14 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for Timewol
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+etherwake
|
||||
PKG_VERSION:=20250407
|
||||
PKG_RELEASE:=2
|
||||
|
||||
define Package/luci-app-timewol/postinst
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
chmod +x /etc/init.d/timewol
|
||||
fi
|
||||
exit 0
|
||||
LUCI_DEPENDS:=+luci-base +etherwake
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
define Package/luci-app-timewol/conffiles
|
||||
/etc/config/timewol
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
@ -1,46 +1,21 @@
|
||||
module("luci.controller.timewol", package.seeall)
|
||||
|
||||
local x = luci.model.uci.cursor()
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/timewol") then return end
|
||||
if not nixio.fs.access("/etc/config/timewol") then return end
|
||||
|
||||
entry({"admin", "control"}, firstchild(), "Control", 44).dependent = false
|
||||
local page = entry({"admin", "control", "timewol"}, cbi("timewol"), _("Timed WOL"))
|
||||
entry({"admin", "control"}, firstchild(), "Control", 44).dependent = false
|
||||
|
||||
local page = entry({"admin", "control", "timewol"}, cbi("timewol"), _("Timed WOL"))
|
||||
page.order = 95
|
||||
page.dependent = true
|
||||
page.acl_depends = { "luci-app-timewol" }
|
||||
entry({"admin", "control", "timewol", "status"}, call("status")).leaf = true
|
||||
entry( {"admin", "control", "timewol", "awake"}, call("awake") ).leaf = true
|
||||
|
||||
entry({"admin", "control", "timewol", "status"}, call("status")).leaf = true
|
||||
end
|
||||
|
||||
function status()
|
||||
local e = {}
|
||||
e.status = luci.sys.call("cat /etc/crontabs/root |grep etherwake >/dev/null") == 0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function awake(sections)
|
||||
lan = x:get("timewol",sections,"maceth")
|
||||
mac = x:get("timewol",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)
|
||||
local e = {}
|
||||
e.status = luci.sys.call("cat /etc/crontabs/root | grep -v '^[ \t]*#' | grep etherwake >/dev/null") == 0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
@ -1,93 +1,90 @@
|
||||
local sys = require "luci.sys"
|
||||
local m, s, o
|
||||
|
||||
-- Create the main map object
|
||||
local map = Map("timewol", translate("Timed Wake on LAN"),
|
||||
translate("Wake up your local area network devices on schedule"))
|
||||
map.template = "timewol/index"
|
||||
m = Map("timewol", translate("Timed Wake on LAN"),
|
||||
translate("Wake up your local area network devices on schedule"))
|
||||
m.template = "timewol/index"
|
||||
|
||||
-- Running Status Section
|
||||
local status_section = map:section(TypedSection, "basic", translate("Running Status"))
|
||||
status_section.anonymous = true
|
||||
s = m:section(TypedSection, "basic", translate("Running Status"))
|
||||
s.anonymous = true
|
||||
|
||||
local status = status_section:option(DummyValue, "timewol_status", translate("Current Status"))
|
||||
status.template = "timewol/timewol"
|
||||
status.value = translate("Collecting data...")
|
||||
o = s:option(DummyValue, "timewol_status", translate("Current Status"))
|
||||
o.template = "timewol/timewol"
|
||||
o.value = translate("Collecting data...")
|
||||
|
||||
-- Basic Settings Section
|
||||
local basic_section = map:section(TypedSection, "basic", translate("Basic Settings"))
|
||||
basic_section.anonymous = true
|
||||
s = m:section(TypedSection, "basic", translate("Basic Settings"))
|
||||
s.anonymous = true
|
||||
|
||||
local enable = basic_section:option(Flag, "enable", translate("Enable"))
|
||||
enable.rmempty = false
|
||||
o = s:option(Flag, "enable", translate("Enable"))
|
||||
o.rmempty = false
|
||||
|
||||
-- Client Settings Section
|
||||
local client_section = map:section(TypedSection, "macclient", translate("Client Settings"))
|
||||
client_section.template = "cbi/tblsection"
|
||||
client_section.anonymous = true
|
||||
client_section.addremove = true
|
||||
s = m:section(TypedSection, "macclient", translate("Client Settings"))
|
||||
s.template = "cbi/tblsection"
|
||||
s.anonymous = true
|
||||
s.addremove = true
|
||||
|
||||
o = s:option(Flag, "enable", translate("Enable"))
|
||||
o.default = 1
|
||||
o.rmempty = false
|
||||
|
||||
-- Client MAC Address
|
||||
local mac_addr = client_section:option(Value, "macaddr", translate("Client MAC"))
|
||||
mac_addr.rmempty = false
|
||||
o = s:option(Value, "macaddr", translate("Client MAC"))
|
||||
o.rmempty = false
|
||||
sys.net.mac_hints(function(mac, hint)
|
||||
mac_addr:value(mac, string.format("%s (%s)", mac, hint))
|
||||
o:value(mac, string.format("%s (%s)", mac, hint))
|
||||
end)
|
||||
|
||||
-- Network Interface
|
||||
local net_iface = client_section:option(Value, "maceth", translate("Network Interface"))
|
||||
net_iface.rmempty = false
|
||||
net_iface.default = "br-lan"
|
||||
o = s:option(Value, "maceth", translate("Network Interface"))
|
||||
o.rmempty = false
|
||||
o.default = "br-lan"
|
||||
for _, device in ipairs(sys.net.devices()) do
|
||||
if device ~= "lo" then
|
||||
net_iface:value(device)
|
||||
end
|
||||
if device ~= "lo" then
|
||||
o:value(device)
|
||||
end
|
||||
end
|
||||
|
||||
-- wake device
|
||||
local btn = client_section:option(Button, "_awake",translate("Wake Up Host"))
|
||||
btn.inputtitle = translate("Awake")
|
||||
btn.inputstyle = "apply"
|
||||
btn.disabled = false
|
||||
btn.template = "timewol/awake"
|
||||
|
||||
-- Function to validate cron field values
|
||||
local function validate_cron_field(option_name, value, min, max, default)
|
||||
if value == "" then
|
||||
return default
|
||||
elseif value == "*" then
|
||||
return value
|
||||
end
|
||||
local num = tonumber(value)
|
||||
if num and num >= min and num <= max then
|
||||
return value
|
||||
else
|
||||
return nil, translatef("Invalid value for %s: %s. Must be between %d and %d or '*'", option_name, value, min, max)
|
||||
end
|
||||
if value == "" then
|
||||
return default
|
||||
elseif value == "*" then
|
||||
return value
|
||||
end
|
||||
local num = tonumber(value)
|
||||
if num and num >= min and num <= max then
|
||||
return value
|
||||
else
|
||||
return nil, translatef("Invalid value for %s: %s. Must be between %d and %d or '*'", option_name, value, min, max)
|
||||
end
|
||||
end
|
||||
|
||||
-- Scheduling Options with Default Values and Range Checks
|
||||
local schedule_options = {
|
||||
{ "minute", translate("Minute"), 0, 59, "0" },
|
||||
{ "hour", translate("Hour"), 0, 23, "0" },
|
||||
{ "day", translate("Day"), 1, 31, "*" },
|
||||
{ "month", translate("Month"), 1, 12, "*" },
|
||||
{ "weeks", translate("Week"), 0, 6, "*" } -- 0 for Sunday, 6 for Saturday
|
||||
{ "minute", translate("Minute"), 0, 59, "0" },
|
||||
{ "hour", translate("Hour"), 0, 23, "0" },
|
||||
{ "day", translate("Day"), 1, 31, "*" },
|
||||
{ "month", translate("Month"), 1, 12, "*" },
|
||||
{ "weeks", translate("Week"), 0, 6, "*" } -- 0 for Sunday, 6 for Saturday
|
||||
}
|
||||
|
||||
for _, opt in ipairs(schedule_options) do
|
||||
local field = client_section:option(Value, opt[1], opt[2])
|
||||
field.default = opt[5] or opt[4] -- Use default value if present, otherwise use maximum value
|
||||
field.optional = false
|
||||
field.validate = function(self, value)
|
||||
return validate_cron_field(opt[2], value, opt[3], opt[4], field.default)
|
||||
end
|
||||
o = s:option(Value, opt[1], opt[2])
|
||||
o.default = opt[5] or opt[4] -- Use default value if present, otherwise use maximum value
|
||||
o.optional = false
|
||||
o.validate = function(self, value)
|
||||
return validate_cron_field(opt[2], value, opt[3], opt[4], o.default)
|
||||
end
|
||||
end
|
||||
|
||||
-- Apply the configuration changes
|
||||
map.apply_on_parse = true
|
||||
function map.on_apply(self)
|
||||
sys.exec("/etc/init.d/timewol restart")
|
||||
m.apply_on_parse = true
|
||||
function m.on_apply(self)
|
||||
sys.exec("/etc/init.d/timewol restart")
|
||||
end
|
||||
|
||||
return map
|
||||
|
||||
return m
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
<%+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%>
|
||||
@ -14,23 +14,5 @@
|
||||
status.innerHTML = result.status?'<%=translate("RUNNING")%>':'<%=translate("NOT RUNNING")%>';
|
||||
}
|
||||
)
|
||||
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]], [[control]], [[timewol]], [[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>
|
||||
|
||||
@ -1 +0,0 @@
|
||||
zh_Hans
|
||||
@ -34,9 +34,6 @@ msgstr "客户端MAC"
|
||||
msgid "Network Interface"
|
||||
msgstr "网络接口"
|
||||
|
||||
msgid "Awake"
|
||||
msgstr "立即唤醒"
|
||||
|
||||
msgid "Minute"
|
||||
msgstr "分钟"
|
||||
|
||||
1
luci-app-timewol/po/zh_Hans
Symbolic link
1
luci-app-timewol/po/zh_Hans
Symbolic link
@ -0,0 +1 @@
|
||||
zh-cn
|
||||
@ -1,8 +1,6 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
#
|
||||
# Copyright (C) 2015 OpenWrt-dist
|
||||
# Copyright (C) 2016 fw867 <ffkykzs@gmail.com>
|
||||
# Copyright (C) 2024 iv7777 <hongba@rocketmail.com>
|
||||
# Copyright (C) 2025 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
@ -13,75 +11,54 @@ CONFIG=timewol
|
||||
CRONTAB_FILE="/etc/crontabs/root"
|
||||
ETHERWAKE_CMD="/usr/bin/etherwake"
|
||||
|
||||
# Function to get UCI configuration values with defaults
|
||||
uci_get_by_type() {
|
||||
local type=$1
|
||||
local option=$2
|
||||
local default=$3
|
||||
local index=${4:-0} # Use 0 if $4 is not provided
|
||||
|
||||
local value
|
||||
value=$(uci get "$CONFIG.@$type[$index].$option" 2>/dev/null) || value=$default
|
||||
echo "$value"
|
||||
config_n_get() {
|
||||
local ret=$(uci -q get "${CONFIG}.${1}.${2}" 2>/dev/null)
|
||||
echo "${ret:=$3}"
|
||||
}
|
||||
|
||||
# Function to check if a value represents a true boolean
|
||||
is_true() {
|
||||
case "$1" in
|
||||
1|on|true|yes|enabled) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
case "$1" in
|
||||
1|on|true|yes|enabled) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Function to load configuration and check if enabled
|
||||
load_config() {
|
||||
local enabled
|
||||
enabled=$(uci_get_by_type basic enable "0")
|
||||
is_true "$enabled"
|
||||
local enabled=$(config_n_get @basic[0] enable 0)
|
||||
is_true "$enabled"
|
||||
}
|
||||
|
||||
# Function to add WoL rules to the crontab
|
||||
add_rule() {
|
||||
# Remove existing etherwake entries
|
||||
sed -i '/etherwake/d' "$CRONTAB_FILE"
|
||||
sed -i '/etherwake/d' "$CRONTAB_FILE"
|
||||
|
||||
for i in $(seq 0 100); do
|
||||
local macaddr
|
||||
local maceth
|
||||
local minute
|
||||
local hour
|
||||
local day
|
||||
local month
|
||||
local weeks
|
||||
|
||||
macaddr=$(uci_get_by_type macclient macaddr "" "$i")
|
||||
maceth=$(uci_get_by_type macclient maceth "" "$i")
|
||||
|
||||
# Stop if no more macaddr entries
|
||||
[ -z "$macaddr" ] && break
|
||||
[ -z "$maceth" ] && break
|
||||
|
||||
minute=$(uci_get_by_type macclient minute "0" "$i")
|
||||
hour=$(uci_get_by_type macclient hour "*" "$i")
|
||||
day=$(uci_get_by_type macclient day "*" "$i")
|
||||
month=$(uci_get_by_type macclient month "*" "$i")
|
||||
weeks=$(uci_get_by_type macclient weeks "*" "$i")
|
||||
|
||||
echo "$minute $hour $day $month $weeks $ETHERWAKE_CMD -D -i $maceth $macaddr" >> "$CRONTAB_FILE"
|
||||
done
|
||||
local ids=$(uci show $CONFIG | grep "=macclient" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
|
||||
[ -n "$ids" ] && {
|
||||
for id in $ids; do
|
||||
local enabled=$(config_n_get $id enable 0)
|
||||
local macaddr=$(config_n_get $id macaddr)
|
||||
local maceth=$(config_n_get $id maceth)
|
||||
[ $enabled -eq 1 ] && [ -n "$macaddr" ] && [ -n "$maceth" ] && {
|
||||
local minute=$(config_n_get $id minute "0")
|
||||
local hour=$(config_n_get $id hour "*")
|
||||
local day=$(config_n_get $id day "*")
|
||||
local month=$(config_n_get $id month "*")
|
||||
local weeks=$(config_n_get $id weeks "*")
|
||||
echo "$minute $hour $day $month $weeks $ETHERWAKE_CMD -D -i $maceth $macaddr" >> "$CRONTAB_FILE"
|
||||
}
|
||||
done
|
||||
}
|
||||
}
|
||||
|
||||
# Function to start the service
|
||||
start() {
|
||||
if load_config; then
|
||||
add_rule
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
if load_config; then
|
||||
add_rule
|
||||
/etc/init.d/cron restart
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to stop the service
|
||||
stop() {
|
||||
# Remove etherwake entries from crontab
|
||||
sed -i '/etherwake/d' "$CRONTAB_FILE"
|
||||
sed -i '/etherwake/d' "$CRONTAB_FILE"
|
||||
/etc/init.d/cron restart
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user