From: Helge Mader Date: Thu, 3 Feb 2022 12:48:10 +0000 (+0100) Subject: uci-app-vnstat2: refactoring X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=164e98c7d9708da55c0c7641f4d409faaeaef4ec;p=project%2Fluci.git uci-app-vnstat2: refactoring This is a huge change to the already existing vnstat2 LuCI module with some improvements and some new features. "Graphs Page": - Implementation of refreshing the graphs. - Only in the UCI configuration existing interfaces will be shown in any case. Before this change, all interfaces existing in the database were shown. - Introduced a button to clear the statistics for all interfaces (in fact this is removing and adding again the interfaces from/to the database). Before clearing the data a confirmation dialog is shown. - Show user hint if service is not running, so no updating of graphs. - "Error image" for a graph which can not be loaded General: - Updated translations, added missing translations for ./po/de - Renamed the menu entry from "vnStat Traffic Monitor" to "Traffic Monitor" only Signed-off-by: Helge Mader --- 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 index 7ac3b3f7e7..7113c4119e 100644 --- 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 @@ -1,9 +1,65 @@ // This is free software, licensed under the Apache License, Version 2.0 'use strict'; +'require poll'; 'require view'; 'require fs'; 'require ui'; +'require uci'; +'require rpc'; + +var RefreshIfaces = ""; +var RefreshTabs = ['s', 't', '5', 'h', 'd', 'm', 'y']; + +var callServiceList = rpc.declare({ + object: 'service', + method: 'list', + params: [ 'name' ], + expect: { '': {} } +}); + +var isReadonlyView = !L.hasViewPermission() || null; + +function RefreshGraphs() { + RefreshTabs.forEach(function (id) { + RefreshIfaces.forEach(function (iface) { + fs.exec_direct('/usr/bin/vnstati', [ '-' + id, '-i', iface, '-o', '-' ], 'blob').then(function(res) { + document.getElementById('graph_' + id + '_' + iface).src = URL.createObjectURL(res); + }); + }); + }); +} + +function IfacesResetData(ev) { + ui.showModal(_('Delete data for ALL interfaces'), [ + E('p', _('The data will be removed from the database permanently. This cannot be undone.')), + E('div', { 'class': 'right' }, [ + E('div', { + 'class': 'btn', + 'click': L.hideModal + }, _('Cancel')), + ' ', + E('div', { + 'class': 'btn cbi-button-negative', + 'click': function(ev) { + var if_count = 0; + + RefreshIfaces.forEach(function (iface) { + fs.exec_direct('/usr/bin/vnstat', [ '--remove', '-i', iface, '--force' ], 'blob').then(function() { + fs.exec_direct('/usr/bin/vnstat', [ '--add', '-i', iface ], 'blob').then(function() { + if_count++; + if (if_count == RefreshIfaces.length) { + RefreshGraphs(); + } + }); + }); + }); + ui.hideModal(); + } + }, _('Delete')) + ]) + ]); +} return view.extend({ renderTab: function(ifaces, style, title) { @@ -16,41 +72,41 @@ return view.extend({ ]); ifaces.forEach(function(iface) { - tab.appendChild(E('span', {}, E('img', { 'data-iface': iface, 'style': 'visibility:hidden; margin:5px 10px' }))); 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.alt = _('Could not load graph, no data available: ') + iface; + img.align = 'middle'; img.style.visibility = 'visible'; + img.id = 'graph_' + style + '_' + iface; tab.firstElementChild.style.display = 'none'; }); + tab.appendChild(E('span', {}, E('img', { 'data-iface': iface, 'style': 'visibility:hidden; margin:5px 10px' }))); }); 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 []; - }); + return Promise.all([ + L.resolveDefault(callServiceList('vnstat'), {}), + uci.load('vnstat'), + ]); }, - render: function(ifaces) { + render: function(data) { + var ifaces = uci.get_first('vnstat', 'vnstat', 'interface') || []; + var isRunning = false; + + try { + isRunning = data[0]['vnstat']['instances']['instance1']['running']; + } catch (e) { } + var view = E([], [ E('h2', [_('vnStat Graphs')]), + + (isRunning == false) ? E('p', { 'class': 'alert-message warning' }, _('Warning: The service is not running, graphs will not be updated!')):E('p'), + E('div', ifaces.length ? [ this.renderTab(ifaces, 's', _('Summary')), this.renderTab(ifaces, 't', _('Top')), @@ -58,13 +114,28 @@ return view.extend({ 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.')]) ]) + 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) + if (ifaces.length) { ui.tabs.initTabGroup(view.lastElementChild.childNodes); + view.appendChild(E('div', { 'class': 'right' }, [ + E('br'), + E('button', { + 'class': 'cbi-button cbi-button-neutral', + 'click': IfacesResetData, + 'disabled': isReadonlyView + }, [ _('Clear data for all interfaces') ]) + ])); + } + + // Preserve the interfaces for the poll/refresh function + RefreshIfaces = ifaces; + + poll.add(RefreshGraphs, 60); + return view; }, 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 index 4aa9dd2aa0..eed7b0a2d7 100644 --- 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 @@ -1,6 +1,6 @@ { "admin/status/vnstat2": { - "title": "vnStat Traffic Monitor", + "title": "Traffic Monitor", "order": 90, "action": { "type": "firstchild" 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 7acf74bd59..5be965a99c 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 @@ -7,6 +7,9 @@ "/usr/bin/vnstat --json f 1": [ "exec" ], "/usr/bin/vnstati -[5dhmsty] -i * -o -": [ "exec" ] }, + "ubus": { + "service": [ "list" ] + }, "uci": [ "vnstat" ] }, "write": {