From 9ddbc1155566a3d0ebc4aef5a2b46b89b075b14e Mon Sep 17 00:00:00 2001 From: Ramon Van Gorkom Date: Thu, 31 Oct 2024 21:38:11 +0100 Subject: [PATCH] luci-app-wifischedule: Convert to JS luci-app-wifischedule: Convert to JS Signed-off-by: Ramon Van Gorkom --- .../view/wifischedule/wifischedule.js | 175 ++++++++++++ .../controller/wifischedule/wifi_schedule.lua | 30 --- .../model/cbi/wifischedule/wifi_schedule.lua | 252 ------------------ .../luci/menu.d/luci-app-wifischedule.json | 9 + .../rpcd/acl.d/luci-app-wifischedule.json | 7 +- 5 files changed, 190 insertions(+), 283 deletions(-) create mode 100644 applications/luci-app-wifischedule/htdocs/luci-static/resources/view/wifischedule/wifischedule.js delete mode 100644 applications/luci-app-wifischedule/luasrc/controller/wifischedule/wifi_schedule.lua delete mode 100644 applications/luci-app-wifischedule/luasrc/model/cbi/wifischedule/wifi_schedule.lua create mode 100644 applications/luci-app-wifischedule/root/usr/share/luci/menu.d/luci-app-wifischedule.json diff --git a/applications/luci-app-wifischedule/htdocs/luci-static/resources/view/wifischedule/wifischedule.js b/applications/luci-app-wifischedule/htdocs/luci-static/resources/view/wifischedule/wifischedule.js new file mode 100644 index 000000000000..4d876c55028f --- /dev/null +++ b/applications/luci-app-wifischedule/htdocs/luci-static/resources/view/wifischedule/wifischedule.js @@ -0,0 +1,175 @@ +// Copyright (c) 2016, prpl Foundation +// +// Permission to use, copy, modify, and/or distribute this software for any purpose with or without +// fee is hereby granted, provided that the above copyright notice and this permission notice appear +// in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE +// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE +// FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +// Author: Nils Koenig +// JS version: Ramon van Gorkom + + +'use strict'; +'require view'; +'require form'; +'require fs'; +'require uci'; + +function timeValidator(value, desc) { + if (value !== null) { + const matches = value.match(/^(\d\d?):(\d\d?)$/); + if (matches) { + const h = parseInt(matches[1], 10); + const m = parseInt(matches[2], 10); + if (h >= 0 && h <= 23 && m >= 0 && m <= 59) { + return true; + } + } + } + return _('The value %s is invalid'.format(desc)); +} + +return view.extend({ + load: function() { + return Promise.all([ + L.resolveDefault(fs.stat('/sbin/wifi'), null), + L.resolveDefault(fs.stat('/usr/bin/wifi_schedule.sh'), null), + L.resolveDefault(fs.exec_direct('/usr/bin/wifi_schedule.sh', [ 'getmodules' ]), null), + L.resolveDefault(fs.stat('/usr/bin/iwinfo'), null) + ]); + }, + + + render: function (data) { + var m, s, o, oUnloadmodules, oModules; + + m = new form.Map('wifi_schedule', _('Wifi Schedule'),_('Defines a schedule when to turn on and off wifi.')); + + s = m.section(form.TypedSection, 'global', _('Manual control')); + s.optional = false; + s.rmempty = false; + s.anonymous = true; + + o = s.option(form.Button, '', _('Activate wifi')); + o.onclick = function (section, value) { + fs.exec('/usr/bin/wifi_schedule.sh', ['start', 'manual']); + } + + o = s.option(form.Button, '', _('Disable wifi gracefully')); + o.onclick = function (section, value) { + fs.exec('/usr/bin/wifi_schedule.sh', ['stop', 'manual']); + } + + o = s.option(form.Button, '', _('Disable wifi forced')); + o.onclick = function (section, value) { + fs.exec('/usr/bin/wifi_schedule.sh', ['forcestop', 'manual']); + } + + s = m.section(form.TypedSection, 'global', _('Global Settings')); + s.optional = false; + s.rmempty = false; + s.anonymous = true; + + o = s.option(form.Flag, 'enabled', _('Enable Wifi Schedule')); + o.optional = false; + o.rmempty = false; + o.validate = function(section_id, value) { + return value !== '1' || (data[0] && data[1]) ? true : _('Could not find required /usr/bin/wifi_schedule.sh or /sbin/wifi'); + }; + + + o = s.option(form.Flag, 'logging', _('Enable logging')); + o.optional = false; + o.rmempty = false; + o.default = 0; + + o = s.option(form.Flag, 'unload_modules', _('Unload Modules (experimental; saves more power)')); + o.optional = false; + o.rmempty = false; + o.default = 0; + + o = s.option(form.TextValue, 'modules', 'Modules to unload') + o.depends('unload_modules', '1'); + o.wrap = 'off'; + o.rows = 10; + o.cfgvalue = function (section) { + let mod = uci.get('wifi_schedule', section, 'modules'); + if (!mod) mod = ""; + return mod.replace(/ /g, "\r\n"); + } + o.write = function (section, value) { + var valueList = value.replace(/[\r\n]+/g, " ").replace(/\s+$/, ''); + return uci.set('wifi_schedule', section, 'modules', valueList); + } + + o = s.option(form.DummyValue, 'detectedmodules', _('Modules detected')); + o.depends('unload_modules', '1'); + o.default = data[2]; + + s = m.section(form.TypedSection, 'entry', _('Schedule events')); + s.addremove = true; + + o = s.option(form.Flag, 'enabled', _('Enable mode')); + o.rmempty = false; + o.optional = false; + + o = s.option(form.MultiValue, 'daysofweek', _('Day(s) of Week')); + o.rmempty = false; + o.optional = false; + o.modalonly = true; + o.multiple = true; + o.size = 7; + o.value('Monday',_('Monday')); + o.value('Tuesday',_('Tuesday')); + o.value('Wednesday',_('Wednesday')); + o.value('Thursday',_('Thursday')); + o.value('Friday',_('Friday')); + o.value('Saturday',_('Saturday')); + o.value('Sunday',_('Sunday')); + o.write = function(section_id, value) { + return this.super('write', [ section_id, L.toArray(value).join(' ') ]); + }; + + o = s.option (form.Value, 'starttime', _('Start WiFi')); + o.rmempty = false; + o.optional = false; + for (let hour = 0; hour <= 23; hour++) { + o.value(`${hour.toString().padStart(2, '0')}:00`); + } + o.validate = function(section_id, value) { + return timeValidator(value, _('Start Time')) + }; + + o = s.option (form.Value, 'stoptime', _('Stop WiFi')); + o.rmempty = false; + o.optional = false; + for (let hour = 0; hour <= 23; hour++) { + o.value(`${hour.toString().padStart(2, '0')}:00`); + } + o.validate = function(section_id, value) { + return timeValidator(value, _('Stop Time')) + }; + + o = s.option(form.Flag, 'forcewifidown', _('Force disabling wifi even if stations associated')); + o.default = false; + o.rmempty = false; + o.validate = function(section_id, value) { + return value !== '0' || data[3] ? true : _("Could not find required program /usr/bin/iwinfo"); + }; + + return m.render() + }, + handleSaveApply: function (ev, mode) { + var Fn = L.bind(function() { + fs.exec('/usr/bin/wifi_schedule.sh', ['cron']); + document.removeEventListener('uci-applied',Fn); + }); + document.addEventListener('uci-applied', Fn); + this.super('handleSaveApply', [ev, mode]); + }, +}); diff --git a/applications/luci-app-wifischedule/luasrc/controller/wifischedule/wifi_schedule.lua b/applications/luci-app-wifischedule/luasrc/controller/wifischedule/wifi_schedule.lua deleted file mode 100644 index 79a67253ac81..000000000000 --- a/applications/luci-app-wifischedule/luasrc/controller/wifischedule/wifi_schedule.lua +++ /dev/null @@ -1,30 +0,0 @@ --- Copyright (c) 2016, prpl Foundation --- --- Permission to use, copy, modify, and/or distribute this software for any purpose with or without --- fee is hereby granted, provided that the above copyright notice and this permission notice appear --- in all copies. --- --- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE --- INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE --- FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM --- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, --- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --- --- Author: Nils Koenig - -module("luci.controller.wifischedule.wifi_schedule", package.seeall) - -local fs = require "nixio.fs" -local sys = require "luci.sys" -local template = require "luci.template" -local i18n = require "luci.i18n" - -function index() - if not nixio.fs.access("/etc/config/wifi_schedule") then - return - end - - local e = entry({"admin", "services", "wifi_schedule"}, cbi("wifischedule/wifi_schedule"), _("Wifi Schedule"), 60) - e.acl_depends = { "luci-app-wifischedule" } - e.dependent = false -end diff --git a/applications/luci-app-wifischedule/luasrc/model/cbi/wifischedule/wifi_schedule.lua b/applications/luci-app-wifischedule/luasrc/model/cbi/wifischedule/wifi_schedule.lua deleted file mode 100644 index 164451416639..000000000000 --- a/applications/luci-app-wifischedule/luasrc/model/cbi/wifischedule/wifi_schedule.lua +++ /dev/null @@ -1,252 +0,0 @@ --- Copyright (c) 2016, prpl Foundation --- --- Permission to use, copy, modify, and/or distribute this software for any purpose with or without --- fee is hereby granted, provided that the above copyright notice and this permission notice appear --- in all copies. --- --- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE --- INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE --- FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM --- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, --- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --- --- Author: Nils Koenig - -local fs = require "nixio.fs" -local sys = require "luci.sys" -local uci = require("luci.model.uci").cursor() - -function time_validator(self, value, desc) - if value ~= nil then - h_str, m_str = string.match(value, "^(%d%d?):(%d%d?)$") - h = tonumber(h_str) - m = tonumber(m_str) - if ( h ~= nil and - h >= 0 and - h <= 23 and - m ~= nil and - m >= 0 and - m <= 59) then - return value - end - end - return nil, translatef("The value %s is invalid", desc) -end - --- ------------------------------------------------------------------------------------------------- - --- BEGIN Map -m = Map("wifi_schedule", translate("Wifi Schedule"), translate("Defines a schedule when to turn on and off wifi.")) -m.apply_on_parse = true - -function m.on_apply(self) - sys.exec("/usr/bin/wifi_schedule.sh cron") -end --- END Map - --- BEGIN Global Section -global_section = m:section(TypedSection, "global", translate("Global Settings")) -global_section.optional = false -global_section.rmempty = false -global_section.anonymous = true --- END Section - --- BEGIN Global Enable Checkbox -global_enable = global_section:option(Flag, "enabled", translate("Enable Wifi Schedule")) -global_enable.optional = false -global_enable.rmempty = false - -function global_enable.validate(self, value, global_section) - if value == "1" then - if ( fs.access("/sbin/wifi") and - fs.access("/usr/bin/wifi_schedule.sh") )then - return value - else - return nil, translate("Could not find required /usr/bin/wifi_schedule.sh or /sbin/wifi") - end - else - return "0" - end -end --- END Global Enable Checkbox - --- BEGIN Global Logging Checkbox -global_logging = global_section:option(Flag, "logging", translate("Enable logging")) -global_logging.optional = false -global_logging.rmempty = false -global_logging.default = 0 --- END Global Enable Checkbox - --- BEGIN Global Activate WiFi Button -enable_wifi = global_section:option(Button, "enable_wifi", translate("Activate wifi")) -function enable_wifi.write() - sys.exec("/usr/bin/wifi_schedule.sh start manual") -end --- END Global Activate Wifi Button - --- BEGIN Global Disable WiFi Gracefully Button -disable_wifi_gracefully = global_section:option(Button, "disable_wifi_gracefully", translate("Disable wifi gracefully")) -function disable_wifi_gracefully.write() - sys.exec("/usr/bin/wifi_schedule.sh stop manual") -end --- END Global Disable Wifi Gracefully Button - --- BEGIN Disable WiFi Forced Button -disable_wifi_forced = global_section:option(Button, "disable_wifi_forced", translate("Disabled wifi forced")) -function disable_wifi_forced.write() - sys.exec("/usr/bin/wifi_schedule.sh forcestop manual") -end --- END Global Disable WiFi Forced Button - --- BEGIN Global Unload Modules Checkbox -global_unload_modules = global_section:option(Flag, "unload_modules", translate("Unload Modules (experimental; saves more power)")) -global_unload_modules.optional = false -global_unload_modules.rmempty = false -global_unload_modules.default = 0 --- END Global Unload Modules Checkbox - - --- BEGIN Modules -modules = global_section:option(TextValue, "modules", "") -modules:depends("unload_modules", global_unload_modules.enabled); -modules.wrap = "off" -modules.rows = 10 - -function modules.cfgvalue(self, section) - mod = uci:get("wifi_schedule", section, "modules") - if mod == nil then - mod = "" - end - return mod:gsub(" ", "\r\n") -end - -function modules.write(self, section, value) - if value then - value_list = value:gsub("\r\n", " ") - ListValue.write(self, section, value_list) - uci:set("wifi_schedule", section, "modules", value_list) - end -end --- END Modules - --- BEGIN Determine Modules -determine_modules = global_section:option(Button, "determine_modules", translate("Determine Modules Automatically")) -determine_modules:depends("unload_modules", global_unload_modules.enabled); -function determine_modules.write(self, section) - output = sys.exec("/usr/bin/wifi_schedule.sh getmodules") - modules:write(section, output) -end --- END Determine Modules - --- BEGIN Section -d = m:section(TypedSection, "entry", translate("Schedule events")) -d.addremove = true ---d.anonymous = true --- END Section - --- BEGIN Enable Checkbox -c = d:option(Flag, "enabled", translate("Enable")) -c.optional = false -c.rmempty = false --- END Enable Checkbox - --- BEGIN Day(s) of Week -dow = d:option(MultiValue, "daysofweek", translate("Day(s) of Week")) -dow.optional = false -dow.rmempty = false -dow:value("Monday", translate("Monday")) -dow:value("Tuesday", translate("Tuesday")) -dow:value("Wednesday", translate("Wednesday")) -dow:value("Thursday", translate("Thursday")) -dow:value("Friday", translate("Friday")) -dow:value("Saturday", translate("Saturday")) -dow:value("Sunday", translate("Sunday")) --- END Day(s) of Weel - --- BEGIN Start Wifi Dropdown -starttime = d:option(Value, "starttime", translate("Start WiFi")) -starttime.optional = false -starttime.rmempty = false -starttime:value("00:00") -starttime:value("01:00") -starttime:value("02:00") -starttime:value("03:00") -starttime:value("04:00") -starttime:value("05:00") -starttime:value("06:00") -starttime:value("07:00") -starttime:value("08:00") -starttime:value("09:00") -starttime:value("10:00") -starttime:value("11:00") -starttime:value("12:00") -starttime:value("13:00") -starttime:value("14:00") -starttime:value("15:00") -starttime:value("16:00") -starttime:value("17:00") -starttime:value("18:00") -starttime:value("19:00") -starttime:value("20:00") -starttime:value("21:00") -starttime:value("22:00") -starttime:value("23:00") - -function starttime.validate(self, value, d) - return time_validator(self, value, translate("Start Time")) -end --- END Start Wifi Dropdown - --- BEGIN Stop Wifi Dropdown -stoptime = d:option(Value, "stoptime", translate("Stop WiFi")) -stoptime.optional = false -stoptime.rmempty = false -stoptime:value("00:00") -stoptime:value("01:00") -stoptime:value("02:00") -stoptime:value("03:00") -stoptime:value("04:00") -stoptime:value("05:00") -stoptime:value("06:00") -stoptime:value("07:00") -stoptime:value("08:00") -stoptime:value("09:00") -stoptime:value("10:00") -stoptime:value("11:00") -stoptime:value("12:00") -stoptime:value("13:00") -stoptime:value("14:00") -stoptime:value("15:00") -stoptime:value("16:00") -stoptime:value("17:00") -stoptime:value("18:00") -stoptime:value("19:00") -stoptime:value("20:00") -stoptime:value("21:00") -stoptime:value("22:00") -stoptime:value("23:00") - -function stoptime.validate(self, value, d) - return time_validator(self, value, translate("Stop Time")) -end --- END Stop Wifi Dropdown - --- BEGIN Force Wifi Stop Checkbox -force_wifi = d:option(Flag, "forcewifidown", translate("Force disabling wifi even if stations associated")) -force_wifi.default = false -force_wifi.rmempty = false - -function force_wifi.validate(self, value, d) - if value == "0" then - if fs.access("/usr/bin/iwinfo") then - return value - else - return nil, translate("Could not find required program /usr/bin/iwinfo") - end - else - return "1" - end -end --- END Force Wifi Checkbox - -return m diff --git a/applications/luci-app-wifischedule/root/usr/share/luci/menu.d/luci-app-wifischedule.json b/applications/luci-app-wifischedule/root/usr/share/luci/menu.d/luci-app-wifischedule.json new file mode 100644 index 000000000000..e88579e9f3c4 --- /dev/null +++ b/applications/luci-app-wifischedule/root/usr/share/luci/menu.d/luci-app-wifischedule.json @@ -0,0 +1,9 @@ +{ + "admin/services/wifischedule": { + "title": "wifischedule", + "action": { + "type": "view", + "path": "wifischedule/wifischedule" + } + } +} diff --git a/applications/luci-app-wifischedule/root/usr/share/rpcd/acl.d/luci-app-wifischedule.json b/applications/luci-app-wifischedule/root/usr/share/rpcd/acl.d/luci-app-wifischedule.json index df44e7c39ef2..dbef438e1b29 100644 --- a/applications/luci-app-wifischedule/root/usr/share/rpcd/acl.d/luci-app-wifischedule.json +++ b/applications/luci-app-wifischedule/root/usr/share/rpcd/acl.d/luci-app-wifischedule.json @@ -2,7 +2,12 @@ "luci-app-wifischedule": { "description": "Grant UCI access for luci-app-wifischedule", "read": { - "uci": [ "wifi_schedule" ] + "uci": [ "wifi_schedule" ], + "file": { + "/usr/bin/iwinfo": [ "read" ], + "/usr/bin/wifi_schedule.sh": ["exec", "read"], + "/sbin/wifi": ["read"] + } }, "write": { "uci": [ "wifi_schedule" ]