Render Page 5: Advanced Vuln Scanner - real scanner status and findings.
(self, image, draw)
| 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 []) |
| 1293 | if a.get('freq')}) |
| 1294 | sig = wa.fast_signal_poll(iface, freqs) |
| 1295 | for a in (st.get('aps') or []): |
| 1296 | s = sig.get(a.get('bssid')) |
| 1297 | if s is not None: |
| 1298 | a['signal'] = s |
| 1299 | except Exception as e: |
| 1300 | logger.debug(f"netdiag fast signal poll error: {e}") |
| 1301 | st['fast_ts'] = time.time() |
| 1302 | st['fast_scanning'] = False |
| 1303 | |
| 1304 | threading.Thread(target=_fast_worker, daemon=True).start() |
| 1305 | return st |
| 1306 | |
| 1307 | def _draw_signal_bar(self, draw, y, dbm, x0, x1): |
| 1308 | """One horizontal signal bar between x0..x1, fill ∝ quality, dBm at the |
| 1309 | right edge. Returns the bar's bottom y.""" |
| 1310 | sx = getattr(self, 'render_sx', self.scale_factor_x) |
| 1311 | sy = getattr(self, 'render_sy', self.scale_factor_y) |
| 1312 | font = self.shared_data.font_arial9 |
| 1313 | q = self._dbm_to_quality(dbm) if dbm is not None else 0 |
| 1314 | q = q or 0 |
| 1315 | bar_h = int(9 * sy) |
| 1316 | dbm_txt = f"{int(dbm)}" if dbm is not None else "—" |
| 1317 | dbm_w = font.getlength(dbm_txt) + int(5 * sx) |
| 1318 | bar_x1 = x1 - dbm_w |
| 1319 | if bar_x1 > x0: |
| 1320 | draw.rectangle([x0, y, bar_x1, y + bar_h], outline=0) |
| 1321 | fill_w = int((bar_x1 - x0) * q / 100.0) |
| 1322 | if fill_w > 0: |
| 1323 | draw.rectangle([x0, y, x0 + fill_w, y + bar_h], fill=0) |
| 1324 | draw.text((bar_x1 + int(4 * sx), y - int(1 * sy)), dbm_txt, font=font, fill=0) |
| 1325 | return y + bar_h |
| 1326 | |
| 1327 | def _draw_signal_bars(self, draw, y, aps): |
| 1328 | """SSID + signal-strength bar list for the net-diag SIGNAL page.""" |
| 1329 | w = getattr(self, 'render_w', self.shared_data.width) |
| 1330 | sx = getattr(self, 'render_sx', self.scale_factor_x) |
| 1331 | sy = getattr(self, 'render_sy', self.scale_factor_y) |
| 1332 | font = self.shared_data.font_arial9 |
| 1333 | pad_x = int(6 * sx) |
| 1334 | row_h = int(15 * sy) |
| 1335 | # Strongest SSID on top: the fast signal poll updates dBm in place |
| 1336 | # without re-sorting, so guarantee the order here at draw time. |
| 1337 | aps = sorted(aps, key=lambda a: -(a.get('signal') or -999)) |
| 1338 | # Give the SSID name the extra room by halving the signal bar's length |
| 1339 | # relative to the old full-width layout (long names now fit on the |
| 1340 | # narrow 1.44" panel). |
| 1341 | full_bar = (w - pad_x) - (pad_x + int(46 * sx)) |
| 1342 | bar_w = max(int(24 * sx), full_bar // 2) |
| 1343 | name_w = (w - pad_x) - bar_w - pad_x # left column reserved for the SSID |
| 1344 | for ap in aps: |
| 1345 | ssid = ap.get('ssid') or 'hidden' |
| 1346 | s = ssid |
| 1347 | while s and font.getlength(s) > name_w: |
| 1348 | s = s[:-1] |
no test coverage detected