some fixs

This commit is contained in:
2025-03-01 01:49:33 +03:00
parent 2368b5df8c
commit a688a19b4e
13 changed files with 100 additions and 57 deletions
Regular → Executable
View File
Regular → Executable
+2 -1
View File
@@ -12,7 +12,7 @@ class config:
"%Y-%m-%d-%H:%M", "%Y-%m-%d-%H:%M",
) )
API_TOKEN = os.environ.get("API_TOKEN") API_TOKEN = os.environ.get("API_TOKEN")
ADMIN_ID = os.environ.get("ADMIN_ID") ADMIN_ID = int(os.environ.get("ADMIN_ID"))
ENV = os.getenv("ENV", "PROD") ENV = os.getenv("ENV", "PROD")
DB_PORT = int(os.getenv("DB_PORT", 27017)) DB_PORT = int(os.getenv("DB_PORT", 27017))
@@ -37,6 +37,7 @@ class Messages:
"Доступные команды:" "\n/start - начать регистрацию", "Доступные команды:" "\n/start - начать регистрацию",
"\n/help - помощь", "\n/help - помощь",
"\n/source - исходный код бота на Github", "\n/source - исходный код бота на Github",
"\n@more_logical - для всех вопросов по мероприятию",
"\n\nCreated by АйТи блок ВМК with love ❤️", "\n\nCreated by АйТи блок ВМК with love ❤️",
# "Начало мероприятия: {} \nЭто через целых {} минут!", # "Начало мероприятия: {} \nЭто через целых {} минут!",
] ]
Regular → Executable
+4 -2
View File
@@ -3,17 +3,19 @@ from config import config
class DB: class DB:
client = pymongo.MongoClient(f"mongodb://localhost:{config.DB_PORT}/") client = pymongo.MongoClient(f"mongodb://mongo:{config.DB_PORT}/")
db = client["rc_coffee"] db = client["rc_coffee"]
def __init__(self, collection): def __init__(self, collection):
if collection not in self.db.list_collection_names():
self.db.create_collection(collection)
self.collection = self.db[collection] self.collection = self.db[collection]
def insert(self, data): def insert(self, data):
self.collection.insert_one(data) self.collection.insert_one(data)
def find(self, query): def find(self, query):
return self.collection.find(query) return list(self.collection.find(query))
def find_one(self, query): def find_one(self, query):
return self.collection.find_one(query) return self.collection.find_one(query)
Regular → Executable
+20 -3
View File
@@ -42,7 +42,7 @@ def start_message(message: types.Message):
Messages.REGISTRATION_CONFIRM.format( Messages.REGISTRATION_CONFIRM.format(
user.name, user.name,
user.age, user.age,
user.gender, "Парень" if user.gender == "man" else "Девушка",
user.faculty, user.faculty,
user.group, user.group,
), ),
@@ -82,9 +82,28 @@ def source(message: types.Message):
return return
@bot.message_handler(func=lambda message: True)
def handle_all_messages(message: types.Message):
help_message(message)
if __name__ == "__main__": if __name__ == "__main__":
print("/t--- Bot started ---") print("/t--- Bot started ---")
admins = Admin.get_all_admins()
for admin in admins:
bot.send_message(
admin["user_id"],
"Служебное сообщение: бот был перезапущен.",
)
# Test connection to the database
try:
User.get_all()
print("Database connection successful.")
except Exception as e:
print(f"Database connection failed: {e}")
time_for_notif = config.DATE_START time_for_notif = config.DATE_START
while True: while True:
@@ -103,5 +122,3 @@ if __name__ == "__main__":
"Отправлено напоминание о скором начале мероприятия.", "Отправлено напоминание о скором начале мероприятия.",
) )
time.sleep(10) time.sleep(10)
exit()
Regular → Executable
+18 -5
View File
@@ -1,5 +1,5 @@
from db import DB from db import DB
import config from config import config
import os import os
import threading import threading
import time import time
@@ -34,17 +34,21 @@ class Admin:
@staticmethod @staticmethod
def get_all_admins(): def get_all_admins():
return Admin._db.find({}) return [
Admin(data["user_id"]) for data in Admin._db.find({}) if "user_id" in data
]
@staticmethod @staticmethod
def is_admin(user_id): def is_admin(user_id):
return Admin._db.find({"user_id": user_id}) is not None return (Admin._db.find_one({"user_id": user_id}) is not None) or (
user_id == config.ADMIN_ID
)
@staticmethod @staticmethod
def add_admin(new_user_id, name, unique_key) -> int: def add_admin(new_user_id, name, unique_key) -> int:
key_data = Admin._db.find_one({"unique_key": unique_key}) key_data = Admin._db.find_one({"unique_key": unique_key})
if new_user_id == config.ADMIN_ID and not Admin.is_admin(new_user_id): if new_user_id == config.ADMIN_ID:
Admin._db.insert({"user_id": new_user_id, "name": name}) Admin._db.insert({"user_id": new_user_id, "name": name})
return new_user_id return new_user_id
@@ -341,16 +345,25 @@ class Admin:
return return
@bot.message_handler(commands=["r", "restart"])
@admin_only
def restart_command(message):
# os.system("python3 main.py")
os._exit(0)
return
class AdminMessages: class AdminMessages:
ADMIN_HELP = ( ADMIN_HELP = (
"Вы администратор! Вот что вы можете сделать:\n" "Вы администратор! Вот что вы можете сделать:\n"
"/remove_admin - удалить админа\n" "/remove_admin - удалить админа\n"
"/generate_key - сгенерировать уникальный ключ (<code>admin_red</code> - чтобы админ добавился)\n" "/generate_key - сгенерировать уникальный ключ (<code>admin_reg</code> - чтобы админ добавился)\n"
"/delete_user - удалить пользователя\n" "/delete_user - удалить пользователя\n"
"/stats - статистика\n" "/stats - статистика\n"
"/send_message - отправить всем сообщение\n" "/send_message - отправить всем сообщение\n"
"/random - зарандомить людей для 1 тура\n" "/random - зарандомить людей для 1 тура\n"
"/random_again - зарандомить людей без повторной регистрации\n" "/random_again - зарандомить людей без повторной регистрации\n"
"<code>clear_all</code> - удаляет ВСЕХ пользователей для их повторной регистрации\n" "<code>clear_all</code> - удаляет ВСЕХ пользователей для их повторной регистрации\n"
"/restart - перезапуск бота"
) )
Regular → Executable
View File
Regular → Executable
+31 -13
View File
@@ -9,15 +9,26 @@ import re
def start_reg_name(message: types.Message): def start_reg_name(message: types.Message):
user = User(message.chat.id, message.text) user = User(message.chat.id)
user.name = message.text
bot.send_message(message.chat.id, Messages.ENTER_AGE) bot.send_message(message.chat.id, Messages.ENTER_AGE)
bot.register_next_step_handler(message, start_reg_age) bot.register_next_step_handler(message, start_reg_age)
return
def start_reg_age(message: types.Message): def start_reg_age(message: types.Message):
user = User(message.chat.id) user = User(message.chat.id)
if not message.text.isdigit():
bot.send_message(message.chat.id, "Введите число")
bot.register_next_step_handler(message, start_reg_age)
return
user.age = int(message.text) user.age = int(message.text)
markup = types.InlineKeyboardMarkup() markup = types.InlineKeyboardMarkup()
@@ -25,9 +36,9 @@ def start_reg_age(message: types.Message):
types.InlineKeyboardButton(Messages.GENDER_WOMAN, callback_data="gender_woman"), types.InlineKeyboardButton(Messages.GENDER_WOMAN, callback_data="gender_woman"),
types.InlineKeyboardButton(Messages.GENDER_MAN, callback_data="gender_man"), types.InlineKeyboardButton(Messages.GENDER_MAN, callback_data="gender_man"),
) )
bot.send_message(message.chat.id, Messages.ENTER_GENDER) bot.send_message(message.chat.id, Messages.ENTER_GENDER, reply_markup=markup)
bot.register_next_step_handler(message, start_reg_gender) return
@bot.callback_query_handler(func=lambda call: "gender" in call.data) @bot.callback_query_handler(func=lambda call: "gender" in call.data)
@@ -70,7 +81,7 @@ def start_reg_group(message: types.Message):
Messages.REGISTRATION_CONFIRM.format( Messages.REGISTRATION_CONFIRM.format(
user.name, user.name,
user.age, user.age,
user.gender, "Парень" if user.gender == "man" else "Девушка",
user.faculty, user.faculty,
user.group, user.group,
), ),
@@ -128,12 +139,10 @@ def test_question(call: types.CallbackQuery):
call.message.chat.id, call.message.message_id, reply_markup=None call.message.chat.id, call.message.message_id, reply_markup=None
) )
if len(user.type) == 4:
show_result(call.message)
return
if call.data != "test_yes": if call.data != "test_yes":
user.type += call.data.split("_")[-1] user.type += TestMessages.TEST_QUESTIONS[len(user.type)]["answers"][
int(call.data[-1])
][1]
bot.edit_message_text( bot.edit_message_text(
call.message.text call.message.text
@@ -145,12 +154,21 @@ def test_question(call: types.CallbackQuery):
call.message.message_id, call.message.message_id,
) # упростить ) # упростить
if len(user.type) == 4:
show_result(call.message)
return
question = TestMessages.TEST_QUESTIONS[len(user.type)] question = TestMessages.TEST_QUESTIONS[len(user.type)]
text = question["question"]
markup = types.InlineKeyboardMarkup() markup = types.InlineKeyboardMarkup()
for answer in question["answers"]: markup.add(
markup.add( types.InlineKeyboardButton("Первый вариант", callback_data=f"test_0"),
types.InlineKeyboardButton(answer[0], callback_data=f"test_{answer[1]}") types.InlineKeyboardButton("Второй вариант", callback_data=f"test_1"),
) )
text += f"\n\n1. {question['answers'][0][0]} \n\n2. {question['answers'][1][0]}"
bot.send_message(call.message.chat.id, text, reply_markup=markup)
return return
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
+15 -17
View File
@@ -10,7 +10,7 @@ users_reg: List["User"] = []
class User: class User:
_db = DB("Users") _db = DB("Users")
def __init__(self, user_id, name): def __init__(self, user_id, name=None):
self.user_id: int = user_id self.user_id: int = user_id
self._name: str = name self._name: str = name
self._age: int = None self._age: int = None
@@ -19,10 +19,6 @@ class User:
self._group: str = None self._group: str = None
self._type: str = None self._type: str = None
self._save()
def __init__(self, user_id):
self.user_id: int = user_id
self._load() self._load()
@property @property
@@ -121,7 +117,8 @@ class User:
def _load(self): def _load(self):
if not self._db.exist({"_id": self.user_id}): if not self._db.exist({"_id": self.user_id}):
raise ValueError("User not found") self._save()
# raise ValueError("User not found")
data = self._db.find_one({"_id": self.user_id}) data = self._db.find_one({"_id": self.user_id})
self._name = data["name"] self._name = data["name"]
@@ -145,19 +142,20 @@ class User:
for user in users: for user in users:
bot.send_message(user.user_id, Messages.MATCHING_START, reply_markup=markup) bot.send_message(user.user_id, Messages.MATCHING_START, reply_markup=markup)
@bot.callback_query_handler(func=lambda call: call.data == "shuffle_agree") return
def add_user_to_reg(call: types.CallbackQuery):
user = User(call.message.chat.id)
users_reg.append(user)
bot.edit_message_text( @staticmethod
call.message.chat.id, @bot.callback_query_handler(func=lambda call: call.data == "shuffle_agree")
call.message.message_id, def add_user_to_reg(call: types.CallbackQuery):
"Вы добавлены в список участников! Пожалуйста, подождите, пока все зарегистрируются", user = User(call.message.chat.id)
reply_markup=None, users_reg.append(user)
)
return bot.edit_message_text(
call.message.chat.id,
call.message.message_id,
"Вы добавлены в список участников! Пожалуйста, подождите, пока все зарегистрируются",
reply_markup=None,
)
return return
Regular → Executable
View File
Regular → Executable
+9 -16
View File
@@ -1,32 +1,25 @@
version: '3.8'
services: services:
bot: bot:
image: python:3.9 image: python:3.9
container_name: python_bot container_name: python_bot
working_dir: /usr/src/app working_dir: /usr/src/app
links:
- "mongodb:mongo"
volumes: volumes:
- ./app:/usr/src/app - ./app:/usr/src/app
networks:
- rc_network
depends_on: depends_on:
- mongodb - mongodb
command: sh -c "pip install -r requirements.txt && python main.py" command: sh -c "pip install -r requirements.txt && python main.py"
restart: unless-stopped
mongodb: mongodb:
image: mongo:latest image: 'mongo:4.4.6'
# image: mongo:8.0-rc ports:
container_name: mongodb - '27017:27017'
networks:
- rc_network
volumes: volumes:
- mongo-data:/data/db - 'mongo-data:/data/db'
networks: restart: unless-stopped
rc_network:
driver: bridge
ipam:
config:
- subnet: 172.25.0.0/16
volumes: volumes:
mongo-data: mongo-data:
@@ -34,4 +27,4 @@ volumes:
driver_opts: driver_opts:
type: none type: none
o: bind o: bind
device: ./.data device: ./.data
Regular → Executable
+1
View File
@@ -46,6 +46,7 @@
- `/random_again` - сгенерировать повторную рассадку для людей первого тура (без повторной регистрации) - `/random_again` - сгенерировать повторную рассадку для людей первого тура (без повторной регистрации)
- `/clear_all` - удалить всех людей из базы данных - `/clear_all` - удалить всех людей из базы данных
- `/remove_admin` - удалить админа по id - `/remove_admin` - удалить админа по id
- `/restart` - перезапуск бота (только для Docker запуска)
## <a id="env">Настройка конфигурации</a> ## <a id="env">Настройка конфигурации</a>