summaryrefslogtreecommitdiffhomepage
path: root/applications
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2020-01-30 12:08:35 +0100
committerJo-Philipp Wich <jo@mein.io>2020-01-31 08:51:55 +0100
commit40c56ddd7797f9e916abe5443784b21ed9ba51cf (patch)
tree2845066826f787cfc2d100a3e073737cfa03cf89 /applications
parent7cfce565530cbf6103275002ad20af57a509ad7b (diff)
luci-app-vnstat2: fully convert to client side rendering
This converts the graph rendering to client side JavaScript and replaces the route registration with declarative JSON. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'applications')
-rw-r--r--applications/luci-app-vnstat2/htdocs/luci-static/resources/view/vnstat2/graphs.js73
-rw-r--r--applications/luci-app-vnstat2/luasrc/controller/vnstat2.lua50
-rw-r--r--applications/luci-app-vnstat2/luasrc/view/vnstat2/graphs.htm55
-rw-r--r--applications/luci-app-vnstat2/root/usr/share/luci/menu.d/luci-app-vnstat2.json33
-rw-r--r--applications/luci-app-vnstat2/root/usr/share/rpcd/acl.d/luci-app-vnstat2.json7
5 files changed, 113 insertions, 105 deletions
diff --git a/applications/luci-app-vnstat2/htdocs/luci-static/resources/view/vnstat2/graphs.js b/applications/luci-app-vnstat2/htdocs/luci-static/resources/view/vnstat2/graphs.js
new file mode 100644
index 000000000..770884655
--- /dev/null
+++ b/applications/luci-app-vnstat2/htdocs/luci-static/resources/view/vnstat2/graphs.js
@@ -0,0 +1,73 @@
+// This is free software, licensed under the Apache License, Version 2.0
+
+'use strict';
+'require fs';
+'require ui';
+
+return L.view.extend({
+ renderTab: function(ifaces, style, title) {
+ var tab = E('div', {
+ 'class': 'cbi-section',
+ 'data-tab': style,
+ 'data-tab-title': title
+ }, [
+ E('p', {}, E('em', { 'class': 'spinning' }, [ _('Loading graphs…') ]))
+ ]);
+
+ ifaces.forEach(function(iface) {
+ tab.appendChild(E('p', {}, E('img', { 'data-iface': iface, 'style': 'display:none' })));
+ fs.exec_direct('/usr/bin/vnstati', [ '-'+style, '-i', iface, '-o', '-' ], 'blob').then(function(res) {
+ var img = tab.querySelector('img[data-iface="%s"]'.format(iface));
+ img.src = URL.createObjectURL(res);
+ img.style.display = '';
+ tab.firstElementChild.style.display = 'none';
+ });
+ });
+
+ return tab;
+ },
+
+ load: function() {
+ return fs.exec_direct('/usr/bin/vnstat', [ '--json', 'f', '1' ], 'text').then(function(res) {
+ var json = null;
+
+ try {
+ json = JSON.parse(res)
+ }
+ catch(e) {
+ throw new Error(res.replace(/^Error: /, ''));
+ }
+
+ return (L.isObject(json) ? L.toArray(json.interfaces) : []).map(function(iface) {
+ return iface.name;
+ }).sort();
+ }).catch(function(err) {
+ ui.addNotification(null, E('p', { 'style': 'white-space:pre' }, [err]));
+ return [];
+ });
+ },
+
+ render: function(ifaces) {
+ var view = E([], [
+ E('h2', [_('vnStat Graphs')]),
+ E('div', ifaces.length ? [
+ this.renderTab(ifaces, 's', _('Summary')),
+ this.renderTab(ifaces, 't', _('Top')),
+ this.renderTab(ifaces, '5', _('5 Minute')),
+ this.renderTab(ifaces, 'h', _('Hourly')),
+ this.renderTab(ifaces, 'd', _('Daily')),
+ this.renderTab(ifaces, 'm', _('Monthly')),
+ this.renderTab(ifaces, 'y', _('Yearly'))
+ ] : [ E('em', [_('No monitored interfaces have been found. Go to the configuration to enable monitoring for one or more interfaces.')]) ])
+ ]);
+
+ if (ifaces.length)
+ ui.tabs.initTabGroup(view.lastElementChild.childNodes);
+
+ return view;
+ },
+
+ handleSave: null,
+ handleSaveApply: null,
+ handleReset: null
+});
diff --git a/applications/luci-app-vnstat2/luasrc/controller/vnstat2.lua b/applications/luci-app-vnstat2/luasrc/controller/vnstat2.lua
deleted file mode 100644
index 139c1f499..000000000
--- a/applications/luci-app-vnstat2/luasrc/controller/vnstat2.lua
+++ /dev/null
@@ -1,50 +0,0 @@
-module("luci.controller.vnstat2", package.seeall)
-
-function index()
- if not nixio.fs.access("/etc/config/vnstat") then
- return
- end
-
- entry({"admin", "status", "vnstat2"}, alias("admin", "status", "vnstat2", "graphs"), _("vnStat Traffic Monitor"), 90)
- entry({"admin", "status", "vnstat2", "graphs"}, template("vnstat2/graphs"), _("Graphs"), 1)
- entry({"admin", "status", "vnstat2", "config"}, view("vnstat2/config"), _("Configuration"), 2)
- entry({"admin", "status", "vnstat2", "graph"}, call("action_graph"), nil, 3)
-end
-
-function action_graph()
- local util = require "luci.util"
-
- local param = luci.http.formvalue
-
- local iface = param("iface")
- local style = param("style")
-
- if not iface or not style then
- luci.http.status(404, "Not Found")
- return
- end
-
- local style_valid = false
- for _, v in ipairs({"s", "t", "5", "h", "d", "m", "y"}) do
- if v == style then
- style_valid = true
- break
- end
- end
-
- if not style_valid then
- luci.http.status(404, "Not Found")
- return
- end
-
- luci.http.prepare_content("image/png")
-
- local cmd = "vnstati -i %s -%s -o -" % {
- util.shellquote(iface),
- util.shellquote(style)
- }
-
- local image = io.popen(cmd)
- luci.http.write(image:read("*a"))
- image:close()
-end
diff --git a/applications/luci-app-vnstat2/luasrc/view/vnstat2/graphs.htm b/applications/luci-app-vnstat2/luasrc/view/vnstat2/graphs.htm
deleted file mode 100644
index 318611a9d..000000000
--- a/applications/luci-app-vnstat2/luasrc/view/vnstat2/graphs.htm
+++ /dev/null
@@ -1,55 +0,0 @@
-<%#
- This is free software, licensed under the Apache License, Version 2.0
--%>
-
-<%-
-
-local util = require "luci.util"
-local json = require "luci.jsonc"
-
-
-local ifaces = {}
-
-local data = util.exec("vnstat --json f 1 2>/dev/null")
-local content = json.parse(data)
-if type(content) == "table" then
- for _, iface in pairs(content["interfaces"]) do
- table.insert(ifaces, iface["name"])
- end
-end
-
-
-local function render_section(style, title)
- %><div class="cbi-section" data-tab="<%=style%>" data-tab-title="<%=title%>"><%
-
- for _, iface in ipairs(ifaces) do
- %><p><img src="<%=url("admin/status/vnstat2/graph")%>?iface=<%=iface%>&amp;style=<%=style%>" alt="" style="max-width:100%" /></p><%
- end
-
- %></div><%
-end
-
-
--%>
-
-<%+header%>
-
-<h2 name="content"><%:vnStat Graphs%></h2>
-
-<div>
- <%
- if #ifaces == 0 then
- %><p><em><%:No monitored interfaces have been found. Go to the configuration to enable monitoring for one or more interfaces.%></em></p><%
- else
- render_section("s", translate("Summary"))
- render_section("t", translate("Top"))
- render_section("5", translate("5 Minute"))
- render_section("h", translate("Hourly"))
- render_section("d", translate("Daily"))
- render_section("m", translate("Monthly"))
- render_section("y", translate("Yearly"))
- end
- %>
-</div>
-
-<%+footer%>
diff --git a/applications/luci-app-vnstat2/root/usr/share/luci/menu.d/luci-app-vnstat2.json b/applications/luci-app-vnstat2/root/usr/share/luci/menu.d/luci-app-vnstat2.json
new file mode 100644
index 000000000..0b3303c36
--- /dev/null
+++ b/applications/luci-app-vnstat2/root/usr/share/luci/menu.d/luci-app-vnstat2.json
@@ -0,0 +1,33 @@
+{
+ "admin/status/vnstat2": {
+ "title": "vnStat Traffic Monitor",
+ "order": 90,
+ "action": {
+ "type": "firstchild"
+ },
+ "depends": {
+ "fs": {
+ "/usr/bin/vnstat": "executable",
+ "/usr/bin/vnstati": "executable"
+ }
+ }
+ },
+
+ "admin/status/vnstat2/graphs": {
+ "title": "Graphs",
+ "order": 1,
+ "action": {
+ "type": "view",
+ "path": "vnstat2/graphs"
+ }
+ },
+
+ "admin/status/vnstat2/config": {
+ "title": "Configuration",
+ "order": 2,
+ "action": {
+ "type": "view",
+ "path": "vnstat2/config"
+ }
+ }
+}
diff --git a/applications/luci-app-vnstat2/root/usr/share/rpcd/acl.d/luci-app-vnstat2.json b/applications/luci-app-vnstat2/root/usr/share/rpcd/acl.d/luci-app-vnstat2.json
index 58a2aa50c..fb16f09c9 100644
--- a/applications/luci-app-vnstat2/root/usr/share/rpcd/acl.d/luci-app-vnstat2.json
+++ b/applications/luci-app-vnstat2/root/usr/share/rpcd/acl.d/luci-app-vnstat2.json
@@ -1,6 +1,13 @@
{
"luci-app-vnstat2": {
"description": "Grant access to LuCI app vnstat2",
+ "read": {
+ "cgi-io": [ "exec" ],
+ "file": {
+ "/usr/bin/vnstat --json f 1": [ "exec" ],
+ "/usr/bin/vnstati -[5dhmsty] -i * -o -": [ "exec" ]
+ }
+ },
"write": {
"file": {
"/usr/bin/vnstat": [ "exec" ]