From 993dc633a95084e02cf55e0e1725016ba9d56078 Mon Sep 17 00:00:00 2001 From: glaszig Date: Thu, 8 Aug 2019 02:10:40 +0200 Subject: [PATCH] load wifi stations via ajax, cache the scan result until the "rescan" button is pressed. speeds up "configure client" page massively. --- ajax/networking/wifi_stations.php | 94 ++++++++++++++++ dist/css/custom.css | 6 ++ img/loading-spinner.gif | Bin 0 -> 2052 bytes includes/config.php | 1 + includes/configure_client.php | 174 +----------------------------- includes/functions.php | 64 +++++++++++ js/custom.js | 16 ++- templates/wifi_stations.php | 93 ++++++++++++++++ 8 files changed, 275 insertions(+), 173 deletions(-) create mode 100644 ajax/networking/wifi_stations.php create mode 100644 img/loading-spinner.gif create mode 100644 templates/wifi_stations.php diff --git a/ajax/networking/wifi_stations.php b/ajax/networking/wifi_stations.php new file mode 100644 index 00000000..e04c2612 --- /dev/null +++ b/ajax/networking/wifi_stations.php @@ -0,0 +1,94 @@ + false, 'configured' => true, 'connected' => false); + } elseif ($network !== null) { + if (preg_match('/^\s*}\s*$/', $line)) { + $networks[$ssid] = $network; + $network = null; + $ssid = null; + } elseif ($lineArr = preg_split('/\s*=\s*/', trim($line))) { + switch (strtolower($lineArr[0])) { + case 'ssid': + $ssid = trim($lineArr[1], '"'); + break; + case 'psk': + if (array_key_exists('passphrase', $network)) { + break; + } + case '#psk': + $network['protocol'] = 'WPA'; + case 'wep_key0': // Untested + $network['passphrase'] = trim($lineArr[1], '"'); + break; + case 'key_mgmt': + if (! array_key_exists('passphrase', $network) && $lineArr[1] === 'NONE') { + $network['protocol'] = 'Open'; + } + break; + case 'priority': + $network['priority'] = trim($lineArr[1], '"'); + break; + } + } + } + } + + exec('sudo wpa_cli -i ' . RASPI_WIFI_CLIENT_INTERFACE . ' scan'); + sleep(3); + exec('sudo wpa_cli -i ' . RASPI_WIFI_CLIENT_INTERFACE . ' scan_results', $scan_return); + array_shift($scan_return); + + foreach ($scan_return as $network) { + $arrNetwork = preg_split("/[\t]+/", $network); // split result into array + + // If network is saved + if (array_key_exists(4, $arrNetwork) && array_key_exists($arrNetwork[4], $networks)) { + $networks[$arrNetwork[4]]['visible'] = true; + $networks[$arrNetwork[4]]['channel'] = ConvertToChannel($arrNetwork[1]); + // TODO What if the security has changed? + } else { + $networks[$arrNetwork[4]] = array( + 'configured' => false, + 'protocol' => ConvertToSecurity($arrNetwork[3]), + 'channel' => ConvertToChannel($arrNetwork[1]), + 'passphrase' => '', + 'visible' => true, + 'connected' => false + ); + } + + // Save RSSI + if (array_key_exists(4, $arrNetwork)) { + $networks[$arrNetwork[4]]['RSSI'] = $arrNetwork[2]; + } + } + + exec('iwconfig ' . RASPI_WIFI_CLIENT_INTERFACE, $iwconfig_return); + foreach ($iwconfig_return as $line) { + if (preg_match('/ESSID:\"([^"]+)\"/i', $line, $iwconfig_ssid)) { + $networks[$iwconfig_ssid[1]]['connected'] = true; + } + } + + return renderTemplate('wifi_stations', compact('networks')); +}); diff --git a/dist/css/custom.css b/dist/css/custom.css index 8901c950..6177909c 100644 --- a/dist/css/custom.css +++ b/dist/css/custom.css @@ -69,3 +69,9 @@ pre.unstyled { margin-top: 0.5em; margin-bottom: 0.5em; } + +.loading-spinner { + background: url("../../img/loading-spinner.gif") no-repeat scroll center center transparent; + min-height: 150px; + width: 100%; +} diff --git a/img/loading-spinner.gif b/img/loading-spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..f7e0378a8ca71410b4cbb6baa30de9f9e8cf150d GIT binary patch literal 2052 zcmZXVc~Fzr8pcn)eEG5g1`-xo!Xn0?fJ_7$;g$xJEi8hhNLeItBLZSrM4+fi2wMb2 zWD`*XQe`Wk2(mXsP!JKuttyTLsfdkSRH~rPz1-MwrkT0t-*e`DelySWyvN(ui@BNi z6qJHRB4}%Cd-Ukh^z?Lhceh9+a&&Y=p-?6!CWC{6<>loZ4rgU$1!x@06=I+#CuECz zkSD|50gX~$S$={s7(fKJU!Q#)3*Z&Oh;L&bQ#IDJ!lj?sv;RE5p*ddFFR&d?IWU#h zypXxDB9{q#Y>iJ2*Cvg`yIh#4OJV;S-txF9b#y-CH)U&@zx~VSrLlFS(5CW+`N40@q)q=CyP!MpDrmaE3Y_HdA91@`3th@nv1o+T)JFW z-_Y3fYjev+Jc4ia#v)jK6x7ZHus))o-~i}zhOk%yMS+l^o9JQZQS2?faWeWQ>Y)=n ziXl%DQTLV3m{B=#_9p24(-HjMJ2?k%l+TNQSpy246(<&_8q|8KX0^HbFq%jo&QY=k zw1!^1OAhmJ-3##@p)*&z+hchGW zigCGMoU?xD$pGKC)>vr2m(Y$IYgp5~kDLD^yhBIJ_v0I>J1Z>KjA1wTQiy zg_qmsyVAC;9d47IobO85J)gS9gz@ z8~wMZ*J2HSRh&(c+x6uX3~EQuz@a0G__(K?$*SjLJ=Yhee|yL~-N3(6bE&A0XUep;Nn-xxjK-}hzd?aWl3Mg*dO3ortP z>IfvMBcMV#seTHq-+DFw0dIRYk3Y2I{Pr4ZysJOW&TM`4T04x6SH%GXse#RPT%A^J zz~~UCE;0a`&QWaNlQ+U@)b@cecTPbTxv(lgK7ah+O-bv2>Yjg@fzTjJa*QaJWFHgd zXXX4I0q=~Tb^l4?PBn%Z(D{b3j_#!D;{>mk2Mh%1(|<9&Mc0)ut1IBv4>@K98k}Wm3A8fE`~2^RQwI?$*R9hFpQl>`zI#AQ zPEKbZ;ZPv7DA1ml7?#Z6LO2!1Hr2q`qsCYbbk!L91tVP~cSqGZpW9O%ICrnApMvv% zFkqc~{fm1LRKS)R$BG`Y)CS9pa%kqUUPKZd1{o#l>7db}ELnIpNacXrvwHpB5=TO_)&}U@bi@fx+ z+KG1;PKRM;@zRKgI`l|wyULsMOD8}`Q!$+qgcHka91L<~to!wCOd=t?eU~KRH{}A) z-z{`x?#AXQAh`igm2(|B`#*dhAbL>VBl{xo*!05@DM-TqNmJF*!XT|H4Si`sk#0W= zM;qCZE%&@ci$&G`E+u-D&AzZdd{o*2H!>_p&?UJ8*D)zmy!EtjG2o;dQE_HSt4A5n z^AFAZ;g1yerclY0!EM(>rd;(wvAJGu{)`4A41h_a5fCKKFoy<7ksqVPNa{hX6g~(} z2{6(m9*3p@6%Sn1UYM()GSzN~WkzejRl{e>y=cP%4ylHMjf@|%w84ffS(VUwx*SW0 z4#VjjVTgZCq|5h`I!9dzyQMC!%xwjz9+k;4T_>9JQCGOBDV;V^D1q!TY;5+Tksqeo^B^Kd5DT%7Zt%320%1X1&4|y zc&A`fojP$CV{L)$pzoU=la0vBr?v6~Lt6f8R{!$z`OrkC6f8(i&`XcBi8jkUMn=a_ zbMy(A6PZaxP8u*#!1r5OVjRr2sJfY|h@K~0T6#49{G1KRCd1U1Xt1y$hJA$22l4HS z1*>PvAWutv$%bMtnZvO3WmV&zCGAX|KthcFhCZ!2QIKLJtIQDkQ&4s&c_S`%xc*5j z6dG%chj)KxjDvkmG_-dD4|O!YRwasLw56mq-$pRK)KHK48E}{QKwP zZ>MyKUMw~05~ZxsrI1KiLY`advc|!3NbWh-YS8Q~S*xXpnviAcp1#8V>v8E&r@N?Y zFJMl=Xh=gb3j9mGpUl*X>P6Y5SDj`Y!g!7-0|rwI?q7-GL&$z_{j4@)YdO;x>Q$Z4b?>c?lLd)%QJ6k|rHLHu|D=lL2i|2@I>;;l c@T5Y*-Bh$tyc#7uvPYQi1ybpdR2R7Z4?Bn+fdBvi literal 0 HcmV?d00001 diff --git a/includes/config.php b/includes/config.php index 8dfd9173..0931caf5 100755 --- a/includes/config.php +++ b/includes/config.php @@ -5,6 +5,7 @@ define('RASPI_CONFIG', '/etc/raspap'); define('RASPI_CONFIG_NETWORKING', RASPI_CONFIG.'/networking'); define('RASPI_ADMIN_DETAILS', RASPI_CONFIG.'/raspap.auth'); define('RASPI_WIFI_CLIENT_INTERFACE', 'wlan0'); +define('RASPI_CACHE_PATH', sys_get_temp_dir() . '/raspap'); // Constants for configuration file paths. // These are typical for default RPi installs. Modify if needed. diff --git a/includes/configure_client.php b/includes/configure_client.php index 1253de82..dccbeaf8 100755 --- a/includes/configure_client.php +++ b/includes/configure_client.php @@ -7,48 +7,6 @@ function DisplayWPAConfig() { $status = new StatusMessages(); - $networks = array(); - - // Find currently configured networks - exec(' sudo cat ' . RASPI_WPA_SUPPLICANT_CONFIG, $known_return); - - $network = null; - $ssid = null; - - foreach ($known_return as $line) { - if (preg_match('/network\s*=/', $line)) { - $network = array('visible' => false, 'configured' => true, 'connected' => false); - } elseif ($network !== null) { - if (preg_match('/^\s*}\s*$/', $line)) { - $networks[$ssid] = $network; - $network = null; - $ssid = null; - } elseif ($lineArr = preg_split('/\s*=\s*/', trim($line))) { - switch (strtolower($lineArr[0])) { - case 'ssid': - $ssid = trim($lineArr[1], '"'); - break; - case 'psk': - if (array_key_exists('passphrase', $network)) { - break; - } - case '#psk': - $network['protocol'] = 'WPA'; - case 'wep_key0': // Untested - $network['passphrase'] = trim($lineArr[1], '"'); - break; - case 'key_mgmt': - if (! array_key_exists('passphrase', $network) && $lineArr[1] === 'NONE') { - $network['protocol'] = 'Open'; - } - break; - case 'priority': - $network['priority'] = trim($lineArr[1], '"'); - break; - } - } - } - } if (isset($_POST['connect'])) { $result = 0; @@ -128,45 +86,6 @@ function DisplayWPAConfig() } } - exec('sudo wpa_cli -i ' . RASPI_WIFI_CLIENT_INTERFACE . ' scan'); - sleep(3); - exec('sudo wpa_cli -i ' . RASPI_WIFI_CLIENT_INTERFACE . ' scan_results', $scan_return); - - array_shift($scan_return); - - // display output - foreach ($scan_return as $network) { - $arrNetwork = preg_split("/[\t]+/", $network); // split result into array - - // If network is saved - if (array_key_exists(4, $arrNetwork) && array_key_exists($arrNetwork[4], $networks)) { - $networks[$arrNetwork[4]]['visible'] = true; - $networks[$arrNetwork[4]]['channel'] = ConvertToChannel($arrNetwork[1]); - // TODO What if the security has changed? - } else { - $networks[$arrNetwork[4]] = array( - 'configured' => false, - 'protocol' => ConvertToSecurity($arrNetwork[3]), - 'channel' => ConvertToChannel($arrNetwork[1]), - 'passphrase' => '', - 'visible' => true, - 'connected' => false - ); - } - - // Save RSSI - if (array_key_exists(4, $arrNetwork)) { - $networks[$arrNetwork[4]]['RSSI'] = $arrNetwork[2]; - } - - } - - exec('iwconfig ' . RASPI_WIFI_CLIENT_INTERFACE, $iwconfig_return); - foreach ($iwconfig_return as $line) { - if (preg_match('/ESSID:\"([^"]+)\"/i', $line, $iwconfig_ssid)) { - $networks[$iwconfig_ssid[1]]['connected'] = true; - } - } ?>
@@ -178,7 +97,7 @@ function DisplayWPAConfig()

showMessages(); ?>

- +
@@ -195,96 +114,7 @@ function DisplayWPAConfig() } - - $network) { ?> - -
-
-
- - -

- -
-
Status
-
- - - - - - -
-
- -
-
Channel
-
- - - - X - -
-
- -
-
RSSI
-
- = -50) { - echo 100; - } elseif ($network['RSSI'] <= -100) { - echo 0; - } else { - echo 2*($network['RSSI'] + 100); - } - echo "%)"; - ?> -
-
- - - - - - -
-
Security
-
-
- -
-
- Passphrase - - - - - - - - -
-
- -
- - " id="update" name="update" /> - - - " id="update" name="update" /> - - " name="delete" /> -
- -
-
-
- - - +
diff --git a/includes/functions.php b/includes/functions.php index 31286d73..67180fc1 100755 --- a/includes/functions.php +++ b/includes/functions.php @@ -571,3 +571,67 @@ function SaveTORAndVPNConfig() } } +/** + * Renders a simple PHP template + */ +function renderTemplate($name, $data) +{ + $file = "../../templates/$name.php"; + if (!file_exists($file)) { + return "template $name ($file) not found"; + } + + if (is_array($data)){ + extract($data); + } + + ob_start(); + include $file; + return ob_get_clean(); +} + +function expandCacheKey($key) +{ + return RASPI_CACHE_PATH . "/" . $key; +} + +function hasCache($key) +{ + $cacheKey = expandCacheKey($key); + return file_exists($cacheKey); +} + +function readCache($key) +{ + $cacheKey = expandCacheKey($key); + if (!file_exists($cacheKey)) { + return null; + } + return file_get_contents($cacheKey); +} + +function writeCache($key, $data) +{ + mkdir(RASPI_CACHE_PATH, 0777, true); + $cacheKey = expandCacheKey($key); + file_put_contents($cacheKey, $data); +} + +function deleteCache($key) +{ + if (hasCache($key)) { + $cacheKey = expandCacheKey($key); + unlink($cacheKey); + } +} + +function cache($key, $callback) +{ + if (hasCache($key)) { + return readCache($key); + } else { + $data = $callback(); + writeCache($key, $data); + return $data; + } +} diff --git a/js/custom.js b/js/custom.js index ac1ec75b..958658b2 100644 --- a/js/custom.js +++ b/js/custom.js @@ -180,6 +180,20 @@ function contentLoaded() { } } +function loadWifiStations(refresh) { + return function() { + var complete = function() { $(this).removeClass('loading-spinner'); } + var qs = refresh === true ? '?refresh' : ''; + $('.js-wifi-stations') + .addClass('loading-spinner') + .empty() + .load('/ajax/networking/wifi_stations.php'+qs, complete); + }; +} + +$(".js-reload-wifi-stations").on("click", loadWifiStations(true)); + $(document) .ajaxSend(setCSRFTokenHeader) - .ready(contentLoaded); + .ready(contentLoaded) + .ready(loadWifiStations()); diff --git a/templates/wifi_stations.php b/templates/wifi_stations.php new file mode 100644 index 00000000..a002b85d --- /dev/null +++ b/templates/wifi_stations.php @@ -0,0 +1,93 @@ + +

+

+ + + $network): ?> +
+
+
+ + +

+ +
+
Status
+
+ + + + + + +
+
+ +
+
Channel
+
+ + + + X + +
+
+ +
+
RSSI
+
+ = -50) { + echo 100; + } elseif ($network['RSSI'] <= -100) { + echo 0; + } else { + echo 2*($network['RSSI'] + 100); + } + echo "%)"; + ?> +
+
+ + + + + + +
+
Security
+
+
+ +
+
+ Passphrase + + + + + + + + +
+
+ +
+ + " id="update" name="update" /> + + + " id="update" name="update" /> + + " name="delete" /> +
+ +
+
+
+ + + \ No newline at end of file