diff --git a/templates/gsm_spy_dashboard.html b/templates/gsm_spy_dashboard.html index 78d1f17..00cc60a 100644 --- a/templates/gsm_spy_dashboard.html +++ b/templates/gsm_spy_dashboard.html @@ -1299,18 +1299,10 @@ - - - - -
-
BANDS TO SCAN:
-
+ +
@@ -1452,42 +1444,52 @@ function updateBandSelector() { const region = document.getElementById('scannerRegion').value; const bands = BAND_CONFIG[region] || []; - const container = document.getElementById('bandCheckboxes'); + const selector = document.getElementById('bandSelector'); - container.innerHTML = ''; + selector.innerHTML = ''; + // Add "All Bands" option + const allOption = document.createElement('option'); + allOption.value = 'ALL'; + allOption.textContent = 'All Bands (Slower)'; + selector.appendChild(allOption); + + // Add individual bands bands.forEach(band => { - const checkbox = document.createElement('label'); - checkbox.style.cssText = 'display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 11px; color: var(--text-primary);'; + const option = document.createElement('option'); + option.value = band.name; + option.textContent = band.label; - const input = document.createElement('input'); - input.type = 'checkbox'; - input.value = band.name; - input.checked = band.recommended; // Recommended bands checked by default - input.style.cssText = 'cursor: pointer;'; - - const labelText = document.createElement('span'); - labelText.textContent = band.label; - - const badge = document.createElement('span'); - if (band.common) { - badge.textContent = '⭐ PRIMARY'; - badge.style.cssText = 'font-size: 8px; padding: 2px 6px; background: rgba(56, 193, 128, 0.2); color: #38c180; border-radius: 3px; font-weight: 600;'; - } else { - badge.textContent = 'SECONDARY'; - badge.style.cssText = 'font-size: 8px; padding: 2px 6px; background: rgba(159, 176, 199, 0.1); color: var(--text-dim); border-radius: 3px;'; + // Select first primary band by default + if (band.recommended && selector.value !== 'ALL' && !selector.querySelector('option:checked')) { + option.selected = true; } - checkbox.appendChild(input); - checkbox.appendChild(labelText); - checkbox.appendChild(badge); - container.appendChild(checkbox); + selector.appendChild(option); }); + + // If no band selected, select first primary band + if (!selector.value || selector.value === 'ALL') { + const firstPrimary = bands.find(b => b.recommended); + if (firstPrimary) { + selector.value = firstPrimary.name; + } + } } function getSelectedBands() { - const checkboxes = document.querySelectorAll('#bandCheckboxes input[type="checkbox"]:checked'); - return Array.from(checkboxes).map(cb => cb.value); + const selector = document.getElementById('bandSelector'); + const selected = selector.value; + + if (selected === 'ALL') { + // Return all bands for the region + const region = document.getElementById('scannerRegion').value; + const bands = BAND_CONFIG[region] || []; + return bands.map(b => b.name); + } else { + // Return single selected band + return [selected]; + } } // ============================================ diff --git a/test_gsm_spy_fixes.sh b/test_gsm_spy_fixes.sh deleted file mode 100755 index 59cfd04..0000000 --- a/test_gsm_spy_fixes.sh +++ /dev/null @@ -1,261 +0,0 @@ -#!/bin/bash -# GSM Spy System - Verification Test Script -# Tests the 4 critical fixes: geocoding, pipeline, scanner loop, process management - -set -e - -echo "==========================================" -echo "GSM Spy System - Verification Tests" -echo "==========================================" -echo "" - -# Colors -GREEN='\033[0;32m' -RED='\033[0;31m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# Test results -TESTS_PASSED=0 -TESTS_FAILED=0 - -function pass_test() { - echo -e "${GREEN}✓ PASS:${NC} $1" - ((TESTS_PASSED++)) -} - -function fail_test() { - echo -e "${RED}✗ FAIL:${NC} $1" - ((TESTS_FAILED++)) -} - -function info() { - echo -e "${YELLOW}ℹ INFO:${NC} $1" -} - -# Test 1: Check that geocoding module exists -echo "Test 1: Geocoding Module" -echo "-------------------------" -if [ -f "utils/gsm_geocoding.py" ]; then - pass_test "Geocoding module exists" - - # Check for key functions - if grep -q "def enrich_tower_data" utils/gsm_geocoding.py; then - pass_test "enrich_tower_data() function present" - else - fail_test "enrich_tower_data() function missing" - fi - - if grep -q "def lookup_cell_coordinates" utils/gsm_geocoding.py; then - pass_test "lookup_cell_coordinates() function present" - else - fail_test "lookup_cell_coordinates() function missing" - fi -else - fail_test "Geocoding module missing" -fi -echo "" - -# Test 2: Check scanner thread improvements -echo "Test 2: Scanner Thread Non-Blocking I/O" -echo "---------------------------------------" -if grep -q "import select" routes/gsm_spy.py; then - pass_test "select module imported" -else - fail_test "select module not imported" -fi - -if grep -q "select.select.*process.stdout" routes/gsm_spy.py; then - pass_test "Non-blocking I/O with select.select() implemented" -else - fail_test "select.select() not found in scanner thread" -fi - -if grep -q "scan_timeout = 120" routes/gsm_spy.py; then - pass_test "Scan timeout configured" -else - fail_test "Scan timeout not configured" -fi - -if grep -q "with app_module.gsm_spy_lock:" routes/gsm_spy.py; then - pass_test "Thread-safe counter updates implemented" -else - fail_test "Thread-safe counter updates missing" -fi -echo "" - -# Test 3: Check geocoding worker -echo "Test 3: Background Geocoding Worker" -echo "-----------------------------------" -if grep -q "def start_geocoding_worker" routes/gsm_spy.py; then - pass_test "start_geocoding_worker() function exists" -else - fail_test "start_geocoding_worker() function missing" -fi - -if grep -q "def geocoding_worker" routes/gsm_spy.py; then - pass_test "geocoding_worker() function exists" -else - fail_test "geocoding_worker() function missing" -fi - -if grep -q "start_geocoding_worker()" routes/gsm_spy.py; then - pass_test "Geocoding worker is started in start_scanner()" -else - fail_test "Geocoding worker not started in start_scanner()" -fi -echo "" - -# Test 4: Check enrichment integration -echo "Test 4: Tower Data Enrichment" -echo "-----------------------------" -if grep -q "from utils.gsm_geocoding import enrich_tower_data" routes/gsm_spy.py; then - pass_test "enrich_tower_data imported in scanner thread" -else - fail_test "enrich_tower_data not imported" -fi - -if grep -q "enriched = enrich_tower_data(parsed)" routes/gsm_spy.py; then - pass_test "Tower data enrichment called in scanner" -else - fail_test "Tower data enrichment not called" -fi -echo "" - -# Test 5: Check monitor pipeline fixes -echo "Test 5: Monitor Pipeline Connection" -echo "-----------------------------------" -if grep -q "Give grgsm_livemon time to initialize" routes/gsm_spy.py; then - pass_test "Pipeline initialization delay comment present" -else - fail_test "Pipeline initialization delay comment missing" -fi - -if grep -A 5 "Start grgsm_livemon" routes/gsm_spy.py | grep -q "time.sleep(2)"; then - pass_test "2-second delay between grgsm_livemon and tshark" -else - fail_test "Initialization delay not implemented" -fi - -if grep -q "Started grgsm_livemon (PID:" routes/gsm_spy.py; then - pass_test "Process verification logging added" -else - fail_test "Process verification logging missing" -fi -echo "" - -# Test 6: Check monitor thread improvements -echo "Test 6: Monitor Thread Non-Blocking I/O" -echo "---------------------------------------" -if grep -q "def monitor_thread(process):" routes/gsm_spy.py; then - pass_test "monitor_thread() function exists" - - if grep -A 20 "def monitor_thread(process):" routes/gsm_spy.py | grep -q "select.select.*process.stdout"; then - pass_test "Monitor thread uses non-blocking I/O" - else - fail_test "Monitor thread doesn't use select.select()" - fi -else - fail_test "monitor_thread() function missing" -fi -echo "" - -# Test 7: Check frontend coordinate validation -echo "Test 7: Frontend Coordinate Validation" -echo "--------------------------------------" -if grep -q "Validate coordinates before creating map marker" templates/gsm_spy_dashboard.html; then - pass_test "Coordinate validation comment present" -else - fail_test "Coordinate validation comment missing" -fi - -if grep -q "isNaN(parseFloat(data.lat))" templates/gsm_spy_dashboard.html; then - pass_test "Coordinate validation checks implemented" -else - fail_test "Coordinate validation checks missing" -fi - -if grep -q "tower_update" templates/gsm_spy_dashboard.html; then - pass_test "tower_update message handler added" -else - fail_test "tower_update message handler missing" -fi -echo "" - -# Test 8: Check process cleanup improvements -echo "Test 8: Process Cleanup & Zombie Prevention" -echo "-------------------------------------------" -if grep -q "process.terminate()" routes/gsm_spy.py; then - pass_test "Process termination implemented" -else - fail_test "Process termination missing" -fi - -if grep -q "subprocess.TimeoutExpired" routes/gsm_spy.py; then - pass_test "Timeout handling for process termination" -else - fail_test "Timeout handling missing" -fi - -if grep -q "process.kill()" routes/gsm_spy.py; then - pass_test "Force kill fallback implemented" -else - fail_test "Force kill fallback missing" -fi -echo "" - -# Test 9: Python syntax check -echo "Test 9: Python Syntax Validation" -echo "--------------------------------" -if python3 -m py_compile routes/gsm_spy.py 2>/dev/null; then - pass_test "routes/gsm_spy.py has valid syntax" -else - fail_test "routes/gsm_spy.py has syntax errors" -fi - -if python3 -m py_compile utils/gsm_geocoding.py 2>/dev/null; then - pass_test "utils/gsm_geocoding.py has valid syntax" -else - fail_test "utils/gsm_geocoding.py has syntax errors" -fi -echo "" - -# Test 10: Check auto-monitor persistence -echo "Test 10: Auto-Monitor Flag Persistence" -echo "--------------------------------------" -if grep -q "auto_monitor_triggered = False.*# Moved outside loop" routes/gsm_spy.py; then - pass_test "auto_monitor_triggered flag moved outside loop" -else - fail_test "auto_monitor_triggered flag not properly placed" -fi - -if grep -q "if current_count >= 3 and not auto_monitor_triggered" routes/gsm_spy.py; then - pass_test "Auto-monitor only triggers once per session" -else - fail_test "Auto-monitor trigger condition incorrect" -fi -echo "" - -# Summary -echo "==========================================" -echo "Test Summary" -echo "==========================================" -echo -e "Tests passed: ${GREEN}${TESTS_PASSED}${NC}" -echo -e "Tests failed: ${RED}${TESTS_FAILED}${NC}" -echo "" - -if [ $TESTS_FAILED -eq 0 ]; then - echo -e "${GREEN}All tests passed! ✓${NC}" - echo "" - echo "Next steps:" - echo "1. Start INTERCEPT: sudo -E venv/bin/python intercept.py" - echo "2. Navigate to GSM Spy dashboard in browser" - echo "3. Click 'Start Scanner' to test tower detection with geocoding" - echo "4. Verify towers appear on map with coordinates" - echo "5. Check that auto-monitor starts after 3+ towers found" - echo "6. Test Stop button for responsive shutdown (< 2 seconds)" - exit 0 -else - echo -e "${RED}Some tests failed. Please review the output above.${NC}" - exit 1 -fi