From 7b2f42f3265d36c325999d82ce3406b0d55cd32e Mon Sep 17 00:00:00 2001 From: D9ping Date: Mon, 10 Sep 2018 16:53:05 +0200 Subject: [PATCH] Added Morris.Js chart and jquery.datatable to bandwidth page. Use ajax for getting bandwidth data. Added support for adding extra scripts in footer if needed. Signed-off-by: D9ping --- ajax/bandwidth/get_bandwidth.php | 96 ++++++++++++++++ includes/authenticate.php | 10 +- includes/vnstat.php | 184 +++++++++++++++---------------- index.php | 25 +++-- js/bandwidthcharts.js | 80 ++++++++++++++ 5 files changed, 289 insertions(+), 106 deletions(-) create mode 100644 ajax/bandwidth/get_bandwidth.php create mode 100644 js/bandwidthcharts.js diff --git a/ajax/bandwidth/get_bandwidth.php b/ajax/bandwidth/get_bandwidth.php new file mode 100644 index 00000000..48cd5156 --- /dev/null +++ b/ajax/bandwidth/get_bandwidth.php @@ -0,0 +1,96 @@ + 0) { + $interface = $interfacesWlo[0]; + } else { + exit('No network interfaces found.'); + } +} + +define('IFNAMSIZ', 16); +if (strlen($interface) > IFNAMSIZ) { + exit('Interface name too long.'); +} elseif(!preg_match('/^[a-zA-Z0-9]+$/', $interface)) { + exit('Invalid interface name.'); +} + +exec(sprintf('vnstat -i %s --json ', escapeshellarg($interface)), $jsonstdoutvnstat, + $exitcodedaily); +if ($exitcodedaily !== 0) { + exit('vnstat error'); +} + +$jsonobj = json_decode($jsonstdoutvnstat[0], true); +$timeunits = filter_input(INPUT_GET, 'tu'); +if ($timeunits === 'm') { + // months + $jsonData = $jsonobj['interfaces'][0]['traffic']['months']; +//} elseif ($timeunits === 'h') { +// $jsonData = $jsonobj['interfaces'][0]['traffic']['hours']; +} else { + // default: days + $jsonData = $jsonobj['interfaces'][0]['traffic']['days']; +} + +$datasizeunits = filter_input(INPUT_GET, 'dsu'); + +header('X-Content-Type-Options: nosniff'); +header('Content-Type: application/json'); +echo '[ '; +$firstelm = true; +for ($i = count($jsonData) - 1; $i >= 0; --$i) { + if ($timeunits === 'm') { + $dt = DateTime::createFromFormat('Y n', $jsonData[$i]['date']['year'].' '. + $jsonData[$i]['date']['month']); +// } elseif ($timeunits === 'h') { +// $dt = DateTime::createFromFormat('Y n j G i', $jsonData[$i]['date']['year'].' '. +// $jsonData[$i]['date']['month'].' '. +// $jsonData[$i]['date']['day'].' '. +// $i.' 00'); + } else { + $dt = DateTime::createFromFormat('Y n j', $jsonData[$i]['date']['year'].' '. + $jsonData[$i]['date']['month'].' '. + $jsonData[$i]['date']['day']); + } + + if ($firstelm) { + $firstelm = false; + } else { + echo ','; + } + + if ($datasizeunits == 'mb') { + $datasend = round($jsonData[$i]['tx'] / 1024, 0); + $datareceived = round($jsonData[$i]['rx'] / 1024, 0); + } else { + $datasend = $jsonData[$i]['rx']; + $datareceived = $jsonData[$i]['rx']; + } + + if ($timeunits === 'm') { + echo '{ "date": "' , $dt->format('Y-m') , '", "rx": "' , $datareceived , + '", "tx": "' , $datasend , '" }'; +// } elseif ($timeunits === 'h') { +// echo '{ "date": "' , $dt->format('Y-m-d H:i') , '", "rx": ' , $datareceived , +// ', "tx": ' , $datasend , ' }'; + } else { + echo '{ "date": "' , $dt->format('Y-m-d') , '", "rx": "' , $datareceived , + '", "tx": "' , $datasend , '" }'; + } +} + +echo ' ]'; + + diff --git a/includes/authenticate.php b/includes/authenticate.php index 79151a24..d6cd2c6e 100755 --- a/includes/authenticate.php +++ b/includes/authenticate.php @@ -6,7 +6,13 @@ $validated = ($user == $config['admin_user']) && password_verify($pass, $config[ if (!$validated) { header('WWW-Authenticate: Basic realm="RaspAP"'); - header('HTTP/1.0 401 Unauthorized'); - die ("Not authorized"); + if (function_exists('http_response_code')) { + // http_response_code will respond with proper HTTP version back. + http_response_code(401); + } else { + header('HTTP/1.0 401 Unauthorized'); + } + + exit('Not authorized'.PHP_EOL); } diff --git a/includes/vnstat.php b/includes/vnstat.php index d9735f25..a0035b9f 100644 --- a/includes/vnstat.php +++ b/includes/vnstat.php @@ -5,116 +5,106 @@ include_once( 'includes/status_messages.php' ); /** * Generate html output for tab with vnstat traffic amount information. */ -function DisplayVnstat() +function DisplayVnstat(&$extraFooterScripts) { - $status = new StatusMessages(); - exec('vnstat -m ', $stdoutvnstatmonthly, $exitcodemonthly); - if ($exitcodemonthly !== 0) { - $status->addMessage(sprinf(_('Getting vnstat %s information failed.'), _('daily')), 'error'); - } - - exec('vnstat -w ', $stdoutvnstatweekly, $exitcodeweekly); - if ($exitcodeweekly !== 0) { - $status->addMessage(sprinf(_('Getting vnstat %s information failed.'), _('weekly')), 'error'); - } - - exec('vnstat -d ', $stdoutvnstatdaily, $exitcodedaily); - if ($exitcodedaily !== 0) { - $status->addMessage(sprinf(_('Getting vnstat %s information failed.'), _('monthly')), - 'error'); - } ?>
-
-
-
-
- -
-
-
-
-

showMessages(); ?>

- - - -
-
-
-
-

Daily traffic amount

+
+
+
+
+
+
+
+
+ +
+
+
+
+

+ + +

+
+
+
+
+
+
+

php echo _("Hourly traffic amount today"); ?

+ + +
+
+*/ +?> +
+
+
+

+ + +

+
+
+
+
+
+
+
+
+
+
+ +
+
'vendor/raphael/raphael.min.js', + 'defer'=>false); + $extraFooterScripts[] = array('src'=>'vendor/morrisjs/morris.min.js', 'defer'=>false); + $extraFooterScripts[] = array('src'=>'vendor/datatables/js/jquery.dataTables.min.js', 'defer'=>false); + $extraFooterScripts[] = array('src'=>'js/bandwidthcharts.js', 'defer'=>false); } diff --git a/index.php b/index.php index ffd4bd53..420483f1 100755 --- a/index.php +++ b/index.php @@ -181,6 +181,7 @@ $theme_url = 'dist/css/'.htmlspecialchars($theme, ENT_QUOTES);
+ +?>
@@ -238,15 +240,24 @@ $theme_url = 'dist/css/'.htmlspecialchars($theme, ENT_QUOTES); - - - - - + +' , PHP_EOL; +} + +?> diff --git a/js/bandwidthcharts.js b/js/bandwidthcharts.js new file mode 100644 index 00000000..df9178c4 --- /dev/null +++ b/js/bandwidthcharts.js @@ -0,0 +1,80 @@ +(function($) { + "use strict"; + + /** + * Create a Morris.js barchart. + */ + function CreateBarChart(placeholder, datasizeunits) { + var barchart = new Morris.Bar({ + element: placeholder, + xkey: 'date', + ykeys: ['rx', 'tx'], + labels: ['Received '+datasizeunits, 'Send '+datasizeunits] // NOI18N + }); + + return barchart; + } + + /** + * Create a bootstrap data table. + */ + function CreateDataTable(placeholder) { + $("#"+placeholder).append('
daterxtx
'); + } + + /** + * Figure out which tab is selected and remove all existing charts and then + * construct the proper barchart. + */ + function ShowBandwidthChartHandler(e) { + // Remove all charts + $("#divBandwidthdaily").empty(); + $("#divBandwidthweekly").empty(); + $("#divBandwidthmonthly").empty(); + // Construct ajax uri for getting proper data. + var timeunit = $("ul#tabbarBandwidth li.active a").attr("href").substr(1); + var uri = 'ajax/bandwidth/get_bandwidth.php?'; + uri += 'inet='; + uri += encodeURIComponent($("#cbxInterface"+timeunit+" option:selected").text()); + uri += '&tu='; + uri += encodeURIComponent(timeunit.substr(0, 1)); + var datasizeunits = 'mb'; + uri += '&dsu='+encodeURIComponent(datasizeunits); + // Init. chart + var barchart = CreateBarChart('divBandwidth'+timeunit, datasizeunits); + // Init. datatable + var datatable = CreateDataTable('divBandwidth'+timeunit); + // Get data for chart + $.ajax({ + url: uri, + dataType: 'json', + beforeSend: function() { + $("#divLoaderBandwidth"+timeunit).removeClass("hidden"); + } + }).done(function(jsondata) { + $("#divLoaderBandwidth"+timeunit).addClass("hidden"); + barchart.setData(jsondata); + $('#tableBandwidth').DataTable({ + "searching": false, + data: jsondata, + "columns": [ + { "data": "date" }, + { "data": "rx", "title": "received "+datasizeunits }, + { "data": "tx", "title": "send "+datasizeunits }] + }); + }).fail(function(xhr, textStatus) { + if (window.console) { + console.error("server error"); + } else { + alert("server error"); + } + }); + } + + $('#tabbarBandwidth a[data-toggle="tab"]').on('shown.bs.tab', ShowBandwidthChartHandler); + $('#cbxInterfacedaily').on('change', ShowBandwidthChartHandler); + $('#cbxInterfaceweekly').on('change', ShowBandwidthChartHandler); + $('#cbxInterfacemonthly').on('change', ShowBandwidthChartHandler); + ShowBandwidthChartHandler(); + +})(jQuery); \ No newline at end of file