mirror of
https://github.com/hak5/nano-tetra-modules.git
synced 2025-10-29 16:58:09 +00:00
Add modules to repository
This commit is contained in:
8
Status/api/fetchcpu.php
Normal file
8
Status/api/fetchcpu.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
$MYDATA=exec("head -n 1 /proc/stat");
|
||||
$MYDATE=exec("date");
|
||||
|
||||
echo $MYDATE."\n".$MYDATA."\n";
|
||||
|
||||
?>
|
||||
8
Status/api/fetchif.php
Normal file
8
Status/api/fetchif.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
$MYDATA=exec("grep ".$_GET['if']." /proc/net/dev | tr -s ' ' ' '");
|
||||
$MYDATE=exec("date");
|
||||
|
||||
echo $MYDATE."\n".$MYDATA."\n";
|
||||
|
||||
?>
|
||||
322
Status/api/module.php
Normal file
322
Status/api/module.php
Normal file
@@ -0,0 +1,322 @@
|
||||
<?php namespace pineapple;
|
||||
putenv('LD_LIBRARY_PATH='.getenv('LD_LIBRARY_PATH').':/sd/lib:/sd/usr/lib');
|
||||
putenv('PATH='.getenv('PATH').':/sd/usr/bin:/sd/usr/sbin');
|
||||
|
||||
class Status extends Module
|
||||
{
|
||||
public function route()
|
||||
{
|
||||
switch ($this->request->action) {
|
||||
case 'refreshInfo':
|
||||
$this->refreshInfo();
|
||||
break;
|
||||
case 'getSystem':
|
||||
$this->getSystem();
|
||||
break;
|
||||
case 'getCPU':
|
||||
$this->getCPU();
|
||||
break;
|
||||
case 'getDHCP':
|
||||
$this->getDHCP();
|
||||
break;
|
||||
case 'getMemory':
|
||||
$this->getMemory();
|
||||
break;
|
||||
case 'getWiFi':
|
||||
$this->getWiFi();
|
||||
break;
|
||||
case 'getSwap':
|
||||
$this->getSwap();
|
||||
break;
|
||||
case 'getStorage':
|
||||
$this->getStorage();
|
||||
break;
|
||||
case 'getInterfaces':
|
||||
$this->getInterfaces();
|
||||
break;
|
||||
case 'getMACInfo':
|
||||
$this->getMACInfo();
|
||||
break;
|
||||
case 'getPingInfo':
|
||||
$this->getPingInfo();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function refreshInfo()
|
||||
{
|
||||
$moduleInfo = @json_decode(file_get_contents("/pineapple/modules/Status/module.info"));
|
||||
$this->response = array('title' => $moduleInfo->title, 'version' => $moduleInfo->version);
|
||||
}
|
||||
|
||||
private function getSystem()
|
||||
{
|
||||
$current_time = exec("date");
|
||||
$up_time = exec("uptime | awk -F, '{sub(\".*up \",x,$1);print $1}'");
|
||||
$hostname = exec("uci get system.@system[0].hostname");
|
||||
$machine = $cpu = trim(exec("cat /proc/cpuinfo | grep machine | awk -F: '{print $2}'"));
|
||||
|
||||
$info = array(
|
||||
'currentTime' => $current_time,
|
||||
'uptime' => $up_time,
|
||||
'hostname' => $hostname,
|
||||
'machine' => $machine
|
||||
);
|
||||
|
||||
$this->response = array('info' => $info);
|
||||
}
|
||||
|
||||
private function getCPU()
|
||||
{
|
||||
$cpu = trim(exec("cat /proc/cpuinfo | grep cpu | awk -F: '{print $2}'"));
|
||||
$bogo = trim(exec("cat /proc/cpuinfo | grep Bogo | awk -F: '{print $2}'"));
|
||||
$type = trim(exec("cat /proc/cpuinfo | grep type | awk -F: '{print $2}'"));
|
||||
|
||||
$stat1 = $this->getCoreInformation(); sleep(1); $stat2 = $this->getCoreInformation();
|
||||
$data = $this->getCpuPercentages($stat1, $stat2);
|
||||
$cpu_load_ptg = 100 - $data['cpu0']['idle'];
|
||||
$cpu_load_all = exec("uptime | awk -F 'average:' '{ print $2}'");
|
||||
|
||||
$info = array(
|
||||
'cpuModel' => $cpu,
|
||||
'bogoMIPS' => $bogo,
|
||||
'type' => $type,
|
||||
'loadAveragePourcentage' => $cpu_load_ptg,
|
||||
'loadAverageAll' => $cpu_load_all
|
||||
);
|
||||
|
||||
$this->response = array('info' => $info);
|
||||
}
|
||||
|
||||
private function getDHCP()
|
||||
{
|
||||
|
||||
$dhcpClients = explode("\n", trim(shell_exec("cat /tmp/dhcp.leases")));
|
||||
$clientsList = array();
|
||||
for($i=0;$i<count($dhcpClients);$i++)
|
||||
{
|
||||
if($dhcpClients[$i] != "")
|
||||
{
|
||||
$dhcp_client = explode(" ", $dhcpClients[$i]);
|
||||
$mac_address = $dhcp_client[1];
|
||||
$ip_address = $dhcp_client[2];
|
||||
$hostname = $dhcp_client[3];
|
||||
|
||||
array_push($clientsList, array("hostname" => $hostname, "mac" => $mac_address, "ip" =>$ip_address));
|
||||
}
|
||||
}
|
||||
|
||||
$info = array(
|
||||
'clientsList' => $clientsList
|
||||
);
|
||||
|
||||
$this->response = array('info' => $info);
|
||||
}
|
||||
|
||||
private function getMemory()
|
||||
{
|
||||
$mem_total = exec("free | grep \"Mem:\" | awk '{ print $2 }'");
|
||||
$mem_used = exec("free | grep \"Mem:\" | awk '{ print $3 }'");
|
||||
$mem_free = exec("free | grep \"Mem:\" | awk '{ print $4 }'");
|
||||
|
||||
$mem_free_ptg = round(($mem_free / $mem_total) * 100);
|
||||
$mem_used_ptg = 100 - $mem_free_ptg;
|
||||
|
||||
$mem_total = $this->kbytesToString($mem_total);
|
||||
$mem_used = $this->kbytesToString($mem_used);
|
||||
$mem_free = $this->kbytesToString($mem_free);
|
||||
|
||||
$info = array(
|
||||
'memoryTotal' => $mem_total,
|
||||
'memoryFree' => $mem_free,
|
||||
'memoryFreePourcentage' => $mem_free_ptg,
|
||||
'memoryUsed' => $mem_used,
|
||||
'memoryUsedPourcentage' => $mem_used_ptg
|
||||
);
|
||||
|
||||
$this->response = array('info' => $info);
|
||||
}
|
||||
|
||||
private function getWiFi()
|
||||
{
|
||||
$wifiClients = explode("\n", trim(shell_exec("iw dev wlan0 station dump | grep \"Station\"")));
|
||||
$wifiClientsList = array();
|
||||
for($i=0;$i<count($wifiClients);$i++)
|
||||
{
|
||||
if($wifiClients[$i] != "")
|
||||
{
|
||||
$wifi_client = explode(" ", $wifiClients[$i]);
|
||||
$mac_address = $wifi_client[1];
|
||||
$ip_address = exec("cat /tmp/dhcp.leases | grep \"".$mac_address."\" | awk '{ print $3}'");
|
||||
$hostname = exec("cat /tmp/dhcp.leases | grep \"".$mac_address."\" | awk '{ print $4}'");
|
||||
|
||||
array_push($wifiClientsList, array("hostname" => $hostname, "mac" => $mac_address, "ip" =>$ip_address));
|
||||
}
|
||||
}
|
||||
|
||||
$info = array(
|
||||
'wifiClientsList' => $wifiClientsList
|
||||
);
|
||||
|
||||
$this->response = array('info' => $info);
|
||||
}
|
||||
|
||||
private function getSwap()
|
||||
{
|
||||
$swap_total = exec("free | grep \"Swap:\" | awk '{ print $2 }'");
|
||||
$swap_used = exec("free | grep \"Swap:\" | awk '{ print $3 }'");
|
||||
$swap_free = exec("free | grep \"Swap:\" | awk '{ print $4 }'");
|
||||
|
||||
if($swap_total != 0) $swap_available = true; else $swap_available = false;
|
||||
|
||||
if($swap_available) $swap_free_ptg = round(($swap_free / $swap_total) * 100); else $swap_free_ptg = 0;
|
||||
$swap_used_ptg = 100 - $swap_free_ptg;
|
||||
|
||||
$swap_total = $this->kbytesToString($swap_total);
|
||||
$swap_used = $this->kbytesToString($swap_used);
|
||||
$swap_free = $this->kbytesToString($swap_free);
|
||||
|
||||
$info = array(
|
||||
'swapAvailable' => $swap_available,
|
||||
'swapTotal' => $swap_total,
|
||||
'swapFree' => $swap_free,
|
||||
'swapFreePourcentage' => $swap_free_ptg,
|
||||
'swapUsed' => $swap_used,
|
||||
'swapUsedPourcentage' => $swap_used_ptg
|
||||
);
|
||||
|
||||
$this->response = array('info' => $info);
|
||||
}
|
||||
|
||||
private function getStorage()
|
||||
{
|
||||
$dfAll = explode("\n", trim(shell_exec("df | grep -v \"Filesystem\"")));
|
||||
$dfList = array();
|
||||
for($i=0;$i<count($dfAll);$i++) {
|
||||
$df_name = exec("df | grep -v \"Filesystem\" | grep \"".$dfAll[$i]."\" | awk '{ print $1}'");
|
||||
$df_mount = exec("df | grep -v \"Filesystem\" | grep \"".$dfAll[$i]."\" | awk '{ print $6}'");
|
||||
$df_total = $this->kbytesToString(exec("df | grep -v \"Filesystem\" | grep \"".$dfAll[$i]."\" | awk '{ print $2}'"));
|
||||
$df_used = $this->kbytesToString(exec("df | grep -v \"Filesystem\" | grep \"".$dfAll[$i]."\" | awk '{ print $3}'"));
|
||||
$df_used_ptg = exec("df | grep -v \"Filesystem\" | grep \"".$dfAll[$i]."\" | awk '{ print $5}'");
|
||||
|
||||
array_push($dfList, array("name" => $df_name, "mount" => $df_mount, "usedPourcentage" =>$df_used_ptg, "used" => $df_used, "total" => $df_total));
|
||||
}
|
||||
|
||||
$info = array(
|
||||
'storagesList' => $dfList
|
||||
);
|
||||
|
||||
$this->response = array('info' => $info);
|
||||
}
|
||||
|
||||
private function getInterfaces()
|
||||
{
|
||||
$interfaces = explode("\n", trim(shell_exec("ifconfig | grep 'encap:Ethernet' | cut -d' ' -f1")));
|
||||
$interfacesList = array();
|
||||
for($i=0;$i<count($interfaces);$i++)
|
||||
{
|
||||
$interface_name = $interfaces[$i];
|
||||
|
||||
$mac_address = exec("ifconfig ".$interfaces[$i]." | grep 'HWaddr' | awk '{ print $5}'"); $mac_address = $mac_address != "" ? $mac_address : "-";
|
||||
$ip_address = exec("ifconfig ".$interfaces[$i]." | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'"); $ip_address = $ip_address != "" ? $ip_address : "-";
|
||||
$subnet_mask = exec("ifconfig ".$interfaces[$i]." | grep 'inet addr:' | cut -d: -f4 | awk '{ print $1}'"); $subnet_mask = $subnet_mask != "" ? $subnet_mask : "-";
|
||||
$gateway = exec("netstat -r | grep 'default' | grep ".$interfaces[$i]." | awk '{ print $2}'"); $gateway = $gateway != "" ? $gateway : "-";
|
||||
|
||||
$mode = exec("iwconfig ".$interfaces[$i]." | grep 'Mode:' | cut -d: -f2 | awk '{ print $1}'");
|
||||
$tx_power = exec("iwconfig ".$interfaces[$i]." | grep 'Tx-Power=' | cut -d= -f2");
|
||||
|
||||
array_push($interfacesList, array("name" => $interface_name, "mac" => $mac_address, "ip" =>$ip_address, "subnet" => $subnet_mask, "gateway" => $gateway, "mode" => $mode, "txpower" => $tx_power));
|
||||
}
|
||||
|
||||
$wan = @file_get_contents("http://cloud.wifipineapple.com/ip.php"); $wan = $wan != "" ? $wan : "-";
|
||||
$gateway = exec("netstat -r | grep 'default' | awk '{ print $2}'"); $gateway = $gateway != "" ? $gateway : "-";
|
||||
$dnsAll = explode("\n", trim(shell_exec("cat /tmp/resolv.conf.auto | grep nameserver | awk '{ print $2}'")));
|
||||
$dnsList = array();
|
||||
for($i=0;$i<count($dnsAll);$i++) {
|
||||
array_push($dnsList, array("name" => "DNS ".($i+1), "ip" => $dnsAll[$i]));
|
||||
}
|
||||
|
||||
$info = array(
|
||||
'wanIpAddress' => $wan,
|
||||
'wanGateway' => $gateway,
|
||||
'dnsList' => $dnsList,
|
||||
'interfacesList' => $interfacesList
|
||||
);
|
||||
|
||||
$this->response = array('info' => $info);
|
||||
}
|
||||
|
||||
private function getMACInfo()
|
||||
{
|
||||
$content = file_get_contents("http://api.macvendors.com/".$this->request->mac);
|
||||
$this->response = array('title' => $this->request->mac, "output" => $content);
|
||||
}
|
||||
|
||||
private function getPingInfo()
|
||||
{
|
||||
exec ("ping -c4 ".$this->request->ip, $output);
|
||||
$this->response = array('title' => $this->request->ip, "output" => implode("\n", array_reverse($output)));
|
||||
}
|
||||
|
||||
private function kbytesToString($kb)
|
||||
{
|
||||
$units = array('TB','GB','MB','KB');
|
||||
$scale = 1024*1024*1024;
|
||||
$ui = 0;
|
||||
|
||||
while (($kb < $scale) && ($scale > 1))
|
||||
{
|
||||
$ui++;
|
||||
$scale = $scale / 1024;
|
||||
}
|
||||
return sprintf("%0.2f %s", ($kb/$scale),$units[$ui]);
|
||||
}
|
||||
|
||||
private function getCoreInformation()
|
||||
{
|
||||
$data = file('/proc/stat');
|
||||
$cores = array();
|
||||
|
||||
foreach( $data as $line )
|
||||
{
|
||||
if( preg_match('/^cpu[0-9]/', $line) )
|
||||
{
|
||||
$info = explode(' ', $line );
|
||||
$cores[] = array(
|
||||
'user' => $info[1],
|
||||
'nice' => $info[2],
|
||||
'sys' => $info[3],
|
||||
'idle' => $info[4]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $cores;
|
||||
}
|
||||
|
||||
private function getCpuPercentages($stat1, $stat2)
|
||||
{
|
||||
if( count($stat1) !== count($stat2) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$cpus = array();
|
||||
|
||||
for( $i = 0, $l = count($stat1); $i < $l; $i++)
|
||||
{
|
||||
$dif = array();
|
||||
$dif['user'] = $stat2[$i]['user'] - $stat1[$i]['user'];
|
||||
$dif['nice'] = $stat2[$i]['nice'] - $stat1[$i]['nice'];
|
||||
$dif['sys'] = $stat2[$i]['sys'] - $stat1[$i]['sys'];
|
||||
$dif['idle'] = $stat2[$i]['idle'] - $stat1[$i]['idle'];
|
||||
$total = array_sum($dif);
|
||||
$cpu = array();
|
||||
|
||||
foreach($dif as $x=>$y) $cpu[$x] = round($y / $total * 100, 1);
|
||||
$cpus['cpu' . $i] = $cpu;
|
||||
}
|
||||
|
||||
return $cpus;
|
||||
}
|
||||
}
|
||||
1358
Status/js/lang_pack/english.js
Normal file
1358
Status/js/lang_pack/english.js
Normal file
File diff suppressed because it is too large
Load Diff
1358
Status/js/lang_pack/language.js
Normal file
1358
Status/js/lang_pack/language.js
Normal file
File diff suppressed because it is too large
Load Diff
310
Status/js/module.js
Normal file
310
Status/js/module.js
Normal file
@@ -0,0 +1,310 @@
|
||||
registerController('Status_Controller', ['$api', '$scope', '$rootScope', '$interval', '$timeout', function($api, $scope, $rootScope, $interval, $timeout) {
|
||||
$scope.title = "Loading...";
|
||||
$scope.version = "Loading...";
|
||||
|
||||
$scope.refreshInfo = (function() {
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: "refreshInfo"
|
||||
}, function(response) {
|
||||
$scope.title = response.title;
|
||||
$scope.version = "v"+response.version;
|
||||
})
|
||||
});
|
||||
|
||||
$scope.refreshInfo();
|
||||
|
||||
}]);
|
||||
|
||||
registerController('Status_SystemController', ['$api', '$scope', '$rootScope', '$filter', function($api, $scope, $rootScope, $filter) {
|
||||
$scope.info = {
|
||||
machine : "Loading...",
|
||||
currentTime : "Loading...",
|
||||
uptime : "Loading...",
|
||||
hostname : "Loading..."
|
||||
};
|
||||
|
||||
$scope.getInfo = function() {
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getSystem'
|
||||
}, function(response) {
|
||||
$scope.info = response.info;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getInfo();
|
||||
|
||||
}]);
|
||||
|
||||
registerController('Status_CPUController', ['$api', '$scope', '$rootScope', '$filter', '$sce', function($api, $scope, $rootScope, $filter, $sce) {
|
||||
$scope.info = {
|
||||
cpuModel : "Loading...",
|
||||
bogoMIPS : "Loading...",
|
||||
type : "Loading...",
|
||||
loadAveragePourcentage : "0",
|
||||
loadAverageAll : "Loading..."
|
||||
};
|
||||
|
||||
$scope.getInfo = function() {
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getCPU'
|
||||
}, function(response) {
|
||||
$scope.info = response.info;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getSrc = (function() {
|
||||
$scope.src = $sce.trustAsResourceUrl('/modules/Status/svg/graph_cpu.svg');
|
||||
});
|
||||
|
||||
$scope.setSrc = (function() {
|
||||
$scope.src = $sce.trustAsResourceUrl('about:blank');
|
||||
});
|
||||
|
||||
$scope.setSrc();
|
||||
$scope.getInfo();
|
||||
|
||||
}]);
|
||||
|
||||
registerController('Status_DHCPController', ['$api', '$scope', '$rootScope', '$filter', function($api, $scope, $rootScope, $filter) {
|
||||
$scope.info = {
|
||||
clientsList : []
|
||||
};
|
||||
|
||||
$scope.title = "Loading...";
|
||||
$scope.output = "Loading...";
|
||||
|
||||
$scope.loading = false;
|
||||
|
||||
$scope.getInfo = function() {
|
||||
$scope.loading = true;
|
||||
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getDHCP'
|
||||
}, function(response) {
|
||||
$scope.info = response.info;
|
||||
$scope.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getMACInfo = function(param) {
|
||||
$scope.title = "Loading...";
|
||||
$scope.output = "Loading...";
|
||||
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getMACInfo',
|
||||
mac: param
|
||||
}, function(response) {
|
||||
$scope.title = response.title;
|
||||
$scope.output = response.output;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getPingInfo = function(param) {
|
||||
$scope.title = "Loading...";
|
||||
$scope.output = "Loading...";
|
||||
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getPingInfo',
|
||||
ip: param
|
||||
}, function(response) {
|
||||
$scope.title = response.title;
|
||||
$scope.output = response.output;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getInfo();
|
||||
|
||||
}]);
|
||||
|
||||
registerController('Status_MemoryController', ['$api', '$scope', '$rootScope', '$filter', function($api, $scope, $rootScope, $filter) {
|
||||
$scope.info = {
|
||||
memoryTotal : "Loading...",
|
||||
memoryFree : "Loading...",
|
||||
memoryFreePourcentage : "0",
|
||||
memoryUsed : "Loading...",
|
||||
memoryUsedPourcentage : "0"
|
||||
};
|
||||
|
||||
$scope.getInfo = function() {
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getMemory'
|
||||
}, function(response) {
|
||||
$scope.info = response.info;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getInfo();
|
||||
|
||||
}]);
|
||||
|
||||
registerController('Status_WiFiController', ['$api', '$scope', '$rootScope', '$filter', function($api, $scope, $rootScope, $filter) {
|
||||
$scope.info = {
|
||||
wifiClientsList : []
|
||||
};
|
||||
$scope.title = "Loading...";
|
||||
$scope.output = "Loading...";
|
||||
$scope.loading = false;
|
||||
|
||||
$scope.getInfo = function() {
|
||||
$scope.loading = true;
|
||||
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getWiFi'
|
||||
}, function(response) {
|
||||
$scope.info = response.info;
|
||||
$scope.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getMACInfo = function(param) {
|
||||
$scope.title = "Loading...";
|
||||
$scope.output = "Loading...";
|
||||
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getMACInfo',
|
||||
mac: param
|
||||
}, function(response) {
|
||||
$scope.title = response.title;
|
||||
$scope.output = response.output;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getPingInfo = function(param) {
|
||||
$scope.title = "Loading...";
|
||||
$scope.output = "Loading...";
|
||||
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getPingInfo',
|
||||
ip: param
|
||||
}, function(response) {
|
||||
$scope.title = response.title;
|
||||
$scope.output = response.output;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getInfo();
|
||||
|
||||
}]);
|
||||
|
||||
registerController('Status_SwapController', ['$api', '$scope', '$rootScope', '$filter', function($api, $scope, $rootScope, $filter) {
|
||||
$scope.info = {
|
||||
swapAvailable : false,
|
||||
swapTotal : "Loading...",
|
||||
swapFree : "Loading...",
|
||||
swapFreePourcentage : "0",
|
||||
swapUsed : "Loading...",
|
||||
swapUsedPourcentage : "0"
|
||||
};
|
||||
|
||||
$scope.getInfo = function() {
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getSwap'
|
||||
}, function(response) {
|
||||
$scope.info = response.info;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getInfo();
|
||||
|
||||
}]);
|
||||
|
||||
registerController('Status_StorageController', ['$api', '$scope', '$rootScope', '$filter', function($api, $scope, $rootScope, $filter) {
|
||||
$scope.info = {
|
||||
storagesList : []
|
||||
};
|
||||
|
||||
$scope.loading = false;
|
||||
|
||||
$scope.getInfo = function() {
|
||||
$scope.loading = true;
|
||||
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getStorage'
|
||||
}, function(response) {
|
||||
$scope.info = response.info;
|
||||
$scope.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getInfo();
|
||||
|
||||
}]);
|
||||
|
||||
registerController('Status_InterfaceController', ['$api', '$scope', '$rootScope', '$filter', '$sce', function($api, $scope, $rootScope, $filter, $sce) {
|
||||
$scope.info = {
|
||||
wanIpAddress : "Loading...",
|
||||
wanGateway : "Loading...",
|
||||
dnsList : [],
|
||||
interfacesList : []
|
||||
};
|
||||
|
||||
$scope.title = "Loading...";
|
||||
$scope.output = "Loading...";
|
||||
|
||||
$scope.loading = false;
|
||||
|
||||
$scope.getMACInfo = function(param) {
|
||||
$scope.title = "Loading...";
|
||||
$scope.output = "Loading...";
|
||||
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getMACInfo',
|
||||
mac: param
|
||||
}, function(response) {
|
||||
$scope.title = response.title;
|
||||
$scope.output = response.output;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getPingInfo = function(param) {
|
||||
$scope.title = "Loading...";
|
||||
$scope.output = "Loading...";
|
||||
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getPingInfo',
|
||||
ip: param
|
||||
}, function(response) {
|
||||
$scope.title = response.title;
|
||||
$scope.output = response.output;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getInfo = function() {
|
||||
$scope.loading = true;
|
||||
|
||||
$api.request({
|
||||
module: 'Status',
|
||||
action: 'getInterfaces'
|
||||
}, function(response) {
|
||||
$scope.info = response.info;
|
||||
$scope.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getSrc = (function(param) {
|
||||
$scope.src = $sce.trustAsResourceUrl('/modules/Status/svg/graph_if.svg?'+param);
|
||||
$scope.interfaceName = param;
|
||||
});
|
||||
|
||||
$scope.setSrc = (function() {
|
||||
$scope.src = $sce.trustAsResourceUrl('about:blank');
|
||||
});
|
||||
|
||||
$scope.setSrc();
|
||||
$scope.getInfo();
|
||||
|
||||
}]);
|
||||
460
Status/module.html
Normal file
460
Status/module.html
Normal file
@@ -0,0 +1,460 @@
|
||||
<div class="panel panel-default" ng-controller="Status_Controller"><div class="panel-heading"><h4 class="panel-title pull-left">{{title}}</h4><span class="pull-right">{{version}}</span><div class="clearfix"></div></div></div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6" ng-controller="Status_SystemController">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title pull-left">System</h4>
|
||||
<button type="button" class="btn btn-info pull-right btn-xs" ng-click="getInfo()">Refresh</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal">
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>Machine</strong></span>
|
||||
<span class="col-sm-5">{{info.machine}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>Current Time</strong></span>
|
||||
<span class="col-sm-5">{{info.currentTime}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>Uptime</strong></span>
|
||||
<span class="col-sm-5">{{info.uptime}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>Hostname</strong></span>
|
||||
<span class="col-sm-5">{{info.hostname}}</span>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6" ng-controller="Status_CPUController">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title pull-left">CPU</h4>
|
||||
<div class="btn-group pull-right">
|
||||
<button type="button" class="btn btn-default btn-xs" ng-click="getSrc()" data-toggle="modal" data-target="#CPUModal">Graph</button>
|
||||
<button type="button" class="btn btn-info btn-xs" ng-click="getInfo()">Refresh</button>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal">
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>CPU Model</strong></span>
|
||||
<span class="col-sm-5">{{info.cpuModel}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>System Type</strong></span>
|
||||
<span class="col-sm-5">{{info.type}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>Load Average</strong></span>
|
||||
<div class="col-sm-5">
|
||||
<div class="progress" style="margin-bottom: 0px;">
|
||||
<div class="progress-bar" role="progressbar" style="min-width: 2em; width: {{info.loadAveragePourcentage}}%;">
|
||||
{{info.loadAveragePourcentage}}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col-sm-3">{{info.loadAverageAll}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>BogoMIPS</strong></span>
|
||||
<span class="col-sm-5">{{info.bogoMIPS}}</span>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="CPUModal" tabindex="-1" role="dialog" aria-labelledby="CPUModal">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" ng-click="setSrc()" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="CPUModalLabel">CPU Monitoring</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<iframe ng-src="{{src}}" width="100%" height="275" frameborder="0" type="image/svg+xml"></iframe>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-info" ng-click="setSrc()" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6" ng-controller="Status_MemoryController">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title pull-left">Memory</h4>
|
||||
<button type="button" class="btn btn-info pull-right btn-xs" ng-click="getInfo()">Refresh</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>Total Available</strong></span>
|
||||
<span class="col-sm-5">{{info.memoryTotal}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>Free</strong></span>
|
||||
<div class="col-sm-5">
|
||||
<div class="progress" style="margin-bottom: 0px;">
|
||||
<div class="progress-bar" role="progressbar" style="min-width: 2em; width: {{info.memoryFreePourcentage}}%;">
|
||||
{{info.memoryFreePourcentage}}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col-sm-3">{{info.memoryFree}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>Used</strong></span>
|
||||
<div class="col-sm-5">
|
||||
<div class="progress" style="margin-bottom: 0px;">
|
||||
<div class="progress-bar" role="progressbar" style="min-width: 2em; width: {{info.memoryUsedPourcentage}}%;">
|
||||
{{info.memoryUsedPourcentage}}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col-sm-3">{{info.memoryUsed}}</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6" ng-controller="Status_SwapController">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title pull-left">Swap</h4>
|
||||
<button type="button" class="btn btn-info pull-right btn-xs" ng-click="getInfo()">Refresh</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal">
|
||||
|
||||
<div class="form-group" ng-show="(info.swapAvailable)">
|
||||
<span class="col-sm-3"><strong>Total Available</strong></span>
|
||||
<span class="col-sm-5">{{info.swapTotal}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-show="(info.swapAvailable)">
|
||||
<span class="col-sm-3"><strong>Free</strong></span>
|
||||
<div class="col-sm-5">
|
||||
<div class="progress" style="margin-bottom: 0px;">
|
||||
<div class="progress-bar" role="progressbar" style="min-width: 2em; width: {{info.swapFreePourcentage}}%;">
|
||||
{{info.swapFreePourcentage}}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col-sm-3">{{info.swapFree}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-show="(info.swapAvailable)">
|
||||
<span class="col-sm-3"><strong>Used</strong></span>
|
||||
<div class="col-sm-5">
|
||||
<div class="progress" style="margin-bottom: 0px;">
|
||||
<div class="progress-bar" role="progressbar" style="min-width: 2em; width: {{info.swapUsedPourcentage}}%;">
|
||||
{{info.swapUsedPourcentage}}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col-sm-3">{{info.swapUsed}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-show="(!info.swapAvailable)">
|
||||
<span class="col-sm-3"><strong>Total Available</strong></span>
|
||||
<span class="col-sm-5"><em>No Swap</em></span>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6" ng-controller="Status_WiFiController">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title pull-left">WiFi Clients <span class="badge">{{info.wifiClientsList.length}}</span></h4>
|
||||
<button type="button" class="btn btn-info pull-right btn-xs" ng-click="getInfo()">Refresh</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form ng-hide="loading" class="form-horizontal">
|
||||
|
||||
<div ng-repeat="wifiClient in info.wifiClientsList" class="form-group">
|
||||
<span class="col-sm-4">{{wifiClient['hostname']}}</span>
|
||||
<span class="col-sm-4">
|
||||
<button type="button" class="btn btn-default btn-xs" ng-click="getMACInfo(wifiClient['mac'])" data-toggle="modal" data-target="#wiFiModal">{{wifiClient['mac']}}</button>
|
||||
</span>
|
||||
<span ng-show="wifiClient['ip'] == '-'" class="col-sm-4">{{wifiClient['ip']}}</span>
|
||||
<span ng-hide="wifiClient['ip'] == '-'" class="col-sm-4">
|
||||
<button type="button" class="btn btn-default btn-xs" ng-click="getPingInfo(wifiClient['ip'])" data-toggle="modal" data-target="#wiFiModal">{{wifiClient['ip']}}</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<span ng-show="(info.wifiClientsList.length === 0 && !loading)">No WiFi Client...</span>
|
||||
<span ng-show="loading">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="wiFiModal" tabindex="-1" role="dialog" aria-labelledby="wiFiModal">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="wiFiModalLabel">{{title}}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre class="scrollable-pre log-pre">{{output}}</pre>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-md-6" ng-controller="Status_DHCPController">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title pull-left">DHCP Clients <span class="badge">{{info.clientsList.length}}</span></h4>
|
||||
<button type="button" class="btn btn-info pull-right btn-xs" ng-click="getInfo()">Refresh</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form ng-hide="loading" class="form-horizontal">
|
||||
|
||||
<div ng-repeat="client in info.clientsList" class="form-group">
|
||||
<span class="col-sm-4">{{client['hostname']}}</span>
|
||||
<span class="col-sm-4">
|
||||
<button type="button" class="btn btn-default btn-xs" ng-click="getMACInfo(client['mac'])" data-toggle="modal" data-target="#clientModal">{{client['mac']}}</button>
|
||||
</span>
|
||||
<span ng-show="client['ip'] == '-'" class="col-sm-4">{{client['ip']}}</span>
|
||||
<span ng-hide="client['ip'] == '-'" class="col-sm-4">
|
||||
<button type="button" class="btn btn-default btn-xs" ng-click="getPingInfo(client['ip'])" data-toggle="modal" data-target="#clientModal">{{client['ip']}}</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<span ng-show="(info.clientsList.length === 0 && !loading)">No DHCP Client...</span>
|
||||
<span ng-show="loading">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="clientModal" tabindex="-1" role="dialog" aria-labelledby="clientModal">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="clientModalLabel">{{title}}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre class="scrollable-pre log-pre">{{output}}</pre>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6" ng-controller="Status_StorageController">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title pull-left">Storage</h4>
|
||||
<button type="button" class="btn btn-info pull-right btn-xs" ng-click="getInfo()">Refresh</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form ng-hide="loading" class="form-horizontal">
|
||||
|
||||
<div ng-repeat="storage in info.storagesList" class="form-group">
|
||||
<span class="col-sm-2"><strong>{{storage['name']}}</strong></span>
|
||||
<span class="col-sm-2">{{storage['mount']}}</span>
|
||||
<div class="col-sm-5">
|
||||
<div class="progress" style="margin-bottom: 0px;">
|
||||
<div class="progress-bar" role="progressbar" style="min-width: 2em; width: {{storage['usedPourcentage']}};">
|
||||
{{storage['usedPourcentage']}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col-sm-3">{{storage['used']}} / {{storage['total']}}</span>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<span ng-show="(info.storagesList.length === 0 && !loading)">No storage...</span>
|
||||
<span ng-show="loading">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6" ng-controller="Status_InterfaceController">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title pull-left">Interfaces</h4>
|
||||
<button type="button" class="btn btn-info pull-right btn-xs" ng-click="getInfo()">Refresh</button>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<div ng-hide="loading" class="panel panel-default" >
|
||||
<div class="panel-heading pointer" data-toggle="collapse" data-target="#wan">wan</div>
|
||||
<div id="wan" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal">
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>IP Address</strong></span>
|
||||
<span ng-show="info.wanIpAddress == '-'" class="col-sm-5">{{info.wanIpAddress}}</span>
|
||||
<span ng-hide="info.wanIpAddress == '-'" class="col-sm-5">
|
||||
<button type="button" class="btn btn-default btn-xs" ng-click="getPingInfo(info.wanIpAddress)" data-toggle="modal" data-target="#interfaceModal">{{info.wanIpAddress}}</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>Gateway</strong></span>
|
||||
<span ng-show="info.wanGateway == '-'" class="col-sm-5">{{info.wanGateway}}</span>
|
||||
<span ng-hide="info.wanGateway == '-'" class="col-sm-5">
|
||||
<button type="button" class="btn btn-default btn-xs" ng-click="getPingInfo(info.wanGateway)" data-toggle="modal" data-target="#interfaceModal">{{info.wanGateway}}</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-repeat="dns in info.dnsList">
|
||||
<span class="col-sm-3"><strong>{{dns['name']}}</strong></span>
|
||||
<span ng-show="dns['ip'] == '-'" class="col-sm-5">{{dns['ip']}}</span>
|
||||
<span ng-hide="dns['ip'] == '-'" class="col-sm-5">
|
||||
<button type="button" class="btn btn-default btn-xs" ng-click="getPingInfo(dns['ip'])" data-toggle="modal" data-target="#interfaceModal">{{dns['ip']}}</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="loading" class="panel panel-default" ng-repeat="interface in info.interfacesList">
|
||||
<div class="panel-heading pointer" data-toggle="collapse" data-target="#{{interface['name']}}">{{interface['name']}}</div>
|
||||
<div id="{{interface['name']}}" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal">
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>MAC Address</strong></span>
|
||||
<span class="col-sm-5">
|
||||
<button type="button" class="btn btn-default btn-xs" ng-click="getMACInfo(interface['mac'])" data-toggle="modal" data-target="#interfaceModal">{{interface['mac']}}</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>IP Address</strong></span>
|
||||
<span ng-show="interface['ip'] == '-'" class="col-sm-5">{{interface['ip']}}</span>
|
||||
<span ng-hide="interface['ip'] == '-'" class="col-sm-5">
|
||||
<button type="button" class="btn btn-default btn-xs" ng-click="getPingInfo(interface['ip'])" data-toggle="modal" data-target="#interfaceModal">{{interface['ip']}}</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>Subnet Mask</strong></span>
|
||||
<span class="col-sm-5">{{interface['subnet']}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-3"><strong>Gateway</strong></span>
|
||||
<span ng-show="interface['gateway'] == '-'" class="col-sm-5">{{interface['gateway']}}</span>
|
||||
<span ng-hide="interface['gateway'] == '-'" class="col-sm-5">
|
||||
<button type="button" class="btn btn-default btn-xs" ng-click="getPingInfo(interface['gateway'])" data-toggle="modal" data-target="#interfaceModal">{{interface['gateway']}}</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-show="interface['mode'] != ''">
|
||||
<span class="col-sm-3"><strong>Mode</strong></span>
|
||||
<span class="col-sm-5">{{interface['mode']}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-show="interface['mode'] != ''">
|
||||
<span class="col-sm-3"><strong>TX Power</strong></span>
|
||||
<span class="col-sm-5">{{interface['txpower']}}</span>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-default btn-xs" data-toggle="modal" ng-click="getSrc(interface['name'])" data-target="#graphModal">Graph</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span ng-show="loading">Loading...</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="graphModal" tabindex="-1" role="dialog" aria-labelledby="graphModal">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" ng-click="setSrc()" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="graphModalLabel">{{interfaceName}} Monitoring</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<iframe ng-src="{{src}}" width="100%" height="275" frameborder="0" type="image/svg+xml"></iframe>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-info" ng-click="setSrc()" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="interfaceModal" tabindex="-1" role="dialog" aria-labelledby="interfaceModal">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="interfaceModalLabel">{{title}}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre class="scrollable-pre log-pre">{{output}}</pre>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-info" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
10
Status/module.info
Normal file
10
Status/module.info
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"author": "Whistle Master",
|
||||
"description": "Display status information of the device",
|
||||
"devices": [
|
||||
"nano",
|
||||
"tetra"
|
||||
],
|
||||
"title": "Status",
|
||||
"version": "1.1"
|
||||
}
|
||||
199
Status/svg/graph_cpu.svg
Normal file
199
Status/svg/graph_cpu.svg
Normal file
@@ -0,0 +1,199 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
OpenWRT port of this file based originally on the following:
|
||||
|
||||
|
||||
$Id: graph_cpu.php 41 2006-01-12 18:48:27Z mkasper $
|
||||
part of m0n0wall (http://m0n0.ch/wall)
|
||||
|
||||
Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
|
||||
and Jonathan Watt <jwatt@jwatt.org>.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
<svg xml:space='preserve' xmlns='http://www.w3.org/2000/svg'
|
||||
xmlns:xlink='http://www.w3.org/1999/xlink'
|
||||
width='100%' height='100%'
|
||||
viewBox='0 0 600 300'
|
||||
preserveAspectRatio='none'
|
||||
onload='init(evt)'
|
||||
>
|
||||
<g id='graph'>
|
||||
<rect id='bg' x1='0' y1='0' width='600' height='300' fill='white' />
|
||||
|
||||
<text id='graph_lbl' x='50' y='15' fill='#435370' text-anchor='end'>CPU</text>
|
||||
<text id='graph_txt' x='54' y='15' fill='#435370'>--</text>
|
||||
|
||||
<text id='error' x='300' y='125' text-anchor='middle' visibility='hidden' fill='blue'>Cannot get data about CPU</text>
|
||||
<text id='collect_initial' x='300' y='125' text-anchor='middle' visibility='hidden' fill='gray'>Collecting initial data, please wait...</text>
|
||||
|
||||
<path id='grid' d='M 2 75 L 600 75 M 2 150 L 600 150 M 2 225 L 600 225' stroke='gray' stroke-opacity='0.5' />
|
||||
<text id='grid_txt3' x='600' y='223' fill='gray' text-anchor='end'>25%</text>
|
||||
<text id='grid_txt2' x='600' y='148' fill='gray' text-anchor='end'>50%</text>
|
||||
<text id='grid_txt1' x='600' y='73' fill='gray' text-anchor='end'>75%</text>
|
||||
|
||||
<path id='graph_cpu' d='' fill='none' stroke='#435370' stroke-width='2' stroke-opacity='0.8' />
|
||||
|
||||
<line id='axis_x' x1='1' y1='299' x2='600' y2='299' stroke='black' />
|
||||
<line id='axis_y' x1='1' y1='299.5' x2='1' y2='0' stroke='black' />
|
||||
</g>
|
||||
<script type="text/ecmascript">
|
||||
<![CDATA[
|
||||
if (typeof getURL == 'undefined') {
|
||||
getURL = function(url, callback) {
|
||||
if (!url)
|
||||
throw '@TR<<graph_No_URL_getURL#No URL for getURL>>';
|
||||
|
||||
try {
|
||||
if (typeof callback.operationComplete == 'function')
|
||||
callback = callback.operationComplete;
|
||||
} catch (e) {}
|
||||
if (typeof callback != 'function')
|
||||
throw '@TR<<graph_No_callback_function#No callback function for getURL>>';
|
||||
|
||||
var http_request = null;
|
||||
if (typeof XMLHttpRequest != 'undefined') {
|
||||
http_request = new XMLHttpRequest();
|
||||
}
|
||||
else if (typeof ActiveXObject != 'undefined') {
|
||||
try {
|
||||
http_request = new ActiveXObject('Msxml2.XMLHTTP');
|
||||
} catch (e) {
|
||||
try {
|
||||
http_request = new ActiveXObject('Microsoft.XMLHTTP');
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
if (!http_request)
|
||||
throw '@TR<<graph_Both_undefined#Both getURL and XMLHttpRequest are undefined>>';
|
||||
|
||||
http_request.onreadystatechange = function() {
|
||||
if (http_request.readyState == 4) {
|
||||
callback( { success : true,
|
||||
content : http_request.responseText,
|
||||
contentType : http_request.getResponseHeader("Content-Type") } );
|
||||
}
|
||||
}
|
||||
http_request.open('GET', url, true);
|
||||
http_request.send(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var SVGDoc = null;
|
||||
var last_cpu_total = 0;
|
||||
var last_cpu_idle = 0;
|
||||
var cpu_data = new Array();
|
||||
|
||||
var max_num_points = 120; // maximum number of plot data points
|
||||
var step = 600 / max_num_points; // plot X division size
|
||||
|
||||
var fetch_url='../api/fetchcpu.php';
|
||||
|
||||
function init(evt) {
|
||||
SVGDoc = evt.target.ownerDocument;
|
||||
fetch_data();
|
||||
setInterval('fetch_data()', 1000);
|
||||
}
|
||||
|
||||
function fetch_data() {
|
||||
if (fetch_url) {
|
||||
getURL(fetch_url, plot_cpu_data);
|
||||
} else {
|
||||
handle_error();
|
||||
}
|
||||
}
|
||||
|
||||
function plot_cpu_data(obj) {
|
||||
if (!obj.success || ''==obj.content) {
|
||||
return handle_error(); // getURL failed to get current CPU load data
|
||||
}
|
||||
|
||||
try {
|
||||
var data=obj.content.split("\n");
|
||||
var ugmt=(Date.parse(data[0]))/1000;
|
||||
data=data[1].split(/\s+/);
|
||||
var tot=parseInt(data[1])+parseInt(data[2])+parseInt(data[3])+parseInt(data[4]);
|
||||
var idle=parseInt(data[4]);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cpu=0;
|
||||
if (tot==last_cpu_total) {
|
||||
cpu=100;
|
||||
} else {
|
||||
cpu=100*(idle-last_cpu_idle)/(tot-last_cpu_total);
|
||||
}
|
||||
cpu=100-cpu;
|
||||
|
||||
last_cpu_idle=idle;
|
||||
last_cpu_total=tot;
|
||||
|
||||
if (!isNumber(cpu)) return handle_error();
|
||||
|
||||
switch (cpu_data.length) {
|
||||
case 0:
|
||||
SVGDoc.getElementById('collect_initial').setAttributeNS(null, 'visibility', 'visible');
|
||||
cpu_data[0] = cpu;
|
||||
fetch_data;
|
||||
return;
|
||||
case 1:
|
||||
SVGDoc.getElementById('collect_initial').setAttributeNS(null, 'visibility', 'hidden');
|
||||
break;
|
||||
case max_num_points:
|
||||
// shift plot to left if the maximum number of plot points has been reached
|
||||
var i = 0;
|
||||
while (i < max_num_points) {
|
||||
cpu_data[i] = cpu_data[++i];
|
||||
}
|
||||
--cpu_data.length;
|
||||
}
|
||||
|
||||
cpu_data[cpu_data.length] = cpu;
|
||||
|
||||
var path_data = "M 2 " + (298 - cpu_data[0]);
|
||||
for (var i = 1; i < cpu_data.length; ++i) {
|
||||
var x = step * i;
|
||||
var y_cpu = 298 - 2.975*cpu_data[i];
|
||||
path_data += " L" + x + " " + y_cpu;
|
||||
}
|
||||
|
||||
|
||||
SVGDoc.getElementById('error').setAttributeNS(null, 'visibility', 'hidden');
|
||||
SVGDoc.getElementById('graph_cpu').setAttributeNS(null, 'd', path_data);
|
||||
SVGDoc.getElementById('graph_txt').firstChild.data = Math.round(cpu*10)/10 + '%';
|
||||
}
|
||||
|
||||
function handle_error() {
|
||||
SVGDoc.getElementById("error").setAttributeNS(null, 'visibility', 'visible');
|
||||
fetch_data();
|
||||
}
|
||||
|
||||
function isNumber(a) {
|
||||
return typeof a == 'number' && isFinite(a);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</svg>
|
||||
335
Status/svg/graph_if.svg
Normal file
335
Status/svg/graph_if.svg
Normal file
@@ -0,0 +1,335 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!--
|
||||
OpenWRT port of this file based originally on the following:
|
||||
|
||||
|
||||
$Id: graph_cpu.php 41 2006-01-12 18:48:27Z mkasper $
|
||||
part of m0n0wall (http://m0n0.ch/wall)
|
||||
|
||||
Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
|
||||
and Jonathan Watt <jwatt@jwatt.org>.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributionss in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
<svg xml:space='preserve' xmlns='http://www.w3.org/2000/svg'
|
||||
xmlns:xlink='http://www.w3.org/1999/xlink'
|
||||
width='100%' height='100%'
|
||||
viewBox='0 0 600 300'
|
||||
preserveAspectRatio='none'
|
||||
onload='init(evt)'
|
||||
>
|
||||
<g id='graph'>
|
||||
<rect id='bg' x1='0' y1='0' width='600' height='300' fill='white' />
|
||||
|
||||
<text id='graph_in_lbl' x='60' y='15' fill='green' text-anchor='end'>In</text>
|
||||
<text id='graph_out_lbl' x='60' y='35' fill='red' text-anchor='end'>Out</text>
|
||||
|
||||
<text id='graph_in_txt' x='70' y='15' fill='green'>--</text>
|
||||
<text id='graph_out_txt' x='70' y='35' fill='red'>--</text>
|
||||
|
||||
<text id='switch_unit' x='250' y='15' fill='#435370' cursor='pointer'>Switch to bytes/s</text>
|
||||
<text id='switch_scale' x='250' y='35' fill='#435370' cursor='pointer'>Autoscale (follow)</text>
|
||||
|
||||
<text id='error' x='300' y='125' text-anchor='middle' visibility='hidden' fill='blue'>Cannot get data about interface</text>
|
||||
<text id='collect_initial' x='300' y='125' text-anchor='middle' visibility='hidden' fill='gray'>Collecting initial data, please wait...</text>
|
||||
|
||||
<path id='grid' d='M 2 75 L 600 75 M 2 150 L 600 150 M 2 225 L 600 225' stroke='gray' stroke-opacity='0.5' />
|
||||
<text id='grid_txt3' x='600' y='223' fill='gray' text-anchor='end'>--</text>
|
||||
<text id='grid_txt2' x='600' y='148' fill='gray' text-anchor='end'>--</text>
|
||||
<text id='grid_txt1' x='600' y='73' fill='gray' text-anchor='end'>--</text>
|
||||
|
||||
<path id='graph_out' d='' fill='none' stroke='red' stroke-width='1' stroke-opacity='0.8' />
|
||||
<path id='graph_in' d='' fill='none' stroke='green' stroke-width='1' stroke-opacity='0.8' />
|
||||
|
||||
<line id='axis_x' x1='2' y1='299' x2='600' y2='299' stroke='black' />
|
||||
<line id='axis_y' x1='1' y1='300' x2='1' y2='0' stroke='black' />
|
||||
</g>
|
||||
<script type="text/ecmascript" xlink:href="../js/lang_pack/english.js" />
|
||||
<script type="text/ecmascript" xlink:href="../js/lang_pack/language.js" />
|
||||
<script type="text/ecmascript">
|
||||
<![CDATA[
|
||||
if (typeof getURL == 'undefined') {
|
||||
getURL = function(url, callback) {
|
||||
if (!url) throw 'No URL for getURL';
|
||||
|
||||
try {
|
||||
if (typeof callback.operationComplete == 'function') {
|
||||
callback = callback.operationComplete;
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
if (typeof callback != 'function') {
|
||||
throw 'No callback function for getURL';
|
||||
}
|
||||
|
||||
var http_request = null;
|
||||
if (typeof XMLHttpRequest != 'undefined') {
|
||||
http_request = new XMLHttpRequest();
|
||||
} else if (typeof ActiveXObject != 'undefined') {
|
||||
try {
|
||||
http_request = new ActiveXObject('Msxml2.XMLHTTP');
|
||||
} catch (e) {
|
||||
try {
|
||||
http_request = new ActiveXObject('Microsoft.XMLHTTP');
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
if (!http_request) {
|
||||
throw 'Both getURL and XMLHttpRequest are undefined';
|
||||
}
|
||||
|
||||
http_request.onreadystatechange = function() {
|
||||
if (http_request.readyState == 4) {
|
||||
callback(
|
||||
{
|
||||
success : true,
|
||||
content : http_request.responseText,
|
||||
contentType : http_request.getResponseHeader("Content-Type")
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
http_request.open('GET', url, true);
|
||||
http_request.send(null);
|
||||
}
|
||||
}
|
||||
|
||||
var SVGDoc = null;
|
||||
var last_ifin = 0;
|
||||
var last_ifout = 0;
|
||||
var last_ugmt = 0;
|
||||
var max = 0;
|
||||
var plot_in = new Array();
|
||||
var plot_out = new Array();
|
||||
|
||||
var max_num_points = 120; // maximum number of plot data points
|
||||
var step = 600 / max_num_points ;
|
||||
var unit = share.bytes;
|
||||
var scale_type = status_band.follow;
|
||||
|
||||
var fetch_url='';
|
||||
|
||||
function init(evt) {
|
||||
/* hacked in fix for all browsers by spectra
|
||||
* he says is 'ugly', and someone may want to redo the 'right' way */
|
||||
fetch_url=location.search.split('?');
|
||||
//fetch_url='/fetchif.cgi?' + fetch_url[fetch_url.length-1];
|
||||
fetch_url='../api/fetchif.php?if=' + fetch_url[fetch_url.length-1];
|
||||
/* end hacked in fix */
|
||||
SVGDoc = evt.target.ownerDocument;
|
||||
do_translation();
|
||||
SVGDoc.getElementById("switch_unit").addEventListener("mousedown", switch_unit, false);
|
||||
SVGDoc.getElementById("switch_scale").addEventListener("mousedown", switch_scale, false);
|
||||
fetch_data();
|
||||
setInterval('fetch_data()', 1000);
|
||||
}
|
||||
|
||||
function do_translation() {
|
||||
SVGDoc.getElementById('graph_in_lbl').firstChild.data = status_band.strin;
|
||||
SVGDoc.getElementById('graph_out_lbl').firstChild.data = status_band.strout;
|
||||
SVGDoc.getElementById('switch_unit').firstChild.data = status_band.chg_unit + unit + '/s';
|
||||
SVGDoc.getElementById('switch_scale').firstChild.data = status_band.chg_scale + ' (' + scale_type + ')';
|
||||
SVGDoc.getElementById('error').firstChild.data = status_band.chg_error;
|
||||
SVGDoc.getElementById('collect_initial').firstChild.data = status_band.chg_collect_initial;
|
||||
}
|
||||
|
||||
function switch_unit(event) {
|
||||
unit = (unit == 'bits') ? share.bytes : 'bits';
|
||||
SVGDoc.getElementById('switch_unit').firstChild.data = status_band.chg_unit + unit + '/s';
|
||||
}
|
||||
|
||||
function switch_scale(event) {
|
||||
scale_type = (scale_type == status_band.up) ? status_band.follow : status_band.up;
|
||||
SVGDoc.getElementById('switch_scale').firstChild.data = status_band.chg_scale + ' (' + scale_type + ')';
|
||||
}
|
||||
|
||||
function fetch_data() {
|
||||
if (fetch_url) {
|
||||
getURL(fetch_url, plot_data);
|
||||
} else {
|
||||
handle_error();
|
||||
}
|
||||
}
|
||||
|
||||
function plot_data(obj) {
|
||||
if (!obj.success) return handle_error(); // getURL failed to get data
|
||||
if (!obj.content) return handle_error(); // getURL get empty data, IE problem
|
||||
|
||||
// parse incoming data
|
||||
// (format: "date" output, newline, proper line of /proc/net/dev)
|
||||
var data=obj.content.split("\n");
|
||||
var dateStr=data[0];
|
||||
//fake timezone cause the real value might confuse JS
|
||||
dateStr=dateStr.replace(/ [A-Z]+ /, ' GMT ');
|
||||
var ugmt=(Date.parse(dateStr))/1000;
|
||||
|
||||
data=data[1].split(/\s+|:/);
|
||||
while (data[0]!=parseInt(data[0])) {
|
||||
data.shift();
|
||||
|
||||
if (0==data.length) return;
|
||||
}
|
||||
var ifin=parseInt(data[0]);
|
||||
var ifout=parseInt(data[8]);
|
||||
|
||||
if (!isNumber(ifin) || !isNumber(ifout)) {
|
||||
return handle_error();
|
||||
}
|
||||
|
||||
var diff_ugmt = ugmt - last_ugmt;
|
||||
var diff_ifin = ifin - last_ifin;
|
||||
var diff_ifout = ifout - last_ifout;
|
||||
|
||||
if (diff_ugmt == 0) diff_ugmt = 1; // avoid division by zero
|
||||
|
||||
last_ugmt = ugmt;
|
||||
last_ifin = ifin;
|
||||
last_ifout = ifout;
|
||||
|
||||
switch (plot_in.length) {
|
||||
case 0:
|
||||
SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'visible');
|
||||
plot_in[0] = diff_ifin / diff_ugmt;
|
||||
plot_out[0] = diff_ifout / diff_ugmt;
|
||||
return;
|
||||
case 1:
|
||||
SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'hidden');
|
||||
break;
|
||||
case max_num_points:
|
||||
// shift plot to left if the maximum number of plot points has been reached
|
||||
var i = 0;
|
||||
while (i < max_num_points) {
|
||||
plot_in[i] = plot_in[i+1];
|
||||
plot_out[i] = plot_out[++i];
|
||||
}
|
||||
plot_in.length--;
|
||||
plot_out.length--;
|
||||
}
|
||||
|
||||
plot_in[plot_in.length] = diff_ifin / diff_ugmt;
|
||||
plot_out[plot_out.length]= diff_ifout / diff_ugmt;
|
||||
var index_plot = plot_in.length - 1;
|
||||
|
||||
SVGDoc.getElementById('graph_in_txt').firstChild.data = formatSpeed(plot_in[index_plot], unit);
|
||||
SVGDoc.getElementById('graph_out_txt').firstChild.data = formatSpeed(plot_out[index_plot], unit);
|
||||
|
||||
// determine peak for sensible scaling
|
||||
if (scale_type == status_band.up) {
|
||||
if (plot_in[index_plot] > max) max = plot_in[index_plot];
|
||||
if (plot_out[index_plot] > max) max = plot_out[index_plot];
|
||||
} else if (scale_type == status_band.follow) {
|
||||
i = 0;
|
||||
max = 0;
|
||||
while (i < plot_in.length) {
|
||||
if (plot_in[i] > max) max = plot_in[i];
|
||||
if (plot_out[i] > max) max = plot_out[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
var rmax=makeRoundMax(max);
|
||||
|
||||
var scale = 298 / rmax;
|
||||
|
||||
// change labels accordingly
|
||||
SVGDoc.getElementById('grid_txt1').firstChild.data = formatSpeed(3*rmax/4, unit);
|
||||
SVGDoc.getElementById('grid_txt2').firstChild.data = formatSpeed(2*rmax/4, unit);
|
||||
SVGDoc.getElementById('grid_txt3').firstChild.data = formatSpeed(rmax/4, unit);
|
||||
|
||||
var path_in = "M 0 " + (298 - (plot_in[0] * scale));
|
||||
var path_out = "M 0 " + (298 - (plot_out[0] * scale));
|
||||
for (i = 1; i < plot_in.length; i++) {
|
||||
var x = step * i;
|
||||
var y_in = 298 - (plot_in[i] * scale);
|
||||
var y_out = 298 - (plot_out[i] * scale);
|
||||
path_in += " L" + x + " " + y_in;
|
||||
path_out += " L" + x + " " + y_out;
|
||||
}
|
||||
|
||||
SVGDoc.getElementById('error').setAttributeNS(null, 'visibility', 'hidden');
|
||||
SVGDoc.getElementById('graph_in').setAttributeNS(null, 'd', path_in);
|
||||
SVGDoc.getElementById('graph_out').setAttributeNS(null, 'd', path_out);
|
||||
}
|
||||
|
||||
function makeRoundMax(max) {
|
||||
if (unit == share.bytes) {
|
||||
rmax = 1250;
|
||||
i = 0;
|
||||
while (max > rmax) {
|
||||
//dump(i+'\n');
|
||||
i++;
|
||||
if (i && (i % 4 == 0)) {
|
||||
rmax *= 1.25;
|
||||
} else {
|
||||
rmax *= 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rmax = 1024;
|
||||
i = 0;
|
||||
while (max > rmax) {
|
||||
i++;
|
||||
if (i && (i % 4 == 0)) {
|
||||
rmax *= 1.25;
|
||||
} else {
|
||||
rmax *= 2;
|
||||
}
|
||||
|
||||
if (i == 8) rmax *= 1.024;
|
||||
}
|
||||
}
|
||||
return rmax;
|
||||
}
|
||||
|
||||
function handle_error() {
|
||||
SVGDoc.getElementById("error").setAttributeNS(null, 'visibility', 'visible');
|
||||
}
|
||||
|
||||
function isNumber(a) {
|
||||
return typeof a == 'number' && isFinite(a);
|
||||
}
|
||||
|
||||
function formatSpeed(speed, unit) {
|
||||
if (unit == 'bits') return formatSpeedBytes(speed);
|
||||
if (unit == share.bytes) return formatSpeedBits(speed);
|
||||
}
|
||||
|
||||
function formatSpeedBits(speed) {
|
||||
// format speed in bits/sec, input: bytes/sec
|
||||
if (speed < 125000) return Math.round(speed / 125) + " Kbps";
|
||||
if (speed < 125000000) return Math.round(speed / 1250)/100 + " Mbps";
|
||||
// else
|
||||
return Math.round(speed / 1250000)/100 + " Gbps"; // wow!
|
||||
}
|
||||
|
||||
function formatSpeedBytes(speed) {
|
||||
// format speed in bytes/sec, input: bytes/sec
|
||||
if (speed < 1048576) return Math.round(speed / 10.24)/100 + " " + share.kbytes + "/s";
|
||||
if (speed < 1073741824) return Math.round(speed / 10485.76)/100 + " " + share.mbytes + "/s";
|
||||
// else
|
||||
return Math.round(speed / 10737418.24)/100 + " " + share.mbytes + "/s"; // wow!
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</svg>
|
||||
Reference in New Issue
Block a user