From 31d3f08f2539eee00659dc4d33c09647a277aa9e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer <mschiffer@universe-factory.net> Date: Wed, 8 Feb 2017 22:19:24 +0100 Subject: [PATCH] treewide: convert all LuCI-based packages to gluon-web --- Makefile | 2 +- docs/dev/configmode.rst | 68 +- docs/dev/i18n.rst | 73 +- docs/dev/upgrade.rst | 2 +- docs/features/private-wlan.rst | 2 +- docs/features/roles.rst | 6 +- docs/features/wired-mesh.rst | 2 +- docs/site-example/site.mk | 8 +- docs/user/site.rst | 8 +- .../gluon-config-mode-autoupdater/Makefile | 6 +- .../wizard/0050-autoupdater-info.lua | 25 +- .../config-mode/wizard/0500-contact-info.lua | 52 +- package/gluon-config-mode-core/Makefile | 4 +- .../web/view/gluon/config-mode/reboot.html | 22 + .../web/view/gluon/config-mode/welcome.html | 11 + .../lua/luci/view/gluon/cbi/config-mode.htm | 53 - .../luci/view/gluon/config-mode/reboot.htm | 17 - .../config-mode/reboot/0900-msg-reboot.lua | 20 +- .../controller/gluon-config-mode/index.lua | 2 + .../web/model/gluon-config-mode/wizard.lua | 64 + .../controller/gluon-config-mode/index.lua | 93 -- .../model/cbi/gluon-config-mode/wizard.lua | 42 - .../config-mode/wizard/0400-geo-location.lua | 115 +- .../config-mode/wizard/0100-hostname.lua | 25 +- .../config-mode/reboot/0100-mesh-vpn.lua | 43 +- .../config-mode/wizard/0300-mesh-vpn.lua | 109 +- .../lua/luci/view/admin/upgrade_reboot.htm | 20 - .../lib/lua/luci/controller/admin/index.lua | 39 - .../lib/lua/luci/controller/admin/upgrade.lua | 139 --- .../lib/lua/luci/model/cbi/admin/remote.lua | 87 -- .../lua/luci/controller/admin/autoupdater.lua | 19 - .../view/gluon/cbi/mesh-vpn-fastd-mode.htm | 32 - .../luci/controller/admin/mesh_vpn_fastd.lua | 5 - .../luci/model/cbi/admin/mesh_vpn_fastd.lua | 40 - .../lua/luci/controller/admin/noderole.lua | 5 - .../lib/lua/luci/model/cbi/admin/noderole.lua | 33 - .../lua/luci/controller/admin/portconfig.lua | 19 - .../lua/luci/model/cbi/admin/portconfig.lua | 167 --- .../lua/luci/controller/admin/privatewifi.lua | 5 - .../lua/luci/model/cbi/admin/privatewifi.lua | 67 -- .../files/etc/uci-defaults/luci-theme-gluon | 6 - .../lib/lua/luci/view/themes/gluon/footer.htm | 19 - .../lib/lua/luci/view/themes/gluon/header.htm | 171 --- .../files/www/luci-static/gluon/cascade.css | 2 - .../luasrc/usr/lib/lua/gluon/luci.lua | 28 - package/gluon-luci-theme/sass/cascade.scss | 1029 ----------------- .../lua/luci/controller/admin/wifi-config.lua | 5 - .../lua/luci/model/cbi/admin/wifi-config.lua | 169 --- package/gluon-setup-mode/Makefile | 2 +- .../gluon/setup-mode/rc.d/S15gluon-setup-mode | 4 +- .../files/lib/gluon/setup-mode/rc.d/S50uhttpd | 2 +- .../files/lib/gluon/setup-mode/www/index.html | 10 - .../lib/gluon/setup-mode/www/luci-static | 1 - .../lib/gluon/setup-mode/www/cgi-bin/luci | 5 - .../Makefile | 14 +- .../files/lib/gluon/web/view/admin/info.html} | 25 +- .../lib/gluon/web/view/admin/upgrade.html} | 29 +- .../web/view/admin/upgrade_confirm.html} | 19 +- .../gluon/web/view/admin/upgrade_reboot.html | 5 + .../i18n/de.po | 30 +- .../i18n/fr.po | 30 +- .../i18n/gluon-web-admin.pot} | 30 +- .../lib/gluon/web/controller/admin/index.lua | 9 + .../gluon/web/controller/admin/upgrade.lua | 139 +++ .../lib/gluon/web/model/admin/remote.lua | 109 ++ .../Makefile | 16 +- .../i18n/de.po | 5 +- .../i18n/fr.po | 5 +- .../i18n/gluon-web-autoupdater.pot} | 3 + .../web/controller/admin/autoupdater.lua | 1 + .../gluon/web/model}/admin/autoupdater.lua | 27 +- .../Makefile | 14 +- .../check_site.lua | 0 .../web/view/gluon/model/mesh-vpn-fastd.html | 32 + .../i18n/de.po | 4 +- .../i18n/fr.po | 0 .../i18n/gluon-web-mesh-vpn-fastd.pot} | 0 .../web/controller/admin/mesh_vpn_fastd.lua | 1 + .../gluon/web/model/admin/mesh_vpn_fastd.lua | 38 + .../Makefile | 16 +- .../i18n/de.po | 21 + .../i18n/fr.po | 21 + .../i18n/gluon-web-network.pot} | 21 + .../gluon/web/controller/admin/network.lua | 1 + .../lib/gluon/web/model/admin/network.lua | 143 +++ .../Makefile | 16 +- .../check_site.lua | 0 .../i18n/de.po | 0 .../i18n/fr.po | 0 .../i18n/gluon-web-node-role.pot} | 0 .../gluon/web/controller/admin/noderole.lua | 1 + .../lib/gluon/web/model/admin/noderole.lua | 28 + .../Makefile | 14 +- .../i18n/de.po | 6 + .../i18n/fr.po | 6 + .../i18n/gluon-web-private-wifi.pot} | 6 + .../web/controller/admin/privatewifi.lua | 1 + .../lib/gluon/web/model/admin/privatewifi.lua | 54 + .../Makefile | 16 +- .../gluon/web/view/themes/gluon/layout.html | 122 ++ .../gluon/web/www/static/gluon/cascade.css | 1 + package/gluon-web-theme/sass/cascade.scss | 598 ++++++++++ .../Makefile | 14 +- .../i18n/de.po | 0 .../i18n/fr.po | 0 .../i18n/gluon-web-wifi-config.pot} | 0 .../web/controller/admin/wifi-config.lua | 1 + .../lib/gluon/web/model/admin/wifi-config.lua | 125 ++ package/gluon.mk | 12 +- targets/generic | 2 - 110 files changed, 2026 insertions(+), 2809 deletions(-) create mode 100644 package/gluon-config-mode-core/files/lib/gluon/web/view/gluon/config-mode/reboot.html create mode 100644 package/gluon-config-mode-core/files/lib/gluon/web/view/gluon/config-mode/welcome.html delete mode 100644 package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/cbi/config-mode.htm delete mode 100644 package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/config-mode/reboot.htm create mode 100644 package/gluon-config-mode-core/luasrc/lib/gluon/web/controller/gluon-config-mode/index.lua create mode 100644 package/gluon-config-mode-core/luasrc/lib/gluon/web/model/gluon-config-mode/wizard.lua delete mode 100644 package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/controller/gluon-config-mode/index.lua delete mode 100644 package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua delete mode 100644 package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_reboot.htm delete mode 100644 package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/index.lua delete mode 100644 package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/upgrade.lua delete mode 100644 package/gluon-luci-admin/luasrc/usr/lib/lua/luci/model/cbi/admin/remote.lua delete mode 100644 package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/controller/admin/autoupdater.lua delete mode 100644 package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm delete mode 100644 package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/controller/admin/mesh_vpn_fastd.lua delete mode 100644 package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua delete mode 100644 package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/controller/admin/noderole.lua delete mode 100644 package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/model/cbi/admin/noderole.lua delete mode 100644 package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/controller/admin/portconfig.lua delete mode 100644 package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/model/cbi/admin/portconfig.lua delete mode 100644 package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/controller/admin/privatewifi.lua delete mode 100644 package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua delete mode 100755 package/gluon-luci-theme/files/etc/uci-defaults/luci-theme-gluon delete mode 100644 package/gluon-luci-theme/files/usr/lib/lua/luci/view/themes/gluon/footer.htm delete mode 100644 package/gluon-luci-theme/files/usr/lib/lua/luci/view/themes/gluon/header.htm delete mode 100644 package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css delete mode 100644 package/gluon-luci-theme/luasrc/usr/lib/lua/gluon/luci.lua delete mode 100644 package/gluon-luci-theme/sass/cascade.scss delete mode 100644 package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/controller/admin/wifi-config.lua delete mode 100644 package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua delete mode 100644 package/gluon-setup-mode/files/lib/gluon/setup-mode/www/index.html delete mode 120000 package/gluon-setup-mode/files/lib/gluon/setup-mode/www/luci-static delete mode 100755 package/gluon-setup-mode/luasrc/lib/gluon/setup-mode/www/cgi-bin/luci rename package/{gluon-luci-admin => gluon-web-admin}/Makefile (67%) rename package/{gluon-luci-admin/files/usr/lib/lua/luci/view/admin/info.htm => gluon-web-admin/files/lib/gluon/web/view/admin/info.html} (58%) rename package/{gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade.htm => gluon-web-admin/files/lib/gluon/web/view/admin/upgrade.html} (55%) rename package/{gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_confirm.htm => gluon-web-admin/files/lib/gluon/web/view/admin/upgrade_confirm.html} (78%) create mode 100644 package/gluon-web-admin/files/lib/gluon/web/view/admin/upgrade_reboot.html rename package/{gluon-luci-admin => gluon-web-admin}/i18n/de.po (91%) rename package/{gluon-luci-admin => gluon-web-admin}/i18n/fr.po (92%) rename package/{gluon-luci-admin/i18n/gluon-luci-admin.pot => gluon-web-admin/i18n/gluon-web-admin.pot} (89%) create mode 100644 package/gluon-web-admin/luasrc/lib/gluon/web/controller/admin/index.lua create mode 100644 package/gluon-web-admin/luasrc/lib/gluon/web/controller/admin/upgrade.lua create mode 100644 package/gluon-web-admin/luasrc/lib/gluon/web/model/admin/remote.lua rename package/{gluon-luci-autoupdater => gluon-web-autoupdater}/Makefile (60%) rename package/{gluon-luci-autoupdater => gluon-web-autoupdater}/i18n/de.po (92%) rename package/{gluon-luci-autoupdater => gluon-web-autoupdater}/i18n/fr.po (93%) rename package/{gluon-luci-autoupdater/i18n/gluon-luci-autoupdater.pot => gluon-web-autoupdater/i18n/gluon-web-autoupdater.pot} (82%) create mode 100644 package/gluon-web-autoupdater/luasrc/lib/gluon/web/controller/admin/autoupdater.lua rename package/{gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/model/cbi => gluon-web-autoupdater/luasrc/lib/gluon/web/model}/admin/autoupdater.lua (58%) rename package/{gluon-luci-mesh-vpn-fastd => gluon-web-mesh-vpn-fastd}/Makefile (63%) rename package/{gluon-luci-mesh-vpn-fastd => gluon-web-mesh-vpn-fastd}/check_site.lua (100%) create mode 100644 package/gluon-web-mesh-vpn-fastd/files/lib/gluon/web/view/gluon/model/mesh-vpn-fastd.html rename package/{gluon-luci-mesh-vpn-fastd => gluon-web-mesh-vpn-fastd}/i18n/de.po (89%) rename package/{gluon-luci-mesh-vpn-fastd => gluon-web-mesh-vpn-fastd}/i18n/fr.po (100%) rename package/{gluon-luci-mesh-vpn-fastd/i18n/gluon-luci-mesh-vpn-fastd.pot => gluon-web-mesh-vpn-fastd/i18n/gluon-web-mesh-vpn-fastd.pot} (100%) create mode 100644 package/gluon-web-mesh-vpn-fastd/luasrc/lib/gluon/web/controller/admin/mesh_vpn_fastd.lua create mode 100644 package/gluon-web-mesh-vpn-fastd/luasrc/lib/gluon/web/model/admin/mesh_vpn_fastd.lua rename package/{gluon-luci-portconfig => gluon-web-network}/Makefile (59%) rename package/{gluon-luci-portconfig => gluon-web-network}/i18n/de.po (77%) rename package/{gluon-luci-portconfig => gluon-web-network}/i18n/fr.po (76%) rename package/{gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot => gluon-web-network/i18n/gluon-web-network.pot} (67%) create mode 100644 package/gluon-web-network/luasrc/lib/gluon/web/controller/admin/network.lua create mode 100644 package/gluon-web-network/luasrc/lib/gluon/web/model/admin/network.lua rename package/{gluon-luci-node-role => gluon-web-node-role}/Makefile (59%) rename package/{gluon-luci-node-role => gluon-web-node-role}/check_site.lua (100%) rename package/{gluon-luci-node-role => gluon-web-node-role}/i18n/de.po (100%) rename package/{gluon-luci-node-role => gluon-web-node-role}/i18n/fr.po (100%) rename package/{gluon-luci-node-role/i18n/gluon-luci-node-role.pot => gluon-web-node-role/i18n/gluon-web-node-role.pot} (100%) create mode 100644 package/gluon-web-node-role/luasrc/lib/gluon/web/controller/admin/noderole.lua create mode 100644 package/gluon-web-node-role/luasrc/lib/gluon/web/model/admin/noderole.lua rename package/{gluon-luci-private-wifi => gluon-web-private-wifi}/Makefile (60%) rename package/{gluon-luci-private-wifi => gluon-web-private-wifi}/i18n/de.po (94%) rename package/{gluon-luci-private-wifi => gluon-web-private-wifi}/i18n/fr.po (94%) rename package/{gluon-luci-private-wifi/i18n/gluon-luci-private-wifi.pot => gluon-web-private-wifi/i18n/gluon-web-private-wifi.pot} (90%) create mode 100644 package/gluon-web-private-wifi/luasrc/lib/gluon/web/controller/admin/privatewifi.lua create mode 100644 package/gluon-web-private-wifi/luasrc/lib/gluon/web/model/admin/privatewifi.lua rename package/{gluon-luci-theme => gluon-web-theme}/Makefile (57%) create mode 100644 package/gluon-web-theme/files/lib/gluon/web/view/themes/gluon/layout.html create mode 100644 package/gluon-web-theme/files/lib/gluon/web/www/static/gluon/cascade.css create mode 100644 package/gluon-web-theme/sass/cascade.scss rename package/{gluon-luci-wifi-config => gluon-web-wifi-config}/Makefile (58%) rename package/{gluon-luci-wifi-config => gluon-web-wifi-config}/i18n/de.po (100%) rename package/{gluon-luci-wifi-config => gluon-web-wifi-config}/i18n/fr.po (100%) rename package/{gluon-luci-wifi-config/i18n/gluon-luci-wifi-config.pot => gluon-web-wifi-config/i18n/gluon-web-wifi-config.pot} (100%) create mode 100644 package/gluon-web-wifi-config/luasrc/lib/gluon/web/controller/admin/wifi-config.lua create mode 100644 package/gluon-web-wifi-config/luasrc/lib/gluon/web/model/admin/wifi-config.lua diff --git a/Makefile b/Makefile index 0108e0a0c..af233eff2 100644 --- a/Makefile +++ b/Makefile @@ -99,7 +99,7 @@ config: FORCE && scripts/target_config.sh generic \ && GLUON_SITEDIR='$(GLUON_SITEDIR)' scripts/target_config.sh '$(GLUON_TARGET)' \ $(foreach pkg,$(GLUON_PACKAGES_YES),&& echo 'CONFIG_PACKAGE_$(pkg)=y') \ - $(foreach lang,$(GLUON_LANGS),&& echo 'CONFIG_LUCI_LANG_$(lang)=y') \ + $(foreach lang,$(GLUON_LANGS),&& echo 'CONFIG_GLUON_WEB_LANG_$(lang)=y') \ && echo 'CONFIG_GLUON_RELEASE="$(GLUON_RELEASE)"' \ && echo 'CONFIG_GLUON_SITEDIR="$(GLUON_SITEDIR)"' \ && echo 'CONFIG_GLUON_BRANCH="$(GLUON_BRANCH)"' \ diff --git a/docs/dev/configmode.rst b/docs/dev/configmode.rst index 9a174d4c4..9c0c24302 100644 --- a/docs/dev/configmode.rst +++ b/docs/dev/configmode.rst @@ -1,7 +1,8 @@ Config Mode =========== -As of 2014.4 `gluon-config-mode` consists of several modules. +The `Config Mode` consists of several modules that provide a range of different +condiguration options: gluon-config-mode-core This modules provides the core functionality for the config mode. @@ -22,20 +23,13 @@ gluon-config-mode-geo-location gluon-config-mode-contact-info Adds a field where the user can provide contact information. -In order to get a config mode close to the one found in 2014.3.x you may add -these modules to your `site.mk`: -gluon-config-mode-hostname, -gluon-config-mode-autoupdater, -gluon-config-mode-mesh-vpn, -gluon-config-mode-geo-location, -gluon-config-mode-contact-info -Writing Config Mode Modules +Writing Config Mode modules ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Config mode modules are located at `/lib/gluon/config-mode/wizard` and -`/lib/gluon/config-mode/reboot`. Modules are named like `0000-name.lua` and -are executed in lexical order. If you take the standard set of modules, the +Config mode modules are located at ``/lib/gluon/config-mode/wizard`` and +``/lib/gluon/config-mode/reboot``. Modules are named like ``0000-name.lua`` and +are executed in lexical order. In the standard package set, the order is, for wizard modules: - 0050-autoupdater-info @@ -44,49 +38,45 @@ order is, for wizard modules: - 0400-geo-location - 0500-contact-info -While for reboot modules it is: +The reboot module order is: - 0100-mesh-vpn - 0900-msg-reboot +All modules are run in the gluon-web model context and have access to the same +variables as "full" gluon-web modules. + Wizards ------- -Wizard modules return a UCI section. A simple module capable of changing the -hostname might look like this:: +Wizard modules must return a function that is provided with the wizard form and an +UCI cursor. The function can create configuration sections in the form: - local cbi = require "luci.cbi" - local uci = luci.model.uci.cursor() +.. code-block:: lua - local M = {} - - function M.section(form) - local s = form:section(cbi.SimpleSection, nil, nil) - local o = s:option(cbi.Value, "_hostname", "Hostname") - o.value = uci:get_first("system", "system", "hostname") - o.rmempty = false + return function(form, uci) + local s = form:section(Section) + local o = s:option(Value, "hostname", "Hostname") + o.default = uci:get_first("system", "system", "hostname") o.datatype = "hostname" - end - function M.handle(data) - uci:set("system", uci:get_first("system", "system"), "hostname", data._hostname) - uci:save("system") - uci:commit("system") + function o:write(data) + uci:set("system", uci:get_first("system", "system"), "hostname", data) + end + + return {'system'} end - return M +The function may return a table of UCI packages to commit after the individual +fields' `write` methods have been executed. This is done to avoid committing the +packages repeatedly when multiple wizard modules modify the same package. Reboot page ----------- -Reboot modules return a function that will be called when the page is to be -rendered or nil (i.e. the module is skipped):: +Reboot modules are simply executed when the reboot page is +rendered: - if no_hello_world_today then - return nil - else - return function () - luci.template.render_string("Hello World!") - end - end +.. code-block:: lua + renderer.render_string("Hello World!") diff --git a/docs/dev/i18n.rst b/docs/dev/i18n.rst index fb7710ca0..1aefb2436 100644 --- a/docs/dev/i18n.rst +++ b/docs/dev/i18n.rst @@ -10,53 +10,56 @@ General guidelines nice-to-have, but not required. If you don't know a language well, rather leave the translation blank, so it is obvious that there is no proper translation yet. * Existing expert mode packages should be made translatable as soon as possible. -* The "message IDs" (which are the arguments to the ``translate`` function) should be the +* The "message IDs" (which are the arguments to the *translate* function) should be the English texts. -i18n support in LuCI --------------------- +i18n support in Gluon +--------------------- -Internationalization support can be found in the ``luci.i18n`` package. -Strings are translated using the ``i18n.translate`` and ``i18n.translatef`` functions -(``translate`` for static strings, ``translatef`` for printf-like formatted string). +Internationalization support is available in all components (models, view and +contrllers) of *gluon-web*-based packages. Strings are translated using the *translate* +and *translatef* functions (*translate* for static strings, *translatef* +for printf-like formatted string); in views, the special tags ``<%:...%>`` can +be used to translate the contained string. -Example from the ``gluon-config-mode-geo-location`` package:: +Example from the *gluon-config-mode-geo-location* package: - local i18n = require "luci.i18n" - o = s:option(cbi.Flag, "_location", i18n.translate("Show node on the map")) +.. code-block:: lua + + local share_location = s:option(Flag, "location", translate("Show node on the map")) Adding translation templates to Gluon packages ---------------------------------------------- The i18n support is based on the standard gettext system. For each translatable package, -a translation template with extension ``.pot`` can be created using the ``i18n-scan.pl`` -script from the LuCI repository:: +a translation template with extension ``.pot`` can be created using the *i18n-scan.pl* +script in the ``contrib`` directory: + +.. code-block:: sh - cd package/gluon-config-mode-geo-location + cd package/gluon-web-mesh-vpn-fastd mkdir i18n cd i18n - ../../../packages/luci/build/i18n-scan.pl ../files > gluon-config-mode-geo-location.pot + ../../../contrib/i18n-scan.pl ../files ../luasrc > gluon-web-mesh-vpn-fastd.pot -The entries in the template can be reordered after the generation if desirable. Lots of standard -translations like "Cancel" are already available in the LuCI base translation file (see -``packages/luci/po/templates/base.pot``) and can be removed from the template. +The same command can be run again to update the template. -In addition, some additions to the Makefile must be made. Instead of OpenWrt's default ``package.mk``, -the Gluon version ``$(GLUONDIR)/include/package.mk`` must be used. The i18n files must be installed +In addition, some additions to the Makefile must be made. Instead of LEDE's default *package.mk*, +the Gluon version (``../gluon.mk`` for core packages) must be used. The i18n files must be installed and PKG_CONFIG_DEPENDS must be added:: ... - include $(GLUONDIR)/include/package.mk + include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) ... define Build/Compile - $(call GluonBuildI18N,gluon-config-mode-geo-location,i18n) + $(call GluonBuildI18N,gluon-web-mesh-vpn-fastd,i18n) endef - define Package/gluon-config-mode-geo-location/install + define Package/gluon-web-mesh-vpn-fastd/install ... - $(call GluonInstallI18N,gluon-config-mode-geo-location,$(1)) + $(call GluonInstallI18N,gluon-web-mesh-vpn-fastd,$(1)) endef ... @@ -64,29 +67,29 @@ and PKG_CONFIG_DEPENDS must be added:: Adding translations ------------------- -A new translation file for a template can be added using the ``msginit`` command:: +A new translation file for a template can be added using the *msginit* command: + +.. code-block:: sh - cd package/gluon-config-mode-geo-location/i18n + cd package/gluon-web-mesh-vpn-fastd/i18n msginit -l de -This will create the file ``de.po`` in which the translations can be added. +This will create the file *de.po* in which the translations can be added. -The translation file can be updated to a new template version using the ``msgmerge`` command:: +The translation file can be updated to a new template version using the *msgmerge* command: - msgmerge -U de.po gluon-config-mode-geo-location.pot +.. code-block:: sh + + msgmerge -U de.po gluon-web-mesh-vpn-fastd.pot After the merge, the translation file should be checked for "fuzzy matched" entries where the original English texts have changed. All entries from the translation file should be -translated in the ``.po`` file (or removed from it, so the original English texts are displayed +translated in the *.po* file (or removed from it, so the original English texts are displayed instead). Adding support for new languages -------------------------------- -A list of all languages supported by LuCI can be found in the ``packages/luci/luci.mk`` file after -Gluon's dependencies have been downloaded using ``make update``. Adding translations for these -languages is straightforward using the ``msginit`` command. - -For other languages, support must be added to LuCI first, which constitutes completely translating -the ``base.pot``. Please contact the upstream LuCI maintainers at https://github.com/openwrt/luci/ -if you'd like to do this. +A list of all languages supported by *gluon-web* can be found in ``package/gluon.mk``. +New languages just need to be added to *GLUON_SUPPORTED_LANGS*, after a human-readable +language name has been defined in the same file. diff --git a/docs/dev/upgrade.rst b/docs/dev/upgrade.rst index 28377235f..64dd59ab8 100644 --- a/docs/dev/upgrade.rst +++ b/docs/dev/upgrade.rst @@ -16,7 +16,7 @@ Best practices -------------- * Most upgrade scripts are written in Lua. This allows using lots of helper functions provided - by LuCi and Gluon, e.g. to access the site configuration or edit UCI configuration files. + by Gluon, e.g. to access the site configuration or edit UCI configuration files. * Whenever possible, scripts shouldn't check if they are running for the first time, but just edit configuration files to achive a valid configuration (without overwriting configuration changes made by the user where desirable). diff --git a/docs/features/private-wlan.rst b/docs/features/private-wlan.rst index 343cd5c38..1c46ed76f 100644 --- a/docs/features/private-wlan.rst +++ b/docs/features/private-wlan.rst @@ -4,7 +4,7 @@ Private WLAN It is possible to set up a private WLAN that bridges the WAN port and is seperated from the mesh network. Please note that you should not enable ``mesh_on_wan`` simultaneously. -The private WLAN can be enabled through the config mode if the package ``gluon-luci-private-wifi`` is installed. +The private WLAN can be enabled through the config mode if the package ``gluon-web-private-wifi`` is installed. You may also enable a private WLAN using the command line:: uci set wireless.wan_radio0=wifi-iface diff --git a/docs/features/roles.rst b/docs/features/roles.rst index 38d84f857..3af09c019 100644 --- a/docs/features/roles.rst +++ b/docs/features/roles.rst @@ -18,13 +18,13 @@ For this the section ``roles`` in ``site.conf`` is needed:: }, }, -The strings to display in the LuCI interface are configured per language in the +The strings to display in the web interface are configured per language in the ``i18n/en.po``, ``i18n/de.po``, etc. files of the site repository using message IDs like -``gluon-luci-node-role:role:node`` and ``gluon-luci-node-role:role:backbone``. +``gluon-web-node-role:role:node`` and ``gluon-web-node-role:role:backbone``. The value of ``default`` is the role every node will initially own. This value should be part of ``list`` as well. If you want node owners to change the defined roles via config-mode you can add the package -``gluon-luci-node-role`` to your ``site.mk``. +``gluon-web-node-role`` to your ``site.mk``. The role is saved in ``gluon-node-info.system.role``. To change the role using command line do:: diff --git a/docs/features/wired-mesh.rst b/docs/features/wired-mesh.rst index 63341f1f5..9e28a3611 100644 --- a/docs/features/wired-mesh.rst +++ b/docs/features/wired-mesh.rst @@ -19,7 +19,7 @@ Configuration ~~~~~~~~~~~~~ Both Mesh-on-WAN and Mesh-on-LAN can be configured on the "Network" page -of the *Advanced settings* (if the package ``gluon-luci-portconfig`` is installed). +of the *Advanced settings* (if the package ``gluon-web-network`` is installed). It is also possible to enable Mesh-on-WAN and Mesh-on-LAN by default by adding ``mesh_on_wan = true`` and ``mesh_on_lan = true`` to ``site.conf``. diff --git a/docs/site-example/site.mk b/docs/site-example/site.mk index 79ecf37ae..9298e6f45 100644 --- a/docs/site-example/site.mk +++ b/docs/site-example/site.mk @@ -15,10 +15,10 @@ GLUON_SITE_PACKAGES := \ gluon-config-mode-mesh-vpn \ gluon-ebtables-filter-multicast \ gluon-ebtables-filter-ra-dhcp \ - gluon-luci-admin \ - gluon-luci-autoupdater \ - gluon-luci-portconfig \ - gluon-luci-wifi-config \ + gluon-web-admin \ + gluon-web-autoupdater \ + gluon-web-network \ + gluon-web-wifi-config \ gluon-mesh-batman-adv-15 \ gluon-mesh-vpn-fastd \ gluon-radvd \ diff --git a/docs/user/site.rst b/docs/user/site.rst index 42ef85c69..021cea217 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -182,7 +182,7 @@ fastd_mesh_vpn with the list from the site configuration. Setting `configurable` to `true` will allow the user to add the method ``null`` to the beginning of the method list or remove ``null`` from it, and make this change survive updates. Setting `configurable` is necessary for the - package `gluon-luci-mesh-vpn-fastd`, which adds a UI for this configuration. + package `gluon-web-mesh-vpn-fastd`, which adds a UI for this configuration. In any case, the ``null`` method should always be the first method in the list if it is supported at all. You should only set `configurable` to `true` if the @@ -288,11 +288,11 @@ roles \: optional the community which roles to define. See the section below as an example. ``default`` takes the default role which is set initially. This value should be part of ``list``. If you want node owners to change the role via config mode add - the package ``gluon-luci-node-role`` to ``site.mk``. + the package ``gluon-web-node-role`` to ``site.mk``. - The strings to display in the LuCI interface are configured per language in the + The strings to display in the web interface are configured per language in the ``i18n/en.po``, ``i18n/de.po``, etc. files of the site repository using message IDs like - ``gluon-luci-node-role:role:node`` and ``gluon-luci-node-role:role:backbone``. + ``gluon-web-node-role:role:node`` and ``gluon-web-node-role:role:backbone``. :: roles = { diff --git a/package/gluon-config-mode-autoupdater/Makefile b/package/gluon-config-mode-autoupdater/Makefile index 2fe1ccb2e..a77c07ded 100644 --- a/package/gluon-config-mode-autoupdater/Makefile +++ b/package/gluon-config-mode-autoupdater/Makefile @@ -13,14 +13,10 @@ PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) define Package/gluon-config-mode-autoupdater SECTION:=gluon CATEGORY:=Gluon - TITLE:=Let the user know whether the autoupdater is enabled or not. + TITLE:=Config Mode: Let the user know whether the autoupdater is enabled or not DEPENDS:=gluon-config-mode-core-virtual +gluon-autoupdater endef -define Package/gluon-config-mode-autoupdater/description - Luci based config mode -endef - define Build/Prepare mkdir -p $(PKG_BUILD_DIR) endef diff --git a/package/gluon-config-mode-autoupdater/luasrc/lib/gluon/config-mode/wizard/0050-autoupdater-info.lua b/package/gluon-config-mode-autoupdater/luasrc/lib/gluon/config-mode/wizard/0050-autoupdater-info.lua index e49bd7d76..6d52744e2 100644 --- a/package/gluon-config-mode-autoupdater/luasrc/lib/gluon/config-mode/wizard/0050-autoupdater-info.lua +++ b/package/gluon-config-mode-autoupdater/luasrc/lib/gluon/config-mode/wizard/0050-autoupdater-info.lua @@ -1,19 +1,8 @@ -local cbi = require "luci.cbi" -local i18n = require "luci.i18n" -local uci = require("simple-uci").cursor() - -local M = {} - -function M.section(form) - local enabled = uci:get_bool("autoupdater", "settings", "enabled") - if enabled then - local s = form:section(cbi.SimpleSection, nil, - i18n.translate('This node will automatically update its firmware when a new version is available.')) - end +return function(form, uci) + if uci:get_bool("autoupdater", "settings", "enabled") then + local s = form:section( + Section, nil, + translate('This node will automatically update its firmware when a new version is available.') + ) + end end - -function M.handle(data) - return -end - -return M diff --git a/package/gluon-config-mode-contact-info/luasrc/lib/gluon/config-mode/wizard/0500-contact-info.lua b/package/gluon-config-mode-contact-info/luasrc/lib/gluon/config-mode/wizard/0500-contact-info.lua index 94d5f00cf..1ef5deaf7 100644 --- a/package/gluon-config-mode-contact-info/luasrc/lib/gluon/config-mode/wizard/0500-contact-info.lua +++ b/package/gluon-config-mode-contact-info/luasrc/lib/gluon/config-mode/wizard/0500-contact-info.lua @@ -1,35 +1,27 @@ -local cbi = require "luci.cbi" -local i18n = require "luci.i18n" -local uci = require("simple-uci").cursor() -local site = require 'gluon.site_config' +return function(form, uci) + local site = require 'gluon.site_config' -local M = {} + local owner = uci:get_first("gluon-node-info", "owner") -function M.section(form) - local s = form:section(cbi.SimpleSection, nil, i18n.translate( - 'Please provide your contact information here to ' - .. 'allow others to contact you. Note that ' - .. 'this information will be visible <em>publicly</em> ' - .. 'on the internet together with your node\'s coordinates.' - ) - ) + local s = form:section(Section, nil, translate( + 'Please provide your contact information here to ' + .. 'allow others to contact you. Note that ' + .. 'this information will be visible <em>publicly</em> ' + .. 'on the internet together with your node\'s coordinates.' + )) - local o = s:option(cbi.Value, "_contact", i18n.translate("Contact info")) - o.default = uci:get_first("gluon-node-info", "owner", "contact", "") - o.rmempty = not ((site.config_mode or {}).owner or {}).obligatory - o.datatype = "string" - o.description = i18n.translate("e.g. E-mail or phone number") - o.maxlen = 140 -end + local o = s:option(Value, "contact", translate("Contact info"), translate("e.g. E-mail or phone number")) + o.default = uci:get("gluon-node-info", owner, "contact") + o.optional = not ((site.config_mode or {}).owner or {}).obligatory + -- without a minimal length, an empty string will be accepted even with "optional = false" + o.datatype = "minlength(1)" + function o:write(data) + if data then + uci:set("gluon-node-info", owner, "contact", data) + else + uci:delete("gluon-node-info", owner, "contact") + end + end -function M.handle(data) - if data._contact ~= nil then - uci:set("gluon-node-info", uci:get_first("gluon-node-info", "owner"), "contact", data._contact) - else - uci:delete("gluon-node-info", uci:get_first("gluon-node-info", "owner"), "contact") - end - uci:save("gluon-node-info") - uci:commit("gluon-node-info") + return {'gluon-node-info'} end - -return M diff --git a/package/gluon-config-mode-core/Makefile b/package/gluon-config-mode-core/Makefile index d629c2653..91b2e51fc 100644 --- a/package/gluon-config-mode-core/Makefile +++ b/package/gluon-config-mode-core/Makefile @@ -16,8 +16,8 @@ PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) define Package/gluon-config-mode-core SECTION:=gluon CATEGORY:=Gluon - TITLE:=Luci based config mode for user friendly setup of new mesh nodes - DEPENDS:=gluon-setup-mode-virtual +gluon-luci-theme +gluon-lock-password +pretty-hostname $(GLUON_I18N_PACKAGES) + TITLE:=Configuration wizard for user friendly setup of new mesh nodes + DEPENDS:=gluon-setup-mode-virtual +gluon-web-theme +gluon-lock-password +pretty-hostname PROVIDES:=gluon-config-mode-core-virtual endef diff --git a/package/gluon-config-mode-core/files/lib/gluon/web/view/gluon/config-mode/reboot.html b/package/gluon-config-mode-core/files/lib/gluon/web/view/gluon/config-mode/reboot.html new file mode 100644 index 000000000..6c65010b8 --- /dev/null +++ b/package/gluon-config-mode-core/files/lib/gluon/web/view/gluon/config-mode/reboot.html @@ -0,0 +1,22 @@ +<h2><%:Your node's setup is now complete.%></h2> +<% + local fs = require "nixio.fs" + local util = require "nixio.util" + + local parts_dir = "/lib/gluon/config-mode/reboot/" + local files = util.consume(fs.dir(parts_dir) or function() end) + table.sort(files) + + local parts = {} + for _, entry in ipairs(files) do + if entry:sub(1, 1) ~= '.' then + local p = assert(loadfile(parts_dir .. entry)) + setfenv(p, getfenv()) + table.insert(parts, p) + end + end + + for _, p in ipairs(parts) do + p() + end +%> diff --git a/package/gluon-config-mode-core/files/lib/gluon/web/view/gluon/config-mode/welcome.html b/package/gluon-config-mode-core/files/lib/gluon/web/view/gluon/config-mode/welcome.html new file mode 100644 index 000000000..b2b8e5775 --- /dev/null +++ b/package/gluon-config-mode-core/files/lib/gluon/web/view/gluon/config-mode/welcome.html @@ -0,0 +1,11 @@ +<%- + local sysconfig = require 'gluon.sysconfig' +-%> +<p> + <%= + renderer.render_string(translate('gluon-config-mode:welcome'), { + hostname = hostname, + sysconfig = sysconfig, + }) + %> +</p> diff --git a/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/cbi/config-mode.htm b/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/cbi/config-mode.htm deleted file mode 100644 index e608b52cf..000000000 --- a/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/cbi/config-mode.htm +++ /dev/null @@ -1,53 +0,0 @@ -<%- - local gluon_luci = require 'gluon.luci' - local sysconfig = require 'gluon.sysconfig' - local i18n = require 'luci.i18n' - local template = require 'luci.template' --%> - -<h2><%:Welcome!%></h2> -<p> - <%= template.render_string(i18n.translate('gluon-config-mode:welcome'), { - hostname = hostname, - sysconfig = sysconfig, - escape = gluon_luci.escape, - urlescape = gluon_luci.urlescape, - }) %> -</p> - -<% if not self.embedded then %> -<form method="post" enctype="multipart/form-data" action="<%=REQUEST_URI%>"> - <div> - <script type="text/javascript" src="<%=resource%>/cbi.js"></script> - <input type="hidden" name="token" value="<%=token%>" /> - <input type="hidden" name="cbi.submit" value="1" /> - </div> -<% end %> - <div class="cbi-map" id="cbi-<%=self.config%>"> - <% if self.title and #self.title > 0 then %><h2><a id="content" name="content"><%=self.title%></a></h2><% end %> - <% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %> - <% self:render_children() %> - <br /> - </div> -<%- if self.message then %> - <div><%=self.message%></div> -<%- end %> -<%- if self.errmessage then %> - <div class="error"><%=self.errmessage%></div> -<%- end %> -<% if not self.embedded then %> - <div class="cbi-page-actions"> -<%- - if type(self.hidden) == "table" then - for k, v in pairs(self.hidden) do --%> - <input type="hidden" id="<%=k%>" name="<%=k%>" value="<%=pcdata(v)%>" /> -<%- - end - end -%> - <input class="cbi-button cbi-button-save" type="submit" value="<%:Save & restart%>" /> - <script type="text/javascript">cbi_d_update();</script> - </div> -</form> -<% end %> diff --git a/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/config-mode/reboot.htm b/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/config-mode/reboot.htm deleted file mode 100644 index 25ad20bfa..000000000 --- a/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/config-mode/reboot.htm +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%=luci.i18n.context.lang%>" lang="<%=luci.i18n.context.lang%>"> - <head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <title><%=escape(hostname)%> is rebooting</title> - <link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" /> - </head> - <body> - <div id="maincontainer"> - <div id="maincontent"> - <h2><%:Your node's setup is now complete.%></h2> - <% for k, v in ipairs(parts) do v() end %> - </div> - </div> - </body> -</html> diff --git a/package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/reboot/0900-msg-reboot.lua b/package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/reboot/0900-msg-reboot.lua index 0e2a7e25d..94ca3c0d8 100644 --- a/package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/reboot/0900-msg-reboot.lua +++ b/package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/reboot/0900-msg-reboot.lua @@ -1,6 +1,4 @@ -local i18n = require 'luci.i18n' local site = require 'gluon.site_config' -local gluon_luci = require 'gluon.luci' local sysconfig = require 'gluon.sysconfig' local pretty_hostname = require 'pretty_hostname' @@ -9,15 +7,11 @@ local uci = require("simple-uci").cursor() local hostname = pretty_hostname.get(uci) local contact = uci:get_first('gluon-node-info', 'owner', 'contact') -local msg = i18n.translate('gluon-config-mode:reboot') +local msg = translate('gluon-config-mode:reboot') -return function () - luci.template.render_string(msg, { - hostname = hostname, - site = site, - sysconfig = sysconfig, - contact = contact, - escape = gluon_luci.escape, - urlescape = gluon_luci.urlescape, - }) -end +renderer.render_string(msg, { + hostname = hostname, + site = site, + sysconfig = sysconfig, + contact = contact, +}) diff --git a/package/gluon-config-mode-core/luasrc/lib/gluon/web/controller/gluon-config-mode/index.lua b/package/gluon-config-mode-core/luasrc/lib/gluon/web/controller/gluon-config-mode/index.lua new file mode 100644 index 000000000..52117ac88 --- /dev/null +++ b/package/gluon-config-mode-core/luasrc/lib/gluon/web/controller/gluon-config-mode/index.lua @@ -0,0 +1,2 @@ +entry({}, alias("wizard")) +entry({"wizard"}, model("gluon-config-mode/wizard"), _("Wizard"), 5) diff --git a/package/gluon-config-mode-core/luasrc/lib/gluon/web/model/gluon-config-mode/wizard.lua b/package/gluon-config-mode-core/luasrc/lib/gluon/web/model/gluon-config-mode/wizard.lua new file mode 100644 index 000000000..6cafb0e23 --- /dev/null +++ b/package/gluon-config-mode-core/luasrc/lib/gluon/web/model/gluon-config-mode/wizard.lua @@ -0,0 +1,64 @@ +local disp = require 'gluon.web.dispatcher' +local fs = require "nixio.fs" +local util = require "gluon.web.util" +local nixio_util = require "nixio.util" + +local uci = require("simple-uci").cursor() + +local wizard_dir = "/lib/gluon/config-mode/wizard/" + +local files = nixio_util.consume(fs.dir(wizard_dir) or function() end) +table.sort(files) + +local wizard = {} +for _, entry in ipairs(files) do + if entry:sub(1, 1) ~= '.' then + local f = assert(loadfile(wizard_dir .. entry)) + setfenv(f, getfenv()) + local w = f() + table.insert(wizard, w) + end +end + +local f = Form(translate("Welcome!")) +f.submit = translate('Save & restart') +f.reset = false + +local s = f:section(Section) +s.template = "gluon/config-mode/welcome" + +local commit = {'gluon-setup-mode'} + +for _, w in ipairs(wizard) do + for _, c in ipairs(w(f, uci) or {}) do + if not util.contains(commit, c) then + table.insert(commit, c) + end + end +end + +function f:write() + local nixio = require "nixio" + + uci:set("gluon-setup-mode", uci:get_first("gluon-setup-mode", "setup_mode"), "configured", true) + + for _, c in ipairs(commit) do + uci:commit(c) + end + + f.template = "gluon/config-mode/reboot" + f.hidenav = true + + if nixio.fork() == 0 then + -- Replace stdout with /dev/null + nixio.dup(nixio.open('/dev/null', 'w'), nixio.stdout) + + -- Sleep a little so the browser can fetch everything required to + -- display the reboot page, then reboot the device. + nixio.nanosleep(1) + + nixio.execp("reboot") + end +end + +return f diff --git a/package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/controller/gluon-config-mode/index.lua b/package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/controller/gluon-config-mode/index.lua deleted file mode 100644 index 4e1f5232a..000000000 --- a/package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/controller/gluon-config-mode/index.lua +++ /dev/null @@ -1,93 +0,0 @@ ---[[ -Copyright 2013 Nils Schneider <nils@nilsschneider.net> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ -]]-- - -module("luci.controller.gluon-config-mode.index", package.seeall) - -function index() - local uci_state = luci.model.uci.cursor_state() - - if uci_state:get_first("gluon-setup-mode", "setup_mode", "running", "0") == "1" then - local root = node() - if not root.target then - root.target = alias("gluon-config-mode") - root.index = true - end - - page = node() - page.lock = true - page.target = alias("gluon-config-mode") - page.subindex = true - page.index = false - - page = node("gluon-config-mode") - page.title = _("Wizard") - page.target = alias("gluon-config-mode", "wizard") - page.order = 5 - page.sysauth = "root" - page.sysauth_authenticator = function() return "root" end - page.index = true - - entry({"gluon-config-mode", "wizard"}, cbi("gluon-config-mode/wizard")).index = true - entry({"gluon-config-mode", "reboot"}, call("action_reboot")) - end -end - -function action_reboot() - local uci = luci.model.uci.cursor() - - uci:set("gluon-setup-mode", uci:get_first("gluon-setup-mode", "setup_mode"), "configured", "1") - uci:save("gluon-setup-mode") - uci:commit("gluon-setup-mode") - - local gluon_luci = require "gluon.luci" - local fs = require "nixio.fs" - local util = require "nixio.util" - local pretty_hostname = require "pretty_hostname" - - local parts_dir = "/lib/gluon/config-mode/reboot/" - local files = util.consume(fs.dir(parts_dir)) - - table.sort(files) - - local parts = {} - - for _, entry in ipairs(files) do - if entry:sub(1, 1) ~= '.' then - local f = dofile(parts_dir .. '/' .. entry) - if f ~= nil then - table.insert(parts, f) - end - end - end - - local hostname = pretty_hostname.get(uci) - - luci.template.render("gluon/config-mode/reboot", - { - parts = parts, - hostname = hostname, - escape = gluon_luci.escape, - urlescape = gluon_luci.urlescape, - } - ) - - if nixio.fork() == 0 then - -- Replace stdout with /dev/null - nixio.dup(nixio.open('/dev/null', 'w'), nixio.stdout) - - -- Sleep a little so the browser can fetch everything required to - -- display the reboot page, then reboot the device. - nixio.nanosleep(1) - - nixio.execp("reboot") - end -end diff --git a/package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua b/package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua deleted file mode 100644 index b5dbe0af4..000000000 --- a/package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua +++ /dev/null @@ -1,42 +0,0 @@ -local wizard_dir = "/lib/gluon/config-mode/wizard/" -local i18n = luci.i18n -local uci = require("simple-uci").cursor() -local fs = require "nixio.fs" -local util = require "nixio.util" -local f, s - -local wizard = {} -local files = {} - -if fs.access(wizard_dir) then - files = util.consume(fs.dir(wizard_dir)) - table.sort(files) -end - -for _, entry in ipairs(files) do - if entry:sub(1, 1) ~= '.' then - table.insert(wizard, dofile(wizard_dir .. '/' .. entry)) - end -end - -f = SimpleForm("wizard") -f.reset = false -f.template = "gluon/cbi/config-mode" - -for _, s in ipairs(wizard) do - s.section(f) -end - -function f.handle(self, state, data) - if state == FORM_VALID then - for _, s in ipairs(wizard) do - s.handle(data) - end - - luci.http.redirect(luci.dispatcher.build_url("gluon-config-mode", "reboot")) - end - - return true -end - -return f diff --git a/package/gluon-config-mode-geo-location/luasrc/lib/gluon/config-mode/wizard/0400-geo-location.lua b/package/gluon-config-mode-geo-location/luasrc/lib/gluon/config-mode/wizard/0400-geo-location.lua index 6821da591..4d7fec016 100644 --- a/package/gluon-config-mode-geo-location/luasrc/lib/gluon/config-mode/wizard/0400-geo-location.lua +++ b/package/gluon-config-mode-geo-location/luasrc/lib/gluon/config-mode/wizard/0400-geo-location.lua @@ -1,75 +1,64 @@ -local cbi = require "luci.cbi" -local i18n = require "luci.i18n" -local uci = require("simple-uci").cursor() -local site = require 'gluon.site_config' +return function(form, uci) + local site = require 'gluon.site_config' -local M = {} + local location = uci:get_first("gluon-node-info", "location") -local function show_altitude() - if ((site.config_mode or {}).geo_location or {}).show_altitude ~= false then - return true - end - if uci:get_first("gluon-node-info", "location", "altitude") then - return true - end - return false -end - -function M.section(form) - local text = i18n.translate('If you want the location of your node to ' - .. 'be displayed on the map, you can enter its coordinates here.') - if show_altitude() then - text = text .. ' ' .. i18n.translate("gluon-config-mode:altitude-help") - end - local s = form:section(cbi.SimpleSection, nil, text) + local function show_altitude() + if ((site.config_mode or {}).geo_location or {}).show_altitude ~= false then + return true + end + return uci:get_bool("gluon-node-info", location, "altitude") + end - local o + local text = translate( + 'If you want the location of your node to ' .. + 'be displayed on the map, you can enter its coordinates here.' + ) + if show_altitude() then + text = text .. ' ' .. translate("gluon-config-mode:altitude-help") + end - o = s:option(cbi.Flag, "_location", i18n.translate("Show node on the map")) - o.default = uci:get_first("gluon-node-info", "location", "share_location", o.disabled) - o.rmempty = false + local s = form:section(Section, nil, text) - o = s:option(cbi.Value, "_latitude", i18n.translate("Latitude")) - o.default = uci:get_first("gluon-node-info", "location", "latitude") - o:depends("_location", "1") - o.rmempty = false - o.datatype = "float" - o.description = i18n.translatef("e.g. %s", "53.873621") + local o - o = s:option(cbi.Value, "_longitude", i18n.translate("Longitude")) - o.default = uci:get_first("gluon-node-info", "location", "longitude") - o:depends("_location", "1") - o.rmempty = false - o.datatype = "float" - o.description = i18n.translatef("e.g. %s", "10.689901") + local share_location = s:option(Flag, "location", translate("Show node on the map")) + share_location.default = uci:get_bool("gluon-node-info", location, "share_location") + function share_location:write(data) + uci:set("gluon-node-info", location, "share_location", data) + end - if show_altitude() then - o = s:option(cbi.Value, "_altitude", i18n.translate("gluon-config-mode:altitude-label")) - o.default = uci:get_first("gluon-node-info", "location", "altitude") - o:depends("_location", "1") - o.rmempty = true - o.datatype = "float" - o.description = i18n.translatef("e.g. %s", "11.51") - end + o = s:option(Value, "latitude", translate("Latitude"), translatef("e.g. %s", "53.873621")) + o.default = uci:get("gluon-node-info", location, "latitude") + o:depends(share_location, true) + o.datatype = "float" + function o:write(data) + uci:set("gluon-node-info", location, "latitude", data) + end -end + o = s:option(Value, "longitude", translate("Longitude"), translatef("e.g. %s", "10.689901")) + o.default = uci:get("gluon-node-info", location, "longitude") + o:depends(share_location, true) + o.datatype = "float" + function o:write(data) + uci:set("gluon-node-info", location, "longitude", data) + end -function M.handle(data) - local sname = uci:get_first("gluon-node-info", "location") + if show_altitude() then + o = s:option(Value, "altitude", translate("gluon-config-mode:altitude-label"), translatef("e.g. %s", "11.51")) + o.default = uci:get("gluon-node-info", location, "altitude") + o:depends(share_location, true) + o.datatype = "float" + o.optional = true + function o:write(data) + if data then + uci:set("gluon-node-info", location, "altitude", data) + else + uci:delete("gluon-node-info", location, "altitude") + end + end + end - uci:set("gluon-node-info", sname, "share_location", data._location) - if data._location and data._latitude ~= nil and data._longitude ~= nil then - uci:set("gluon-node-info", sname, "latitude", data._latitude:trim()) - uci:set("gluon-node-info", sname, "longitude", data._longitude:trim()) - if data._altitude ~= nil then - uci:set("gluon-node-info", sname, "altitude", data._altitude:trim()) - else - uci:delete("gluon-node-info", sname, "altitude") - end - end - uci:save("gluon-node-info") - uci:commit("gluon-node-info") + return {'gluon-node-info'} end - -return M diff --git a/package/gluon-config-mode-hostname/luasrc/lib/gluon/config-mode/wizard/0100-hostname.lua b/package/gluon-config-mode-hostname/luasrc/lib/gluon/config-mode/wizard/0100-hostname.lua index 0f7d0b2c8..8661d4bde 100644 --- a/package/gluon-config-mode-hostname/luasrc/lib/gluon/config-mode/wizard/0100-hostname.lua +++ b/package/gluon-config-mode-hostname/luasrc/lib/gluon/config-mode/wizard/0100-hostname.lua @@ -1,20 +1,13 @@ -local cbi = require "luci.cbi" -local i18n = require "luci.i18n" -local pretty_hostname = require "pretty_hostname" -local uci = require("simple-uci").cursor() +return function(form, uci) + local pretty_hostname = require "pretty_hostname" -local M = {} + local s = form:section(Section) + local o = s:option(Value, "hostname", translate("Node name")) + o.default = pretty_hostname.get(uci) -function M.section(form) - local s = form:section(cbi.SimpleSection, nil, nil) - local o = s:option(cbi.Value, "_hostname", i18n.translate("Node name")) - o.value = pretty_hostname.get(uci) - o.rmempty = false -end + function o:write(data) + pretty_hostname.set(uci, data) + end -function M.handle(data) - pretty_hostname.set(uci, data._hostname) - uci:commit("system") + return {'system'} end - -return M diff --git a/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/reboot/0100-mesh-vpn.lua b/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/reboot/0100-mesh-vpn.lua index f68d230e3..f5868c605 100644 --- a/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/reboot/0100-mesh-vpn.lua +++ b/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/reboot/0100-mesh-vpn.lua @@ -2,32 +2,27 @@ local uci = require("simple-uci").cursor() local meshvpn_enabled = uci:get_bool("fastd", "mesh_vpn", "enabled") if not meshvpn_enabled then - return nil -else - local i18n = require "luci.i18n" - local util = require "luci.util" + return +end - local gluon_luci = require 'gluon.luci' - local site = require 'gluon.site_config' - local sysconfig = require 'gluon.sysconfig' +local lutil = require "gluon.web.util" - local pretty_hostname = require 'pretty_hostname' +local site = require 'gluon.site_config' +local sysconfig = require 'gluon.sysconfig' +local util = require "gluon.util" - local pubkey = util.trim(util.exec("/etc/init.d/fastd show_key " .. "mesh_vpn")) - local hostname = pretty_hostname.get(uci) - local contact = uci:get_first("gluon-node-info", "owner", "contact") +local pretty_hostname = require 'pretty_hostname' - local msg = i18n.translate('gluon-config-mode:pubkey') +local pubkey = util.trim(lutil.exec("/etc/init.d/fastd show_key mesh_vpn")) +local hostname = pretty_hostname.get(uci) +local contact = uci:get_first("gluon-node-info", "owner", "contact") - return function () - luci.template.render_string(msg, { - pubkey = pubkey, - hostname = hostname, - site = site, - sysconfig = sysconfig, - contact = contact, - escape = gluon_luci.escape, - urlescape = gluon_luci.urlescape, - }) - end -end +local msg = translate('gluon-config-mode:pubkey') + +renderer.render_string(msg, { + pubkey = pubkey, + hostname = hostname, + site = site, + sysconfig = sysconfig, + contact = contact, +}) diff --git a/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua b/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua index 87109f379..6aa4ee52a 100644 --- a/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua +++ b/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua @@ -1,64 +1,47 @@ -local cbi = require "luci.cbi" -local i18n = require "luci.i18n" -local uci = require("simple-uci").cursor() - -local M = {} - -function M.section(form) - local msg = i18n.translate('Your internet connection can be used to establish an ' .. - 'encrypted connection with other nodes. ' .. - 'Enable this option if there are no other nodes reachable ' .. - 'over WLAN in your vicinity or you want to make a part of ' .. - 'your connection\'s bandwidth available for the network. You can limit how ' .. - 'much bandwidth the node will use at most.') - local s = form:section(cbi.SimpleSection, nil, msg) - - local o - - o = s:option(cbi.Flag, "_meshvpn", i18n.translate("Use internet connection (mesh VPN)")) - o.default = uci:get_bool("fastd", "mesh_vpn", "enabled") and o.enabled or o.disabled - o.rmempty = false - - o = s:option(cbi.Flag, "_limit_enabled", i18n.translate("Limit bandwidth")) - o:depends("_meshvpn", "1") - o.default = uci:get_bool("simple-tc", "mesh_vpn", "enabled") and o.enabled or o.disabled - o.rmempty = false - - o = s:option(cbi.Value, "_limit_ingress", i18n.translate("Downstream (kbit/s)")) - o:depends("_limit_enabled", "1") - o.value = uci:get("simple-tc", "mesh_vpn", "limit_ingress") - o.rmempty = false - o.datatype = "uinteger" - - o = s:option(cbi.Value, "_limit_egress", i18n.translate("Upstream (kbit/s)")) - o:depends("_limit_enabled", "1") - o.value = uci:get("simple-tc", "mesh_vpn", "limit_egress") - o.rmempty = false - o.datatype = "uinteger" +return function(form, uci) + local msg = translate( + 'Your internet connection can be used to establish an ' .. + 'encrypted connection with other nodes. ' .. + 'Enable this option if there are no other nodes reachable ' .. + 'over WLAN in your vicinity or you want to make a part of ' .. + 'your connection\'s bandwidth available for the network. You can limit how ' .. + 'much bandwidth the node will use at most.' + ) + + local s = form:section(Section, nil, msg) + + local o + + local meshvpn = s:option(Flag, "meshvpn", translate("Use internet connection (mesh VPN)")) + meshvpn.default = uci:get_bool("fastd", "mesh_vpn", "enabled") + function meshvpn:write(data) + uci:set("fastd", "mesh_vpn", "enabled", data) + end + + local limit = s:option(Flag, "limit_enabled", translate("Limit bandwidth")) + limit:depends(meshvpn, true) + limit.default = uci:get_bool("simple-tc", "mesh_vpn", "enabled") + function limit:write(data) + uci:set("simple-tc", "mesh_vpn", "interface") + uci:set("simple-tc", "mesh_vpn", "enabled", data) + uci:set("simple-tc", "mesh_vpn", "ifname", "mesh-vpn") + end + + o = s:option(Value, "limit_ingress", translate("Downstream (kbit/s)")) + o:depends(limit, true) + o.default = uci:get("simple-tc", "mesh_vpn", "limit_ingress") + o.datatype = "uinteger" + function o:write(data) + uci:set("simple-tc", "mesh_vpn", "limit_ingress", data) + end + + o = s:option(Value, "limit_egress", translate("Upstream (kbit/s)")) + o:depends(limit, true) + o.default = uci:get("simple-tc", "mesh_vpn", "limit_egress") + o.datatype = "uinteger" + function o:write(data) + uci:set("simple-tc", "mesh_vpn", "limit_egress", data) + end + + return {'fastd', 'simple-tc'} end - -function M.handle(data) - uci:set("fastd", "mesh_vpn", "enabled", data._meshvpn) - uci:save("fastd") - uci:commit("fastd") - - -- checks for nil needed due to o:depends(...) - if data._limit_enabled ~= nil then - uci:set("simple-tc", "mesh_vpn", "interface") - uci:set("simple-tc", "mesh_vpn", "enabled", data._limit_enabled) - uci:set("simple-tc", "mesh_vpn", "ifname", "mesh-vpn") - - if data._limit_ingress ~= nil then - uci:set("simple-tc", "mesh_vpn", "limit_ingress", data._limit_ingress:trim()) - end - - if data._limit_egress ~= nil then - uci:set("simple-tc", "mesh_vpn", "limit_egress", data._limit_egress:trim()) - end - - uci:save("simple-tc") - uci:commit("simple-tc") - end -end - -return M diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_reboot.htm b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_reboot.htm deleted file mode 100644 index 3e89e7782..000000000 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_reboot.htm +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%=luci.i18n.context.lang%>" lang="<%=luci.i18n.context.lang%>"> - <head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <title><%:Upgrading firmware%></title> - <link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" /> - </head> - <body> - <div id="maincontainer"> - <div id="maincontent"> - <p> - <%:The firmware is currently being upgraded.%> - <strong><%:Don't switch off the device in any circumstance!%></strong> - <%:The upgrade will take a few minutes. When it is finished, your node will reboot automatically.%> - </p> - </div> - </div> - </body> -</html> diff --git a/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/index.lua b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/index.lua deleted file mode 100644 index 5a468f16a..000000000 --- a/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/index.lua +++ /dev/null @@ -1,39 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface - -Copyright 2008 Steven Barth <steven@midlink.org> -Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ -]]-- - -module("luci.controller.admin.index", package.seeall) - -function index() - local uci_state = luci.model.uci.cursor_state() - - -- Disable gluon-luci-admin when setup mode is not enabled - if uci_state:get_first('gluon-setup-mode', 'setup_mode', 'running', '0') ~= '1' then - return - end - - local root = node() - if not root.lock then - root.target = alias("admin") - root.index = true - end - - local page = entry({"admin"}, alias("admin", "index"), _("Advanced settings"), 10) - page.sysauth = "root" - page.sysauth_authenticator = function() return "root" end - page.index = true - - entry({"admin", "index"}, template("admin/info"), _("Information"), 1) - entry({"admin", "remote"}, cbi("admin/remote"), _("Remote access"), 10) -end diff --git a/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/upgrade.lua b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/upgrade.lua deleted file mode 100644 index 1930e9ec2..000000000 --- a/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/upgrade.lua +++ /dev/null @@ -1,139 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface - -Copyright 2008 Steven Barth <steven@midlink.org> -Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ -]]-- - -module("luci.controller.admin.upgrade", package.seeall) - -function index() - local has_platform = nixio.fs.access("/lib/upgrade/platform.sh") - if has_platform then - entry({"admin", "upgrade"}, call("action_upgrade"), _("Upgrade firmware"), 90) - entry({"admin", "upgrade", "reboot"}, template("admin/upgrade_reboot"), nil, nil) - end -end - -function action_upgrade() - local tmpfile = "/tmp/firmware.img" - - -- Install upload handler - local file - luci.http.setfilehandler( - function(meta, chunk, eof) - if not nixio.fs.access(tmpfile) and not file and chunk and #chunk > 0 then - file = io.open(tmpfile, "w") - end - if file and chunk then - file:write(chunk) - end - if file and eof then - file:close() - end - end - ) - - -- Determine state - local step = tonumber(luci.http.formvalue("step") or 1) - - if step ~= 1 and not luci.dispatcher.test_post_security() then - nixio.fs.unlink(tmpfile) - return - end - - local has_image = nixio.fs.access(tmpfile) - local has_support = image_supported(tmpfile) - - -- Step 1: file upload, error on unsupported image format - if not has_image or not has_support or step == 1 then - -- If there is an image but user has requested step 1 - -- or type is not supported, then remove it. - if has_image then - nixio.fs.unlink(tmpfile) - end - - luci.template.render("admin/upgrade", { - bad_image=(has_image and not has_support or false) - } ) - - -- Step 2: present uploaded file, show checksum, confirmation - elseif step == 2 then - luci.template.render("admin/upgrade_confirm", { - checksum=image_checksum(tmpfile), - filesize=nixio.fs.stat(tmpfile).size, - flashsize=storage_size(), - keepconfig=luci.http.formvalue("keepcfg") == "1" - } ) - elseif step == 3 then - local keepcfg = luci.http.formvalue("keepcfg") == "1" - fork_exec("/sbin/sysupgrade %s %q" % { keepcfg and "" or "-n", tmpfile }) - luci.http.redirect(luci.dispatcher.build_url("admin", "upgrade", "reboot")) - end -end - -function fork_exec(command) - local pid = nixio.fork() - if pid > 0 then - return - elseif pid == 0 then - -- change to root dir - nixio.chdir("/") - - -- patch stdin, out, err to /dev/null - local null = nixio.open("/dev/null", "w+") - if null then - nixio.dup(null, nixio.stderr) - nixio.dup(null, nixio.stdout) - nixio.dup(null, nixio.stdin) - if null:fileno() > 2 then - null:close() - end - end - - -- replace with target command - nixio.exec("/bin/sh", "-c", command) - end -end - -function image_supported(tmpfile) - -- XXX: yay... - return ( 0 == os.execute( - "/sbin/sysupgrade -T %q >/dev/null" - % tmpfile - ) ) -end - -function storage_size() - local size = 0 - if nixio.fs.access("/proc/mtd") then - for l in io.lines("/proc/mtd") do - local d, s, e, n = l:match('^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+"([^%s]+)"') - if n == "linux" then - size = tonumber(s, 16) - break - end - end - elseif nixio.fs.access("/proc/partitions") then - for l in io.lines("/proc/partitions") do - local x, y, b, n = l:match('^%s*(%d+)%s+(%d+)%s+([^%s]+)%s+([^%s]+)') - if b and n and not n:match('[0-9]') then - size = tonumber(b) * 1024 - break - end - end - end - return size -end - -function image_checksum(tmpfile) - return (luci.sys.exec("md5sum %q" % tmpfile):match("^([^%s]+)")) -end diff --git a/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/model/cbi/admin/remote.lua b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/model/cbi/admin/remote.lua deleted file mode 100644 index 796482ba7..000000000 --- a/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/model/cbi/admin/remote.lua +++ /dev/null @@ -1,87 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface - -Copyright 2008 Steven Barth <steven@midlink.org> -Copyright 2011 Jo-Philipp Wich <xm@subsignal.org> -Copyright 2013 Nils Schneider <nils@nilsschneider.net> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ -]]-- - -local fs = require "nixio.fs" - -local f_keys = SimpleForm('keys', translate("SSH keys"), translate("You can provide your SSH keys here (one per line):")) -f_keys.hidden = { submit_keys = '1' } - -local keys - -keys = f_keys:field(TextValue, "keys", "") -keys.wrap = "off" -keys.rows = 5 -keys.rmempty = true - -function keys.cfgvalue() - return fs.readfile("/etc/dropbear/authorized_keys") or "" -end - -function keys.write(self, section, value) - if not f_keys:formvalue('submit_keys') then return end - - fs.writefile("/etc/dropbear/authorized_keys", value:gsub("\r\n", "\n"):trim() .. "\n") -end - -function keys.remove(self, section) - if not f_keys:formvalue('submit_keys') then return end - - fs.remove("/etc/dropbear/authorized_keys") -end - -local f_password = SimpleForm('password', translate("Password"), - translate( - "Alternatively, you can set a password to access you node. Please choose a secure password you don't use anywhere else.<br /><br />" - .. "If you set an empty password, login via password will be disabled. This is the default." - ) -) -f_password.hidden = { submit_password = '1' } -f_password.reset = false - -local pw1 = f_password:field(Value, "pw1", translate("Password")) -pw1.password = true -function pw1.cfgvalue() - return '' -end - -local pw2 = f_password:field(Value, "pw2", translate("Confirmation")) -pw2.password = true -function pw2.cfgvalue() - return '' -end - -function f_password:handle(state, data) - if not f_password:formvalue('submit_password') then return end - - if data.pw1 ~= data.pw2 then - f_password.errmessage = translate("The password and the confirmation differ.") - return - end - - if data.pw1 and #data.pw1 > 0 then - if luci.sys.user.setpasswd('root', data.pw1) == 0 then - f_password.message = translate("Password changed.") - else - f_password.errmessage = translate("Unable to change the password.") - end - else - -- We don't check the return code here as the error 'password for root is already locked' is normal... - os.execute('passwd -l root >/dev/null') - f_password.message = translate("Password removed.") - end -end - -return f_keys, f_password diff --git a/package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/controller/admin/autoupdater.lua b/package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/controller/admin/autoupdater.lua deleted file mode 100644 index 64e1acbdf..000000000 --- a/package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/controller/admin/autoupdater.lua +++ /dev/null @@ -1,19 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface - -Copyright 2013 Nils Schneider <nils@nilsschneider.net> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ -]]-- - -module("luci.controller.admin.autoupdater", package.seeall) - -function index() - entry({"admin", "autoupdater"}, cbi("admin/autoupdater"), _("Automatic updates"), 80) -end diff --git a/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm b/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm deleted file mode 100644 index 0899fa1d3..000000000 --- a/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm +++ /dev/null @@ -1,32 +0,0 @@ -<div class="cbi-value"> - <div class="cbi-value-title"> - <input class="cbi-input-radio" onclick="cbi_d_update(this.id)" onchange="cbi_d_update(this.id)" type="radio" value="security"<%= attr("id", cbid..'1') .. attr("name", cbid) .. ifattr((self:cfgvalue(section) or self.default) == "security", "checked", "checked") %> /> - </div> - <div class="cbi-value-field-long"> - <label<%= attr("for", cbid..'1') %> class="cbi-value-title"><%:Security mode%></label> - <br /> - <%= translate( - 'In security mode, the mesh VPN uses an encrypted tunnel to connect to the VPN servers. ' .. - 'The encryption ensures that it is impossible for your internet access provider to see what ' .. - 'data is exchanged over your node.' - ) %> - <br /> - </div> - <div class="cbi-value-field-long-after"></div> -</div> - -<div class="cbi-value cbi-value-last"> - <div class="cbi-value-title"> - <input class="cbi-input-radio" onclick="cbi_d_update(this.id)" onchange="cbi_d_update(this.id)" type="radio" value="performance"<%= attr("id", cbid..'2') .. attr("name", cbid) .. ifattr((self:cfgvalue(section) or self.default) == "performance", "checked", "checked") %> /> - </div> - <div class="cbi-value-field-long"> - <label<%= attr("for", cbid..'2') %> class="cbi-value-title"><%:Performance mode%></label> - <br /> - <%= translate( - 'In performance mode, no encryption is used. This usually allows for higher throughput, but the data exchanged over your node is not ' .. - 'protected against eavesdropping.' - ) %> - <br /> - </div> - <div class="cbi-value-field-long-after"></div> -</div> diff --git a/package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/controller/admin/mesh_vpn_fastd.lua b/package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/controller/admin/mesh_vpn_fastd.lua deleted file mode 100644 index 8141c44a1..000000000 --- a/package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/controller/admin/mesh_vpn_fastd.lua +++ /dev/null @@ -1,5 +0,0 @@ -module("luci.controller.admin.mesh_vpn_fastd", package.seeall) - -function index() - entry({"admin", "mesh_vpn_fastd"}, cbi("admin/mesh_vpn_fastd"), _("Mesh VPN"), 20) -end diff --git a/package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua b/package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua deleted file mode 100644 index 7dc5267ca..000000000 --- a/package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua +++ /dev/null @@ -1,40 +0,0 @@ -local uci = require("simple-uci").cursor() -local util = luci.util - -local f = SimpleForm('mesh_vpn', translate('Mesh VPN')) - -local s = f:section(SimpleSection) - -local o = s:option(Value, 'mode') -o.template = "gluon/cbi/mesh-vpn-fastd-mode" - -local methods = uci:get('fastd', 'mesh_vpn', 'method') -if util.contains(methods, 'null') then - o.default = 'performance' -else - o.default = 'security' -end - -function f.handle(self, state, data) - if state == FORM_VALID then - local site = require 'gluon.site_config' - - local methods = {} - if data.mode == 'performance' then - table.insert(methods, 'null') - end - - for _, method in ipairs(site.fastd_mesh_vpn.methods) do - if method ~= 'null' then - table.insert(methods, method) - end - end - - uci:set('fastd', 'mesh_vpn', 'method', methods) - - uci:save('fastd') - uci:commit('fastd') - end -end - -return f diff --git a/package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/controller/admin/noderole.lua b/package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/controller/admin/noderole.lua deleted file mode 100644 index cfca1275b..000000000 --- a/package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/controller/admin/noderole.lua +++ /dev/null @@ -1,5 +0,0 @@ -module("luci.controller.admin.noderole", package.seeall) - -function index() - entry({"admin", "noderole"}, cbi("admin/noderole"), "Node role", 20) -end diff --git a/package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/model/cbi/admin/noderole.lua b/package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/model/cbi/admin/noderole.lua deleted file mode 100644 index ea8202a41..000000000 --- a/package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/model/cbi/admin/noderole.lua +++ /dev/null @@ -1,33 +0,0 @@ -local f, s, o -local site = require 'gluon.site_config' -local i18n = require "luci.i18n" -local uci = require("simple-uci").cursor() -local config = 'gluon-node-info' - --- where to read the configuration from -local role = uci:get(config, uci:get_first(config, "system"), "role") - -f = SimpleForm("role", i18n.translate("Node role")) - -s = f:section(SimpleSection, nil, i18n.translate( - "If this node has a special role within the freifunk network you can specify this role here. " - .. "Please find out about the available roles and their impact first. " - .. "Only change the role if you know what you are doing.")) - -o = s:option(ListValue, "role", i18n.translate("Role")) -o.default = role -o.rmempty = false -for _, role in ipairs(site.roles.list) do - o:value(role, i18n.translate('gluon-luci-node-role:role:' .. role)) -end - -function f.handle(self, state, data) - if state == FORM_VALID then - uci:set(config, uci:get_first(config, "system"), "role", data.role) - - uci:save(config) - uci:commit(config) - end -end - -return f diff --git a/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/controller/admin/portconfig.lua b/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/controller/admin/portconfig.lua deleted file mode 100644 index 037b56c84..000000000 --- a/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/controller/admin/portconfig.lua +++ /dev/null @@ -1,19 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface - -Copyright 2013 Nils Schneider <nils@nilsschneider.net> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ -]]-- - -module("luci.controller.admin.portconfig", package.seeall) - -function index() - entry({"admin", "portconfig"}, cbi("admin/portconfig"), _("Network"), 20) -end diff --git a/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/model/cbi/admin/portconfig.lua b/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/model/cbi/admin/portconfig.lua deleted file mode 100644 index 13d87b51b..000000000 --- a/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/model/cbi/admin/portconfig.lua +++ /dev/null @@ -1,167 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface - -Copyright 2014 Nils Schneider <nils@nilsschneider.net> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ -]]-- - -local uci = require("simple-uci").cursor() -local sysconfig = require 'gluon.sysconfig' -local util = require 'gluon.util' - -local wan = uci:get_all("network", "wan") -local wan6 = uci:get_all("network", "wan6") -local dns = uci:get_first("gluon-wan-dnsmasq", "static") - -local f = SimpleForm("portconfig", translate("WAN connection")) - -local s -local o - -s = f:section(SimpleSection, nil, nil) - -o = s:option(ListValue, "ipv4", translate("IPv4")) -o:value("dhcp", translate("Automatic (DHCP)")) -o:value("static", translate("Static")) -o:value("none", translate("Disabled")) -o.default = wan.proto - -o = s:option(Value, "ipv4_addr", translate("IP address")) -o:depends("ipv4", "static") -o.value = wan.ipaddr -o.datatype = "ip4addr" -o.rmempty = false - -o = s:option(Value, "ipv4_netmask", translate("Netmask")) -o:depends("ipv4", "static") -o.value = wan.netmask or "255.255.255.0" -o.datatype = "ip4addr" -o.rmempty = false - -o = s:option(Value, "ipv4_gateway", translate("Gateway")) -o:depends("ipv4", "static") -o.value = wan.gateway -o.datatype = "ip4addr" -o.rmempty = false - - -s = f:section(SimpleSection, nil, nil) - -o = s:option(ListValue, "ipv6", translate("IPv6")) -o:value("dhcpv6", translate("Automatic (RA/DHCPv6)")) -o:value("static", translate("Static")) -o:value("none", translate("Disabled")) -o.default = wan6.proto - -o = s:option(Value, "ipv6_addr", translate("IP address")) -o:depends("ipv6", "static") -o.value = wan6.ip6addr -o.datatype = "ip6addr" -o.rmempty = false - -o = s:option(Value, "ipv6_gateway", translate("Gateway")) -o:depends("ipv6", "static") -o.value = wan6.ip6gw -o.datatype = "ip6addr" -o.rmempty = false - - -if dns then - s = f:section(SimpleSection, nil, nil) - - o = s:option(DynamicList, "dns", translate("Static DNS servers")) - o:write(nil, uci:get("gluon-wan-dnsmasq", dns, "server")) - o.datatype = "ipaddr" -end - -s = f:section(SimpleSection, nil, nil) - -o = s:option(Flag, "mesh_wan", translate("Enable meshing on the WAN interface")) -o.default = uci:get_bool("network", "mesh_wan", "auto") and o.enabled or o.disabled -o.rmempty = false - -if sysconfig.lan_ifname then - o = s:option(Flag, "mesh_lan", translate("Enable meshing on the LAN interface")) - o.default = uci:get_bool("network", "mesh_lan", "auto") and o.enabled or o.disabled - o.rmempty = false -end - -if uci:get('system', 'gpio_switch_poe_passthrough') then - s = f:section(SimpleSection, nil, nil) - o = s:option(Flag, "poe_passthrough", translate("Enable PoE passthrough")) - o.default = uci:get_bool("system", "gpio_switch_poe_passthrough", "value") and o.enabled or o.disabled - o.rmempty = false -end - -function f.handle(self, state, data) - if state == FORM_VALID then - uci:set("network", "wan", "proto", data.ipv4) - if data.ipv4 == "static" then - uci:set("network", "wan", "ipaddr", data.ipv4_addr:trim()) - uci:set("network", "wan", "netmask", data.ipv4_netmask:trim()) - uci:set("network", "wan", "gateway", data.ipv4_gateway:trim()) - else - uci:delete("network", "wan", "ipaddr") - uci:delete("network", "wan", "netmask") - uci:delete("network", "wan", "gateway") - end - - uci:set("network", "wan6", "proto", data.ipv6) - if data.ipv6 == "static" then - uci:set("network", "wan6", "ip6addr", data.ipv6_addr:trim()) - uci:set("network", "wan6", "ip6gw", data.ipv6_gateway:trim()) - else - uci:delete("network", "wan6", "ip6addr") - uci:delete("network", "wan6", "ip6gw") - end - - uci:set("network", "mesh_wan", "auto", data.mesh_wan) - - if sysconfig.lan_ifname then - uci:set("network", "mesh_lan", "auto", data.mesh_lan) - - local interfaces = uci:get_list("network", "client", "ifname") - - for lanif in sysconfig.lan_ifname:gmatch('%S+') do - if data.mesh_lan == '1' then - util.remove_from_set(interfaces, lanif) - else - util.add_to_set(interfaces, lanif) - end - end - - uci:set_list("network", "client", "ifname", interfaces) - end - - uci:save("network") - uci:commit("network") - - if uci:get('system', 'gpio_switch_poe_passthrough') then - uci:set('system', 'gpio_switch_poe_passthrough', 'value', data.poe_passthrough) - uci:save('system') - uci:commit('system') - end - - if dns then - if #data.dns > 0 then - uci:set("gluon-wan-dnsmasq", dns, "server", data.dns) - else - uci:delete("gluon-wan-dnsmasq", dns, "server") - end - - uci:save("gluon-wan-dnsmasq") - uci:commit("gluon-wan-dnsmasq") - end - end - - return true -end - -return f diff --git a/package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/controller/admin/privatewifi.lua b/package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/controller/admin/privatewifi.lua deleted file mode 100644 index e11ba58b7..000000000 --- a/package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/controller/admin/privatewifi.lua +++ /dev/null @@ -1,5 +0,0 @@ -module("luci.controller.admin.privatewifi", package.seeall) - -function index() - entry({"admin", "privatewifi"}, cbi("admin/privatewifi"), _("Private WLAN"), 10) -end diff --git a/package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua b/package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua deleted file mode 100644 index 08e987a56..000000000 --- a/package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua +++ /dev/null @@ -1,67 +0,0 @@ -local uci = require("simple-uci").cursor() -local util = require 'gluon.util' - -local f, s, o, ssid - --- where to read the configuration from -local primary_iface = 'wan_radio0' -local ssid = uci:get('wireless', primary_iface, "ssid") - -f = SimpleForm("wifi", translate("Private WLAN")) - -s = f:section(SimpleSection, nil, translate( - 'Your node can additionally extend your private network by bridging the WAN interface ' - .. 'with a separate WLAN. This feature is completely independent of the mesh functionality. ' - .. 'Please note that the private WLAN and meshing on the WAN interface should not be enabled ' - .. 'at the same time.' -)) - -o = s:option(Flag, "enabled", translate("Enabled")) -o.default = (ssid and not uci:get_bool('wireless', primary_iface, "disabled")) and o.enabled or o.disabled -o.rmempty = false - -o = s:option(Value, "ssid", translate("Name (SSID)")) -o:depends("enabled", '1') -o.datatype = "maxlength(32)" -o.default = ssid - -o = s:option(Value, "key", translate("Key"), translate("8-63 characters")) -o:depends("enabled", '1') -o.datatype = "wpakey" -o.default = uci:get('wireless', primary_iface, "key") - -function f.handle(self, state, data) - if state == FORM_VALID then - util.iterate_radios( - function(radio, index) - local name = "wan_" .. radio - - if data.enabled == '1' then - local macaddr = util.get_wlan_mac(radio, index, 4) - - -- set up WAN wifi-iface - uci:section('wireless', "wifi-iface", name, - { - device = radio, - network = "wan", - mode = 'ap', - encryption = 'psk2', - ssid = data.ssid, - key = data.key, - macaddr = macaddr, - disabled = false, - } - ) - else - -- disable WAN wifi-iface - uci:set('wireless', name, "disabled", true) - end - end - ) - - uci:save('wireless') - uci:commit('wireless') - end -end - -return f diff --git a/package/gluon-luci-theme/files/etc/uci-defaults/luci-theme-gluon b/package/gluon-luci-theme/files/etc/uci-defaults/luci-theme-gluon deleted file mode 100755 index 795bd186a..000000000 --- a/package/gluon-luci-theme/files/etc/uci-defaults/luci-theme-gluon +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -uci batch <<-EOF - set luci.themes.Gluon=/luci-static/gluon - commit luci -EOF - diff --git a/package/gluon-luci-theme/files/usr/lib/lua/luci/view/themes/gluon/footer.htm b/package/gluon-luci-theme/files/usr/lib/lua/luci/view/themes/gluon/footer.htm deleted file mode 100644 index 6b7090307..000000000 --- a/package/gluon-luci-theme/files/usr/lib/lua/luci/view/themes/gluon/footer.htm +++ /dev/null @@ -1,19 +0,0 @@ -<%# -LuCI - Lua Configuration Interface -Copyright 2008 Steven Barth <steven@midlink.org> -Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ - --%> -</div> -</div> - -</body> -</html> diff --git a/package/gluon-luci-theme/files/usr/lib/lua/luci/view/themes/gluon/header.htm b/package/gluon-luci-theme/files/usr/lib/lua/luci/view/themes/gluon/header.htm deleted file mode 100644 index 8b374c575..000000000 --- a/package/gluon-luci-theme/files/usr/lib/lua/luci/view/themes/gluon/header.htm +++ /dev/null @@ -1,171 +0,0 @@ -<%# -LuCI - Lua Configuration Interface -Copyright 2008 Steven Barth <steven@midlink.org> -Copyright 2008-2010 Jo-Philipp Wich <xm@subsignal.org> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ - --%> -<% - local sys = require "luci.sys" - local http = require "luci.http" - local disp = require "luci.dispatcher" - local uci = require("simple-uci").cursor() - local fs = require "nixio.fs" - local gluon_luci = require "gluon.luci" - local pretty_hostname = require "pretty_hostname" - - local hostname = pretty_hostname.get(uci) - local release = fs.readfile("/lib/gluon/release") - - local request = disp.context.path - local request2 = disp.context.request - - local category = request[1] - local cattree = category and disp.node(category) - - local leaf = request2[#request2] - - local tree = disp.node() - local node = disp.context.dispatched - - local categories = disp.node_childs(tree) - - local c = tree - local i, r - - -- tag all nodes leading to this page - for i, r in ipairs(request) do - if c.nodes and c.nodes[r] then - c = c.nodes[r] - c._menu_selected = true - end - end - - http.prepare_content("application/xhtml+xml") - - local function nodeurl(prefix, name, query) - local url = controller .. prefix .. name .. "/" - if query then - url = url .. http.build_querystring(query) - end - return pcdata(url) - end - - local function subtree(prefix, node, level) - if not level then - level = 1 - end - - local childs = disp.node_childs(node) - if #childs > 0 then -%> - <div class="tabmenu<%=level%>"> - <ul class="tabmenu l<%=level%>"> - <% - local selected_node - local selected_name - local i, v - - for i, v in ipairs(childs) do - local nnode = node.nodes[v] - if nnode._menu_selected then - selected_node = nnode - selected_name = v - end - %> - <li class="tabmenu-item-<%=v%><% if nnode._menu_selected or (node.leaf and v == leaf) then %> active<% end %>"> - <a href="<%=nodeurl(prefix, v, nnode.query)%>"><%=striptags(translate(nnode.title))%></a> - </li> - <% - end - %> - </ul> - <br style="clear:both" /> -<% - if selected_node then - subtree(prefix .. selected_name .. "/", selected_node, level + 1) - end -%> - </div> -<% - end - end --%> - -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%=luci.i18n.context.lang%>" lang="<%=luci.i18n.context.lang%>"> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta http-equiv="Content-Script-Type" content="text/javascript" /> -<link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" /> -<% if node and node.css then %><link rel="stylesheet" type="text/css" media="screen" href="<%=resource%>/<%=node.css%>" /> -<% end -%> -<% if css then %><style title="text/css"> -<%= css %> -</style> -<% end -%> -<script type="text/javascript" src="<%=resource%>/xhr.js"></script> -<title><%=gluon_luci.escape( hostname .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI</title> -</head> -<body class="lang_<%=luci.i18n.context.lang%>"> - -<div id="menubar"> -<div class="hostinfo"> - <%=gluon_luci.escape(hostname)%> - <% if release then %> - / <%=gluon_luci.escape(release)%> - <% end %> - <span id="xhr_poll_status" style="display:none" onclick="XHR.running() ? XHR.halt() : XHR.run()"> - | <%:Auto Refresh%>: - <span id="xhr_poll_status_on"><%:on%></span> - <span id="xhr_poll_status_off" style="display:none"><%:off%></span> - </span> -</div> - -<% if #categories > 1 then %> - <ul id="modemenu"> - <% for i, r in ipairs(categories) do %> - <li><a<% if request[1] == r then %> class="active"<%end%> href="<%=controller%>/<%=r%>/"><%=striptags(translate(tree.nodes[r].title))%></a></li> - <% end %> - </ul> -<% end %> - -<% -if tree.nodes[category] and tree.nodes[category].ucidata then - local ucic = 0 - for i, j in pairs(require("simple-uci").cursor():changes()) do - for k, l in pairs(j) do - for m, n in pairs(l) do - ucic = ucic + 1; - end - end - end --%> -<div id="savemenu"> - <% if ucic > 0 then %> - <a class="warning" href="<%=controller%>/<%=category%>/uci/changes/?redir=<%=luci.http.urlencode(luci.http.formvalue("redir") or REQUEST_URI)%>"><%:Unsaved Changes%>: <%=ucic%></a> - <%- else -%> - <a href="#"><%:Changes%>: 0</a> - <% end -%> -</div><% end %> - -</div> - -<div id="maincontainer"> - <% if category then subtree("/" .. category .. "/", cattree) end %> - - <div id="maincontent"> - <noscript> - <div class="errorbox"> - <strong><%:Java Script required!%></strong><br /> - <%:You must enable Java Script in your browser or LuCI will not work properly.%> - </div> - </noscript> diff --git a/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css b/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css deleted file mode 100644 index eb9833df2..000000000 --- a/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css +++ /dev/null @@ -1,2 +0,0 @@ -.lang_he{direction:RTL;unicode-bidi:embed}.hidden{display:none}html{min-height:100%;height:auto;position:relative}body,input,select,option{font-family:'Open Sans', Arial, sans-serif;font-size:12pt}body{color:#4d4e53;line-height:1.5em;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:#f3f3f3}a img{border:none;text-decoration:none}.tabmenu1{text-align:center}ul.tabmenu{list-style:none;padding:0;margin:2em 0;display:inline-flex}ul.tabmenu li{white-space:nowrap;margin:0 0.5em;padding:0;text-align:center}ul.tabmenu li a{display:block;text-decoration:none;padding:1em;margin:0;color:#333;border-radius:2em}ul.tabmenu li a:hover{background:#ffe9b3}ul.tabmenu li.active a{font-weight:bold;background:white;color:#333}abbr,acronym{font-style:normal;font-variant:normal}abbr[title],acronym[title]{border-bottom:1px dotted;cursor:help}a:link abbr[title],a:visited abbr[title],a:link acronym[title],a:visited acronym[title]{cursor:pointer}code{font-family:monospace;white-space:pre}#maincontent ul{margin-left:2em}.warning{color:red;background-color:white;font-weight:bold}.clear{clear:both}.error{color:#ff0000;background-color:white}div.hostinfo{margin:0;padding:0;font-size:80%;padding:0.5em;flex:1;font-weight:bold}#xhr_poll_status{cursor:pointer}#xhr_poll_status #xhr_poll_status_off{font-weight:bold;color:#FF0000}#xhr_poll_status #xhr_poll_status_on{font-weight:bold;color:#00FF00}#menubar{display:flex;background:#dc0067;color:#ffffff}#menubar .warning{color:red;background-color:#557788}#menubar a:link,#menubar a:visited{position:relative;display:block;padding:0.5em;text-decoration:none;font-size:80%;font-weight:normal;color:white}#menubar a:link:hover,#menubar a:visited:hover,#menubar a:link:focus,#menubar a:visited:focus{background:#ffb400;color:black}#menubar a:link.active,#menubar a:visited.active{background:#ffb400;color:black;font-weight:bold}#menubar a:link.warning,#menubar a:visited.warning{background:#000000;color:red;font-weight:bold}#modemenu{list-style:none;margin:0;padding:0}#modemenu li{display:inline-block}.lang_de #submenu_admin_uci{width:12em}.lang_ru #submenu_admin_uci{width:11.5em}textarea#syslog{width:98%;min-height:500px;border:3px solid #cccccc;padding:5px;font-family:monospace}#maincontent{padding:0 1em 2em;max-width:60em;min-width:40em;margin:1em auto}.lang_he #maincontent{direction:rtl}#maincontent p{margin-bottom:1em}.cbi-section{margin:0;padding:0;border:none}.cbi-section legend{font-size:1.4em;font-weight:bold;position:relative;padding:0;margin-bottom:0.5em}.cbi-section h2{margin:0em 0 0.5em -0.5em !important}.cbi-section h3{text-decoration:none !important;font-weight:bold !important;color:#555555 !important;margin:0.25em !important;font-size:100% !important}.cbi-section-descr{margin-bottom:2em}.cbi-title-ref{color:inherit;text-decoration:none;padding-right:18px;background:url("../resources/cbi/link.gif") no-repeat scroll right center;background-color:inherit}ul.cbi-apply{font-size:90%}input:-webkit-input-placeholder{color:#AAAAAA}input:-moz-placeholder{color:#AAAAAA}input:-ms-input-placeholder{color:#AAAAAA}input[type=checkbox]{display:none}input[type=checkbox]+label{display:inline-block;width:1em;height:1em;margin:0}input[type=checkbox]:checked+label:after{content:'✔';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.5em;width:100%;text-align:center;font-size:1.7em}input[type=submit],input[type=reset],input[type=image],input[type=button]{cursor:pointer}select,input,textarea,input[type=checkbox]+label{color:#003247;border:none;background:#ffe199;border-radius:3pt;padding:0.5em}input[type=image]{border:none}select,input[type=text],input[type=password]{width:20em}td select,td input[type=text],td input[type=password]{width:99%}img.cbi-image-button{cursor:pointer;margin:0 2px;vertical-align:middle}input.cbi-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);border:none transparent;background-color:#E6E6E6;text-decoration:none;border-radius:2px;-webkit-transition:0.1s linear -webkit-box-shadow;-moz-transition:0.1s linear -moz-box-shadow;-ms-transition:0.1s linear box-shadow;-o-transition:0.1s linear box-shadow;transition:0.1s linear box-shadow;margin-left:0.5em;background-repeat:no-repeat}input.cbi-button::-moz-focus-inner{padding:0;border:0}input.cbi-button:active{box-shadow:0 0 0 1px rgba(0,0,0,0.15) inset,0 0 6px rgba(0,0,0,0.2) inset}input.cbi-button:focus{outline:0}input.cbi-button:hover,input.cbi-button:focus{background-image:-webkit-gradient(linear, 0 0, 0 100%, from(transparent), color-stop(40%, rgba(0,0,0,0.05)), to(rgba(0,0,0,0.1)));background-image:-webkit-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:-moz-linear-gradient(top, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.1));background-image:-o-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1))}input.cbi-button[disabled]{border:none;background-image:none;opacity:0.40;cursor:not-allowed;box-shadow:none}input.cbi-input-user{background-image:url("../resources/cbi/user.gif");background-repeat:no-repeat;background-position:1px center;color:#000000;text-indent:17px}input.cbi-input-find,input.cbi-button-find{background-image:url("../resources/cbi/find.gif");color:#000000;padding-left:17px}input.cbi-input-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px}input.cbi-input-add,input.cbi-button-add{background-image:url("../resources/cbi/add.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-fieldadd,input.cbi-button-fieldadd{background-image:url(../resources/cbi/fieldadd.gif);color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-reset,input.cbi-button-reset{background-color:#e30;color:#fff}input.cbi-input-save,input.cbi-button-save{background-color:#009ee0;color:#fff}input.cbi-input-apply,input.cbi-button-apply{background-color:#009ee0;color:#fff}input.cbi-input-link,input.cbi-button-link{background-image:url("../resources/cbi/link.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-download,input.cbi-button-download{background-image:url("../resources/cbi/download.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-remove,div.cbi-section-remove input{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-up{background-image:url("../resources/cbi/up.gif");padding-left:11px;padding-right:1px}input.cbi-button-down{background-image:url("../resources/cbi/down.gif");padding-left:11px;padding-right:1px}input.cbi-button-edit{background-image:url("../resources/cbi/edit.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-remove{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}.cbi-input-invalid{background:#e30 !important;color:white}div.cbi-section-remove input{border-bottom:none}textarea{margin-left:-1px;margin-bottom:0.5em}table td,table th{color:#000000}table.smalltext{background:#f5f5f5;color:#000000;border-top:1px solid #666666;border-right:1px solid #666666;border-bottom:1px solid #666666;font-size:90%;width:80%;margin-left:auto;margin-right:auto;border-collapse:collapse}table.smalltext tr:hover td{background-color:#bbddee;color:#000000}table.smalltext tr th{padding:0 0.25em;border-left:1px solid #666666;text-align:left}table.smalltext tr td{padding:0 0.25em;border-top:1px solid #666666;border-left:1px solid #666666}table.cbi-section-table .cbi-rowstyle-1{background-color:#eeeeff;color:#000000}table.cbi-section-table .cbi-rowstyle-1:hover,table.cbi-section-table .cbi-rowstyle-2:hover{background-color:#b2c8d4;color:#000000}table.cbi-section-table .cbi-section-table-cell{padding:3px;white-space:nowrap}.cbi-section .cbi-rowstyle-1 h3{background-color:#eeeeff;color:#555555}.cbi-rowstyle-2{color:#000000}div.cbi-value{display:flex;flex-direction:row;margin-bottom:0.5em}.cbi-value-title{flex:2;text-align:right;padding-right:1em;font-weight:bold}div.cbi-value-field{flex:3;position:relative}div.cbi-value-field input,div.cbi-value-field select,div.cbi-value-field input+label{position:relative;top:-0.39em}div.cbi-value-field-long{flex:10;position:relative}div.cbi-value-field-long input,div.cbi-value-field-long select,div.cbi-value-field-long input+label{position:relative;top:-0.39em}div.cbi-value-field-long-after{flex:2}div.cbi-value-description{font-size:8pt}div.cbi-section-create{clear:left;white-space:nowrap;vertical-align:top}div.cbi-section-create .cbi-button{margin:0.25em}input.cbi-section-create-name{margin-right:-0.25em}div.cbi-map-descr{margin-bottom:1em}.cbi-map-descr:empty,.cbi-section-descr:empty{display:none}.cbi-map-descr,.cbi-section-descr,.cbi-page-actions{padding:1em;background:#ececec}.cbi-page-actions{text-align:right;display:flex;display:-moz-flex;-moz-flex-flow:row-reverse;flex-flow:row-reverse}div.cbi-optionals{padding:0.25em;border-bottom:1px dotted #bbbbbb}div.cbi-section-remove{float:right}.cbi-section-node{clear:both;position:relative;border:none}.cbi-section-node-tabbed{border-top-left-radius:0}.cbi-section-node .cbi-value-last{border-bottom:none}.cbi-section-node table div{padding-bottom:0;border-bottom:none}.cbi-section-node div.cbi-section-table-row{margin:0.25em}table.cbi-section-table{width:100%;font-size:95%}table.cbi-section-table th,table.cbi-section-table td{text-align:center}tr.cbi-section-table-descr th{font-weight:normal;font-size:90%;vertical-align:top}td.cbi-section-table-optionals{text-align:left !important;padding-top:1em}.cbi-value-helpicon img{display:none}div.cbi-error{font-size:95%;font-weight:bold;color:#ff0000;background-color:#ffffff}td.cbi-value-error{border-color:red}.cbi-value-error input,.cbi-value-error select{background-color:#ffcccc}.cbi-section-error{color:red;background-color:white;font-size:95%;border:1px dotted red;margin:3px;padding:3px}.cbi-value-field var{color:#2222FF}ul.cbi-tabmenu{padding:3px 0;margin-left:0 !important;list-style-type:none;position:relative;z-index:10;top:4px;line-height:20px}ul.cbi-tabmenu li.cbi-tab,ul.cbi-tabmenu li.cbi-tab-disabled{display:inline;margin:0}ul.cbi-tabmenu li.cbi-tab a,ul.cbi-tabmenu li.cbi-tab-disabled a{text-decoration:none;padding:3px 7px;margin-right:3px;border:1px solid #BBBBBB;border-bottom:none;border-radius:3px 3px 0 0;background-color:#EEEEEE;color:#BBBBBB}ul.cbi-tabmenu li.cbi-tab-highlighted a{color:#000000;background-color:#FFEEAA}ul.cbi-tabmenu li a:hover{color:#000000}ul.cbi-tabmenu li.cbi-tab a{padding-top:4px;color:#000000;background-color:#FFFFFF}div.cbi-tab-descr{background-image:url(/luci-static/resources/cbi/help.gif);background-position:0.25em 50%;background-repeat:no-repeat;border-bottom:1px solid #CCCCCC;margin:0.25em 0.25em 2em;padding:0.5em 0.5em 0.5em 2em}.left{text-align:left !important}.right{text-align:right !important}.luci{position:absolute;bottom:0;left:1em;height:1.5em;font-size:80%}.luci a:link,.luci a:visited{background-color:transparent;color:#666666;text-decoration:none;font-size:70%}.inline{display:inline}.error500{white-space:normal;border:1px dotted #ff0000;background-color:#ffffff;color:#000000;padding:0.5em}.errorbox{border:1px solid #FF0000;background-color:#FFCCCC;padding:5px;margin-bottom:5px}.errorbox a{color:#000000 !important}.ifacebox{background-color:#FFFFFF;border:1px solid #CCCCCC;margin:0 10px;text-align:center;white-space:nowrap}.ifacebox .ifacebox-head{border-bottom:1px solid #CCCCCC;padding:2px}.ifacebox .ifacebox-body{padding:2px}.ifacebadge{background-color:#FFFFFF;border:1px solid #CCCCCC;padding:2px;margin-left:2px;display:inline-block}.ifacebadge-active{border-color:#000000;font-weight:bold}.zonebadge{padding:2px;display:inline-block;white-space:nowrap;cursor:pointer}.zonebadge em,.zonebadge strong{margin:3px;display:inline-block}.zonebadge input{width:6em;height:1.5em}.zonebadge-empty{border:1px dashed #AAAAAA;color:#AAAAAA;font-style:italic;font-size:smaller}.uci-change-list{font-family:monospace}.uci-change-list ins,.uci-change-legend-label ins{text-decoration:none;border:1px solid #00FF00;background-color:#CCFFCC;display:block;padding:2px}.uci-change-list del,.uci-change-legend-label del{text-decoration:none;border:1px solid #FF0000;background-color:#FFCCCC;display:block;font-style:normal;padding:2px}.uci-change-list var,.uci-change-legend-label var{text-decoration:none;border:1px solid #CCCCCC;background-color:#EEEEEE;display:block;font-style:normal;padding:2px}.uci-change-list var ins,.uci-change-list var del{border:none;white-space:pre;font-style:normal;padding:0px}.uci-change-legend{padding:5px}.uci-change-legend-label{width:150px;float:left;font-size:80%}.uci-change-legend-label>ins,.uci-change-legend-label>del,.uci-change-legend-label>var{float:left;margin-right:4px;width:10px;height:10px;display:block}.uci-change-legend-label var ins,.uci-change-legend-label var del{line-height:6px;border:none}.cbi-input-password+img{display:none}.the-key{text-align:left;font-size:1.4em;background:#ffe9b3;border:3pt dashed #dc0067;margin-bottom:0.5em;padding:0.5em} -/*# sourceMappingURL=cascade.css.map */ diff --git a/package/gluon-luci-theme/luasrc/usr/lib/lua/gluon/luci.lua b/package/gluon-luci-theme/luasrc/usr/lib/lua/gluon/luci.lua deleted file mode 100644 index 6d0278273..000000000 --- a/package/gluon-luci-theme/luasrc/usr/lib/lua/gluon/luci.lua +++ /dev/null @@ -1,28 +0,0 @@ --- Config mode utility functions - -local string = string - -module 'gluon.luci' - -function escape(s) - return (string.gsub(s, '[<>&"]', { - ['<'] = '<', - ['>'] = '>', - ['&'] = '&', - ['"'] = '"', - })) -end - -function urlescape(s) - return (string.gsub(s, '[^a-zA-Z0-9%-_%.~]', - function(c) - local ret = '' - - for i = 1, string.len(c) do - ret = ret .. string.format('%%%02X', string.byte(c, i, i)) - end - - return ret - end - )) -end diff --git a/package/gluon-luci-theme/sass/cascade.scss b/package/gluon-luci-theme/sass/cascade.scss deleted file mode 100644 index bfcfc58cd..000000000 --- a/package/gluon-luci-theme/sass/cascade.scss +++ /dev/null @@ -1,1029 +0,0 @@ -/* ATTENTION: This file is not compiled when building gluon. - The compiled version is at ../files/www/luci-static/gluon/cascade.css - - Use sass like this to update it: - - sass cascade.scss ../files/www/luci-static/gluon/cascade.css - - When commiting changes to this file make sure to commit the respective - changes to the compilid version within the same commit! - */ - -@charset "utf-8"; - -$ffyellow: #ffb400; -$ffmagenta: #dc0067; -$ffzusatz: #009ee0; -$red: #ee3300; - -@mixin button { - &::-moz-focus-inner { - padding: 0; - border: 0; - } - - display: inline-block; - zoom: 1; - line-height: normal; - white-space: nowrap; - vertical-align: baseline; - text-align: center; - cursor: pointer; - -webkit-user-drag: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - - font-size: 100%; - padding: 0.5em 1em; - color: rgba(0, 0, 0, 0.80); - border: none rgba(0, 0, 0, 0); - background-color: #E6E6E6; - text-decoration: none; - border-radius: 2px; - - /* Transitions */ - -webkit-transition: 0.1s linear -webkit-box-shadow; - -moz-transition: 0.1s linear -moz-box-shadow; - -ms-transition: 0.1s linear box-shadow; - -o-transition: 0.1s linear box-shadow; - transition: 0.1s linear box-shadow; - - &:active { - box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 6px rgba(0,0,0, 0.20) inset; - } - - &:focus { - outline: 0; - } - - &:hover, &:focus { - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(transparent), color-stop(40%, rgba(0,0,0, 0.05)), to(rgba(0,0,0, 0.10))); - background-image: -webkit-linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10)); - background-image: -moz-linear-gradient(top, rgba(0,0,0, 0.05) 0%, rgba(0,0,0, 0.10)); - background-image: -o-linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10)); - background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10)); - } - - &[disabled] { - border: none; - background-image: none; - opacity: 0.40; - cursor: not-allowed; - box-shadow: none; - } -} - -@mixin button-primary { - background-color: $ffzusatz; - color: #fff; -} - -.lang_he { - direction: RTL; - unicode-bidi: embed; -} - -.hidden { - display: none; -} - -html { - min-height: 100%; - height: auto; - position:relative; -} - -body, input, select, option { - font-family: 'Open Sans', Arial, sans-serif; - font-size: 12pt; -} - -body { - color: rgb(77, 78, 83); - line-height: 1.5em; - margin: 0; - display: flex; - flex-direction: column; - min-height: 100vh; - background-color: #f3f3f3; -} - -a img { - border: none; - text-decoration: none; -} - -.tabmenu1 { - text-align: center; -} - -ul.tabmenu { - list-style: none; - padding: 0; - margin: 2em 0; - display: inline-flex; -} - -ul.tabmenu li { - white-space: nowrap; - margin: 0 0.5em; - padding: 0; - text-align: center; - - a { - display: block; - text-decoration: none; - padding: 1em; - margin: 0; - color: #333; - border-radius: 2em; - - &:hover { - background: lighten($ffyellow, 35); - } - } - - &.active a { - font-weight: bold; - background: white; - color: #333; - } -} - -abbr, -acronym { - font-style: normal; - font-variant: normal; -} - -abbr[title], -acronym[title] { - border-bottom: 1px dotted; - cursor: help; -} - -a:link abbr[title], -a:visited abbr[title], -a:link acronym[title], -a:visited acronym[title] { - cursor: pointer; -} - -code { - font-family: monospace; - white-space: pre; -} - -#maincontent ul { - margin-left: 2em; -} - -.warning { - color: red; - background-color: white; - font-weight: bold; -} - -.clear { - clear: both; -} - -.error { - color: #ff0000; - background-color: white; -} - -div.hostinfo { - margin: 0; - padding: 0; - font-size: 80%; - padding: 0.5em; - flex: 1; - font-weight: bold; -} - -#xhr_poll_status { - cursor: pointer; -} - -#xhr_poll_status #xhr_poll_status_off { - font-weight: bold; - color: #FF0000; -} - -#xhr_poll_status #xhr_poll_status_on { - font-weight: bold; - color: #00FF00; -} - -#menubar { - display: flex; - background: $ffmagenta; - color: #ffffff; -} - -#menubar .warning { - color: red; - background-color: #557788; -} - -#menubar a:link, -#menubar a:visited { - position: relative; - display: block; - padding: 0.5em; - text-decoration: none; - font-size: 80%; - font-weight: normal; - color: white; -} - -#menubar a:link:hover, -#menubar a:visited:hover, -#menubar a:link:focus, -#menubar a:visited:focus { - background: $ffyellow; - color: black; -} - -#menubar a:link.active, -#menubar a:visited.active { - background: $ffyellow; - color: black; - font-weight: bold; -} - -#menubar a:link.warning, -#menubar a:visited.warning { - background: #000000; - color: red; - font-weight: bold; -} - -#modemenu { - list-style: none; - margin: 0; - padding: 0; -} - -#modemenu li { - display: inline-block; -} - -#savemenu { -} - -.lang_he #savemenu { -} - -.lang_de #submenu_admin_uci { - width: 12em; -} - -.lang_ru #submenu_admin_uci { - width: 11.5em; -} - -textarea#syslog { - width: 98%; - min-height: 500px; - border: 3px solid #cccccc; - padding: 5px; - font-family: monospace; -} - -#maincontent { - padding: 0 1em 2em; - max-width: 60em; - min-width: 40em; - margin: 1em auto; -} - -.lang_he #maincontent { - direction: rtl; -} - -#maincontent h2 { -} - -#maincontent h3 { -} - -#maincontent p { - margin-bottom: 1em; -} - -.cbi-section { - margin: 0; - padding: 0; - border: none; -} - -.cbi-section legend { - font-size: 1.4em; - font-weight: bold; - position: relative; - padding: 0; - margin-bottom: 0.5em; -} - -.cbi-section h2 { - margin: 0em 0 0.5em -0.5em !important; -} - -.cbi-section h3 { - text-decoration: none !important; - font-weight: bold !important; - color: #555555 !important; - margin: 0.25em !important; - font-size: 100% !important; -} - -.cbi-section-descr { - margin-bottom: 2em; -} - -.cbi-title-ref { - color: inherit; - text-decoration: none; - padding-right: 18px; - background: url('../resources/cbi/link.gif') no-repeat scroll right center; - background-color: inherit; -} - -ul.cbi-apply { - font-size: 90%; -} - -input:-webkit-input-placeholder { - color: #AAAAAA; -} - -input:-moz-placeholder { - color: #AAAAAA; -} - -input:-ms-input-placeholder { - color: #AAAAAA; -} - -input[type=checkbox] { - display: none; - - & + label { - display: inline-block; - width: 1em; - height: 1em; - margin: 0; - } - - &:checked + label:after { - content: '✔'; - color: $ffmagenta; - vertical-align: middle; - position: absolute; - top: 50%; - left: 0; - margin-top: -0.5em; - width: 100%; - text-align: center; - font-size: 1.7em; - } -} - -input[type=submit], -input[type=reset], -input[type=image], -input[type=button] { - cursor: pointer; -} - -select, -input, -textarea, -input[type=checkbox] + label { - color: darken($ffzusatz, 30); - border: none; - background: lighten($ffyellow, 30); - border-radius: 3pt; - padding: 0.5em; -} - -input[type=image] { - border: none; -} - -select, -input[type=text], -input[type=password] { - width: 20em; -} - -td select, -td input[type=text], -td input[type=password] { - width: 99%; -} - -img.cbi-image-button { - cursor: pointer; - margin: 0 2px; - vertical-align: middle; -} - -input.cbi-button { - @include button; - - margin-left: 0.5em; - background-repeat: no-repeat; -} - -input.cbi-input-user { - background-image: url('../resources/cbi/user.gif'); - background-repeat: no-repeat; - background-position: 1px center; - color: #000000; - text-indent: 17px; -} - -input.cbi-input-find, -input.cbi-button-find { - background-image: url('../resources/cbi/find.gif'); - color: #000000; - padding-left: 17px; -} - -input.cbi-input-reload { - background-image: url('../resources/cbi/reload.gif'); - color: #000000; - padding-left: 17px; -} - -input.cbi-input-add, -input.cbi-button-add { - background-image: url('../resources/cbi/add.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} - -input.cbi-input-fieldadd, -input.cbi-button-fieldadd { - background-image: url(../resources/cbi/fieldadd.gif); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} - -input.cbi-input-reset, -input.cbi-button-reset { - background-color: $red; - color: #fff; -} - -input.cbi-input-save, -input.cbi-button-save { - @include button-primary; -} - -input.cbi-input-apply, -input.cbi-button-apply { - @include button-primary; -} - -input.cbi-input-link, -input.cbi-button-link { - background-image: url('../resources/cbi/link.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} - -input.cbi-input-download, -input.cbi-button-download { - background-image: url('../resources/cbi/download.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} - -input.cbi-input-remove, -div.cbi-section-remove input { - background-image: url('../resources/cbi/remove.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} - -input.cbi-button-up { - background-image: url('../resources/cbi/up.gif'); - padding-left: 11px; - padding-right: 1px; -} - -input.cbi-button-down { - background-image: url('../resources/cbi/down.gif'); - padding-left: 11px; - padding-right: 1px; -} - -input.cbi-button-edit { - background-image: url('../resources/cbi/edit.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} - -input.cbi-button-reload { - background-image: url('../resources/cbi/reload.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} - -input.cbi-button-remove { - background-image: url('../resources/cbi/remove.gif'); - color: #000000; - padding-left: 17px; - padding-right: 1px; -} - -.cbi-input-invalid { - background: $red !important; - color: white; -} - -div.cbi-section-remove input { - border-bottom: none; -} - -textarea { - margin-left: -1px; - margin-bottom: 0.5em; -} - -table td, -table th { - color: #000000; -} - -table.smalltext { - background: #f5f5f5; - color: #000000; - border-top: 1px solid #666666; - border-right: 1px solid #666666; - border-bottom: 1px solid #666666; - font-size: 90%; - width: 80%; - margin-left: auto; - margin-right: auto; - border-collapse: collapse; -} - -table.smalltext tr:hover td { - background-color: #bbddee; - color: #000000; -} - -table.smalltext tr th { - padding: 0 0.25em; - border-left: 1px solid #666666; - text-align: left; -} - -table.smalltext tr td { - padding: 0 0.25em; - border-top: 1px solid #666666; - border-left: 1px solid #666666; -} - -table.cbi-section-table .cbi-rowstyle-1 { - background-color: #eeeeff; - color: #000000; -} - -table.cbi-section-table .cbi-rowstyle-1:hover, -table.cbi-section-table .cbi-rowstyle-2:hover { - background-color: #b2c8d4; - color: #000000; -} - -table.cbi-section-table .cbi-section-table-cell { - padding: 3px; - white-space: nowrap; -} - -.cbi-section .cbi-rowstyle-1 h3 { - background-color: #eeeeff; - color: #555555; -} - -.cbi-rowstyle-2 { - color: #000000; -} - -div.cbi-value { - display: flex; - flex-direction: row; - margin-bottom: 0.5em; -} - -.cbi-value-title { - flex: 2; - text-align: right; - padding-right: 1em; - font-weight: bold; -} - -div.cbi-value-field { - flex: 3; - position: relative; - - input, select, input + label { - position: relative; - top: -0.39em; - } -} - -div.cbi-value-field-long { - flex: 10; - position: relative; - - - input, select, input + label { - position: relative; - top: -0.39em; - } -} - -div.cbi-value-field-long-after { - flex: 2; -} - -div.cbi-value-description { - font-size: 8pt; -} - -div.cbi-section-create { - clear: left; - white-space: nowrap; - vertical-align: top; -} - -div.cbi-section-create .cbi-button { - margin: 0.25em; -} - -input.cbi-section-create-name { - margin-right: -0.25em; -} - -div.cbi-map-descr { - margin-bottom: 1em; -} - -.cbi-map-descr:empty, .cbi-section-descr:empty { - display: none; -} - -.cbi-map-descr, .cbi-section-descr, .cbi-page-actions { - padding: 1em; - background: #ececec; -} - -.cbi-page-actions { - text-align: right; - display: flex; - display: -moz-flex; - -moz-flex-flow: row-reverse; - flex-flow: row-reverse; -} - -div.cbi-optionals { - padding: 0.25em; - border-bottom: 1px dotted #bbbbbb; -} - -div.cbi-section-remove { - float: right; -} - -.cbi-section-node { - clear: both; - position: relative; - border: none; -} - -.cbi-section-node-tabbed { - border-top-left-radius: 0; -} - -.cbi-section-node .cbi-value-last { - border-bottom: none; -} - -.cbi-section-node table div { - padding-bottom: 0; - border-bottom: none; -} - -.cbi-section-node div.cbi-section-table-row { - margin: 0.25em; -} - -table.cbi-section-table { - width: 100%; - font-size: 95%; -} - -table.cbi-section-table th, -table.cbi-section-table td { - text-align: center; -} - -tr.cbi-section-table-descr th { - font-weight: normal; - font-size: 90%; - vertical-align: top; -} - -td.cbi-section-table-optionals { - text-align: left !important; - padding-top: 1em; -} - -.cbi-value-helpicon img { - display: none; -} - -div.cbi-error { - font-size: 95%; - font-weight: bold; - color: #ff0000; - background-color: #ffffff; -} - -td.cbi-value-error { - border-color: red; -} - -.cbi-value-error input, -.cbi-value-error select { - background-color: #ffcccc; -} - -.cbi-section-error { - color: red; - background-color: white; - font-size: 95%; - border: 1px dotted red; - margin: 3px; - padding: 3px; -} - -.cbi-value-field var { - color: #2222FF; -} - -ul.cbi-tabmenu { - padding: 3px 0; - margin-left: 0 !important; - list-style-type: none; - position: relative; - z-index: 10; - top: 4px; - line-height: 20px; -} - -ul.cbi-tabmenu li.cbi-tab, -ul.cbi-tabmenu li.cbi-tab-disabled { - display: inline; - margin: 0; -} - -ul.cbi-tabmenu li.cbi-tab a, -ul.cbi-tabmenu li.cbi-tab-disabled a { - text-decoration: none; - padding: 3px 7px; - margin-right: 3px; - border: 1px solid #BBBBBB; - border-bottom: none; - border-radius: 3px 3px 0 0; - background-color: #EEEEEE; - color: #BBBBBB; -} - -ul.cbi-tabmenu li.cbi-tab-highlighted a { - color: #000000; - background-color: #FFEEAA; -} - -ul.cbi-tabmenu li a:hover { - color: #000000; -} - -ul.cbi-tabmenu li.cbi-tab a { - padding-top: 4px; - color: #000000; - background-color: #FFFFFF; -} - -div.cbi-tab-descr { - background-image: url(/luci-static/resources/cbi/help.gif); - background-position: 0.25em 50%; - background-repeat: no-repeat; - border-bottom: 1px solid #CCCCCC; - margin: 0.25em 0.25em 2em; - padding: 0.5em 0.5em 0.5em 2em; -} - -.left { - text-align: left !important; -} - -.right { - text-align: right !important; -} - -.luci { - position: absolute; - bottom: 0; - left: 1em; - height: 1.5em; - font-size: 80%; -} - -.luci a:link, -.luci a:visited { - background-color: transparent; - color: #666666; - text-decoration: none; - font-size: 70%; -} - -.inline { - display: inline; -} - -.error500 { - white-space: normal; - border: 1px dotted #ff0000; - background-color: #ffffff; - color: #000000; - padding: 0.5em; -} - -.errorbox { - border: 1px solid #FF0000; - background-color: #FFCCCC; - padding: 5px; - margin-bottom: 5px; -} - -.errorbox a { - color: #000000 !important; -} - - -.ifacebox { - background-color: #FFFFFF; - border: 1px solid #CCCCCC; - margin: 0 10px; - text-align: center; - white-space: nowrap; -} - -.ifacebox .ifacebox-head { - border-bottom: 1px solid #CCCCCC; - padding: 2px; -} - -.ifacebox .ifacebox-body { - padding: 2px; -} - - -.ifacebadge { - background-color: #FFFFFF; - border: 1px solid #CCCCCC; - padding: 2px; - margin-left: 2px; - display: inline-block; -} - -.ifacebadge-active { - border-color: #000000; - font-weight: bold; -} - - -.zonebadge { - padding: 2px; - display: inline-block; - white-space: nowrap; - cursor: pointer; -} - -.zonebadge em, -.zonebadge strong { - margin: 3px; - display: inline-block; -} - -.zonebadge input { - width: 6em; - height: 1.5em; -} - -.zonebadge-empty { - border: 1px dashed #AAAAAA; - color: #AAAAAA; - font-style: italic; - font-size: smaller; -} - - -.uci-change-list { - font-family: monospace; -} - -.uci-change-list ins, -.uci-change-legend-label ins { - text-decoration: none; - border: 1px solid #00FF00; - background-color: #CCFFCC; - display: block; - padding: 2px; -} - -.uci-change-list del, -.uci-change-legend-label del { - text-decoration: none; - border: 1px solid #FF0000; - background-color: #FFCCCC; - display: block; - font-style: normal; - padding: 2px; -} - -.uci-change-list var, -.uci-change-legend-label var { - text-decoration: none; - border: 1px solid #CCCCCC; - background-color: #EEEEEE; - display: block; - font-style: normal; - padding: 2px; -} - -.uci-change-list var ins, -.uci-change-list var del { - /*display: inline;*/ - border: none; - white-space: pre; - font-style: normal; - padding: 0px; -} - -.uci-change-legend { - padding: 5px; -} - -.uci-change-legend-label { - width: 150px; - float: left; - font-size: 80%; -} - -.uci-change-legend-label>ins, -.uci-change-legend-label>del, -.uci-change-legend-label>var { - float: left; - margin-right: 4px; - width: 10px; - height: 10px; - display: block; -} - -.uci-change-legend-label var ins, -.uci-change-legend-label var del { - line-height: 6px; - border: none; -} - -// Hide show/hide password toggle image -.cbi-input-password + img { - display: none; -} - -.the-key { - text-align: left; - font-size: 1.4em; - background: lighten($ffyellow, 35); - border: 3pt dashed $ffmagenta; - margin-bottom: 0.5em; - padding: 0.5em -} diff --git a/package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/controller/admin/wifi-config.lua b/package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/controller/admin/wifi-config.lua deleted file mode 100644 index 2ff1cb847..000000000 --- a/package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/controller/admin/wifi-config.lua +++ /dev/null @@ -1,5 +0,0 @@ -module("luci.controller.admin.wifi-config", package.seeall) - -function index() - entry({"admin", "wifi-config"}, cbi("admin/wifi-config"), _("WLAN"), 20) -end diff --git a/package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua b/package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua deleted file mode 100644 index 903d33a6b..000000000 --- a/package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua +++ /dev/null @@ -1,169 +0,0 @@ -local uci = require("simple-uci").cursor() -local fs = require 'nixio.fs' -local iwinfo = require 'iwinfo' - - -local function find_phy_by_path(path) - for phy in fs.glob("/sys/devices/" .. path .. "/ieee80211/phy*") do - return phy:match("([^/]+)$") - end -end - -local function find_phy_by_macaddr(macaddr) - local addr = macaddr:lower() - for file in fs.glob("/sys/class/ieee80211/*/macaddress") do - if luci.util.trim(fs.readfile(file)) == addr then - return file:match("([^/]+)/macaddress$") - end - end -end - -local function txpower_list(phy) - local list = iwinfo.nl80211.txpwrlist(phy) or { } - local off = tonumber(iwinfo.nl80211.txpower_offset(phy)) or 0 - local new = { } - local prev = -1 - local _, val - for _, val in ipairs(list) do - local dbm = val.dbm + off - local mw = math.floor(10 ^ (dbm / 10)) - if mw ~= prev then - prev = mw - table.insert(new, { - display_dbm = dbm, - display_mw = mw, - driver_dbm = val.dbm, - }) - end - end - return new -end - - -local f = SimpleForm("wifi", translate("WLAN")) - -local s = f:section(SimpleSection, nil, translate( - "You can enable or disable your node's client and mesh network " - .. "SSIDs here. Please don't disable the mesh network without " - .. "a good reason, so other nodes can mesh with yours.<br /><br />" - .. "It is also possible to configure the WLAN adapters transmission power " - .. "here. Please note that the transmission power values include the antenna gain " - .. "where available, but there are many devices for which the gain is unavailable or inaccurate." -)) - -local radios = {} - --- look for wifi interfaces and add them to the array -uci:foreach('wireless', 'wifi-device', - function(s) - table.insert(radios, s['.name']) - end -) - --- add a client and mesh checkbox for each interface -for _, radio in ipairs(radios) do - local config = uci:get_all('wireless', radio) - local p - - if config.hwmode == '11g' or config.hwmode == '11ng' then - p = f:section(SimpleSection, translate("2.4GHz WLAN")) - elseif config.hwmode == '11a' or config.hwmode == '11na' then - p = f:section(SimpleSection, translate("5GHz WLAN")) - end - - if p then - local o - - if uci:get('wireless', 'client_' .. radio) then - o = p:option(Flag, radio .. '_client_enabled', translate("Enable client network (access point)")) - o.default = uci:get_bool('wireless', 'client_' .. radio, "disabled") and o.disabled or o.enabled - o.rmempty = false - end - - if uci:get('wireless', 'mesh_' .. radio) then - o = p:option(Flag, radio .. '_mesh_enabled', translate("Enable mesh network (802.11s)")) - o.default = uci:get_bool('wireless', 'mesh_' .. radio, "disabled") and o.disabled or o.enabled - o.rmempty = false - end - - if uci:get('wireless', 'ibss_' .. radio) then - o = p:option(Flag, radio .. '_ibss_enabled', translate("Enable mesh network (IBSS)")) - o.default = uci:get_bool('wireless', 'ibss_' .. radio, "disabled") and o.disabled or o.enabled - o.rmempty = false - end - - local phy - - if config.path then - phy = find_phy_by_path(config.path) - elseif config.macaddr then - phy = find_phy_by_macaddr(config.macaddr) - end - - if phy then - local txpowers = txpower_list(phy) - - if #txpowers > 1 then - local tp = p:option(ListValue, radio .. '_txpower', translate("Transmission power")) - tp.rmempty = true - tp.default = uci:get('wireless', radio, 'txpower') or 'default' - - tp:value('default', translate("(default)")) - - table.sort(txpowers, function(a, b) return a.driver_dbm > b.driver_dbm end) - - for _, entry in ipairs(txpowers) do - tp:value(entry.driver_dbm, "%i dBm (%i mW)" % {entry.display_dbm, entry.display_mw}) - end - end - end - end - -end - ---when the save-button is pushed -function f.handle(self, state, data) - if state == FORM_VALID then - - for _, radio in ipairs(radios) do - - if uci:get('wireless', 'client_' .. radio) then - local disabled = 0 - if data[radio .. '_client_enabled'] == '0' then - disabled = 1 - end - uci:set('wireless', 'client_' .. radio, "disabled", disabled) - end - - if uci:get('wireless', 'mesh_' .. radio) then - local disabled = 0 - if data[radio .. '_mesh_enabled'] == '0' then - disabled = 1 - end - uci:set('wireless', 'mesh_' .. radio, "disabled", disabled) - end - - if uci:get('wireless', 'ibss_' .. radio) then - local disabled = 0 - if data[radio .. '_ibss_enabled'] == '0' then - disabled = 1 - end - uci:set('wireless', 'ibss_' .. radio, "disabled", disabled) - end - - if data[radio .. '_txpower'] then - if data[radio .. '_txpower'] == 'default' then - uci:delete('wireless', radio, 'txpower') - else - uci:set('wireless', radio, 'txpower', data[radio .. '_txpower']) - end - end - - end - - uci:save('wireless') - uci:commit('wireless') - end -end - -return f diff --git a/package/gluon-setup-mode/Makefile b/package/gluon-setup-mode/Makefile index 4e993d45d..5840d3fd4 100644 --- a/package/gluon-setup-mode/Makefile +++ b/package/gluon-setup-mode/Makefile @@ -15,7 +15,7 @@ define Package/gluon-setup-mode SECTION:=gluon CATEGORY:=Gluon TITLE:=Setup mode - DEPENDS:=+gluon-core +luci-base +uhttpd +dnsmasq + DEPENDS:=+gluon-core +gluon-web +ubus +uhttpd +dnsmasq PROVIDES:=gluon-setup-mode-virtual endef diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S15gluon-setup-mode b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S15gluon-setup-mode index df8a0e2be..80127cc4b 100755 --- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S15gluon-setup-mode +++ b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S15gluon-setup-mode @@ -10,9 +10,7 @@ boot() { uci set 'gluon-setup-mode.@setup_mode[0].enabled=0' uci commit gluon-setup-mode - if [ "$enabled" = 1 -o "$configured" != 1 ]; then - lua -e 'uci_state=require("luci.model.uci").cursor_state(); uci_state:section("gluon-setup-mode", "setup_mode", nil, { running = "1" }); uci_state:save("gluon-setup-mode")' - else + if [ "$enabled" != 1 -a "$configured" = 1 ]; then # This can happen after an upgrade from a version before the config file was called gluon-setup-mode # We'll just reboot to return to the normal mode... /etc/init.d/done boot diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50uhttpd b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50uhttpd index 53118704b..ffe799c98 100755 --- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50uhttpd +++ b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50uhttpd @@ -9,6 +9,6 @@ UHTTPD_BIN="/usr/sbin/uhttpd" start_service() { procd_open_instance procd_set_param respawn - procd_set_param command "$UHTTPD_BIN" -f -h /lib/gluon/setup-mode/www -x /cgi-bin -A 1 -R -p 0.0.0.0:80 + procd_set_param command "$UHTTPD_BIN" -f -h /lib/gluon/web/www -x /cgi-bin -A 1 -R -p 0.0.0.0:80 procd_close_instance } diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/www/index.html b/package/gluon-setup-mode/files/lib/gluon/setup-mode/www/index.html deleted file mode 100644 index 0a7238b55..000000000 --- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/www/index.html +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> -<meta http-equiv="refresh" content="0; URL=/cgi-bin/luci" /> -</head> -<body style="background-color: black"> -<a style="color: white; text-decoration: none" href="/cgi-bin/luci">LuCI - Lua Configuration Interface</a> -</body> -</html> diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/www/luci-static b/package/gluon-setup-mode/files/lib/gluon/setup-mode/www/luci-static deleted file mode 120000 index aea80e059..000000000 --- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/www/luci-static +++ /dev/null @@ -1 +0,0 @@ -/www/luci-static \ No newline at end of file diff --git a/package/gluon-setup-mode/luasrc/lib/gluon/setup-mode/www/cgi-bin/luci b/package/gluon-setup-mode/luasrc/lib/gluon/setup-mode/www/cgi-bin/luci deleted file mode 100755 index c5c984734..000000000 --- a/package/gluon-setup-mode/luasrc/lib/gluon/setup-mode/www/cgi-bin/luci +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/lua -require "luci.cacheloader" -require "luci.sgi.cgi" -luci.dispatcher.indexcache = "/tmp/luci-indexcache" -luci.sgi.cgi.run() diff --git a/package/gluon-luci-admin/Makefile b/package/gluon-web-admin/Makefile similarity index 67% rename from package/gluon-luci-admin/Makefile rename to package/gluon-web-admin/Makefile index bb6f8350d..726cbbe8b 100644 --- a/package/gluon-luci-admin/Makefile +++ b/package/gluon-web-admin/Makefile @@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk -PKG_NAME:=gluon-luci-admin +PKG_NAME:=gluon-web-admin PKG_VERSION:=1 PKG_RELEASE:=1 @@ -14,10 +14,10 @@ include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) -define Package/gluon-luci-admin +define Package/gluon-web-admin SECTION:=gluon CATEGORY:=Gluon - TITLE:=Luci based simple administration interface for mesh nodes + TITLE:=Web-based simple administration interface for mesh nodes DEPENDS:=gluon-config-mode-core-virtual +pretty-hostname endef @@ -29,14 +29,14 @@ define Build/Configure endef define Build/Compile - $(call GluonBuildI18N,gluon-luci-admin,i18n) + $(call GluonBuildI18N,gluon-web-admin,i18n) $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/) endef -define Package/gluon-luci-admin/install +define Package/gluon-web-admin/install $(CP) ./files/* $(1)/ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/ - $(call GluonInstallI18N,gluon-luci-admin,$(1)) + $(call GluonInstallI18N,gluon-web-admin,$(1)) endef -$(eval $(call BuildPackage,gluon-luci-admin)) +$(eval $(call BuildPackage,gluon-web-admin)) diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/info.htm b/package/gluon-web-admin/files/lib/gluon/web/view/admin/info.html similarity index 58% rename from package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/info.htm rename to package/gluon-web-admin/files/lib/gluon/web/view/admin/info.html index c60761e54..6e93b7079 100644 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/info.htm +++ b/package/gluon-web-admin/files/lib/gluon/web/view/admin/info.html @@ -1,24 +1,23 @@ <%- local fs = require 'nixio.fs' local uci = require('simple-uci').cursor() - local util = require 'luci.util' - local i18n = require 'luci.i18n' + local lutil = require 'gluon.web.util' local pretty_hostname = require 'pretty_hostname' - local gluon_luci = require "gluon.luci" local site = require 'gluon.site_config' local sysconfig = require 'gluon.sysconfig' local platform = require 'gluon.platform' + local util = require "gluon.util" local keys = { - hostname = i18n.translate('Hostname'), - primary_mac = i18n.translate('MAC address'), - model = i18n.translate('Hardware model'), - version = i18n.translate('Gluon version'), - release = i18n.translate('Firmware release'), - site = i18n.translate('Site'), - pubkey = i18n.translate('Public VPN key'), + hostname = translate('Hostname'), + primary_mac = translate('MAC address'), + model = translate('Hardware model'), + version = translate('Gluon version'), + release = translate('Firmware release'), + site = translate('Site'), + pubkey = translate('Public VPN key'), } local values = { @@ -33,7 +32,7 @@ local meshvpn_enabled = uci:get_bool("fastd", "mesh_vpn", "enabled") if meshvpn_enabled then - local pubkey = util.trim(util.exec('/etc/init.d/fastd show_key mesh_vpn')) + local pubkey = util.trim(lutil.exec('/etc/init.d/fastd show_key mesh_vpn')) if pubkey ~= '' then values.pubkey = pubkey end @@ -41,7 +40,7 @@ -%> <h2><%:Information%></h2> <% for _, key in ipairs({'hostname', 'primary_mac', 'model', 'version', 'release', 'site', 'pubkey'}) do %> -<div class="cbi-value"> - <div class="cbi-value-title"><%=keys[key]%></div><div class="cbi-value-field"><%=gluon_luci.escape(values[key] or 'n/a')%></div> +<div class="gluon-value"> + <div class="gluon-value-title"><%=keys[key]%></div><div class="gluon-value-field"><%=pcdata(values[key] or 'n/a')%></div> </div> <% end %> diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade.htm b/package/gluon-web-admin/files/lib/gluon/web/view/admin/upgrade.html similarity index 55% rename from package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade.htm rename to package/gluon-web-admin/files/lib/gluon/web/view/admin/upgrade.html index 87702918a..5ce815f7f 100644 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade.htm +++ b/package/gluon-web-admin/files/lib/gluon/web/view/admin/upgrade.html @@ -1,5 +1,4 @@ <%# -LuCI - Lua Configuration Interface Copyright 2008 Steven Barth <steven@midlink.org> Copyright 2008-2009 Jo-Philipp Wich <xm@subsignal.org> @@ -12,44 +11,40 @@ You may obtain a copy of the License at $Id$ -%> - -<%+header%> - <h2><%:Upgrade firmware%></h2> -<form method="post" action="<%=REQUEST_URI%>" enctype="multipart/form-data"> +<form method="post" enctype="multipart/form-data" action="<%=url(request)%>"> <p> <%:You can manually upgrade your firmware here.%> </p> <% if bad_image then %> <p class="error"><%:The provided firmware image is not valid for this device.%></p> <% end %> - <div class="cbi-section-node"> - <div class="cbi-value"> - <label class="cbi-value-title"> + <div class="gluon-section-node"> + <div class="gluon-value"> + <label class="gluon-value-title"> <%:Firmware image%> </label> - <div class="cbi-value-field"> - <input class="cbi-input-file" type="file" name="image" /> + <div class="gluon-value-field"> + <input class="gluon-input-file" type="file" name="image" /> </div> </div> - <div class="cbi-value cbi-value-last"> - <label class="cbi-value-title"> + <div class="gluon-value gluon-value-last"> + <label class="gluon-value-title"> <%:Keep settings%> </label> - <div class="cbi-value-field"> - <input id="keepcfg" class="cbi-input-checkbox" type="checkbox" name="keepcfg" value="1" checked="checked" /> + <div class="gluon-value-field"> + <input id="keepcfg" class="gluon-input-checkbox" type="checkbox" name="keepcfg" value="1" checked="checked" /> <label for="keepcfg"></label> </div> </div> </div> - <div class="cbi-page-actions right"> + <div class="gluon-page-actions right"> <input type="hidden" name="step" value="2" /> <input type="hidden" name="token" value="<%=token%>" /> - <input class="cbi-button cbi-button-apply" type="submit" value="<%:Upload image%>" /> + <input class="gluon-button gluon-button-submit" type="submit" value="<%:Upload image%>" /> </div> </form> -<%+footer%> diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_confirm.htm b/package/gluon-web-admin/files/lib/gluon/web/view/admin/upgrade_confirm.html similarity index 78% rename from package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_confirm.htm rename to package/gluon-web-admin/files/lib/gluon/web/view/admin/upgrade_confirm.html index a5ef81096..6659d3638 100644 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_confirm.htm +++ b/package/gluon-web-admin/files/lib/gluon/web/view/admin/upgrade_confirm.html @@ -1,5 +1,4 @@ <%# -LuCI - Lua Configuration Interface Copyright 2008 Steven Barth <steven@midlink.org> Copyright 2008-2009 Jo-Philipp Wich <xm@subsignal.org> @@ -8,13 +7,8 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ - -%> -<%+header%> - <h2><%:Upgrade firmware%></h2> <p> @@ -43,7 +37,7 @@ $Id$ write(byte_format(filesize)) if flashsize > 0 then - write(luci.i18n.translatef( + write(translatef( " (%s available)", byte_format(flashsize) )) @@ -51,18 +45,17 @@ $Id$ %></li> </ul> </p> -<div class="cbi-page-actions"> - <form method="post" action="<%=REQUEST_URI%>" style="display:inline"> +<div class="gluon-page-actions"> + <form method="post" enctype="multipart/form-data" action="<%=url(request)%>" style="display:inline"> <input type="hidden" name="step" value="3" /> <input type="hidden" name="keepcfg" value="<%=keepconfig and "1" or "0"%>" /> <input type="hidden" name="token" value="<%=token%>" /> - <input class="cbi-button cbi-button-apply" type="submit" value="<%:Continue%>" /> + <input class="gluon-button gluon-button-submit" type="submit" value="<%:Continue%>" /> </form> - <form method="post" action="<%=REQUEST_URI%>" style="display:inline"> + <form method="post" enctype="multipart/form-data" action="<%=url(request)%>" style="display:inline"> <input type="hidden" name="step" value="1" /> <input type="hidden" name="keepcfg" value="<%=keepconfig and "1" or "0"%>" /> <input type="hidden" name="token" value="<%=token%>" /> - <input class="cbi-button cbi-button-reset" type="submit" value="<%:Cancel%>" /> + <input class="gluon-button gluon-button-reset" type="submit" value="<%:Cancel%>" /> </form> </div> -<%+footer%> diff --git a/package/gluon-web-admin/files/lib/gluon/web/view/admin/upgrade_reboot.html b/package/gluon-web-admin/files/lib/gluon/web/view/admin/upgrade_reboot.html new file mode 100644 index 000000000..44f0e3cc4 --- /dev/null +++ b/package/gluon-web-admin/files/lib/gluon/web/view/admin/upgrade_reboot.html @@ -0,0 +1,5 @@ +<p> + <%:The firmware is currently being upgraded.%> + <strong><%:Don't switch off the device in any circumstance!%></strong> + <%:The upgrade will take a few minutes. When it is finished, your node will reboot automatically.%> +</p> diff --git a/package/gluon-luci-admin/i18n/de.po b/package/gluon-web-admin/i18n/de.po similarity index 91% rename from package/gluon-luci-admin/i18n/de.po rename to package/gluon-web-admin/i18n/de.po index e2a371d83..fdfb685dd 100644 --- a/package/gluon-luci-admin/i18n/de.po +++ b/package/gluon-web-admin/i18n/de.po @@ -10,6 +10,12 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +msgid "(%s available)" +msgstr "(%s verfügbar)" + +msgid "Advanced settings" +msgstr "Erweiterte Einstellungen" + msgid "" "Alternatively, you can set a password to access you node. Please choose a " "secure password you don't use anywhere else.<br /><br />If you set an empty " @@ -20,15 +26,18 @@ msgstr "" "leeren Passworts wird der Login per Passwort gesperrt (dies ist die Standard-" "Einstellung)." +msgid "Cancel" +msgstr "Abbrechen" + +msgid "Confirmation" +msgstr "Bestätigung" + msgid "Continue" msgstr "Fortfahren" msgid "Don't switch off the device in any circumstance!" msgstr "Unterbrich auf keinen Fall die Stromversorgung!" -msgid "Advanced settings" -msgstr "Erweiterte Einstellungen" - msgid "Firmware image" msgstr "Firmware-Datei" @@ -41,12 +50,21 @@ msgstr "Gluon-Version" msgid "Hardware model" msgstr "Hardware-Modell" +msgid "Hostname" +msgstr "Hostname" + msgid "Information" msgstr "Info" +msgid "Keep settings" +msgstr "Konfiguration behalten" + msgid "MAC address" msgstr "MAC-Adresse" +msgid "Password" +msgstr "Passwort" + msgid "Password changed." msgstr "Passwort geändert." @@ -65,6 +83,9 @@ msgstr "SSH-Schlüssel" msgid "Site" msgstr "Site" +msgid "Size" +msgstr "Größe" + msgid "" "The firmware image has been transmitted. Please ensure the MD5 checksum and " "image size are correct and click \"continue\"." @@ -97,9 +118,6 @@ msgstr "Das Passwort konnte nicht geändert werden." msgid "Upgrade firmware" msgstr "Firmware aktualisieren" -msgid "Upgrading firmware" -msgstr "Firmware wird aktualisiert" - msgid "Upload image" msgstr "Datei hochladen" diff --git a/package/gluon-luci-admin/i18n/fr.po b/package/gluon-web-admin/i18n/fr.po similarity index 92% rename from package/gluon-luci-admin/i18n/fr.po rename to package/gluon-web-admin/i18n/fr.po index 0a876a35f..6a0f73a42 100644 --- a/package/gluon-luci-admin/i18n/fr.po +++ b/package/gluon-web-admin/i18n/fr.po @@ -10,6 +10,12 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +msgid "(%s available)" +msgstr "" + +msgid "Advanced settings" +msgstr "Paramètres avancés" + msgid "" "Alternatively, you can set a password to access you node. Please choose a " "secure password you don't use anywhere else.<br /><br />If you set an empty " @@ -21,15 +27,18 @@ msgstr "" "par mot de passe sera désactivée. La connexion par mot de passe est " "désactivée par défaut." +msgid "Cancel" +msgstr "Annuler" + +msgid "Confirmation" +msgstr "Confirmation" + msgid "Continue" msgstr "Continuer" msgid "Don't switch off the device in any circumstance!" msgstr "N'interrompez en aucun cas l'alimentation!" -msgid "Advanced settings" -msgstr "Paramètres avancés" - msgid "Firmware image" msgstr "Fichier image" @@ -42,12 +51,21 @@ msgstr "Version de Gluon" msgid "Hardware model" msgstr "Modèle du Matériel" +msgid "Hostname" +msgstr "Nom d'hôte" + msgid "Information" msgstr "Informations" +msgid "Keep settings" +msgstr "Garder le paramètrage" + msgid "MAC address" msgstr "Adresse MAC" +msgid "Password" +msgstr "Mot de passe" + msgid "Password changed." msgstr "Mot de passe changé." @@ -66,6 +84,9 @@ msgstr "Clé SSH" msgid "Site" msgstr "Site" +msgid "Size" +msgstr "Taille" + msgid "" "The firmware image has been transmitted. Please ensure the MD5 checksum and " "image size are correct and click \"continue\"." @@ -98,9 +119,6 @@ msgstr "Le mot de passe n'a pas pu être changé." msgid "Upgrade firmware" msgstr "Mettre à jour la firmware" -msgid "Upgrading firmware" -msgstr "Mise à jour de la firmware" - msgid "Upload image" msgstr "Transférer l'image" diff --git a/package/gluon-luci-admin/i18n/gluon-luci-admin.pot b/package/gluon-web-admin/i18n/gluon-web-admin.pot similarity index 89% rename from package/gluon-luci-admin/i18n/gluon-luci-admin.pot rename to package/gluon-web-admin/i18n/gluon-web-admin.pot index d8a0adb0e..ace05e8f8 100644 --- a/package/gluon-luci-admin/i18n/gluon-luci-admin.pot +++ b/package/gluon-web-admin/i18n/gluon-web-admin.pot @@ -1,19 +1,28 @@ msgid "" msgstr "Content-Type: text/plain; charset=UTF-8" +msgid "(%s available)" +msgstr "" + +msgid "Advanced settings" +msgstr "" + msgid "" "Alternatively, you can set a password to access you node. Please choose a " "secure password you don't use anywhere else.<br /><br />If you set an empty " "password, login via password will be disabled. This is the default." msgstr "" -msgid "Continue" +msgid "Cancel" msgstr "" -msgid "Don't switch off the device in any circumstance!" +msgid "Confirmation" msgstr "" -msgid "Advanced settings" +msgid "Continue" +msgstr "" + +msgid "Don't switch off the device in any circumstance!" msgstr "" msgid "Firmware image" @@ -28,12 +37,21 @@ msgstr "" msgid "Hardware model" msgstr "" +msgid "Hostname" +msgstr "" + msgid "Information" msgstr "" +msgid "Keep settings" +msgstr "" + msgid "MAC address" msgstr "" +msgid "Password" +msgstr "" + msgid "Password changed." msgstr "" @@ -52,6 +70,9 @@ msgstr "" msgid "Site" msgstr "" +msgid "Size" +msgstr "" + msgid "" "The firmware image has been transmitted. Please ensure the MD5 checksum and " "image size are correct and click \"continue\"." @@ -80,9 +101,6 @@ msgstr "" msgid "Upgrade firmware" msgstr "" -msgid "Upgrading firmware" -msgstr "" - msgid "Upload image" msgstr "" diff --git a/package/gluon-web-admin/luasrc/lib/gluon/web/controller/admin/index.lua b/package/gluon-web-admin/luasrc/lib/gluon/web/controller/admin/index.lua new file mode 100644 index 000000000..109f009a4 --- /dev/null +++ b/package/gluon-web-admin/luasrc/lib/gluon/web/controller/admin/index.lua @@ -0,0 +1,9 @@ +local root = node() +if not root.target then + root.target = alias("admin") +end + +entry({"admin"}, alias("admin", "info"), _("Advanced settings"), 10) + +entry({"admin", "info"}, template("admin/info"), _("Information"), 1) +entry({"admin", "remote"}, model("admin/remote"), _("Remote access"), 10) diff --git a/package/gluon-web-admin/luasrc/lib/gluon/web/controller/admin/upgrade.lua b/package/gluon-web-admin/luasrc/lib/gluon/web/controller/admin/upgrade.lua new file mode 100644 index 000000000..a41483d0d --- /dev/null +++ b/package/gluon-web-admin/luasrc/lib/gluon/web/controller/admin/upgrade.lua @@ -0,0 +1,139 @@ +--[[ +Copyright 2008 Steven Barth <steven@midlink.org> +Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 +]]-- + +local fs = require 'nixio.fs' + +local tmpfile = "/tmp/firmware.img" + + +local function filehandler(meta, chunk, eof) + if not fs.access(tmpfile) and not file and chunk and #chunk > 0 then + file = io.open(tmpfile, "w") + end + if file and chunk then + file:write(chunk) + end + if file and eof then + file:close() + end +end + +local function action_upgrade(http, renderer) + local disp = require 'gluon.web.dispatcher' + local nixio = require 'nixio' + + local function fork_exec(...) + local pid = nixio.fork() + if pid > 0 then + return + elseif pid == 0 then + -- change to root dir + nixio.chdir("/") + + -- patch stdin, out, err to /dev/null + local null = nixio.open("/dev/null", "w+") + if null then + nixio.dup(null, nixio.stderr) + nixio.dup(null, nixio.stdout) + nixio.dup(null, nixio.stdin) + if null:fileno() > 2 then + null:close() + end + end + + -- Sleep a little so the browser can fetch everything required to + -- display the reboot page, then reboot the device. + nixio.nanosleep(1) + + -- replace with target command + nixio.exec(...) + end + end + + local function image_supported(tmpfile) + -- XXX: yay... + return (os.execute(string.format("/sbin/sysupgrade -T %q >/dev/null", tmpfile)) == 0) + end + + local function storage_size() + local size = 0 + if fs.access("/proc/mtd") then + for l in io.lines("/proc/mtd") do + local d, s, e, n = l:match('^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+"([^%s]+)"') + if n == "linux" then + size = tonumber(s, 16) + break + end + end + elseif fs.access("/proc/partitions") then + for l in io.lines("/proc/partitions") do + local x, y, b, n = l:match('^%s*(%d+)%s+(%d+)%s+([^%s]+)%s+([^%s]+)') + if b and n and not n:match('[0-9]') then + size = tonumber(b) * 1024 + break + end + end + end + return size + end + + local function image_checksum(tmpfile) + return (gluon.web.util.exec(string.format("md5sum %q", tmpfile)):match("^([^%s]+)")) + end + + + -- Determine state + local step = tonumber(http:getenv("REQUEST_METHOD") == "POST" and http:formvalue("step")) or 1 + + local has_image = fs.access(tmpfile) + local has_support = has_image and image_supported(tmpfile) + + -- Step 1: file upload, error on unsupported image format + if step == 1 or not has_support then + -- If there is an image but user has requested step 1 + -- or type is not supported, then remove it. + if has_image then + fs.unlink(tmpfile) + end + + renderer.render("layout", { + content = "admin/upgrade", + bad_image = has_image and not has_support, + }) + + -- Step 2: present uploaded file, show checksum, confirmation + elseif step == 2 then + renderer.render("layout", { + content = "admin/upgrade_confirm", + checksum = image_checksum(tmpfile), + filesize = fs.stat(tmpfile).size, + flashsize = storage_size(), + keepconfig = (http:formvalue("keepcfg") == "1"), + }) + elseif step == 3 then + if http:formvalue("keepcfg") == "1" then + fork_exec("/sbin/sysupgrade", tmpfile) + else + fork_exec("/sbin/sysupgrade", "-n", tmpfile) + end + renderer.render("layout", { + content = "admin/upgrade_reboot", + hidenav = true, + }) + end +end + + +local has_platform = fs.access("/lib/upgrade/platform.sh") +if has_platform then + local upgrade = entry({"admin", "upgrade"}, call(action_upgrade), _("Upgrade firmware"), 90) + upgrade.filehandler = filehandler +end diff --git a/package/gluon-web-admin/luasrc/lib/gluon/web/model/admin/remote.lua b/package/gluon-web-admin/luasrc/lib/gluon/web/model/admin/remote.lua new file mode 100644 index 000000000..ba1424d32 --- /dev/null +++ b/package/gluon-web-admin/luasrc/lib/gluon/web/model/admin/remote.lua @@ -0,0 +1,109 @@ +--[[ +Copyright 2008 Steven Barth <steven@midlink.org> +Copyright 2011 Jo-Philipp Wich <xm@subsignal.org> +Copyright 2013 Nils Schneider <nils@nilsschneider.net> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 +]]-- + +local nixio = require "nixio" +local fs = require "nixio.fs" +local util = require "gluon.util" + +local f_keys = Form(translate("SSH keys"), translate("You can provide your SSH keys here (one per line):"), 'keys') +local s = f_keys:section(Section) +local keys = s:option(TextValue, "keys") +keys.wrap = "off" +keys.rows = 5 +keys.default = fs.readfile("/etc/dropbear/authorized_keys") or "" + +function keys:write(value) + value = util.trim(value:gsub("\r", "")) + if value ~= "" then + fs.writefile("/etc/dropbear/authorized_keys", value .. "\n") + else + fs.remove("/etc/dropbear/authorized_keys") + end +end + + +local f_password = Form(translate("Password"), + translate( + "Alternatively, you can set a password to access you node. Please choose a secure password you don't use anywhere else.<br /><br />" + .. "If you set an empty password, login via password will be disabled. This is the default." + ), 'password' +) +f_password.reset = false + +local s = f_password:section(Section) + +local pw1 = s:option(Value, "pw1", translate("Password")) +pw1.password = true +function pw1.cfgvalue() + return '' +end + +local pw2 = s:option(Value, "pw2", translate("Confirmation")) +pw2.password = true +function pw2.cfgvalue() + return '' +end + +local function set_password(password) + local inr, inw = nixio.pipe() + local pid = nixio.fork() + + if pid < 0 then + return false + elseif pid == 0 then + inw:close() + + local null = nixio.open('/dev/null', 'w') + nixio.dup(null, nixio.stderr) + nixio.dup(null, nixio.stdout) + if null:fileno() > 2 then + null:close() + end + + nixio.dup(inr, nixio.stdin) + inr:close() + + nixio.execp('passwd') + os.exit(127) + end + + inr:close() + + inw:write(string.format('%s\n%s\n', password, password)) + inw:close() + + local wpid, status, code = nixio.waitpid(pid) + return wpid and status == 'exited' and code == 0 +end + +function f_password:write() + if pw1.data ~= pw2.data then + f_password.errmessage = translate("The password and the confirmation differ.") + return + end + + local pw = pw1.data + + if #pw > 0 then + if set_password(pw) then + f_password.message = translate("Password changed.") + else + f_password.errmessage = translate("Unable to change the password.") + end + else + -- We don't check the return code here as the error 'password for root is already locked' is normal... + os.execute('passwd -l root >/dev/null') + f_password.message = translate("Password removed.") + end +end + +return f_keys, f_password diff --git a/package/gluon-luci-autoupdater/Makefile b/package/gluon-web-autoupdater/Makefile similarity index 60% rename from package/gluon-luci-autoupdater/Makefile rename to package/gluon-web-autoupdater/Makefile index 4cecb10ac..398aa75c3 100644 --- a/package/gluon-luci-autoupdater/Makefile +++ b/package/gluon-web-autoupdater/Makefile @@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk -PKG_NAME:=gluon-luci-autoupdater +PKG_NAME:=gluon-web-autoupdater PKG_VERSION:=1 PKG_RELEASE:=1 @@ -14,11 +14,11 @@ include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) -define Package/gluon-luci-autoupdater +define Package/gluon-web-autoupdater SECTION:=gluon CATEGORY:=Gluon - TITLE:=Luci module for gluon-autoupdater - DEPENDS:=+gluon-luci-admin +gluon-autoupdater + TITLE:=gluon-web module for gluon-autoupdater + DEPENDS:=+gluon-web-admin +gluon-autoupdater endef define Build/Prepare @@ -29,13 +29,13 @@ define Build/Configure endef define Build/Compile - $(call GluonBuildI18N,gluon-luci-autoupdater,i18n) + $(call GluonBuildI18N,gluon-web-autoupdater,i18n) $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/) endef -define Package/gluon-luci-autoupdater/install +define Package/gluon-web-autoupdater/install $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/ - $(call GluonInstallI18N,gluon-luci-autoupdater,$(1)) + $(call GluonInstallI18N,gluon-web-autoupdater,$(1)) endef -$(eval $(call BuildPackage,gluon-luci-autoupdater)) +$(eval $(call BuildPackage,gluon-web-autoupdater)) diff --git a/package/gluon-luci-autoupdater/i18n/de.po b/package/gluon-web-autoupdater/i18n/de.po similarity index 92% rename from package/gluon-luci-autoupdater/i18n/de.po rename to package/gluon-web-autoupdater/i18n/de.po index 9fd4cf537..9f1fbecf7 100644 --- a/package/gluon-luci-autoupdater/i18n/de.po +++ b/package/gluon-web-autoupdater/i18n/de.po @@ -1,12 +1,12 @@ msgid "" msgstr "" -"Content-Type: text/plain; charset=UTF-8\n" "Project-Id-Version: PACKAGE VERSION\n" "PO-Revision-Date: 2015-05-04 01:55+0200\n" "Last-Translator: <mschiffer@universe-factory.net>\n" "Language-Team: German\n" "Language: de\n" "MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" @@ -15,3 +15,6 @@ msgstr "Automatische Updates" msgid "Branch" msgstr "Branch" + +msgid "Enable" +msgstr "Aktivieren" diff --git a/package/gluon-luci-autoupdater/i18n/fr.po b/package/gluon-web-autoupdater/i18n/fr.po similarity index 93% rename from package/gluon-luci-autoupdater/i18n/fr.po rename to package/gluon-web-autoupdater/i18n/fr.po index 28263806a..fec24176b 100644 --- a/package/gluon-luci-autoupdater/i18n/fr.po +++ b/package/gluon-web-autoupdater/i18n/fr.po @@ -1,12 +1,12 @@ msgid "" msgstr "" -"Content-Type: text/plain; charset=UTF-8\n" "Project-Id-Version: PACKAGE VERSION\n" "PO-Revision-Date: 2015-08-19 20:20+0100\n" "Last-Translator: Bernot Tobias <tqbs@airmail.cc>\n" "Language-Team: French\n" "Language: fr\n" "MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" @@ -15,3 +15,6 @@ msgstr "Mise a jour automatique" msgid "Branch" msgstr "Branche" + +msgid "Enable" +msgstr "Activer" diff --git a/package/gluon-luci-autoupdater/i18n/gluon-luci-autoupdater.pot b/package/gluon-web-autoupdater/i18n/gluon-web-autoupdater.pot similarity index 82% rename from package/gluon-luci-autoupdater/i18n/gluon-luci-autoupdater.pot rename to package/gluon-web-autoupdater/i18n/gluon-web-autoupdater.pot index 678bdbaf6..1cce85c36 100644 --- a/package/gluon-luci-autoupdater/i18n/gluon-luci-autoupdater.pot +++ b/package/gluon-web-autoupdater/i18n/gluon-web-autoupdater.pot @@ -6,3 +6,6 @@ msgstr "" msgid "Branch" msgstr "" + +msgid "Enable" +msgstr "" diff --git a/package/gluon-web-autoupdater/luasrc/lib/gluon/web/controller/admin/autoupdater.lua b/package/gluon-web-autoupdater/luasrc/lib/gluon/web/controller/admin/autoupdater.lua new file mode 100644 index 000000000..abf2b7822 --- /dev/null +++ b/package/gluon-web-autoupdater/luasrc/lib/gluon/web/controller/admin/autoupdater.lua @@ -0,0 +1 @@ +entry({"admin", "autoupdater"}, model("admin/autoupdater"), _("Automatic updates"), 80) diff --git a/package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua b/package/gluon-web-autoupdater/luasrc/lib/gluon/web/model/admin/autoupdater.lua similarity index 58% rename from package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua rename to package/gluon-web-autoupdater/luasrc/lib/gluon/web/model/admin/autoupdater.lua index 1b9fcc0f4..adf7cbd6d 100644 --- a/package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua +++ b/package/gluon-web-autoupdater/luasrc/lib/gluon/web/model/admin/autoupdater.lua @@ -1,6 +1,4 @@ --[[ -LuCI - Lua Configuration Interface - Copyright 2013 Nils Schneider <nils@nilsschneider.net> Licensed under the Apache License, Version 2.0 (the "License"); @@ -8,20 +6,20 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ ]]-- local uci = require("simple-uci").cursor() local autoupdater = uci:get_first("autoupdater", "autoupdater") -local f = SimpleForm("autoupdater", translate("Automatic updates")) -local s = f:section(SimpleSection, nil, nil) +local f = Form(translate("Automatic updates")) +local s = f:section(Section) local o o = s:option(Flag, "enabled", translate("Enable")) -o.default = uci:get_bool("autoupdater", autoupdater, "enabled") and o.enabled or o.disabled -o.rmempty = false +o.default = uci:get_bool("autoupdater", autoupdater, "enabled") +function o:write(data) + uci:set("autoupdater", autoupdater, "enabled", data) +end o = s:option(ListValue, "branch", translate("Branch")) uci:foreach("autoupdater", "branch", @@ -30,16 +28,11 @@ uci:foreach("autoupdater", "branch", end ) o.default = uci:get("autoupdater", autoupdater, "branch") +function o:write(data) + uci:set("autoupdater", autoupdater, "branch", data) +end -function f.handle(self, state, data) - if state ~= FORM_VALID then - return - end - - uci:set("autoupdater", autoupdater, "enabled", data.enabled) - uci:set("autoupdater", autoupdater, "branch", data.branch) - - uci:save("autoupdater") +function f:write() uci:commit("autoupdater") end diff --git a/package/gluon-luci-mesh-vpn-fastd/Makefile b/package/gluon-web-mesh-vpn-fastd/Makefile similarity index 63% rename from package/gluon-luci-mesh-vpn-fastd/Makefile rename to package/gluon-web-mesh-vpn-fastd/Makefile index 71dadce79..bdc1828f5 100644 --- a/package/gluon-luci-mesh-vpn-fastd/Makefile +++ b/package/gluon-web-mesh-vpn-fastd/Makefile @@ -1,6 +1,6 @@ include $(TOPDIR)/rules.mk -PKG_NAME:=gluon-luci-mesh-vpn-fastd +PKG_NAME:=gluon-web-mesh-vpn-fastd PKG_VERSION:=1 PKG_RELEASE:=1 @@ -11,11 +11,11 @@ include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) -define Package/gluon-luci-mesh-vpn-fastd +define Package/gluon-web-mesh-vpn-fastd SECTION:=gluon CATEGORY:=Gluon - TITLE:=Luci module to enable and disable encryption for the mesh VPN - DEPENDS:=+gluon-luci-admin +gluon-mesh-vpn-fastd + TITLE:=gluon-web module to enable and disable encryption for the mesh VPN + DEPENDS:=+gluon-web-admin +gluon-mesh-vpn-fastd endef define Build/Prepare @@ -30,15 +30,15 @@ define Build/Compile $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/) endef -define Package/gluon-luci-mesh-vpn-fastd/install +define Package/gluon-web-mesh-vpn-fastd/install $(CP) ./files/* $(1)/ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/ $(call GluonInstallI18N,gluon-mesh-vpn-fastd,$(1)) endef -define Package/gluon-luci-mesh-vpn-fastd/postinst +define Package/gluon-web-mesh-vpn-fastd/postinst #!/bin/sh $(call GluonCheckSite,check_site.lua) endef -$(eval $(call BuildPackage,gluon-luci-mesh-vpn-fastd)) +$(eval $(call BuildPackage,gluon-web-mesh-vpn-fastd)) diff --git a/package/gluon-luci-mesh-vpn-fastd/check_site.lua b/package/gluon-web-mesh-vpn-fastd/check_site.lua similarity index 100% rename from package/gluon-luci-mesh-vpn-fastd/check_site.lua rename to package/gluon-web-mesh-vpn-fastd/check_site.lua diff --git a/package/gluon-web-mesh-vpn-fastd/files/lib/gluon/web/view/gluon/model/mesh-vpn-fastd.html b/package/gluon-web-mesh-vpn-fastd/files/lib/gluon/web/view/gluon/model/mesh-vpn-fastd.html new file mode 100644 index 000000000..ab5d61bdc --- /dev/null +++ b/package/gluon-web-mesh-vpn-fastd/files/lib/gluon/web/view/gluon/model/mesh-vpn-fastd.html @@ -0,0 +1,32 @@ +<div class="gluon-value"> + <div class="gluon-value-title"> + <input class="gluon-input-radio" data-update="change" type="radio" value="security"<%= attr("id", id..'1') .. attr("name", id) .. attr("checked", ((self:cfgvalue() or self.default) == "security") and "checked") %> /> + </div> + <div class="gluon-value-field-long"> + <label<%= attr("for", id..'1') %> class="gluon-value-title"><%:Security mode%></label> + <br /> + <%= translate( + 'In security mode, the mesh VPN uses an encrypted tunnel to connect to the VPN servers. ' .. + 'The encryption ensures that it is impossible for your internet access provider to see what ' .. + 'data is exchanged over your node.' + ) %> + <br /> + </div> + <div class="gluon-value-field-long-after"></div> +</div> + +<div class="gluon-value gluon-value-last"> + <div class="gluon-value-title"> + <input class="gluon-input-radio" data-update="change" type="radio" value="performance"<%= attr("id", id..'2') .. attr("name", id) .. attr("checked", ((self:cfgvalue() or self.default) == "performance") and "checked") %> /> + </div> + <div class="gluon-value-field-long"> + <label<%= attr("for", id..'2') %> class="gluon-value-title"><%:Performance mode%></label> + <br /> + <%= translate( + 'In performance mode, no encryption is used. This usually allows for higher throughput, but the data exchanged over your node is not ' .. + 'protected against eavesdropping.' + ) %> + <br /> + </div> + <div class="gluon-value-field-long-after"></div> +</div> diff --git a/package/gluon-luci-mesh-vpn-fastd/i18n/de.po b/package/gluon-web-mesh-vpn-fastd/i18n/de.po similarity index 89% rename from package/gluon-luci-mesh-vpn-fastd/i18n/de.po rename to package/gluon-web-mesh-vpn-fastd/i18n/de.po index 12e48439b..eb2b751cd 100644 --- a/package/gluon-luci-mesh-vpn-fastd/i18n/de.po +++ b/package/gluon-web-mesh-vpn-fastd/i18n/de.po @@ -15,7 +15,7 @@ msgid "" "throughput, but the data exchanged over your node is not protected against " "eavesdropping." msgstr "" -"Im Modus „Hohe Geschwindigkeit“ wird auf Verschlüsselung " +"Im Modus „Hohe Geschwindigkeit“ wird auf Verschlüsselung " "verzichtet. Dies erlaubt häufig eine höhere Bandbreite als mit " "Verschlüsselung, aber die Verbindung ist nicht gegen Abhören geschützt." @@ -24,7 +24,7 @@ msgid "" "VPN servers. The encryption ensures that it is impossible for your internet " "access provider to see what data is exchanged over your node." msgstr "" -"Im Modus „Hohe Sicherheit“ wird ein verschlüsselter Tunnel " +"Im Modus „Hohe Sicherheit“ wird ein verschlüsselter Tunnel " "verwendet. Dies schließt aus, dass dein Internetzugangsprovider herausfinden " "kann, was für Daten über deinen Knoten übertragen werden." diff --git a/package/gluon-luci-mesh-vpn-fastd/i18n/fr.po b/package/gluon-web-mesh-vpn-fastd/i18n/fr.po similarity index 100% rename from package/gluon-luci-mesh-vpn-fastd/i18n/fr.po rename to package/gluon-web-mesh-vpn-fastd/i18n/fr.po diff --git a/package/gluon-luci-mesh-vpn-fastd/i18n/gluon-luci-mesh-vpn-fastd.pot b/package/gluon-web-mesh-vpn-fastd/i18n/gluon-web-mesh-vpn-fastd.pot similarity index 100% rename from package/gluon-luci-mesh-vpn-fastd/i18n/gluon-luci-mesh-vpn-fastd.pot rename to package/gluon-web-mesh-vpn-fastd/i18n/gluon-web-mesh-vpn-fastd.pot diff --git a/package/gluon-web-mesh-vpn-fastd/luasrc/lib/gluon/web/controller/admin/mesh_vpn_fastd.lua b/package/gluon-web-mesh-vpn-fastd/luasrc/lib/gluon/web/controller/admin/mesh_vpn_fastd.lua new file mode 100644 index 000000000..55f8b4a28 --- /dev/null +++ b/package/gluon-web-mesh-vpn-fastd/luasrc/lib/gluon/web/controller/admin/mesh_vpn_fastd.lua @@ -0,0 +1 @@ +entry({"admin", "mesh_vpn_fastd"}, model("admin/mesh_vpn_fastd"), _("Mesh VPN"), 20) diff --git a/package/gluon-web-mesh-vpn-fastd/luasrc/lib/gluon/web/model/admin/mesh_vpn_fastd.lua b/package/gluon-web-mesh-vpn-fastd/luasrc/lib/gluon/web/model/admin/mesh_vpn_fastd.lua new file mode 100644 index 000000000..73ba6cacf --- /dev/null +++ b/package/gluon-web-mesh-vpn-fastd/luasrc/lib/gluon/web/model/admin/mesh_vpn_fastd.lua @@ -0,0 +1,38 @@ +local uci = require("simple-uci").cursor() +local util = gluon.web.util + +local f = Form(translate('Mesh VPN')) + +local s = f:section(Section) + +local mode = s:option(Value, 'mode') +mode.template = "gluon/model/mesh-vpn-fastd" + +local methods = uci:get('fastd', 'mesh_vpn', 'method') +if util.contains(methods, 'null') then + mode.default = 'performance' +else + mode.default = 'security' +end + +function mode:write(data) + local site = require 'gluon.site_config' + + local methods = {} + if data == 'performance' then + table.insert(methods, 'null') + end + + for _, method in ipairs(site.fastd_mesh_vpn.methods) do + if method ~= 'null' then + table.insert(methods, method) + end + end + + uci:set('fastd', 'mesh_vpn', 'method', methods) + + uci:save('fastd') + uci:commit('fastd') +end + +return f diff --git a/package/gluon-luci-portconfig/Makefile b/package/gluon-web-network/Makefile similarity index 59% rename from package/gluon-luci-portconfig/Makefile rename to package/gluon-web-network/Makefile index eaec9db49..07538365d 100644 --- a/package/gluon-luci-portconfig/Makefile +++ b/package/gluon-web-network/Makefile @@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk -PKG_NAME:=gluon-luci-portconfig +PKG_NAME:=gluon-web-network PKG_VERSION:=1 PKG_RELEASE:=1 @@ -14,11 +14,11 @@ include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) -define Package/gluon-luci-portconfig +define Package/gluon-web-network SECTION:=gluon CATEGORY:=Gluon - TITLE:=Luci module for advanced ethernet port configuration - DEPENDS:=+gluon-luci-admin +gluon-client-bridge + TITLE:=gluon-web module for network port configuration + DEPENDS:=+gluon-web-admin +gluon-client-bridge endef define Build/Prepare @@ -29,13 +29,13 @@ define Build/Configure endef define Build/Compile - $(call GluonBuildI18N,gluon-luci-portconfig,i18n) + $(call GluonBuildI18N,gluon-web-network,i18n) $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/) endef -define Package/gluon-luci-portconfig/install +define Package/gluon-web-network/install $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/ - $(call GluonInstallI18N,gluon-luci-portconfig,$(1)) + $(call GluonInstallI18N,gluon-web-network,$(1)) endef -$(eval $(call BuildPackage,gluon-luci-portconfig)) +$(eval $(call BuildPackage,gluon-web-network)) diff --git a/package/gluon-luci-portconfig/i18n/de.po b/package/gluon-web-network/i18n/de.po similarity index 77% rename from package/gluon-luci-portconfig/i18n/de.po rename to package/gluon-web-network/i18n/de.po index a94e7d41d..6b321f3ee 100644 --- a/package/gluon-luci-portconfig/i18n/de.po +++ b/package/gluon-web-network/i18n/de.po @@ -16,6 +16,9 @@ msgstr "Automatisch (DHCP)" msgid "Automatic (RA/DHCPv6)" msgstr "Automatisch (RA/DHCPv6)" +msgid "Disabled" +msgstr "Deaktiviert" + msgid "Enable PoE passthrough" msgstr "PoE-Passthrough aktivieren" @@ -25,6 +28,24 @@ msgstr "Mesh auf dem LAN-Port aktivieren" msgid "Enable meshing on the WAN interface" msgstr "Mesh auf dem WAN-Port aktivieren" +msgid "Gateway" +msgstr "Gateway" + +msgid "IP address" +msgstr "IP-Adresse" + +msgid "IPv4" +msgstr "IPv4" + +msgid "IPv6" +msgstr "IPv6" + +msgid "Netmask" +msgstr "Netzmaske" + +msgid "Network" +msgstr "Netzwerk" + msgid "Static" msgstr "Statisch" diff --git a/package/gluon-luci-portconfig/i18n/fr.po b/package/gluon-web-network/i18n/fr.po similarity index 76% rename from package/gluon-luci-portconfig/i18n/fr.po rename to package/gluon-web-network/i18n/fr.po index 3ec593959..1e36a201b 100644 --- a/package/gluon-luci-portconfig/i18n/fr.po +++ b/package/gluon-web-network/i18n/fr.po @@ -16,6 +16,9 @@ msgstr "Automatique (DHCP)" msgid "Automatic (RA/DHCPv6)" msgstr "Automatique (RA/DHCPv6)" +msgid "Disabled" +msgstr "Désactivé" + msgid "Enable PoE passthrough" msgstr "" @@ -25,6 +28,24 @@ msgstr "Activer le réseau MESH sur le port LAN" msgid "Enable meshing on the WAN interface" msgstr "Activer le réseau MESH sur les ports WAN" +msgid "Gateway" +msgstr "Passerelle" + +msgid "IP address" +msgstr "Adresse IP" + +msgid "IPv4" +msgstr "IPv4" + +msgid "IPv6" +msgstr "IPv6" + +msgid "Netmask" +msgstr "Masque de réseau" + +msgid "Network" +msgstr "Réseau" + msgid "Static" msgstr "Statique" diff --git a/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot b/package/gluon-web-network/i18n/gluon-web-network.pot similarity index 67% rename from package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot rename to package/gluon-web-network/i18n/gluon-web-network.pot index 5945016be..5b793a23d 100644 --- a/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot +++ b/package/gluon-web-network/i18n/gluon-web-network.pot @@ -7,6 +7,9 @@ msgstr "" msgid "Automatic (RA/DHCPv6)" msgstr "" +msgid "Disabled" +msgstr "" + msgid "Enable PoE passthrough" msgstr "" @@ -16,6 +19,24 @@ msgstr "" msgid "Enable meshing on the WAN interface" msgstr "" +msgid "Gateway" +msgstr "" + +msgid "IP address" +msgstr "" + +msgid "IPv4" +msgstr "" + +msgid "IPv6" +msgstr "" + +msgid "Netmask" +msgstr "" + +msgid "Network" +msgstr "" + msgid "Static" msgstr "" diff --git a/package/gluon-web-network/luasrc/lib/gluon/web/controller/admin/network.lua b/package/gluon-web-network/luasrc/lib/gluon/web/controller/admin/network.lua new file mode 100644 index 000000000..1197d2d96 --- /dev/null +++ b/package/gluon-web-network/luasrc/lib/gluon/web/controller/admin/network.lua @@ -0,0 +1 @@ +entry({"admin", "network"}, model("admin/network"), _("Network"), 20) diff --git a/package/gluon-web-network/luasrc/lib/gluon/web/model/admin/network.lua b/package/gluon-web-network/luasrc/lib/gluon/web/model/admin/network.lua new file mode 100644 index 000000000..eb178da2f --- /dev/null +++ b/package/gluon-web-network/luasrc/lib/gluon/web/model/admin/network.lua @@ -0,0 +1,143 @@ +--[[ +Copyright 2014 Nils Schneider <nils@nilsschneider.net> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 +]]-- + +local uci = require("simple-uci").cursor() +local sysconfig = require 'gluon.sysconfig' +local util = require 'gluon.util' + +local wan = uci:get_all("network", "wan") +local wan6 = uci:get_all("network", "wan6") +local dns_static = uci:get_first("gluon-wan-dnsmasq", "static") + +local f = Form(translate("WAN connection")) + +local s = f:section(Section) + +local ipv4 = s:option(ListValue, "ipv4", translate("IPv4")) +ipv4:value("dhcp", translate("Automatic (DHCP)")) +ipv4:value("static", translate("Static")) +ipv4:value("none", translate("Disabled")) +ipv4.default = wan.proto + +local ipv4_addr = s:option(Value, "ipv4_addr", translate("IP address")) +ipv4_addr:depends(ipv4, "static") +ipv4_addr.default = wan.ipaddr +ipv4_addr.datatype = "ip4addr" + +local ipv4_netmask = s:option(Value, "ipv4_netmask", translate("Netmask")) +ipv4_netmask:depends(ipv4, "static") +ipv4_netmask.default = wan.netmask or "255.255.255.0" +ipv4_netmask.datatype = "ip4addr" + +local ipv4_gateway = s:option(Value, "ipv4_gateway", translate("Gateway")) +ipv4_gateway:depends(ipv4, "static") +ipv4_gateway.default = wan.gateway +ipv4_gateway.datatype = "ip4addr" + + +local s = f:section(Section) + +local ipv6 = s:option(ListValue, "ipv6", translate("IPv6")) +ipv6:value("dhcpv6", translate("Automatic (RA/DHCPv6)")) +ipv6:value("static", translate("Static")) +ipv6:value("none", translate("Disabled")) +ipv6.default = wan6.proto + +local ipv6_addr = s:option(Value, "ipv6_addr", translate("IP address")) +ipv6_addr:depends(ipv6, "static") +ipv6_addr.default = wan6.ip6addr +ipv6_addr.datatype = "ip6addr" + +local ipv6_gateway = s:option(Value, "ipv6_gateway", translate("Gateway")) +ipv6_gateway:depends(ipv6, "static") +ipv6_gateway.default = wan6.ip6gw +ipv6_gateway.datatype = "ip6addr" + +if dns_static then + local s = f:section(Section) + + local dns = s:option(DynamicList, "dns", translate("Static DNS servers")) + dns.default = uci:get_list("gluon-wan-dnsmasq", dns_static, "server") + dns.datatype = "ipaddr" + dns.optional = true + + function dns:write(data) + uci:set_list("gluon-wan-dnsmasq", dns_static, "server", data) + uci:commit("gluon-wan-dnsmasq") + end +end + +local s = f:section(Section) + +local mesh_wan = s:option(Flag, "mesh_wan", translate("Enable meshing on the WAN interface")) +mesh_wan.default = uci:get_bool("network", "mesh_wan", "auto") + +function mesh_wan:write(data) + uci:set("network", "mesh_wan", "auto", data) +end + +if sysconfig.lan_ifname then + local mesh_lan = s:option(Flag, "mesh_lan", translate("Enable meshing on the LAN interface")) + mesh_lan.default = uci:get_bool("network", "mesh_lan", "auto") + + function mesh_lan:write(data) + uci:set("network", "mesh_lan", "auto", data) + + local interfaces = uci:get_list("network", "client", "ifname") + + for lanif in sysconfig.lan_ifname:gmatch('%S+') do + if data then + util.remove_from_set(interfaces, lanif) + else + util.add_to_set(interfaces, lanif) + end + end + + uci:set_list("network", "client", "ifname", interfaces) + end +end + +if uci:get('system', 'gpio_switch_poe_passthrough') then + local s = f:section(Section) + local poe_passthrough = s:option(Flag, "poe_passthrough", translate("Enable PoE passthrough")) + poe_passthrough.default = uci:get_bool("system", "gpio_switch_poe_passthrough", "value") + + function poe_passthrough:write(data) + uci:set('system', 'gpio_switch_poe_passthrough', 'value', data) + end +end + +function f:write() + uci:set("network", "wan", "proto", ipv4.data) + if ipv4.data == "static" then + uci:set("network", "wan", "ipaddr", ipv4_addr.data) + uci:set("network", "wan", "netmask", ipv4_netmask.data) + uci:set("network", "wan", "gateway", ipv4_gateway.data) + else + uci:delete("network", "wan", "ipaddr") + uci:delete("network", "wan", "netmask") + uci:delete("network", "wan", "gateway") + end + + uci:set("network", "wan6", "proto", ipv6.data) + if ipv6.data == "static" then + uci:set("network", "wan6", "ip6addr", ipv6_addr.data) + uci:set("network", "wan6", "ip6gw", ipv6_gateway.data) + else + uci:delete("network", "wan6", "ip6addr") + uci:delete("network", "wan6", "ip6gw") + end + + + uci:commit("network") + uci:commit('system') +end + +return f diff --git a/package/gluon-luci-node-role/Makefile b/package/gluon-web-node-role/Makefile similarity index 59% rename from package/gluon-luci-node-role/Makefile rename to package/gluon-web-node-role/Makefile index 058e879cb..9eea13e1d 100644 --- a/package/gluon-luci-node-role/Makefile +++ b/package/gluon-web-node-role/Makefile @@ -1,6 +1,6 @@ include $(TOPDIR)/rules.mk -PKG_NAME:=gluon-luci-node-role +PKG_NAME:=gluon-web-node-role PKG_VERSION:=0.1 PKG_RELEASE:=1 @@ -11,10 +11,10 @@ include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) -define Package/gluon-luci-node-role +define Package/gluon-web-node-role SECTION:=gluon CATEGORY:=Gluon - DEPENDS:=+gluon-luci-admin +gluon-node-info + DEPENDS:=+gluon-web-admin +gluon-node-info TITLE:=UI for specifying node role endef @@ -26,18 +26,18 @@ define Build/Configure endef define Build/Compile - $(call GluonBuildI18N,gluon-luci-node-role,i18n) + $(call GluonBuildI18N,gluon-web-node-role,i18n) $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/) endef -define Package/gluon-luci-node-role/install +define Package/gluon-web-node-role/install $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/ - $(call GluonInstallI18N,gluon-luci-node-role,$(1)) + $(call GluonInstallI18N,gluon-web-node-role,$(1)) endef -define Package/gluon-luci-node-role/postinst +define Package/gluon-web-node-role/postinst #!/bin/sh $(call GluonCheckSite,check_site.lua) endef -$(eval $(call BuildPackage,gluon-luci-node-role)) +$(eval $(call BuildPackage,gluon-web-node-role)) diff --git a/package/gluon-luci-node-role/check_site.lua b/package/gluon-web-node-role/check_site.lua similarity index 100% rename from package/gluon-luci-node-role/check_site.lua rename to package/gluon-web-node-role/check_site.lua diff --git a/package/gluon-luci-node-role/i18n/de.po b/package/gluon-web-node-role/i18n/de.po similarity index 100% rename from package/gluon-luci-node-role/i18n/de.po rename to package/gluon-web-node-role/i18n/de.po diff --git a/package/gluon-luci-node-role/i18n/fr.po b/package/gluon-web-node-role/i18n/fr.po similarity index 100% rename from package/gluon-luci-node-role/i18n/fr.po rename to package/gluon-web-node-role/i18n/fr.po diff --git a/package/gluon-luci-node-role/i18n/gluon-luci-node-role.pot b/package/gluon-web-node-role/i18n/gluon-web-node-role.pot similarity index 100% rename from package/gluon-luci-node-role/i18n/gluon-luci-node-role.pot rename to package/gluon-web-node-role/i18n/gluon-web-node-role.pot diff --git a/package/gluon-web-node-role/luasrc/lib/gluon/web/controller/admin/noderole.lua b/package/gluon-web-node-role/luasrc/lib/gluon/web/controller/admin/noderole.lua new file mode 100644 index 000000000..72f89c4bc --- /dev/null +++ b/package/gluon-web-node-role/luasrc/lib/gluon/web/controller/admin/noderole.lua @@ -0,0 +1 @@ +entry({"admin", "noderole"}, model("admin/noderole"), "Node role", 20) diff --git a/package/gluon-web-node-role/luasrc/lib/gluon/web/model/admin/noderole.lua b/package/gluon-web-node-role/luasrc/lib/gluon/web/model/admin/noderole.lua new file mode 100644 index 000000000..a686d8607 --- /dev/null +++ b/package/gluon-web-node-role/luasrc/lib/gluon/web/model/admin/noderole.lua @@ -0,0 +1,28 @@ +local f, s, o +local site = require 'gluon.site_config' +local uci = require("simple-uci").cursor() +local config = 'gluon-node-info' + +-- where to read the configuration from +local role = uci:get(config, uci:get_first(config, "system"), "role") + +f = Form(translate("Node role")) + +s = f:section(Section, nil, translate( + "If this node has a special role within the freifunk network you can specify this role here. " + .. "Please find out about the available roles and their impact first. " + .. "Only change the role if you know what you are doing." +)) + +o = s:option(ListValue, "role", translate("Role")) +o.default = role +for _, role in ipairs(site.roles.list) do + o:value(role, translate('gluon-web-node-role:role:' .. role)) +end + +function o:write(data) + uci:set(config, uci:get_first(config, "system"), "role", data) + uci:commit(config) +end + +return f diff --git a/package/gluon-luci-private-wifi/Makefile b/package/gluon-web-private-wifi/Makefile similarity index 60% rename from package/gluon-luci-private-wifi/Makefile rename to package/gluon-web-private-wifi/Makefile index ef6f2a0ad..acee32b29 100644 --- a/package/gluon-luci-private-wifi/Makefile +++ b/package/gluon-web-private-wifi/Makefile @@ -1,6 +1,6 @@ include $(TOPDIR)/rules.mk -PKG_NAME:=gluon-luci-private-wifi +PKG_NAME:=gluon-web-private-wifi PKG_VERSION:=1 PKG_RELEASE:=1 @@ -11,10 +11,10 @@ include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) -define Package/gluon-luci-private-wifi +define Package/gluon-web-private-wifi SECTION:=gluon CATEGORY:=Gluon - DEPENDS:=+gluon-luci-admin + DEPENDS:=+gluon-web-admin TITLE:=UI for activating a private WLAN endef @@ -26,13 +26,13 @@ define Build/Configure endef define Build/Compile - $(call GluonBuildI18N,gluon-luci-private-wifi,i18n) + $(call GluonBuildI18N,gluon-web-private-wifi,i18n) $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/) endef -define Package/gluon-luci-private-wifi/install +define Package/gluon-web-private-wifi/install $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/ - $(call GluonInstallI18N,gluon-luci-private-wifi,$(1)) + $(call GluonInstallI18N,gluon-web-private-wifi,$(1)) endef -$(eval $(call BuildPackage,gluon-luci-private-wifi)) +$(eval $(call BuildPackage,gluon-web-private-wifi)) diff --git a/package/gluon-luci-private-wifi/i18n/de.po b/package/gluon-web-private-wifi/i18n/de.po similarity index 94% rename from package/gluon-luci-private-wifi/i18n/de.po rename to package/gluon-web-private-wifi/i18n/de.po index 5b2ac19da..09ba09c2e 100644 --- a/package/gluon-luci-private-wifi/i18n/de.po +++ b/package/gluon-web-private-wifi/i18n/de.po @@ -13,6 +13,12 @@ msgstr "" msgid "8-63 characters" msgstr "8-63 Zeichen" +msgid "Enabled" +msgstr "Aktiviert" + +msgid "Key" +msgstr "Schlüssel" + msgid "Name (SSID)" msgstr "Name (SSID)" diff --git a/package/gluon-luci-private-wifi/i18n/fr.po b/package/gluon-web-private-wifi/i18n/fr.po similarity index 94% rename from package/gluon-luci-private-wifi/i18n/fr.po rename to package/gluon-web-private-wifi/i18n/fr.po index c95ecd0a2..b43a2d2fc 100644 --- a/package/gluon-luci-private-wifi/i18n/fr.po +++ b/package/gluon-web-private-wifi/i18n/fr.po @@ -13,6 +13,12 @@ msgstr "" msgid "8-63 characters" msgstr "8-63 charactères" +msgid "Enabled" +msgstr "Activé" + +msgid "Key" +msgstr "Clé" + msgid "Name (SSID)" msgstr "Nom (SSID)" diff --git a/package/gluon-luci-private-wifi/i18n/gluon-luci-private-wifi.pot b/package/gluon-web-private-wifi/i18n/gluon-web-private-wifi.pot similarity index 90% rename from package/gluon-luci-private-wifi/i18n/gluon-luci-private-wifi.pot rename to package/gluon-web-private-wifi/i18n/gluon-web-private-wifi.pot index 98d41bf85..0919ddb3f 100644 --- a/package/gluon-luci-private-wifi/i18n/gluon-luci-private-wifi.pot +++ b/package/gluon-web-private-wifi/i18n/gluon-web-private-wifi.pot @@ -4,6 +4,12 @@ msgstr "Content-Type: text/plain; charset=UTF-8" msgid "8-63 characters" msgstr "" +msgid "Enabled" +msgstr "" + +msgid "Key" +msgstr "" + msgid "Name (SSID)" msgstr "" diff --git a/package/gluon-web-private-wifi/luasrc/lib/gluon/web/controller/admin/privatewifi.lua b/package/gluon-web-private-wifi/luasrc/lib/gluon/web/controller/admin/privatewifi.lua new file mode 100644 index 000000000..67a2a6601 --- /dev/null +++ b/package/gluon-web-private-wifi/luasrc/lib/gluon/web/controller/admin/privatewifi.lua @@ -0,0 +1 @@ +entry({"admin", "privatewifi"}, model("admin/privatewifi"), _("Private WLAN"), 10) diff --git a/package/gluon-web-private-wifi/luasrc/lib/gluon/web/model/admin/privatewifi.lua b/package/gluon-web-private-wifi/luasrc/lib/gluon/web/model/admin/privatewifi.lua new file mode 100644 index 000000000..5e8095e43 --- /dev/null +++ b/package/gluon-web-private-wifi/luasrc/lib/gluon/web/model/admin/privatewifi.lua @@ -0,0 +1,54 @@ +local uci = require("simple-uci").cursor() +local util = require 'gluon.util' + +-- where to read the configuration from +local primary_iface = 'wan_radio0' + +local f = Form(translate("Private WLAN")) + +local s = f:section(Section, nil, translate( + 'Your node can additionally extend your private network by bridging the WAN interface ' + .. 'with a separate WLAN. This feature is completely independent of the mesh functionality. ' + .. 'Please note that the private WLAN and meshing on the WAN interface should not be enabled ' + .. 'at the same time.' +)) + +local enabled = s:option(Flag, "enabled", translate("Enabled")) +enabled.default = (ssid and not uci:get_bool('wireless', primary_iface, "disabled")) + +local ssid = s:option(Value, "ssid", translate("Name (SSID)")) +ssid:depends(enabled, true) +ssid.datatype = "maxlength(32)" +ssid.default = uci:get('wireless', primary_iface, "ssid") + +local key = s:option(Value, "key", translate("Key"), translate("8-63 characters")) +key:depends(enabled, true) +key.datatype = "wpakey" +key.default = uci:get('wireless', primary_iface, "key") + +function f:write() + util.iterate_radios(function(radio, index) + local name = "wan_" .. radio + + if enabled.data then + local macaddr = util.get_wlan_mac(radio, index, 4) + + uci:section('wireless', "wifi-iface", name, { + device = radio, + network = "wan", + mode = 'ap', + encryption = 'psk2', + ssid = ssid.data, + key = key.data, + macaddr = macaddr, + disabled = false, + }) + else + uci:set('wireless', name, "disabled", true) + end + end) + + uci:commit('wireless') +end + +return f diff --git a/package/gluon-luci-theme/Makefile b/package/gluon-web-theme/Makefile similarity index 57% rename from package/gluon-luci-theme/Makefile rename to package/gluon-web-theme/Makefile index 2486519a3..386cf96fb 100644 --- a/package/gluon-luci-theme/Makefile +++ b/package/gluon-web-theme/Makefile @@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk -PKG_NAME:=gluon-luci-theme +PKG_NAME:=gluon-web-theme PKG_VERSION:=0.1 PKG_RELEASE:=1 @@ -12,17 +12,13 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) include ../gluon.mk -define Package/gluon-luci-theme +define Package/gluon-web-theme SECTION:=gluon CATEGORY:=Gluon - TITLE:=Luci theme for Gluon + TITLE:=gluon-web theme DEPENDS:=+pretty-hostname endef -define Package/gluon-luci-theme/description - Luci based config mode -endef - define Build/Prepare mkdir -p $(PKG_BUILD_DIR) endef @@ -31,12 +27,10 @@ define Build/Configure endef define Build/Compile - $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/) endef -define Package/gluon-luci-theme/install +define Package/gluon-web-theme/install $(CP) ./files/* $(1)/ - $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/ endef -$(eval $(call BuildPackage,gluon-luci-theme)) +$(eval $(call BuildPackage,gluon-web-theme)) diff --git a/package/gluon-web-theme/files/lib/gluon/web/view/themes/gluon/layout.html b/package/gluon-web-theme/files/lib/gluon/web/view/themes/gluon/layout.html new file mode 100644 index 000000000..f5da5d447 --- /dev/null +++ b/package/gluon-web-theme/files/lib/gluon/web/view/themes/gluon/layout.html @@ -0,0 +1,122 @@ +<%# +Copyright 2008 Steven Barth <steven@midlink.org> +Copyright 2008-2010 Jo-Philipp Wich <xm@subsignal.org> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 +-%> +<% + local uci = require("simple-uci").cursor() + local disp = require "gluon.web.dispatcher" + local fs = require "nixio.fs" + local pretty_hostname = require "pretty_hostname" + + local hostname = pretty_hostname.get(uci) + local release = fs.readfile("/lib/gluon/release") + + local root = node() + local rnode = node(unpack(request)) + + local category = request[1] + local cattree = category and node(category) + + local categories = disp.node_children(root) + + http:prepare_content("application/xhtml+xml") + + local function append(xs, x) + local r = {unpack(xs)} + r[#r+1] = x + return r + end + + local function subtree(prefix, node, name, ...) + if not node then return end + + local children = disp.node_children(node) + if #children == 0 then return end + + %> + <div class="tabmenu<%=#prefix%>"> + <ul class="tabmenu l<%=#prefix%>"> + <% + for i, v in ipairs(children) do + local child = node.nodes[v] + local active = (v == name) + %> + <li class="tabmenu-item-<%=v%><% if active then %> active<% end %>"> + <a href="<%=url(append(prefix, v))%>"><%=pcdata(translate(child.title))%></a> + </li> + <% + end + %> + </ul> + <br style="clear:both" /> + <% + subtree(append(prefix, name), node.nodes[name], ...) + %> + </div> + <% + end + + local function menutree(path, ...) + subtree({path}, root.nodes[category], ...) + end +-%> +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> + <head> + <meta charset="UTF-8" /> + <link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" /> + <title><%=pcdata( hostname .. ( (rnode and rnode.title) and ' - ' .. translate(rnode.title) or '')) %></title> + </head> + <body> + + <div id="menubar"> + <div class="hostinfo"> + <a href="<%=url({})%>"> + <%=pcdata(hostname)%> + <% if release then %> + / <%=pcdata(release)%> + <% end %> + </a> + </div> + + <% if #categories > 1 and not hidenav then %> + <ul id="topmenu"> + <% for i, r in ipairs(categories) do %> + <li><a class="topcat<% if request[1] == r then %> active<%end%>" href="<%=url({r})%>"><%=pcdata(translate(root.nodes[r].title))%></a></li> + <% end %> + </ul> + <% end %> + </div> + + <div id="maincontainer"> + <% + if not hidenav then + menutree(unpack(request)) + end + %> + + <div id="maincontent"> + <noscript> + <div class="errorbox"> + <strong><%:JavaScript required!%></strong><br /> + <%:You must enable JavaScript in your browser or the web interface will not work properly.%> + </div> + </noscript> + + <% + ok, err = pcall(include, content) + if not ok then + renderer.render('error500', {message = err}) + end + %> + + </div> + </div> + </body> +</html> diff --git a/package/gluon-web-theme/files/lib/gluon/web/www/static/gluon/cascade.css b/package/gluon-web-theme/files/lib/gluon/web/www/static/gluon/cascade.css new file mode 100644 index 000000000..5739ffc5d --- /dev/null +++ b/package/gluon-web-theme/files/lib/gluon/web/www/static/gluon/cascade.css @@ -0,0 +1 @@ +.lang_he{direction:RTL;unicode-bidi:embed}.hidden{display:none}html{min-height:100%;height:auto;position:relative}body,input,select,option{font-family:'Open Sans', Arial, sans-serif;font-size:12pt}body{color:#4d4e53;line-height:1.5em;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:#f3f3f3}a img{border:none;text-decoration:none}.tabmenu1{text-align:center}ul.tabmenu{list-style:none;padding:0;margin:2em 0;display:inline-flex}ul.tabmenu li{white-space:nowrap;margin:0 0.5em;padding:0;text-align:center}ul.tabmenu li a{display:block;text-decoration:none;padding:1em;margin:0;color:#333;border-radius:2em}ul.tabmenu li a:hover{background:#ffe9b3}ul.tabmenu li.active a{font-weight:bold;background:white;color:#333}abbr,acronym{font-style:normal;font-variant:normal}abbr[title],acronym[title]{border-bottom:1px dotted;cursor:help}a:link abbr[title],a:visited abbr[title],a:link acronym[title],a:visited acronym[title]{cursor:pointer}code{font-family:monospace;white-space:pre}#maincontent ul{margin-left:2em}.clear{clear:both}.error{color:#ff0000;background-color:white}#menubar{display:flex;background:#dc0067;color:#ffffff}#menubar a:link.topcat,#menubar a:visited.topcat{position:relative;display:block;padding:0.5em;text-decoration:none;font-size:80%;font-weight:normal;color:white}#menubar a:link.topcat:hover,#menubar a:link.topcat:focus,#menubar a:visited.topcat:hover,#menubar a:visited.topcat:focus{background:#ffb400;color:black}#menubar a:link.topcat.active,#menubar a:visited.topcat.active{background:#ffb400;color:black;font-weight:bold}#menubar div.hostinfo{position:relative;margin:0;padding:0.5em;flex:1;font-weight:bold;font-size:80%}#menubar div.hostinfo a:link,#menubar div.hostinfo a:visited{text-decoration:none;font-weight:bold;color:white}#menubar div.hostinfo a:link:hover,#menubar div.hostinfo a:link:focus,#menubar div.hostinfo a:visited:hover,#menubar div.hostinfo a:visited:focus{text-decoration:underline}#topmenu{list-style:none;margin:0;padding:0}#topmenu li{display:inline-block}#maincontent{padding:0 1em 2em;max-width:60em;min-width:40em;margin:1em auto}#maincontent p{margin-bottom:1em}.gluon-section{margin:0;padding:0;border:none;margin-bottom:1.3em}.gluon-section:last-child{margin-bottom:0.7em}.gluon-section legend{font-size:1.4em;font-weight:bold;position:relative;padding:0;margin-bottom:0.5em}.gluon-section h2{margin:0em 0 0.5em -0.5em !important}.gluon-section h3{text-decoration:none !important;font-weight:bold !important;color:#555555 !important;margin:0.25em !important;font-size:100% !important}.gluon-section-descr{margin-bottom:2em}input:placeholder{color:#aaaaaa}input:-webkit-input-placeholder{color:#aaaaaa}input:-moz-placeholder{color:#aaaaaa}input:-ms-input-placeholder{color:#aaaaaa}input[type=checkbox]{display:none}input[type=checkbox]+label{display:inline-block;width:1em;height:1em;margin:0}input[type=checkbox]:checked+label:after{content:'✔';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.5em;width:100%;text-align:center;font-size:1.7em}input[type=submit],input[type=reset],input[type=image],input[type=button]{cursor:pointer}select,input,textarea,input[type=checkbox]+label{color:#003247;border:none;background:#ffe199;border-radius:3pt;padding:0.5em;margin-top:1px;margin-bottom:2px}input[type=image]{border:none}select,input[type=text],input[type=password]{width:20em}input.gluon-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;user-select:none;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);border:none transparent;background-color:#E6E6E6;text-decoration:none;border-radius:2px;transition:0.1s linear box-shadow;margin-left:0.5em;background-repeat:no-repeat}input.gluon-button::-moz-focus-inner{padding:0;border:0}input.gluon-button:active{box-shadow:0 0 0 1px rgba(0,0,0,0.15) inset,0 0 6px rgba(0,0,0,0.2) inset}input.gluon-button:focus{outline:0}input.gluon-button:hover,input.gluon-button:focus{background-image:linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1))}input.gluon-button[disabled]{border:none;background-image:none;opacity:0.40;cursor:not-allowed;box-shadow:none}input.gluon-button-reset{background-color:#e30;color:#fff}input.gluon-button-submit{background-color:#009ee0;color:#fff}.gluon-input-invalid{background:#e30 !important;color:white}div.gluon-section-remove input{border-bottom:none}textarea{margin-left:-1px;margin-bottom:0.5em}.gluon-section .gluon-rowstyle-1 h3{background-color:#eeeeff;color:#555555}.gluon-rowstyle-2{color:#000000}div.gluon-value{display:flex;flex-direction:row;margin-bottom:0.5em}.gluon-section-node .gluon-value:last-child{margin-bottom:0}.gluon-value-title{flex:2;text-align:right;padding-right:1em;font-weight:bold}div.gluon-value-field{flex:3;position:relative}div.gluon-value-field input,div.gluon-value-field select,div.gluon-value-field input+label{position:relative;top:-0.39em}div.gluon-value-field-long{flex:10;position:relative}div.gluon-value-field-long input,div.gluon-value-field-long select,div.gluon-value-field-long input+label{position:relative;top:-0.39em}div.gluon-value-field-long-after{flex:2}div.gluon-value-description{font-size:8pt}div.gluon-section-create{clear:left;white-space:nowrap;vertical-align:top}div.gluon-section-create .gluon-button{margin:0.25em}input.gluon-section-create-name{margin-right:-0.25em}div.gluon-map-descr{margin-bottom:1em}.gluon-map-descr:empty,.gluon-section-descr:empty{display:none}.gluon-map-descr,.gluon-section-descr,.gluon-page-actions{padding:1em;background:#ececec}.gluon-page-actions{text-align:right;display:flex;flex-flow:row-reverse}div.gluon-optionals{padding:0.25em;border-bottom:1px dotted #bbbbbb}div.gluon-section-remove{float:right}.gluon-section-node{clear:both;position:relative;border:none}.gluon-section-node-tabbed{border-top-left-radius:0}div.gluon-error{font-size:95%;font-weight:bold;color:#ff0000;background-color:#ffffff}.gluon-value-error input,.gluon-value-error select{background-color:#ffcccc}.gluon-section-error{color:red;background-color:white;font-size:95%;border:1px dotted red;margin:3px;padding:3px}.gluon-value-field var{color:#2222FF}.gluon-add:after,.gluon-remove:after{cursor:pointer;display:inline-block;text-align:center;vertical-align:middle;font-size:180%;width:1.2em;height:1em}.gluon-add{color:#008000;position:relative;left:21em}input+.gluon-add{left:0;top:-0.35em}.gluon-add:first-child{top:0.04em;left:-0.08em}.gluon-add:after{content:'+'}.gluon-remove{color:#800000;position:relative;top:-0.42em}.gluon-remove:after{content:'–'}.left{text-align:left !important}.right{text-align:right !important}.inline{display:inline}.error500{border:1px dotted #ff0000;background-color:#ffffff;color:#000000;padding:0.5em}.errorbox{border:1px solid #FF0000;background-color:#FFCCCC;padding:5px;margin-bottom:5px}.errorbox a{color:#000000 !important}.the-key{text-align:left;font-size:1.4em;background:#ffe9b3;border:3pt dashed #dc0067;margin-bottom:0.5em;padding:0.5em} diff --git a/package/gluon-web-theme/sass/cascade.scss b/package/gluon-web-theme/sass/cascade.scss new file mode 100644 index 000000000..ab22c0627 --- /dev/null +++ b/package/gluon-web-theme/sass/cascade.scss @@ -0,0 +1,598 @@ +/* + ATTENTION: This file is not compiled when building gluon. + The compiled version is at ../files/lib/gluon/web/www/static/gluon/cascade.css + + Use sass like this to update it: + + sass --sourcemap=none -C -t compressed sass/cascade.scss files/lib/gluon/web/www/static/gluon/cascade.css + + When commiting changes to this file make sure to commit the respective + changes to the compilid version within the same commit! +*/ + +@charset "utf-8"; + +$ffyellow: #ffb400; +$ffmagenta: #dc0067; +$ffzusatz: #009ee0; +$red: #ee3300; + +@mixin button { + &::-moz-focus-inner { + padding: 0; + border: 0; + } + + display: inline-block; + zoom: 1; + line-height: normal; + white-space: nowrap; + vertical-align: baseline; + text-align: center; + cursor: pointer; + user-select: none; + + + font-size: 100%; + padding: 0.5em 1em; + color: rgba(0, 0, 0, 0.80); + border: none rgba(0, 0, 0, 0); + background-color: #E6E6E6; + text-decoration: none; + border-radius: 2px; + + /* Transitions */ + transition: 0.1s linear box-shadow; + + &:active { + box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 6px rgba(0,0,0, 0.20) inset; + } + + &:focus { + outline: 0; + } + + &:hover, &:focus { + background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10)); + } + + &[disabled] { + border: none; + background-image: none; + opacity: 0.40; + cursor: not-allowed; + box-shadow: none; + } +} + +@mixin button-primary { + background-color: $ffzusatz; + color: #fff; +} + +.lang_he { + direction: RTL; + unicode-bidi: embed; +} + +.hidden { + display: none; +} + +html { + min-height: 100%; + height: auto; + position:relative; +} + +body, input, select, option { + font-family: 'Open Sans', Arial, sans-serif; + font-size: 12pt; +} + +body { + color: rgb(77, 78, 83); + line-height: 1.5em; + margin: 0; + display: flex; + flex-direction: column; + min-height: 100vh; + background-color: #f3f3f3; +} + +a img { + border: none; + text-decoration: none; +} + +.tabmenu1 { + text-align: center; +} + +ul.tabmenu { + list-style: none; + padding: 0; + margin: 2em 0; + display: inline-flex; +} + +ul.tabmenu li { + white-space: nowrap; + margin: 0 0.5em; + padding: 0; + text-align: center; + + a { + display: block; + text-decoration: none; + padding: 1em; + margin: 0; + color: #333; + border-radius: 2em; + + &:hover { + background: lighten($ffyellow, 35); + } + } + + &.active a { + font-weight: bold; + background: white; + color: #333; + } +} + +abbr, +acronym { + font-style: normal; + font-variant: normal; +} + +abbr[title], +acronym[title] { + border-bottom: 1px dotted; + cursor: help; +} + +a:link abbr[title], +a:visited abbr[title], +a:link acronym[title], +a:visited acronym[title] { + cursor: pointer; +} + +code { + font-family: monospace; + white-space: pre; +} + +#maincontent ul { + margin-left: 2em; +} + +.clear { + clear: both; +} + +.error { + color: #ff0000; + background-color: white; +} + +#menubar { + display: flex; + background: $ffmagenta; + color: #ffffff; +} + +#menubar a:link.topcat, +#menubar a:visited.topcat { + position: relative; + display: block; + padding: 0.5em; + text-decoration: none; + font-size: 80%; + font-weight: normal; + color: white; + + &:hover, &:focus { + background: $ffyellow; + color: black; + } + + &.active { + background: $ffyellow; + color: black; + font-weight: bold; + } +} + +#menubar div.hostinfo { + position: relative; + margin: 0; + padding: 0.5em; + flex: 1; + font-weight: bold; + font-size: 80%; +} + +#menubar div.hostinfo a { + &:link, &:visited { + text-decoration: none; + font-weight: bold; + color: white; + + &:hover, &:focus { + text-decoration: underline; + } + } +} + +#topmenu { + list-style: none; + margin: 0; + padding: 0; +} + +#topmenu li { + display: inline-block; +} + +#maincontent { + padding: 0 1em 2em; + max-width: 60em; + min-width: 40em; + margin: 1em auto; +} + +#maincontent p { + margin-bottom: 1em; +} + +.gluon-section { + margin: 0; + padding: 0; + border: none; + margin-bottom: 1.3em; +} + +.gluon-section:last-child { + margin-bottom: 0.7em; +} + +.gluon-section legend { + font-size: 1.4em; + font-weight: bold; + position: relative; + padding: 0; + margin-bottom: 0.5em; +} + +.gluon-section h2 { + margin: 0em 0 0.5em -0.5em !important; +} + +.gluon-section h3 { + text-decoration: none !important; + font-weight: bold !important; + color: #555555 !important; + margin: 0.25em !important; + font-size: 100% !important; +} + +.gluon-section-descr { + margin-bottom: 2em; +} + +input:placeholder { + color: #aaaaaa; +} + +input:-webkit-input-placeholder { + color: #aaaaaa; +} + +input:-moz-placeholder { + color: #aaaaaa; +} + +input:-ms-input-placeholder { + color: #aaaaaa; +} + +input[type=checkbox] { + display: none; + + & + label { + display: inline-block; + width: 1em; + height: 1em; + margin: 0; + } + + &:checked + label:after { + content: '✔'; + color: $ffmagenta; + vertical-align: middle; + position: absolute; + top: 50%; + left: 0; + margin-top: -0.5em; + width: 100%; + text-align: center; + font-size: 1.7em; + } +} + +input[type=submit], +input[type=reset], +input[type=image], +input[type=button] { + cursor: pointer; +} + +select, +input, +textarea, +input[type=checkbox] + label { + color: darken($ffzusatz, 30); + border: none; + background: lighten($ffyellow, 30); + border-radius: 3pt; + padding: 0.5em; + margin-top: 1px; + margin-bottom: 2px; +} + +input[type=image] { + border: none; +} + +select, +input[type=text], +input[type=password] { + width: 20em; +} + +input.gluon-button { + @include button; + + margin-left: 0.5em; + background-repeat: no-repeat; +} + +input.gluon-button-reset { + background-color: $red; + color: #fff; +} +input.gluon-button-submit { + @include button-primary; +} + +.gluon-input-invalid { + background: $red !important; + color: white; +} + +div.gluon-section-remove input { + border-bottom: none; +} + +textarea { + margin-left: -1px; + margin-bottom: 0.5em; +} + +.gluon-section .gluon-rowstyle-1 h3 { + background-color: #eeeeff; + color: #555555; +} + +.gluon-rowstyle-2 { + color: #000000; +} + +div.gluon-value { + display: flex; + flex-direction: row; + margin-bottom: 0.5em; +} + +.gluon-section-node .gluon-value:last-child { + margin-bottom: 0; +} + +.gluon-value-title { + flex: 2; + text-align: right; + padding-right: 1em; + font-weight: bold; +} + +div.gluon-value-field { + flex: 3; + position: relative; + + input, select, input + label { + position: relative; + top: -0.39em; + } +} + +div.gluon-value-field-long { + flex: 10; + position: relative; + + + input, select, input + label { + position: relative; + top: -0.39em; + } +} + +div.gluon-value-field-long-after { + flex: 2; +} + +div.gluon-value-description { + font-size: 8pt; +} + +div.gluon-section-create { + clear: left; + white-space: nowrap; + vertical-align: top; +} + +div.gluon-section-create .gluon-button { + margin: 0.25em; +} + +input.gluon-section-create-name { + margin-right: -0.25em; +} + +div.gluon-map-descr { + margin-bottom: 1em; +} + +.gluon-map-descr:empty, .gluon-section-descr:empty { + display: none; +} + +.gluon-map-descr, .gluon-section-descr, .gluon-page-actions { + padding: 1em; + background: #ececec; +} + +.gluon-page-actions { + text-align: right; + display: flex; + flex-flow: row-reverse; +} + +div.gluon-optionals { + padding: 0.25em; + border-bottom: 1px dotted #bbbbbb; +} + +div.gluon-section-remove { + float: right; +} + +.gluon-section-node { + clear: both; + position: relative; + border: none; +} + +.gluon-section-node-tabbed { + border-top-left-radius: 0; +} + +div.gluon-error { + font-size: 95%; + font-weight: bold; + color: #ff0000; + background-color: #ffffff; +} + +.gluon-value-error input, +.gluon-value-error select { + background-color: #ffcccc; +} + +.gluon-section-error { + color: red; + background-color: white; + font-size: 95%; + border: 1px dotted red; + margin: 3px; + padding: 3px; +} + +.gluon-value-field var { + color: #2222FF; +} + +.gluon-add:after, .gluon-remove:after { + cursor: pointer; + display: inline-block; + text-align: center; + vertical-align: middle; + font-size: 180%; + width: 1.2em; + height: 1em; +} + +.gluon-add { + color: #008000; + + position: relative; + left: 21em; + + input + & { + left: 0; + top: -0.35em; + } + + &:first-child { + top: 0.04em; + left: -0.08em; + } + + &:after { + content: '+'; + } +} + +.gluon-remove { + color: #800000; + + position: relative; + top: -0.42em; + + &:after { + content: '–'; + } +} + +.left { + text-align: left !important; +} + +.right { + text-align: right !important; +} + +.inline { + display: inline; +} + +.error500 { + border: 1px dotted #ff0000; + background-color: #ffffff; + color: #000000; + padding: 0.5em; +} + +.errorbox { + border: 1px solid #FF0000; + background-color: #FFCCCC; + padding: 5px; + margin-bottom: 5px; +} + +.errorbox a { + color: #000000 !important; +} + + +.the-key { + text-align: left; + font-size: 1.4em; + background: lighten($ffyellow, 35); + border: 3pt dashed $ffmagenta; + margin-bottom: 0.5em; + padding: 0.5em +} diff --git a/package/gluon-luci-wifi-config/Makefile b/package/gluon-web-wifi-config/Makefile similarity index 58% rename from package/gluon-luci-wifi-config/Makefile rename to package/gluon-web-wifi-config/Makefile index 881f2f0ed..bd1ed8a29 100644 --- a/package/gluon-luci-wifi-config/Makefile +++ b/package/gluon-web-wifi-config/Makefile @@ -1,6 +1,6 @@ include $(TOPDIR)/rules.mk -PKG_NAME:=gluon-luci-wifi-config +PKG_NAME:=gluon-web-wifi-config PKG_VERSION:=1 PKG_RELEASE:=1 @@ -11,10 +11,10 @@ include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) -define Package/gluon-luci-wifi-config +define Package/gluon-web-wifi-config SECTION:=gluon CATEGORY:=Gluon - DEPENDS:=+gluon-luci-admin +libiwinfo-lua + DEPENDS:=+gluon-web-admin +libiwinfo-lua TITLE:=UI for Wifi Settings endef @@ -26,13 +26,13 @@ define Build/Configure endef define Build/Compile - $(call GluonBuildI18N,gluon-luci-wifi-config,i18n) + $(call GluonBuildI18N,gluon-web-wifi-config,i18n) $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/) endef -define Package/gluon-luci-wifi-config/install +define Package/gluon-web-wifi-config/install $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/ - $(call GluonInstallI18N,gluon-luci-wifi-config,$(1)) + $(call GluonInstallI18N,gluon-web-wifi-config,$(1)) endef -$(eval $(call BuildPackage,gluon-luci-wifi-config)) +$(eval $(call BuildPackage,gluon-web-wifi-config)) diff --git a/package/gluon-luci-wifi-config/i18n/de.po b/package/gluon-web-wifi-config/i18n/de.po similarity index 100% rename from package/gluon-luci-wifi-config/i18n/de.po rename to package/gluon-web-wifi-config/i18n/de.po diff --git a/package/gluon-luci-wifi-config/i18n/fr.po b/package/gluon-web-wifi-config/i18n/fr.po similarity index 100% rename from package/gluon-luci-wifi-config/i18n/fr.po rename to package/gluon-web-wifi-config/i18n/fr.po diff --git a/package/gluon-luci-wifi-config/i18n/gluon-luci-wifi-config.pot b/package/gluon-web-wifi-config/i18n/gluon-web-wifi-config.pot similarity index 100% rename from package/gluon-luci-wifi-config/i18n/gluon-luci-wifi-config.pot rename to package/gluon-web-wifi-config/i18n/gluon-web-wifi-config.pot diff --git a/package/gluon-web-wifi-config/luasrc/lib/gluon/web/controller/admin/wifi-config.lua b/package/gluon-web-wifi-config/luasrc/lib/gluon/web/controller/admin/wifi-config.lua new file mode 100644 index 000000000..bd76ba4aa --- /dev/null +++ b/package/gluon-web-wifi-config/luasrc/lib/gluon/web/controller/admin/wifi-config.lua @@ -0,0 +1 @@ +entry({"admin", "wifi-config"}, model("admin/wifi-config"), _("WLAN"), 20) diff --git a/package/gluon-web-wifi-config/luasrc/lib/gluon/web/model/admin/wifi-config.lua b/package/gluon-web-wifi-config/luasrc/lib/gluon/web/model/admin/wifi-config.lua new file mode 100644 index 000000000..7df669b00 --- /dev/null +++ b/package/gluon-web-wifi-config/luasrc/lib/gluon/web/model/admin/wifi-config.lua @@ -0,0 +1,125 @@ +local fs = require 'nixio.fs' +local iwinfo = require 'iwinfo' +local uci = require("simple-uci").cursor() +local util = require 'gluon.util' + + +local function find_phy_by_path(path) + for phy in fs.glob("/sys/devices/" .. path .. "/ieee80211/phy*") do + return phy:match("([^/]+)$") + end +end + +local function find_phy_by_macaddr(macaddr) + local addr = macaddr:lower() + for file in fs.glob("/sys/class/ieee80211/*/macaddress") do + if util.trim(fs.readfile(file)) == addr then + return file:match("([^/]+)/macaddress$") + end + end +end + +local function txpower_list(phy) + local list = iwinfo.nl80211.txpwrlist(phy) or { } + local off = tonumber(iwinfo.nl80211.txpower_offset(phy)) or 0 + local new = { } + local prev = -1 + local _, val + for _, val in ipairs(list) do + local dbm = val.dbm + off + local mw = math.floor(10 ^ (dbm / 10)) + if mw ~= prev then + prev = mw + table.insert(new, { + display_dbm = dbm, + display_mw = mw, + driver_dbm = val.dbm, + }) + end + end + return new +end + + +local f = Form(translate("WLAN")) + +local s = f:section(Section, nil, translate( + "You can enable or disable your node's client and mesh network " + .. "SSIDs here. Please don't disable the mesh network without " + .. "a good reason, so other nodes can mesh with yours.<br /><br />" + .. "It is also possible to configure the WLAN adapters transmission power " + .. "here. Please note that the transmission power values include the antenna gain " + .. "where available, but there are many devices for which the gain is unavailable or inaccurate." +)) + + +uci:foreach('wireless', 'wifi-device', function(config) + local radio = config['.name'] + + local title + if config.hwmode == '11g' or config.hwmode == '11ng' then + title = translate("2.4GHz WLAN") + elseif config.hwmode == '11a' or config.hwmode == '11na' then + title = translate("5GHz WLAN") + else + return + end + + local p = f:section(Section, title) + + local function vif_option(t, msg) + if not uci:get('wireless', t .. '_' .. radio) then + return + end + + local o = p:option(Flag, radio .. '_' .. t .. '_enabled', msg) + o.default = not uci:get_bool('wireless', t .. '_' .. radio, 'disabled') + + function o:write(data) + uci:set('wireless', t .. '_' .. radio, 'disabled', not data) + end + end + + vif_option('client', translate('Enable client network (access point)')) + vif_option('mesh', translate("Enable mesh network (802.11s)")) + vif_option('ibss', translate("Enable mesh network (IBSS)")) + + local phy + if config.path then + phy = find_phy_by_path(config.path) + elseif config.macaddr then + phy = find_phy_by_macaddr(config.macaddr) + else + return + end + + local txpowers = txpower_list(phy) + if #txpowers <= 1 then + return + end + + local tp = p:option(ListValue, radio .. '_txpower', translate("Transmission power")) + tp.default = uci:get('wireless', radio, 'txpower') or 'default' + + tp:value('default', translate("(default)")) + + table.sort(txpowers, function(a, b) return a.driver_dbm > b.driver_dbm end) + + for _, entry in ipairs(txpowers) do + tp:value(entry.driver_dbm, string.format("%i dBm (%i mW)", entry.display_dbm, entry.display_mw)) + end + + function tp:write(data) + if data == 'default' then + uci:delete('wireless', radio, 'txpower') + else + uci:set('wireless', radio, 'txpower', data) + end + end +end) + +function f:write() + uci:commit('wireless') +end + +return f diff --git a/package/gluon.mk b/package/gluon.mk index b6fbfea68..ab46dc22f 100644 --- a/package/gluon.mk +++ b/package/gluon.mk @@ -15,14 +15,12 @@ $(shell cat '$(TOPDIR)/../scripts/check_site_lib.lua' '$(1)' | sed -ne '1h; 1!H; END__GLUON__CHECK__SITE endef -# Languages supported by LuCi -GLUON_SUPPORTED_LANGS := ca cs de el en es fr he hu it ja ms no pl pt-br pt ro ru sk sv tr uk vi zh-cn zh-tw +GLUON_SUPPORTED_LANGS := de fr GLUON_LANG_de := German GLUON_LANG_fr := French -GLUON_I18N_PACKAGES := $(foreach lang,$(GLUON_SUPPORTED_LANGS),+LUCI_LANG_$(lang):luci-i18n-base-$(lang)) -GLUON_I18N_CONFIG := $(foreach lang,$(GLUON_SUPPORTED_LANGS),CONFIG_LUCI_LANG_$(lang)) -GLUON_ENABLED_LANGS := $(foreach lang,$(GLUON_SUPPORTED_LANGS),$(if $(CONFIG_LUCI_LANG_$(lang)),$(lang))) +GLUON_I18N_CONFIG := $(foreach lang,$(GLUON_SUPPORTED_LANGS),CONFIG_GLUON_WEB_LANG_$(lang)) +GLUON_ENABLED_LANGS := en $(foreach lang,$(GLUON_SUPPORTED_LANGS),$(if $(CONFIG_GLUON_WEB_LANG_$(lang)),$(lang))) define GluonBuildI18N @@ -36,10 +34,10 @@ define GluonBuildI18N endef define GluonInstallI18N - $$(INSTALL_DIR) $(2)/usr/lib/lua/luci/i18n + $$(INSTALL_DIR) $(2)/lib/gluon/web/i18n for lang in $$(GLUON_ENABLED_LANGS); do \ if [ -e $$(PKG_BUILD_DIR)/i18n/$(1).$$$$lang.lmo ]; then \ - $$(INSTALL_DATA) $$(PKG_BUILD_DIR)/i18n/$(1).$$$$lang.lmo $(2)/usr/lib/lua/luci/i18n/$(1).$$$$lang.lmo; \ + $$(INSTALL_DATA) $$(PKG_BUILD_DIR)/i18n/$(1).$$$$lang.lmo $(2)/lib/gluon/web/i18n/$(1).$$$$lang.lmo; \ fi; \ done endef diff --git a/targets/generic b/targets/generic index acc19ba13..dbf65e924 100644 --- a/targets/generic +++ b/targets/generic @@ -8,8 +8,6 @@ config '# CONFIG_BUSYBOX_CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set' config 'CONFIG_PACKAGE_ATH_DEBUG=y' -config 'CONFIG_LUCI_SRCDIET=y' - config 'CONFIG_TARGET_MULTI_PROFILE=y' config 'CONFIG_TARGET_PER_DEVICE_ROOTFS=y' -- GitLab