Render Page 4: Discovered - real credentials, loot, and attack data.
(self, image, draw)
| 1249 | 'spectrum': None, 'bands': None, 'iface': None, |
| 1250 | 'fast_ts': 0, 'fast_scanning': False} |
| 1251 | now = time.time() |
| 1252 | if (not st['scanning'] and not st.get('fast_scanning', False) |
| 1253 | and (now - st['ts']) > 45): |
| 1254 | st['scanning'] = True |
| 1255 | |
| 1256 | def _worker(): |
| 1257 | aps = None |
| 1258 | spectrum = bands = None |
| 1259 | iface = self._netdiag_scan_iface() |
| 1260 | try: |
| 1261 | import wifi_analyzer as wa |
| 1262 | d = wa.do_scan(interface=iface, band='all') |
| 1263 | if 'error' not in d: |
| 1264 | aps = sorted(d.get('aps', []), |
| 1265 | key=lambda a: -(a.get('signal') or -999))[:5] |
| 1266 | # Full per-channel spectrum feeds the SPECTRUM card too. |
| 1267 | spectrum = d.get('spectrum') or {} |
| 1268 | bands = d.get('supported_bands') or {} |
| 1269 | except Exception as e: |
| 1270 | logger.debug(f"netdiag wifi scan error: {e}") |
| 1271 | st['iface'] = iface |
| 1272 | if aps is not None: |
| 1273 | st['aps'] = aps |
| 1274 | st['spectrum'] = spectrum |
| 1275 | st['bands'] = bands |
| 1276 | st['ts'] = time.time() |
| 1277 | st['scanning'] = False |
| 1278 | |
| 1279 | threading.Thread(target=_worker, daemon=True).start() |
| 1280 | elif (st.get('aps') and not st['scanning'] |
| 1281 | and not st.get('fast_scanning', False) |
| 1282 | and (now - st.get('fast_ts', 0)) > 1.0): |
| 1283 | # Fast path: passively re-visit only the channels of the APs |
| 1284 | # already on screen. Values update in place (no re-sort) so the |
| 1285 | # rows stay put while their bars move. |
| 1286 | st['fast_scanning'] = True |
| 1287 | |
| 1288 | def _fast_worker(): |
| 1289 | try: |
| 1290 | import wifi_analyzer as wa |
| 1291 | iface = st.get('iface') or self._netdiag_scan_iface() |
| 1292 | freqs = sorted({int(round(a['freq'])) for a in (st.get('aps') or []) |
no test coverage detected