JSON was remove
BOT_open_sesam/pipeline/head This commit looks good
Details
BOT_open_sesam/pipeline/head This commit looks good
Details
Теперь вся информация получается по запросам к API, локально хранится только BOT_TOKEN в файле .envtest
parent
e319ea2e73
commit
3b5ac43c30
|
|
@ -9,3 +9,4 @@
|
||||||
- [x] Изменить json хранящийся локально на запросы к API
|
- [x] Изменить json хранящийся локально на запросы к API
|
||||||
- [x] Изменить названия комнта в локальном json
|
- [x] Изменить названия комнта в локальном json
|
||||||
- [x] Ограничить логи внутри докера
|
- [x] Ограничить логи внутри докера
|
||||||
|
- [x] Избавиться от json файла, переместить токен в .env файл, информацию от замков получать через запрос по API
|
||||||
|
|
|
||||||
12
auth.py
12
auth.py
|
|
@ -1,4 +1,3 @@
|
||||||
from config import config
|
|
||||||
import re
|
import re
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
|
|
@ -6,25 +5,18 @@ AUTHORIZED_USERS = {}
|
||||||
|
|
||||||
|
|
||||||
def normalize_phone(phone: str) -> str:
|
def normalize_phone(phone: str) -> str:
|
||||||
print(phone)
|
|
||||||
digits = re.sub(r"\D", "", phone)
|
digits = re.sub(r"\D", "", phone)
|
||||||
if len(digits) > 10:
|
if len(digits) > 10:
|
||||||
digits = digits[-10:]
|
digits = digits[-10:]
|
||||||
print(digits)
|
|
||||||
return digits
|
return digits
|
||||||
|
|
||||||
|
|
||||||
async def authorize_user(user_id: int, phone: str) -> bool:
|
async def authorize_user(user_id: int, phone: str) -> bool:
|
||||||
normalized = normalize_phone(phone)
|
normalized = normalize_phone(phone)
|
||||||
api_url = config.get("user_api_url")
|
api_url = "https://papi.dataekb.ru/check_access"
|
||||||
if not api_url:
|
|
||||||
print("Не указан user_api_url в конфигурации")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
try:
|
try:
|
||||||
async with session.get(api_url, params={"tel": normalized}) as response:
|
async with session.get(api_url, params={"tel": normalized}) as response:
|
||||||
print(response.status)
|
|
||||||
if response.status != 200:
|
if response.status != 200:
|
||||||
print(f"Ошибка запроса к API: статус {response.status}")
|
print(f"Ошибка запроса к API: статус {response.status}")
|
||||||
return False
|
return False
|
||||||
|
|
@ -34,7 +26,7 @@ async def authorize_user(user_id: int, phone: str) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if data.get("response") != "1":
|
if data.get("response") != "1":
|
||||||
print(f"Доступ запрещен для номера: {normalized}")
|
print(f"Доступ запрещён для номера: {normalized}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
zone_str = data["data"].get("zone", "")
|
zone_str = data["data"].get("zone", "")
|
||||||
|
|
|
||||||
25
config.py
25
config.py
|
|
@ -1,11 +1,20 @@
|
||||||
import json
|
def load_env(path=".env") -> dict:
|
||||||
|
env = {}
|
||||||
CONFIG_PATH = "bot_config.json"
|
try:
|
||||||
|
|
||||||
|
|
||||||
def load_config(path: str = CONFIG_PATH) -> dict:
|
|
||||||
with open(path, "r", encoding="utf-8") as f:
|
with open(path, "r", encoding="utf-8") as f:
|
||||||
return json.load(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
|
||||||
|
|
||||||
|
|
||||||
config = load_config()
|
config = load_env()
|
||||||
|
|
|
||||||
|
|
@ -9,24 +9,22 @@ def register_contact_handler(dp: Dispatcher):
|
||||||
@dp.message(F.contact)
|
@dp.message(F.contact)
|
||||||
async def contact_handler(msg: Message):
|
async def contact_handler(msg: Message):
|
||||||
user_id = msg.from_user.id
|
user_id = msg.from_user.id
|
||||||
|
|
||||||
if msg.contact is None:
|
if msg.contact is None:
|
||||||
await msg.answer("Ошибка: номер телефона не получен")
|
await msg.answer("Ошибка: номер телефона не получен")
|
||||||
return
|
return
|
||||||
|
|
||||||
phone = msg.contact.phone_number
|
phone = msg.contact.phone_number
|
||||||
if not await authorize_user(user_id, phone):
|
if not await authorize_user(user_id, phone):
|
||||||
await msg.answer("Доступ запрещен, номер не идентифицирован")
|
await msg.answer("Доступ запрещён, номер не идентифицирован")
|
||||||
return
|
return
|
||||||
|
|
||||||
user_data = AUTHORIZED_USERS.get(user_id)
|
user_data = AUTHORIZED_USERS.get(user_id)
|
||||||
if not user_data:
|
if not user_data:
|
||||||
await msg.answer("Ошибка получения данных пользователя")
|
await msg.answer("Ошибка авторизации.")
|
||||||
return
|
return
|
||||||
|
|
||||||
allowed_zones = user_data["zones"]
|
allowed_zones = user_data["zones"]
|
||||||
reply_markup = get_locks_keyboard(allowed_zones)
|
reply_markup = await get_locks_keyboard(allowed_zones)
|
||||||
|
|
||||||
await msg.answer(
|
await msg.answer(
|
||||||
"Номер подтвержден. Выберите дверь для открытия", reply_markup=reply_markup
|
"Номер подтверждён. Выберите дверь для открытия", reply_markup=reply_markup
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,7 @@ from aiogram import Dispatcher
|
||||||
from aiogram.types import Message
|
from aiogram.types import Message
|
||||||
|
|
||||||
from auth import AUTHORIZED_USERS, is_user_auth
|
from auth import AUTHORIZED_USERS, is_user_auth
|
||||||
from config import config
|
from locks_api import get_lock_by_label
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
def register_open_door_handler(dp: Dispatcher):
|
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):
|
async def open_door_handler(msg: Message):
|
||||||
user_id = msg.from_user.id
|
user_id = msg.from_user.id
|
||||||
if not is_user_auth(user_id):
|
if not is_user_auth(user_id):
|
||||||
await msg.answer(
|
await msg.answer("Доступ запрещён. Предоставьте номер телефона.")
|
||||||
"Доступ запрщен. Необходимо предоставить свой номер телефона."
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
user_data = AUTHORIZED_USERS.get(user_id)
|
user_data = AUTHORIZED_USERS.get(user_id)
|
||||||
if not user_data:
|
if not user_data:
|
||||||
await msg.answer("Ошибка авторизации пользователя.")
|
await msg.answer("Ошибка авторизации.")
|
||||||
return
|
return
|
||||||
|
|
||||||
lock_code = get_lock_code(msg.text)
|
lock_info = await get_lock_by_label(msg.text)
|
||||||
lock_conf = config.get("locks", {}).get(lock_code)
|
if not lock_info:
|
||||||
if not lock_conf:
|
await msg.answer("Информация по замку не найдена.")
|
||||||
await msg.answer("Информации по замку не найдено")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
url = f"http://{lock_conf['ip']}/cgi-bin/ext"
|
url = f"http://{lock_info['ip']}/cgi-bin/ext"
|
||||||
auth_info = ("ext", lock_conf["pass"])
|
auth_info = ("ext", lock_info["code"])
|
||||||
payload = f"CARD={user_data['card']}&DIR=0"
|
payload = f"CARD={user_data['card']}&DIR=0"
|
||||||
headers = {"Content-Type": "application/x-www-form-urlencoded"}
|
headers = {"Content-Type": "application/x-www-form-urlencoded"}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,18 +13,14 @@ def register_start_handler(dp: Dispatcher):
|
||||||
if is_user_auth(user_id):
|
if is_user_auth(user_id):
|
||||||
user_data = AUTHORIZED_USERS.get(user_id)
|
user_data = AUTHORIZED_USERS.get(user_id)
|
||||||
if not user_data:
|
if not user_data:
|
||||||
await msg.answer("Номер не найден")
|
await msg.answer("Ошибка авторизации.")
|
||||||
return
|
return
|
||||||
|
|
||||||
allowed_zones = user_data["zones"]
|
allowed_zones = user_data["zones"]
|
||||||
reply_markup = get_locks_keyboard(allowed_zones)
|
reply_markup = await get_locks_keyboard(allowed_zones)
|
||||||
await msg.answer(
|
await msg.answer("Авторизация прошла успешно", reply_markup=reply_markup)
|
||||||
"Авторизация прошла успешно",
|
|
||||||
reply_markup=reply_markup,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
reply_markup = get_contact_keyboard()
|
reply_markup = get_contact_keyboard()
|
||||||
await msg.answer(
|
await msg.answer(
|
||||||
"Для пользования ботом, предоставьте номер телефона",
|
"Для пользования ботом предоставьте номер телефона",
|
||||||
reply_markup=reply_markup,
|
reply_markup=reply_markup,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
13
keyboard.py
13
keyboard.py
|
|
@ -1,14 +1,15 @@
|
||||||
from aiogram.utils.keyboard import ReplyKeyboardBuilder
|
from aiogram.utils.keyboard import ReplyKeyboardBuilder
|
||||||
from aiogram.types import KeyboardButton
|
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()
|
kb = ReplyKeyboardBuilder()
|
||||||
locks_map = config.get("locks_map", {})
|
locks = await fetch_locks()
|
||||||
for lock in allowed_locks:
|
for zone in allowed_locks:
|
||||||
display_text = locks_map.get(lock, lock)
|
lock_info = locks.get(zone)
|
||||||
kb.button(text=display_text)
|
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)
|
return kb.as_markup(resize_keyboard=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {}
|
||||||
3
main.py
3
main.py
|
|
@ -9,8 +9,7 @@ from aiogram.client.default import DefaultBotProperties
|
||||||
from handlers import register_all_handlers
|
from handlers import register_all_handlers
|
||||||
from config import config
|
from config import config
|
||||||
|
|
||||||
|
BOT_TOKEN = config["BOT_TOKEN"]
|
||||||
BOT_TOKEN = config["bot_token"]
|
|
||||||
|
|
||||||
dp = Dispatcher()
|
dp = Dispatcher()
|
||||||
register_all_handlers(dp)
|
register_all_handlers(dp)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue