diff --git a/adacam_api/app.py b/adacam_api/app.py index 57c3a3a..03f0afb 100644 --- a/adacam_api/app.py +++ b/adacam_api/app.py @@ -110,6 +110,18 @@ def create_app(): ) return jsonify({'ok': True, 'ssh_enabled': enable}) + # ── DEBUG ENDPOINTS ──────────────────────────────────────────────────── + @app.route('/api/1/debug/redis-keys') + def redis_keys(): + """Debug endpoint — list Redis keys for GPS/IMU troubleshooting.""" + try: + import redis + r = redis.Redis(host='localhost', port=6379, decode_responses=True) + keys = r.keys('*') + return jsonify({'keys': sorted(keys)}) + except Exception as e: + return jsonify({'error': str(e)}), 503 + # Start background forwarder thread forwarder.start_retry_thread() diff --git a/adacam_api/routes/frames.py b/adacam_api/routes/frames.py index f2ef8e9..7525008 100644 --- a/adacam_api/routes/frames.py +++ b/adacam_api/routes/frames.py @@ -5,18 +5,36 @@ from flask import Blueprint, jsonify bp = Blueprint("frames", __name__, url_prefix="/api/1/recording") -FRAMES_DIR = "/tmp/recording/pics" +FRAMES_DIR = "/tmp/adacam/pics" @bp.route("/frames/latest", methods=["GET"]) def latest_frame(): """Get path to most recent frame file.""" + # Handle case where capture hasn't started yet + if not os.path.exists(FRAMES_DIR): + return jsonify({'frames': [], 'message': 'capture not started'}), 200 + if not os.path.isdir(FRAMES_DIR): - return jsonify({"error": "No frames directory"}), 404 + return jsonify({"error": "Frames directory invalid"}), 500 files = glob.glob(os.path.join(FRAMES_DIR, "*")) if not files: - return jsonify({"error": "No frames available"}), 404 + return jsonify({'frames': [], 'message': 'no frames captured yet'}), 200 latest = max(files, key=os.path.getmtime) return jsonify({"path": latest}) + + +@bp.route("/frames", methods=["GET"]) +def list_frames(): + """List all available frames.""" + if not os.path.exists(FRAMES_DIR): + return jsonify({'frames': [], 'message': 'capture not started'}) + + files = glob.glob(os.path.join(FRAMES_DIR, "*")) + files.sort(key=os.path.getmtime, reverse=True) + return jsonify({ + 'frames': files[:100], # limit to 100 most recent + 'total': len(files) + }) diff --git a/adacam_api/routes/wigle.py b/adacam_api/routes/wigle.py index d9220ed..46ec206 100644 --- a/adacam_api/routes/wigle.py +++ b/adacam_api/routes/wigle.py @@ -91,9 +91,28 @@ def wigle_stats(): return jsonify({'error': str(e), 'total_networks': 0, 'uploaded_networks': 0, 'pending_upload': 0, 'scans_today': 0}) +@bp.route('/config', methods=['GET']) +def get_wigle_config(): + """Get WiGLE configuration (unauthenticated, tokens masked).""" + try: + conn = _get_db() + cfg = _get_config(conn) + conn.close() + + return jsonify({ + 'enabled': cfg.get('enabled', '0') == '1', + 'api_name': cfg.get('api_name', ''), + 'api_token_set': bool(cfg.get('api_token')), + 'scan_interval_seconds': int(cfg.get('scan_interval_seconds', '30')), + 'upload_interval_seconds': int(cfg.get('upload_interval_seconds', '300')), + }) + except Exception as e: + return jsonify({'error': str(e)}), 500 + + @bp.route('/config', methods=['POST']) @require_auth -def wigle_config(): +def set_wigle_config(): """Set WiGLE configuration (authenticated).""" data = request.get_json() or {} diff --git a/install.sh b/install.sh index 919384b..3c722b9 100755 --- a/install.sh +++ b/install.sh @@ -21,14 +21,14 @@ cp systemd/adacam-api.service /etc/systemd/system/ systemctl daemon-reload systemctl enable adacam-api -# Generate device ID if not present +# Note: Config is generated by liberate.sh or on first API start +# We don't validate Python imports here as the working directory matters if [ ! -f "$DATA_DIR/config.json" ]; then - python3 -c "from adacam_api import config; config.load()" - echo "[*] Generated new device ID" + echo "[*] Config will be generated on first API start" fi echo "[*] Starting adacam-api..." systemctl restart adacam-api -systemctl status adacam-api --no-pager +systemctl status adacam-api --no-pager || true echo "[+] Installation complete. API running on port 5000"