From 3b5ac43c304f53203a913fd5655099b4a4835c55 Mon Sep 17 00:00:00 2001 From: dl Date: Thu, 29 May 2025 17:10:51 +0500 Subject: [PATCH] JSON was remove MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Теперь вся информация получается по запросам к API, локально хранится только BOT_TOKEN в файле .env --- .env | 1 + README.md | 1 + auth.py | 12 ++---------- config.py | 27 ++++++++++++++++++--------- handlers/contact_handler.py | 10 ++++------ handlers/doors_handler.py | 27 ++++++++------------------- handlers/start_handler.py | 12 ++++-------- keyboard.py | 13 +++++++------ locks_api.py | 35 +++++++++++++++++++++++++++++++++++ main.py | 3 +-- 10 files changed, 81 insertions(+), 60 deletions(-) create mode 100644 .env create mode 100644 locks_api.py diff --git a/.env b/.env new file mode 100644 index 0000000..bfb6be5 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +BOT_TOKEN= diff --git a/README.md b/README.md index a815989..1d7c874 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,4 @@ - [x] Изменить json хранящийся локально на запросы к API - [x] Изменить названия комнта в локальном json - [x] Ограничить логи внутри докера +- [x] Избавиться от json файла, переместить токен в .env файл, информацию от замков получать через запрос по API diff --git a/auth.py b/auth.py index 7b494b9..a6bc809 100644 --- a/auth.py +++ b/auth.py @@ -1,4 +1,3 @@ -from config import config import re import aiohttp @@ -6,25 +5,18 @@ AUTHORIZED_USERS = {} def normalize_phone(phone: str) -> str: - print(phone) digits = re.sub(r"\D", "", phone) if len(digits) > 10: digits = digits[-10:] - print(digits) return digits async def authorize_user(user_id: int, phone: str) -> bool: normalized = normalize_phone(phone) - api_url = config.get("user_api_url") - if not api_url: - print("Не указан user_api_url в конфигурации") - return False - + api_url = "https://papi.dataekb.ru/check_access" async with aiohttp.ClientSession() as session: try: async with session.get(api_url, params={"tel": normalized}) as response: - print(response.status) if response.status != 200: print(f"Ошибка запроса к API: статус {response.status}") return False @@ -34,7 +26,7 @@ async def authorize_user(user_id: int, phone: str) -> bool: return False if data.get("response") != "1": - print(f"Доступ запрещен для номера: {normalized}") + print(f"Доступ запрещён для номера: {normalized}") return False zone_str = data["data"].get("zone", "") diff --git a/config.py b/config.py index 54cdee5..9f43429 100644 --- a/config.py +++ b/config.py @@ -1,11 +1,20 @@ -import json - -CONFIG_PATH = "bot_config.json" +def load_env(path=".env") -> dict: + env = {} + try: + with open(path, "r", encoding="utf-8") as f: + for line in f: + line = line.strip() + # Пропускаем пустые строки и строки-комментарии + if not line or line.startswith("#"): + continue + if "=" in line: + key, value = line.split("=", 1) + env[key.strip()] = value.strip() + except FileNotFoundError: + raise Exception( + f"Файл {path} не найден. Проверьте наличие файла .env в корне проекта." + ) + return env -def load_config(path: str = CONFIG_PATH) -> dict: - with open(path, "r", encoding="utf-8") as f: - return json.load(f) - - -config = load_config() +config = load_env() diff --git a/handlers/contact_handler.py b/handlers/contact_handler.py index 067f8c6..0594d96 100644 --- a/handlers/contact_handler.py +++ b/handlers/contact_handler.py @@ -9,24 +9,22 @@ def register_contact_handler(dp: Dispatcher): @dp.message(F.contact) async def contact_handler(msg: Message): user_id = msg.from_user.id - if msg.contact is None: await msg.answer("Ошибка: номер телефона не получен") return phone = msg.contact.phone_number if not await authorize_user(user_id, phone): - await msg.answer("Доступ запрещен, номер не идентифицирован") + await msg.answer("Доступ запрещён, номер не идентифицирован") return user_data = AUTHORIZED_USERS.get(user_id) if not user_data: - await msg.answer("Ошибка получения данных пользователя") + await msg.answer("Ошибка авторизации.") return allowed_zones = user_data["zones"] - reply_markup = get_locks_keyboard(allowed_zones) - + reply_markup = await get_locks_keyboard(allowed_zones) await msg.answer( - "Номер подтвержден. Выберите дверь для открытия", reply_markup=reply_markup + "Номер подтверждён. Выберите дверь для открытия", reply_markup=reply_markup ) diff --git a/handlers/doors_handler.py b/handlers/doors_handler.py index c55d2c8..b4e95c3 100644 --- a/handlers/doors_handler.py +++ b/handlers/doors_handler.py @@ -5,15 +5,7 @@ from aiogram import Dispatcher from aiogram.types import Message from auth import AUTHORIZED_USERS, is_user_auth -from config import config - - -def get_lock_code(display_text: str) -> str: - locks_map = config.get("locks_map", {}) - for code, friendly in locks_map.items(): - if friendly == display_text: - return code - return display_text +from locks_api import get_lock_by_label def register_open_door_handler(dp: Dispatcher): @@ -21,24 +13,21 @@ def register_open_door_handler(dp: Dispatcher): async def open_door_handler(msg: Message): user_id = msg.from_user.id if not is_user_auth(user_id): - await msg.answer( - "Доступ запрщен. Необходимо предоставить свой номер телефона." - ) + await msg.answer("Доступ запрещён. Предоставьте номер телефона.") return user_data = AUTHORIZED_USERS.get(user_id) if not user_data: - await msg.answer("Ошибка авторизации пользователя.") + await msg.answer("Ошибка авторизации.") return - lock_code = get_lock_code(msg.text) - lock_conf = config.get("locks", {}).get(lock_code) - if not lock_conf: - await msg.answer("Информации по замку не найдено") + lock_info = await get_lock_by_label(msg.text) + if not lock_info: + await msg.answer("Информация по замку не найдена.") return - url = f"http://{lock_conf['ip']}/cgi-bin/ext" - auth_info = ("ext", lock_conf["pass"]) + url = f"http://{lock_info['ip']}/cgi-bin/ext" + auth_info = ("ext", lock_info["code"]) payload = f"CARD={user_data['card']}&DIR=0" headers = {"Content-Type": "application/x-www-form-urlencoded"} diff --git a/handlers/start_handler.py b/handlers/start_handler.py index 5c98082..1b93306 100644 --- a/handlers/start_handler.py +++ b/handlers/start_handler.py @@ -13,18 +13,14 @@ def register_start_handler(dp: Dispatcher): if is_user_auth(user_id): user_data = AUTHORIZED_USERS.get(user_id) if not user_data: - await msg.answer("Номер не найден") + await msg.answer("Ошибка авторизации.") return - allowed_zones = user_data["zones"] - reply_markup = get_locks_keyboard(allowed_zones) - await msg.answer( - "Авторизация прошла успешно", - reply_markup=reply_markup, - ) + reply_markup = await get_locks_keyboard(allowed_zones) + await msg.answer("Авторизация прошла успешно", reply_markup=reply_markup) else: reply_markup = get_contact_keyboard() await msg.answer( - "Для пользования ботом, предоставьте номер телефона", + "Для пользования ботом предоставьте номер телефона", reply_markup=reply_markup, ) diff --git a/keyboard.py b/keyboard.py index e46062e..146ef0c 100755 --- a/keyboard.py +++ b/keyboard.py @@ -1,14 +1,15 @@ from aiogram.utils.keyboard import ReplyKeyboardBuilder from aiogram.types import KeyboardButton -from config import config +from locks_api import fetch_locks -def get_locks_keyboard(allowed_locks: list): +async def get_locks_keyboard(allowed_locks: list): kb = ReplyKeyboardBuilder() - locks_map = config.get("locks_map", {}) - for lock in allowed_locks: - display_text = locks_map.get(lock, lock) - kb.button(text=display_text) + locks = await fetch_locks() + for zone in allowed_locks: + lock_info = locks.get(zone) + btn_text = lock_info["name"] if lock_info and "name" in lock_info else zone + kb.button(text=btn_text) return kb.as_markup(resize_keyboard=True) diff --git a/locks_api.py b/locks_api.py new file mode 100644 index 0000000..91e6c25 --- /dev/null +++ b/locks_api.py @@ -0,0 +1,35 @@ +import aiohttp +import json + +LOCKS_API_URL = "https://papi.dataekb.ru/get_pacs" + + +async def fetch_locks() -> dict: + async with aiohttp.ClientSession() as session: + try: + async with session.get(LOCKS_API_URL) as response: + if response.status != 200: + print(f"Ошибка при получении данных замков: {response.status}") + return {} + text = await response.text() + except Exception as e: + print(f"Исключение при запросе данных замков: {str(e)}") + return {} + try: + data = json.loads(text) + if not data or not isinstance(data, list): + print("Неверный формат данных о замках, ожидался список.") + return {} + locks_dict = data[0] # предполагается, что список содержит один словарь + return locks_dict + except Exception as e: + print(f"Ошибка при разборе данных замков: {str(e)}") + return {} + + +async def get_lock_by_label(label: str) -> dict: + locks = await fetch_locks() + for lock_id, details in locks.items(): + if label == lock_id or details.get("name") == label: + return details + return {} diff --git a/main.py b/main.py index b47c41c..56ffed5 100755 --- a/main.py +++ b/main.py @@ -9,8 +9,7 @@ from aiogram.client.default import DefaultBotProperties from handlers import register_all_handlers from config import config - -BOT_TOKEN = config["bot_token"] +BOT_TOKEN = config["BOT_TOKEN"] dp = Dispatcher() register_all_handlers(dp)