mirror of
				https://github.com/billz/raspap-webgui.git
				synced 2025-03-01 10:31:47 +00:00 
			
		
		
		
	Merge pull request #231 from D9ping/bandwidthmonitoring
Data usage monitoring page
This commit is contained in:
		
							
								
								
									
										85
									
								
								ajax/bandwidth/get_bandwidth.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								ajax/bandwidth/get_bandwidth.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| <?php | ||||
| require_once '../../includes/config.php'; | ||||
| require_once RASPI_CONFIG.'/raspap.php'; | ||||
|  | ||||
| session_start(); | ||||
| header('X-Frame-Options: DENY'); | ||||
| header("Content-Security-Policy: default-src 'none'; connect-src 'self'"); | ||||
| require_once '../../includes/authenticate.php'; | ||||
|  | ||||
|  | ||||
| $interface = filter_input(INPUT_GET, 'inet', FILTER_SANITIZE_SPECIAL_CHARS); | ||||
| if (empty($interface)) { | ||||
|     // Use first interface if inet parameter not provided. | ||||
|     exec("ip -o link show | awk -F ': ' '{print $2}' | grep -v lo ", $interfacesWlo); | ||||
|     if (count($interfacesWlo) > 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']; | ||||
| } 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']); | ||||
|     } 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 , '" }'; | ||||
|     } else { | ||||
|         echo '{ "date": "' , $dt->format('Y-m-d') , '", "rx": "' , $datareceived ,  | ||||
|         '", "tx": "' , $datasend , '" }'; | ||||
|     } | ||||
| } | ||||
|  | ||||
| echo ' ]'; | ||||
|  | ||||
|  | ||||
| @@ -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); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -26,6 +26,7 @@ define('RASPI_OPENVPN_ENABLED', false ); | ||||
| define('RASPI_TORPROXY_ENABLED', false ); | ||||
| define('RASPI_CONFAUTH_ENABLED', true ); | ||||
| define('RASPI_CHANGETHEME_ENABLED', true ); | ||||
| define('RASPI_VNSTAT_ENABLED', true ); | ||||
|  | ||||
| // Locale settings | ||||
| define('LOCALE_ROOT', 'locale'); | ||||
|   | ||||
							
								
								
									
										91
									
								
								includes/data_usage.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								includes/data_usage.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Generate html for displaying data usage. | ||||
