From c9202aeedf3c9da5bfc9ac8165984e9849cb4d22 Mon Sep 17 00:00:00 2001 From: Vadim Vetrov Date: Sat, 21 Dec 2024 02:56:11 +0300 Subject: [PATCH] Remaster luci-app-youtubeUnblock from deprecated lua scripts to client-side JS --- luci-app-youtubeUnblock/Makefile | 2 +- .../resources/view/youtubeUnblock/status.js | 239 ++++++++++++++++++ .../luasrc/controller/youtubeUnblock.lua | 5 - .../luasrc/model/cbi/youtubeUnblock.lua | 105 -------- .../luci/menu.d/luci-app-youtubeUnblock.json | 28 ++ .../rpcd/acl.d/luci-app-youtubeUnblock.json | 25 ++ 6 files changed, 293 insertions(+), 111 deletions(-) create mode 100644 luci-app-youtubeUnblock/htdocs/luci-static/resources/view/youtubeUnblock/status.js delete mode 100644 luci-app-youtubeUnblock/luasrc/controller/youtubeUnblock.lua delete mode 100644 luci-app-youtubeUnblock/luasrc/model/cbi/youtubeUnblock.lua create mode 100644 luci-app-youtubeUnblock/root/usr/share/luci/menu.d/luci-app-youtubeUnblock.json create mode 100644 luci-app-youtubeUnblock/root/usr/share/rpcd/acl.d/luci-app-youtubeUnblock.json diff --git a/luci-app-youtubeUnblock/Makefile b/luci-app-youtubeUnblock/Makefile index daa18af..d0f16e0 100644 --- a/luci-app-youtubeUnblock/Makefile +++ b/luci-app-youtubeUnblock/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=LuCI Support for youtubeUnblock -LUCI_DEPENDS:=+luci-base +luci-compat +LUCI_DEPENDS:=+luci-base PKG_LICENSE:=GPL PKG_MAINTAINER:=Vadim Vetrov diff --git a/luci-app-youtubeUnblock/htdocs/luci-static/resources/view/youtubeUnblock/status.js b/luci-app-youtubeUnblock/htdocs/luci-static/resources/view/youtubeUnblock/status.js new file mode 100644 index 0000000..01de834 --- /dev/null +++ b/luci-app-youtubeUnblock/htdocs/luci-static/resources/view/youtubeUnblock/status.js @@ -0,0 +1,239 @@ +'use strict'; +'require view'; +'require poll'; +'require fs'; +'require ui'; +'require uci'; +'require form'; +'require tools.widgets as widgets'; +'require tools.views as views'; + +/** + * Big thanks to luci-app-adblock for the best reference implementation + */ + + +/* + button handling +*/ +function handleAction(act, event) { + if (event.target.classList.contains('disabled') || event.target.classList.contains('cbi-button-inactive')) + return; + + function roll_inact(target) { + target.classList.add('spinning'); + target.classList.add('disabled'); + } + function unroll_inact(target) { + target.classList.remove('spinning'); + target.classList.remove('disabled'); + } + function thn_disp() { + unroll_inact(event.target); + } + function thn_inc() { + roll_inact(event.target); + } + + roll_inact(event.target); + if (act == "restart") { + fs.exec_direct('/etc/init.d/youtubeUnblock', [ 'restart' ]).then(thn_disp); + } else if (act == "fw_reload") { + fs.exec_direct('/etc/init.d/firewall', [ 'reload' ]).then(thn_disp); + } else if (act == "status") { + if (event.target.classList.contains('cbi-button-positive')) { + fs.exec_direct('/etc/init.d/youtubeUnblock', [ 'start' ]).then(thn_inc); + } else { + fs.exec_direct('/etc/init.d/youtubeUnblock', [ 'stop' ]).then(thn_inc); + } + } else if (act == "autostart") { + if (event.target.classList.contains('cbi-button-positive')) { + fs.exec_direct('/etc/init.d/youtubeUnblock', [ 'enable' ]).then(thn_inc); + } else { + fs.exec_direct('/etc/init.d/youtubeUnblock', [ 'disable' ]).then(thn_inc); + } + } else { + unroll_inact(event.target); + } + +} + +return view.extend({ + load: function() { + return Promise.all([ + uci.load('youtubeUnblock'), + ]); + }, + + render: function(result) { + let m, s, o; +"youtubeUnblock", "youtubeUnblock", "Bypasses Deep Packet Inspection (DPI) systems that rely on SNI" + m = new form.Map('youtubeUnblock', 'youtubeUnblock', _("Bypasses Deep Packet Inspection (DPI) systems that rely on SNI.
Check the README for more details https://github.com/Waujito/youtubeUnblock")); + + /* + poll runtime information + */ + pollData: poll.add(function() { + fs.exec_direct('/etc/init.d/youtubeUnblock', ['status']) + .then(function(res) { + const status = document.getElementById('ytb_status'); + const btn_status = document.getElementById('btn_status'); + if (status == null || btn_status == null) { + return; + } + + status.classList.remove("spinning"); + res = res.trim(); + status.textContent = res; + + if (res != "inactive" && res != "running") { + return; + } + + btn_status.classList.remove("spinning"); + btn_status.classList.remove("cbi-button-inactive"); + btn_status.classList.remove("cbi-button-negative"); + btn_status.classList.remove("cbi-button-positive"); + btn_status.classList.remove("disabled"); + + + if (res == "running") { + btn_status.textContent = "Stop"; + btn_status.classList.add("cbi-button-negative"); + } else { + btn_status.textContent = "Start"; + btn_status.classList.add("cbi-button-positive"); + } + }); + + fs.exec_direct('/usr/bin/youtubeUnblock', ['--version']) + .then(function(res) { + const elversion = document.getElementById('ytb_version'); + if (elversion == null) { + return; + } + + elversion.classList.remove("spinning"); + + elversion.textContent = res; + }); + + fs.exec('/etc/init.d/youtubeUnblock', ['enabled']) + .then(function(res) { + const autostart = document.getElementById('ytb_autostart'); + const btn_autostart = document.getElementById('btn_autostart'); + if (autostart == null || btn_autostart == null) { + return; + } + + autostart.classList.remove("spinning"); + + btn_autostart.classList.remove("spinning"); + btn_autostart.classList.remove("cbi-button-inactive"); + btn_autostart.classList.remove("cbi-button-negative"); + btn_autostart.classList.remove("cbi-button-positive"); + btn_autostart.classList.remove("disabled"); + + if (res.code == 0) { + autostart.textContent = "enabled"; + btn_autostart.textContent = "Disable"; + btn_autostart.classList.add("cbi-button-negative"); + } else { + autostart.textContent = "disabled"; + btn_autostart.textContent = "Enable"; + btn_autostart.classList.add("cbi-button-positive"); + } + }); + + fs.exec_direct("/sbin/logread", ['-e', "youtubeUnblock", '-l', 200]).then(function(res) { + const log = document.getElementById("ytb_logger"); + if (log == null) + return; + + if (res) { + log.value = res.trim(); + } else { + log.value = _('No related logs yet!'); + } + log.scrollTop = log.scrollHeight; + }); + + }, 1); + + /* + runtime information and buttons + */ + s = m.section(form.NamedSection, 'global'); + s.render = L.bind(function(view, section_id) { + return E('div', { 'class': 'cbi-section' }, [ + E('h3', _('Information')), + E('div', { 'class': 'cbi-value' }, [ + E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Version')), + E('div', { 'class': 'cbi-value-field spinning', 'id': 'ytb_version', 'style': 'color:#37c' },'\xa0') + ]), + E('div', { 'class': 'cbi-value' }, [ + E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Status')), + E('div', { 'class': 'cbi-value-field spinning', 'id': 'ytb_status', 'style': 'color:#37c' },'\xa0') + ]), + E('div', { 'class': 'cbi-value' }, [ + E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Autostart')), + E('div', { 'class': 'cbi-value-field spinning', 'id': 'ytb_autostart', 'style': 'color:#37c' },'\xa0') + ]), + E('div', { class: 'right' }, [ + E('button', { + 'class': 'btn cbi-button cbi-button-inactive disabled spinning', + 'id': 'btn_autostart', + 'click': ui.createHandlerFn(this, function(event) { + return handleAction('autostart', event); + }) + }, [ _('Autostart') ]), + '\xa0\xa0\xa0', + E('button', { + 'class': 'btn cbi-button cbi-button-inactive disabled spinning', + 'id': 'btn_status', + 'click': ui.createHandlerFn(this, function(event) { + return handleAction('status', event); + }) + }, [ _('Status') ]), + '\xa0\xa0\xa0', + E('button', { + 'class': 'btn cbi-button cbi-button-apply', + 'click': ui.createHandlerFn(this, function(event) { + return handleAction('restart', event); + }) + }, [ _('Restart') ]), + '\xa0\xa0\xa0', + E('button', { + 'class': 'btn cbi-button cbi-button-apply', + 'id': 'btn_fw_reload', + 'click': ui.createHandlerFn(this, function(event) { + return handleAction('fw_reload', event); + }) + }, [ _('Firewall reload') ]), + ]) + ]); + }, o, this); + + const logs_s = m.section(form.NamedSection, 'ytb_logs'); + logs_s.render = L.bind(function(view, section_id) { + return E('div', { class: 'cbi-map' }, + E('div', { class: 'cbi-section' }, [ + E('div', { class: 'cbi-section-descr' }, _('The syslog output, pre-filtered for messages related to: youtubeUnblock')), + E('textarea', { + 'id': 'ytb_logger', + 'style': 'width: 100% !important; padding: 5px; font-family: monospace', + 'readonly': 'readonly', + 'wrap': 'off', + 'rows': 25 + }) + ])); + }); + this.pollData; + + return m.render(); + }, + handleReset: null, + handleSaveApply: null, + handleSave: null, +}); + diff --git a/luci-app-youtubeUnblock/luasrc/controller/youtubeUnblock.lua b/luci-app-youtubeUnblock/luasrc/controller/youtubeUnblock.lua deleted file mode 100644 index cab80c5..0000000 --- a/luci-app-youtubeUnblock/luasrc/controller/youtubeUnblock.lua +++ /dev/null @@ -1,5 +0,0 @@ -module("luci.controller.youtubeUnblock", package.seeall) - -function index() - entry( {"admin", "services", "youtubeUnblock"}, cbi("youtubeUnblock"), _("youtubeUnblock")) -end diff --git a/luci-app-youtubeUnblock/luasrc/model/cbi/youtubeUnblock.lua b/luci-app-youtubeUnblock/luasrc/model/cbi/youtubeUnblock.lua deleted file mode 100644 index a8fc410..0000000 --- a/luci-app-youtubeUnblock/luasrc/model/cbi/youtubeUnblock.lua +++ /dev/null @@ -1,105 +0,0 @@ -local sys = require "luci.sys" -local redirect_path = luci.dispatcher.build_url( - "admin", "services", "youtubeUnblock" -) - --- local uci = require "luci.model.uci".cursor() -local m = Map("youtubeUnblock", "youtubeUnblock", "Bypasses Deep Packet Inspection (DPI) systems that rely on SNI") -local s = m:section(NamedSection, "youtubeUnblock", "youtubeUnblock", "youtubeUnblock", "Config. Check the README for more details https://github.com/Waujito/youtubeUnblock") - -local o = s:option(TextValue, "args", "args", "Pass your list of arguments here.") - -s = m:section(NamedSection, "youtubeUnblock", "youtubeUnblock", "Service status") - -o = s:option(Button, "_autostart", "Autostart") -o._state = false -function o.cbid(self, section) - local service_enabled = sys.call("/etc/init.d/youtubeUnblock enabled &>/dev/null") - self._state = tonumber(service_enabled) == 1 - self.option = self._state and "disabled" or "enabled" - return AbstractValue.cbid(self, section) -end -function o.cfgvalue(self, section) - self.title = self._state and "Enable" or "Disable" - self.inputstyle = self._state and "positive" or "negative" - self.description = "youtubeUnblock is currently " .. self.option -end -function o.write(self, section) - if self._state then - sys.call("/etc/init.d/youtubeUnblock enable &>/dev/null") - else - sys.call("/etc/init.d/youtubeUnblock disable &>/dev/null") - end - luci.http.redirect(redirect_path) -end - -o = s:option(Button, "_status", "Autostart") -o._state = false -function o.cbid(self, section) - local service_running = sys.call("/etc/init.d/youtubeUnblock running &>/dev/null") - self._state = tonumber(service_running) == 1 - self.option = self._state and "down" or "active" - return AbstractValue.cbid(self, section) -end -function o.cfgvalue(self, section) - self.title = self._state and "Start" or "Stop" - self.inputstyle = self._state and "positive" or "negative" - self.description = "youtubeUnblock is currently " .. self.option -end -function o.write(self, section) - if self._state then - sys.call("/etc/init.d/youtubeUnblock start &>/dev/null") - else - sys.call("/etc/init.d/youtubeUnblock stop &>/dev/null") - end - luci.http.redirect(redirect_path) -end - -local o = s:option(Button, "_restart", "Restart") -o.inputstyle = "action" -function o.write(self, section) - sys.call("/etc/init.d/youtubeUnblock restart &>/dev/null") - luci.http.redirect(redirect_path) -end - -local o = s:option(Button, "_firewall", "Firewall") -o.inputtitle = "Reload" -o.inputstyle = "action" -function o.write(self, section) - sys.call("/etc/init.d/firewall reload") - luci.http.redirect(redirect_path) -end - -local o = s:option(Button, "_reset_settings", "Reset settings to defaults") -o.inputtitle = "Reset" -o.inputstyle = "negative" -function o.write(self, section) - sys.call("/usr/share/youtubeUnblock/youtubeUnblock_defaults.sh --force") - luci.http.redirect(redirect_path) -end - -s = m:section(NamedSection, "youtubeUnblock", "youtubeUnblock", "Service logs") - -local o = s:option(Button, "_reload_logs", "Reload") -o.inputstyle = "reload" -o.inputtitle = "Reload logs" -o.redirect = redirect_path .. "#" .. AbstractValue.cbid(o, "youtubeUnblock") -function o.write(self, section) - luci.http.redirect(self.redirect) -end - -local logs_opt = s:option(DummyValue, "_logs", "Logs") -logs_opt.rawhtml = true -logs_opt.wrap = "off" -logs_opt.rows = 33 -logs_opt.readonly = true -logs_opt.template = "cbi/tvalue" -logs_opt.width = "100%" - -function logs_opt.cbid(self, section) - local logs = sys.exec("logread -l 800 -p youtubeUnblock | grep youtubeUnblock | sed '1!G;h;$!d'") - self.value = logs - return AbstractValue.cbid(self, section) -end - -return m diff --git a/luci-app-youtubeUnblock/root/usr/share/luci/menu.d/luci-app-youtubeUnblock.json b/luci-app-youtubeUnblock/root/usr/share/luci/menu.d/luci-app-youtubeUnblock.json new file mode 100644 index 0000000..623698b --- /dev/null +++ b/luci-app-youtubeUnblock/root/usr/share/luci/menu.d/luci-app-youtubeUnblock.json @@ -0,0 +1,28 @@ +{ + "admin/services/youtubeUnblock": { + "title": "youtubeUnblock", + "order": 60, + "action": { + "type": "alias", + "path": "admin/services/youtubeUnblock/status" + }, + "depends": { + "acl": [ "luci-app-youtubeUnblock" ], + "fs": { + "/usr/bin/youtubeUnblock": "executable", + "/etc/init.d/youtubeUnblock": "executable" + }, + "uci": { "youtubeUnblock": true } + } + + }, + + "admin/services/youtubeUnblock/status": { + "title": "Service Status", + "order": 10, + "action": { + "type": "view", + "path": "youtubeUnblock/status" + } + } +} diff --git a/luci-app-youtubeUnblock/root/usr/share/rpcd/acl.d/luci-app-youtubeUnblock.json b/luci-app-youtubeUnblock/root/usr/share/rpcd/acl.d/luci-app-youtubeUnblock.json new file mode 100644 index 0000000..dd52c9c --- /dev/null +++ b/luci-app-youtubeUnblock/root/usr/share/rpcd/acl.d/luci-app-youtubeUnblock.json @@ -0,0 +1,25 @@ +{ + "luci-app-youtubeUnblock": { + "description": "Grant UCI access for luci-app-youtubeUnblock", + "read": { + "cgi-io": [ "exec" ], + "file": { + "/etc/init.d/youtubeUnblock status" : [ "exec" ], + "/etc/init.d/youtubeUnblock enabled" : [ "exec" ], + "/etc/init.d/youtubeUnblock start" : [ "exec" ], + "/etc/init.d/youtubeUnblock stop" : [ "exec" ], + "/etc/init.d/youtubeUnblock restart" : [ "exec" ], + "/etc/init.d/youtubeUnblock enable" : [ "exec" ], + "/etc/init.d/youtubeUnblock disable" : [ "exec" ], + "/etc/init.d/firewall reload" : [ "exec" ], + "/usr/bin/youtubeUnblock --version" : [ "exec" ], + "/sbin/logread -e youtubeUnblock -l [0-9]*": [ "exec" ], + "/usr/sbin/logread -e youtubeUnblock -l [0-9]*": [ "exec" ] + }, + "uci": [ "youtubeUnblock" ] + }, + "write": { + "uci": [ "youtubeUnblock" ] + } + } +}