"""elmAI — точка входа Flask-приложения. Запуск через gunicorn: gunicorn -w 4 -b 127.0.0.1:8000 web.app:app Структура модулей: api/ — REST-эндпоинты, БД, скрипты brain/ — LLM-клиент, промпты obd/ — ELM327-протокол (AndrOBD) """ import sys import logging from pathlib import Path # Добавляем корень проекта в PYTHONPATH для импорта api/, brain/, obd/ sys.path.insert(0, str(Path(__file__).parent.parent)) from flask import Flask, jsonify, redirect, render_template, request, send_from_directory from api.config import load from api.routes import register as register_api from api.dtc import register as register_dtc from api.ping import register as register_ping from api.raw_elm import bp as raw_bp, is_raw_mode logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(name)s] %(message)s") app = Flask(__name__) config = load() register_api(app) register_dtc(app) register_ping(app) app.register_blueprint(raw_bp) # ── Режим RAW: отключаем все эндпоинты кроме /elm/raw/* ── _RAW_PREFIX = "/api/v1/elm/raw" @app.before_request def _check_raw_mode(): """В режиме RAW все эндпоинты кроме /elm/raw/* отключены.""" if is_raw_mode() and not request.path.startswith(_RAW_PREFIX): # Разрешаем только статику и корень if request.path not in ("/", "/elmer.apk") and not request.path.startswith("/static"): return jsonify({ "error": "raw_mode_active", "hint": "Сервер в режиме сырого взаимодействия с ELM327. " "Все остальные эндпоинты отключены. " "Используйте /api/v1/elm/raw/mode чтобы выключить." }), 503 @app.route("/") def index(): """Главная страница.""" return render_template("index.html") @app.route("/elmer.apk") def download_apk(): """Прямая ссылка на APK.""" return send_from_directory("static", "app-debug.apk", as_attachment=True, download_name="elmer.apk") @app.route("/elm-raw.apk") def download_raw_apk(): """Прямая ссылка на APK Raw Relay.""" return send_from_directory("static", "elm-raw.apk", as_attachment=True, download_name="elm-raw.apk") if __name__ == "__main__": print(f"🌐 elmAI Web: http://localhost:5005") app.run(host="0.0.0.0", port=5005, debug=False)