|  */ | ||||
| function DisplayDataUsage(&$extraFooterScripts) | ||||
| { | ||||
| ?> | ||||
|   <div class="row"> | ||||
|     <div class="col-lg-12"> | ||||
|       <div class="panel panel-primary"> | ||||
|         <div class="panel-heading"><i class="fa fa-bar-chart fa-fw"></i> <?php echo _("Data usage monitoring"); ?></div> | ||||
|           <div class="panel-body"> | ||||
|             <div class="row"> | ||||
|               <div class="col-md-12"> | ||||
|                 <div class="panel panel-default"> | ||||
|                   <div class="panel-body"> | ||||
|                     <ul id="tabbarBandwidth" class="nav nav-tabs" role="tablist"> | ||||
|                       <li role="presentation" class="active"><a href="#daily" aria-controls="daily" role="tab" data-toggle="tab"><?php echo _("Daily"); ?></a></li> | ||||
|                       <li role="presentation" class=""><a href="#monthly" aria-controls="monthly" role="tab" data-toggle="tab"><?php echo _("Monthly"); ?></a></li> | ||||
|                     </ul> | ||||
|                     <div id="tabsBandwidth" class="tabcontenttraffic tab-content"> | ||||
|                       <div role="tabpanel" class="tab-pane active fade in" id="daily"> | ||||
|                         <div class="row"> | ||||
|                           <div class="col-lg-12"> | ||||
|                             <h4><?php echo _('Daily traffic amount'); ?></h4> | ||||
|                             <label for="cbxInterfacedaily"><?php echo _('interface'); ?></label>  | ||||
|                             <select id="cbxInterfacedaily" class="form-control" name="interfacedaily"> | ||||
| <?php | ||||
| exec("ip -o link show | awk -F ': ' '{print $2}' | grep -v lo ", $interfacesWlo); | ||||
| foreach ($interfacesWlo as $interface) { | ||||
|     echo '                              <option value="' , htmlentities($interface, ENT_QUOTES) , '">' , | ||||
|             htmlentities($interface, ENT_QUOTES) , '</option>' , PHP_EOL; | ||||
| } | ||||
|  | ||||
| ?> | ||||
|                             </select> | ||||
|                             <div class="hidden alert alert-info" id="divLoaderBandwidthdaily"><?php | ||||
|                             echo sprintf(_("Loading %s bandwidth chart"), _('daily')); ?></div> | ||||
|                             <div id="divChartBandwidthdaily"></div> | ||||
|                             <div id="divTableBandwidthdaily"></div> | ||||
|                           </div> | ||||
|                         </div> | ||||
|                       </div><!-- /.tab-pane --> | ||||
|                       <div role="tabpanel" class="tab-pane fade" id="monthly"> | ||||
|                         <div class="row"> | ||||
|                           <div class="col-lg-12"> | ||||
|                             <h4><?php echo _("Monthly traffic amount"); ?></h4> | ||||
|                             <label for="cbxInterfacemonthly"><?php echo _('interface'); ?></label>  | ||||
|                             <select id="cbxInterfacemonthly" class="form-control" name="interfacemonthly"> | ||||
| <?php | ||||
| foreach ($interfacesWlo as $interface) { | ||||
|     echo '                            <option value="' , htmlentities($interface, ENT_QUOTES) , '">' , | ||||
|             htmlentities($interface, ENT_QUOTES) , '</option>' , PHP_EOL; | ||||
| } | ||||
|  | ||||
| ?> | ||||
|                             </select> | ||||
|                             <div class="hidden alert alert-info" id="divLoaderBandwidthmonthly"> | ||||
|                             <?php echo sprintf(_("Loading %s bandwidth chart"), _('monthly')); ?> | ||||
|                             </div> | ||||
|                             <div id="divChartBandwidthmonthly"></div> | ||||
|                             <div id="divTableBandwidthmonthly"></div> | ||||
|                           </div> | ||||
|                         </div> | ||||
|                       </div><!-- /.tab-pane --> | ||||
|                     </div><!-- /.tabsBandwidth --> | ||||
|                   </div><!-- /.panel-default --> | ||||
|                 </div><!-- /.col-md-6 --> | ||||
|               </div><!-- /.row --> | ||||
|            </div><!-- /.panel-body --> | ||||
|          </div><!-- /.panel-primary --> | ||||
|        <div class="panel-footer"><?php echo _("Information provided by vnstat"); ?></div> | ||||
|       </div><!-- /.panel-primary --> | ||||
|     </div><!-- /.col-lg-12 --> | ||||
|   </div><!-- /.row --> | ||||
| <script type="text/javascript"<?php //echo ' nonce="'.$csp_page_nonce.'"'; ?>> | ||||
| // js translations: | ||||
| var t = new Array(); | ||||
| t['send'] = '<?php echo addslashes(_('Send')); ?>'; | ||||
| t['receive'] = '<?php echo addslashes(_('Receive')); ?>'; | ||||
| </script> | ||||
| <?php | ||||
|  | ||||
|     $extraFooterScripts[] = array('src'=>'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); | ||||
| } | ||||
|  | ||||
							
								
								
									
										32
									
								
								index.php
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								index.php
									
									
									
									
									
								
							| @@ -33,6 +33,7 @@ include_once( 'includes/system.php' ); | ||||
| include_once( 'includes/configure_client.php' ); | ||||
| include_once( 'includes/networking.php' ); | ||||
| include_once( 'includes/themes.php' ); | ||||
| include_once( 'includes/data_usage.php' ); | ||||
|  | ||||
| $output = $return = 0; | ||||
| $page = $_GET['page']; | ||||
| @@ -155,6 +156,11 @@ $theme_url = 'dist/css/'.htmlspecialchars($theme, ENT_QUOTES); | ||||
|                 <a href="index.php?page=theme_conf"><i class="fa fa-wrench fa-fw"></i> <?php echo _("Change Theme"); ?></a> | ||||
|               </li> | ||||
|               <?php endif; ?> | ||||
|               <?php if ( RASPI_VNSTAT_ENABLED ) : ?> | ||||
|               <li> | ||||
|                 <a href="index.php?page=data_use"><i class="fa fa-bar-chart fa-fw"></i> <?php echo _("Data usage"); ?></a> | ||||
|               </li> | ||||
|               <?php endif; ?> | ||||
|               <li> | ||||
|                 <a href="index.php?page=system_info"><i class="fa fa-cube fa-fw"></i> <?php echo _("System"); ?></a> | ||||
|               </li> | ||||
| @@ -175,6 +181,7 @@ $theme_url = 'dist/css/'.htmlspecialchars($theme, ENT_QUOTES); | ||||
|         </div><!-- /.row --> | ||||
|  | ||||
|         <?php  | ||||
| $extraFooterScripts = array(); | ||||
|         // handle page actions | ||||
|         switch( $page ) { | ||||
|           case "wlan0_info": | ||||
| @@ -207,13 +214,17 @@ $theme_url = 'dist/css/'.htmlspecialchars($theme, ENT_QUOTES); | ||||
|           case "theme_conf": | ||||
|             DisplayThemeConfig(); | ||||
|             break; | ||||
|           case "data_use": | ||||
|             DisplayDataUsage($extraFooterScripts); | ||||
|             break; | ||||
|           case "system_info": | ||||
|             DisplaySystem(); | ||||
|             break; | ||||
|           default: | ||||
|             DisplayDashboard(); | ||||
|         } | ||||
|         ?> | ||||
|  | ||||
| ?> | ||||
|       </div><!-- /#page-wrapper -->  | ||||
|     </div><!-- /#wrapper --> | ||||
|  | ||||
| @@ -229,15 +240,24 @@ $theme_url = 'dist/css/'.htmlspecialchars($theme, ENT_QUOTES); | ||||
|     <!-- Metis Menu Plugin JavaScript --> | ||||
|     <script src="vendor/metisMenu/metisMenu.min.js"></script> | ||||
|  | ||||
|     <!-- Morris Charts JavaScript --> | ||||
|     <!--script src="vendor/raphael/raphael-min.js"></script--> | ||||
|     <!--script src="vendor/morrisjs/morris.min.js"></script--> | ||||
|     <!--script src="js/morris-data.js"></script--> | ||||
|  | ||||
|     <!-- Custom Theme JavaScript --> | ||||
|     <script src="dist/js/sb-admin-2.js"></script> | ||||
|  | ||||
|     <!-- Custom RaspAP JS --> | ||||
|     <script src="js/custom.js"></script> | ||||
|  | ||||
| <?php | ||||
| // Load non default JS/ECMAScript in footer. | ||||
| foreach ($extraFooterScripts as $script) { | ||||
|     echo '    <script type="text/javascript" src="' , $script['src'] , '"'; | ||||
|     if ($script['defer']) { | ||||
|         echo ' defer="defer"'; | ||||
|     } | ||||
|  | ||||
|     // if ($script['async']) { echo ( echo ' defer="async"'; ), intrigity=, nonce=  etc. etc. | ||||
|     echo '></script>' , PHP_EOL; | ||||
| } | ||||
|  | ||||
| ?> | ||||
|   </body> | ||||
| </html> | ||||
|   | ||||
| @@ -9,7 +9,7 @@ function update_system_packages() { | ||||
|  | ||||
| function install_dependencies() { | ||||
|     install_log "Installing required packages" | ||||
|     sudo apt-get install lighttpd $php_package git hostapd dnsmasq || install_error "Unable to install dependencies" | ||||
|     sudo apt-get install lighttpd $php_package git hostapd dnsmasq vnstat || install_error "Unable to install dependencies" | ||||
| } | ||||
|  | ||||
| install_raspap | ||||
|   | ||||
							
								
								
									
										90
									
								
								js/bandwidthcharts.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								js/bandwidthcharts.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| (function($, _t) { | ||||
|     "use strict"; | ||||
|  | ||||
|     /** | ||||
|      * Create a Morris.js barchart. | ||||
|      */ | ||||
|     function CreateBarChart(placeholder, datasizeunits) { | ||||
|         var barchart = new Morris.Bar({ | ||||
|             element: placeholder, | ||||
|             xkey: 'date', | ||||
|             ykeys: ['rx', 'tx'], | ||||
|             labels: [_t['send']+' '+datasizeunits.toUpperCase(),  | ||||
|                      _t['receive']+' '+datasizeunits.toUpperCase()] | ||||
|         }); | ||||
|  | ||||
|       return barchart; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create a jquery bootstrap datatable. | ||||
|      */ | ||||
|     function CreateDataTable(placeholder, timeunits) { | ||||
|         $("#"+placeholder).append('<table id="tableBandwidth'+timeunits+ | ||||
|             '" class="table table-responsive table-striped container-fluid"><thead>'+ | ||||
|             '<tr><th>date</th><th>rx</th><th>tx</th></tr></thead><tbody></tbody></table>'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Figure out which tab is selected and remove all existing charts and then  | ||||
|      * construct the proper barchart. | ||||
|      */ | ||||
|     function ShowBandwidthChartHandler(e) { | ||||
|         // Remove all morrisjs charts | ||||
|         $('#divChartBandwidthdaily').empty(); | ||||
|         $('#divChartBandwidthmonthly').empty(); | ||||
|         // Remove all datatables | ||||
|         $('#divTableBandwidthdaily').empty(); | ||||
|         $('#divTableBandwidthmonthly').empty(); | ||||
|         // Construct ajax uri for getting the 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('divChartBandwidth'+timeunit, datasizeunits); | ||||
|         // Init. datatable html | ||||
|         var datatable = CreateDataTable('divTableBandwidth'+timeunit, 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'+timeunit).DataTable({ | ||||
|                 'searching': false, | ||||
|                 'paging': false, | ||||
|                 'data': jsondata, | ||||
|                 'order': [[ 0, 'ASC' ]], | ||||
|                 'columns': [ | ||||
|                     { 'data': 'date' }, | ||||
|                     { 'data': 'rx', "title": _t['send']+' '+datasizeunits.toUpperCase() }, | ||||
|                     { 'data': 'tx', "title": _t['receive']+' '+datasizeunits.toUpperCase() }] | ||||
|             }); | ||||
|         }).fail(function(xhr, textStatus) { | ||||
|             if (window.console) { | ||||
|                 console.error('server error'); | ||||
|             } else { | ||||
|                 alert("server error"); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     $(document).ready(function() { | ||||
|         $('#tabbarBandwidth a[data-toggle="tab"]').on('shown.bs.tab', ShowBandwidthChartHandler); | ||||
|         $('#cbxInterfacedaily').on('change', ShowBandwidthChartHandler); | ||||
|         $('#cbxInterfaceweekly').on('change', ShowBandwidthChartHandler); | ||||
|         $('#cbxInterfacemonthly').on('change', ShowBandwidthChartHandler); | ||||
|         ShowBandwidthChartHandler(); | ||||
|     }); | ||||
|  | ||||
| })(jQuery, t); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user