Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c29d366255 | ||
|
|
65a63b5596 | ||
|
|
82a2a5dafb | ||
|
|
e616a28fbe | ||
|
|
20dbcaac62 | ||
|
|
a0c0726865 | ||
|
|
9cda21ea29 | ||
|
|
67b708bdff | ||
|
|
4692287d41 | ||
|
|
a688a19b4e |
@@ -0,0 +1,10 @@
|
|||||||
|
DATE_START=2024-07-01
|
||||||
|
TIME_START=12:00
|
||||||
|
API_TOKEN="your_api_token_here"
|
||||||
|
ADMIN_ID=your_admin_id_here
|
||||||
|
DB_PORT=27017
|
||||||
|
ENV=PROD
|
||||||
|
SSH_HOST=your_ssh_host_here
|
||||||
|
SSH_USER=your_ssh_user_here
|
||||||
|
SSH_KEY=path_to_your_ssh_key_here
|
||||||
|
SSH_PASSWORD=your_ssh_password_here
|
||||||
@@ -1,20 +1,207 @@
|
|||||||
# Ignore everything
|
# Byte-compiled / optimized / DLL files
|
||||||
*
|
|
||||||
|
|
||||||
# Except these files
|
|
||||||
!.gitignore
|
|
||||||
!docker-compose.yaml
|
|
||||||
!requirements.txt
|
|
||||||
!readme.md
|
|
||||||
|
|
||||||
# Except these directories and their contents
|
|
||||||
!/app
|
|
||||||
!/app/*
|
|
||||||
!/app/plugin
|
|
||||||
!/app/plugin/*
|
|
||||||
|
|
||||||
# Ignore specific files and directories
|
|
||||||
app/bot.py
|
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
*.py[codz]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py.cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# UV
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
#uv.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
#poetry.toml
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
||||||
|
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
||||||
|
#pdm.lock
|
||||||
|
#pdm.toml
|
||||||
|
.pdm-python
|
||||||
|
.pdm-build/
|
||||||
|
|
||||||
|
# pixi
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
||||||
|
#pixi.lock
|
||||||
|
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
||||||
|
# in the .venv directory. It is recommended not to include this directory in version control.
|
||||||
|
.pixi
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
.env
|
.env
|
||||||
.venv
|
.envrc
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
|
||||||
|
# Abstra
|
||||||
|
# Abstra is an AI-powered process automation framework.
|
||||||
|
# Ignore directories containing user credentials, local state, and settings.
|
||||||
|
# Learn more at https://abstra.io/docs
|
||||||
|
.abstra/
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
||||||
|
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
||||||
|
# you could uncomment the following to ignore the entire vscode folder
|
||||||
|
# .vscode/
|
||||||
|
|
||||||
|
# Ruff stuff:
|
||||||
|
.ruff_cache/
|
||||||
|
|
||||||
|
# PyPI configuration file
|
||||||
|
.pypirc
|
||||||
|
|
||||||
|
# Cursor
|
||||||
|
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
||||||
|
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
||||||
|
# refer to https://docs.cursor.com/context/ignore-files
|
||||||
|
.cursorignore
|
||||||
|
.cursorindexingignore
|
||||||
|
|
||||||
|
# Marimo
|
||||||
|
marimo/_static/
|
||||||
|
marimo/_lsp/
|
||||||
|
__marimo__/
|
||||||
@@ -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))
|
||||||
@@ -31,33 +31,46 @@ class config:
|
|||||||
|
|
||||||
class Messages:
|
class Messages:
|
||||||
WELCOME_LIST = [
|
WELCOME_LIST = [
|
||||||
"Привет! Это бот Quick dates (Random Coffee). Чтобы зарегистрироваться, пожалуйста, ответь на следующие вопросы." # несколько сообщений подряд
|
(
|
||||||
|
"Привет! Это бот <b>Random Coffee</b>."
|
||||||
|
"\n\nЧтобы зарегистрироваться, ответь на следующие вопросы ⬇️"
|
||||||
|
) # несколько сообщений подряд
|
||||||
]
|
]
|
||||||
HELPS = [
|
HELPS = [
|
||||||
"Доступные команды:" "\n/start - начать регистрацию",
|
(
|
||||||
"\n/help - помощь",
|
"Доступные команды:"
|
||||||
"\n/source - исходный код бота на Github",
|
"\n/start - начать регистрацию"
|
||||||
"\n\nCreated by АйТи блок ВМК with love ❤️",
|
"\n/help - помощь"
|
||||||
# "Начало мероприятия: {} \nЭто через целых {} минут!",
|
"\n/source - исходный код бота на Github"
|
||||||
|
"\n\nCreated by АйТи блок ВМК with love ❤️"
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
ERROR = "Произошла ошибка"
|
ERROR = "Произошла ошибка"
|
||||||
ENTER_NAME = "Как тебя зовут?"
|
ENTER_NAME = "Как тебя зовут?"
|
||||||
ENTER_AGE = "Сколько тебе лет?"
|
ENTER_AGE = "Сколько тебе лет?"
|
||||||
ENTER_GENDER = "Выбери пол (женский, мужской)"
|
ENTER_GENDER = "Выбери пол"
|
||||||
GENDER_WOMAN = "Я девушка" # кнопки выбора
|
GENDER_WOMAN = "Я девушка" # кнопки выбора
|
||||||
GENDER_MAN = "Я парень" # кнопки выбора
|
GENDER_MAN = "Я парень" # кнопки выбора
|
||||||
ENTER_FACULTY = "С какого ты факультета?"
|
ENTER_FACULTY = "С какого ты факультета?"
|
||||||
ENTER_GROUP = "Напиши номер своей группы"
|
ENTER_GROUP = "Напиши номер своей группы"
|
||||||
REGISTRATION_CONFIRM = "Ты ввел следующие данные:\
|
ENTER_AGREE_UPLOAD = (
|
||||||
\n\nИмя: {}\
|
"Согласен ли ты на сохранение своих данных в общую базу для подбора пар?"
|
||||||
\nВозраст: {}\
|
)
|
||||||
\nПол: {}\
|
REGISTRATION_CONFIRM = "<u>Твои данные:</u>\
|
||||||
\nФакультет: {}\
|
\n\n<b>Имя:</b> {}\
|
||||||
\nГруппа: {}\
|
\n<b>Возраст:</b> {}\
|
||||||
|
\n<b>Пол:</b> {}\
|
||||||
|
\n<b>Факультет:</b> {}\
|
||||||
|
\n<b>Группа:</b> {}\
|
||||||
|
\n<b>Согласие на сохранение данных:</b> {}\
|
||||||
\n\nВсё верно?"
|
\n\nВсё верно?"
|
||||||
ALREADY_REGISTERED = "Ты уже зарегистрирован. Хочешь изменить данные?"
|
ALREADY_REGISTERED = "Ты уже зарегистрирован. Хочешь изменить данные?"
|
||||||
MATCHING_START = (
|
MATCHING_START = (
|
||||||
"Мы начали подбор пар. Пожалуйста, подтверди, что ты находишься в аудитории"
|
"Мы начали подбор пар 🤩" "\nПодтверди своё нахождение в аудитории."
|
||||||
|
)
|
||||||
|
START_DATE = (
|
||||||
|
"Мероприятие начнётся:"
|
||||||
|
"\n🗓️ <b>3 апреля в 18:00</b>"
|
||||||
|
"\n\nСледите за новостями!"
|
||||||
)
|
)
|
||||||
START_DATE = f"Наше мероприятие начнётся {os.environ.get('DATE_START')} следите за новостями!"
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
import os
|
|
||||||
import sys
|
|
||||||
import telebot
|
|
||||||
import threading
|
|
||||||
from config import config, Messages
|
from config import config, Messages
|
||||||
from telebot import types
|
from telebot import types
|
||||||
from plugin.user import User
|
from plugin.user import User
|
||||||
@@ -42,9 +38,10 @@ 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,
|
||||||
|
"Да" if user.agree_upload else "Нет",
|
||||||
),
|
),
|
||||||
reply_markup=markup,
|
reply_markup=markup,
|
||||||
)
|
)
|
||||||
@@ -66,7 +63,7 @@ def help_message(message: types.Message):
|
|||||||
for msg in Messages.HELPS:
|
for msg in Messages.HELPS:
|
||||||
bot.send_message(message.chat.id, msg)
|
bot.send_message(message.chat.id, msg)
|
||||||
else:
|
else:
|
||||||
bot.send_message(message.chat.id, AdminMessages.ADMIN_HELP, parse_mode="HTML")
|
bot.send_message(message.chat.id, AdminMessages.ADMIN_HELP)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -75,15 +72,43 @@ def help_message(message: types.Message):
|
|||||||
def source(message: types.Message):
|
def source(message: types.Message):
|
||||||
bot.send_message(
|
bot.send_message(
|
||||||
message.chat.id,
|
message.chat.id,
|
||||||
"[Страничка бота на Github!](https://github.com/kr0sh512/rc-tgbot)",
|
(
|
||||||
parse_mode="Markdown",
|
"<a href='https://github.com/kr0sh512/rc-tgbot'>Страничка бота на Github!</a>"
|
||||||
|
"\n\nСтарался раб профкомский <a href='https://t.me/kr0sh_512'>Дмитрий</a>. mewow."
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
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()
|
||||||
|
|
||||||
|
print(admins)
|
||||||
|
|
||||||
|
print(Admin._db.find({}))
|
||||||
|
|
||||||
|
print([(data, "user_id" in data) for data in Admin._db.find({})])
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
@@ -92,16 +117,20 @@ if __name__ == "__main__":
|
|||||||
users = User.get_all()
|
users = User.get_all()
|
||||||
for user in users:
|
for user in users:
|
||||||
bot.send_message(
|
bot.send_message(
|
||||||
user["user_id"],
|
user.user_id,
|
||||||
"Напоминание, что наше мероприятие пройдёт уже завтра! Следите за новостями)",
|
"Напоминание, что наше мероприятие пройдёт уже завтра! Следите за новостями)",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if len(user.type) != 4:
|
||||||
|
bot.send_message(
|
||||||
|
user.user_id,
|
||||||
|
"Вы ещё не прошли тест! Пожалуйста, пройдите его, чтобы мы могли вас зарегистрировать.",
|
||||||
|
)
|
||||||
|
|
||||||
admins = Admin.get_all_admins()
|
admins = Admin.get_all_admins()
|
||||||
for admin in admins:
|
for admin in admins:
|
||||||
bot.send_message(
|
bot.send_message(
|
||||||
admin["user_id"],
|
admin.user_id,
|
||||||
"Отправлено напоминание о скором начале мероприятия.",
|
"Отправлено напоминание о скором начале мероприятия.",
|
||||||
)
|
)
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
|
|
||||||
exit()
|
|
||||||
|
|||||||
|
After Width: | Height: | Size: 409 KiB |
|
After Width: | Height: | Size: 257 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 157 KiB |
|
After Width: | Height: | Size: 187 KiB |
|
After Width: | Height: | Size: 612 KiB |
|
After Width: | Height: | Size: 161 KiB |
|
After Width: | Height: | Size: 135 KiB |
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 229 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 153 KiB |
@@ -1,9 +1,9 @@
|
|||||||
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
|
||||||
from plugin.user import User
|
from plugin.user import User, users_reg
|
||||||
from plugin.shuffle import Shuffle, already_matched
|
from plugin.shuffle import Shuffle, already_matched
|
||||||
|
|
||||||
from plugin.bot_instance import bot
|
from plugin.bot_instance import bot
|
||||||
@@ -26,7 +26,7 @@ class Admin:
|
|||||||
data = self._db.find_one({"user_id": self.user_id})
|
data = self._db.find_one({"user_id": self.user_id})
|
||||||
if data:
|
if data:
|
||||||
self.name = data["name"]
|
self.name = data["name"]
|
||||||
self.added_by = data["added_by"]
|
self.added_by = data.get("added_by")
|
||||||
else:
|
else:
|
||||||
raise ValueError("Admin not found")
|
raise ValueError("Admin not found")
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -105,6 +109,7 @@ class Admin:
|
|||||||
# ----------------- TELEBOT ----------------- #
|
# ----------------- TELEBOT ----------------- #
|
||||||
|
|
||||||
def admin_only(func):
|
def admin_only(func):
|
||||||
|
|
||||||
def wrapper(message, *args, **kwargs):
|
def wrapper(message, *args, **kwargs):
|
||||||
if Admin.is_admin(message.chat.id):
|
if Admin.is_admin(message.chat.id):
|
||||||
return func(message, *args, **kwargs)
|
return func(message, *args, **kwargs)
|
||||||
@@ -147,7 +152,6 @@ class Admin:
|
|||||||
bot.send_message(
|
bot.send_message(
|
||||||
message.chat.id,
|
message.chat.id,
|
||||||
"Ваш ключ: <code>{}</code>".format(key),
|
"Ваш ключ: <code>{}</code>".format(key),
|
||||||
parse_mode="HTML",
|
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
bot.send_message(message.chat.id, str(e))
|
bot.send_message(message.chat.id, str(e))
|
||||||
@@ -198,7 +202,7 @@ class Admin:
|
|||||||
f.write("Количество пользователей: {}\n".format(len(users)))
|
f.write("Количество пользователей: {}\n".format(len(users)))
|
||||||
|
|
||||||
for user in users:
|
for user in users:
|
||||||
f.write(str(user) + "\n")
|
f.write(str(user) + "\n\n")
|
||||||
|
|
||||||
with open("stats.txt", "rb") as f:
|
with open("stats.txt", "rb") as f:
|
||||||
bot.send_document(message.chat.id, f)
|
bot.send_document(message.chat.id, f)
|
||||||
@@ -208,7 +212,7 @@ class Admin:
|
|||||||
f.write("Количество админов: {}\n".format(len(admins)))
|
f.write("Количество админов: {}\n".format(len(admins)))
|
||||||
|
|
||||||
for admin in admins:
|
for admin in admins:
|
||||||
f.write(str(admin) + "\n")
|
f.write(str(admin) + "\n\n")
|
||||||
|
|
||||||
with open("admin_stats.txt", "rb") as f:
|
with open("admin_stats.txt", "rb") as f:
|
||||||
bot.send_document(message.chat.id, f)
|
bot.send_document(message.chat.id, f)
|
||||||
@@ -248,7 +252,6 @@ class Admin:
|
|||||||
bot.send_message(
|
bot.send_message(
|
||||||
message.chat.id,
|
message.chat.id,
|
||||||
"Отправьте <code>delete all</code> для подтверждения. \n\nВнимание, вы вряд ли хотите это делать.",
|
"Отправьте <code>delete all</code> для подтверждения. \n\nВнимание, вы вряд ли хотите это делать.",
|
||||||
parse_mode="HTML",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -272,35 +275,29 @@ class Admin:
|
|||||||
|
|
||||||
for admin in Admin.get_all_admins():
|
for admin in Admin.get_all_admins():
|
||||||
bot.send_message(
|
bot.send_message(
|
||||||
admin["user_id"],
|
admin.user_id,
|
||||||
"Отправлено приглашение пользователем. В данный момент подтвердило участие 0 человек. Запускайте команду /end_random для завершения регистрации",
|
"Отправлено приглашение пользователем. В данный момент подтвердило участие 0 человек.\
|
||||||
|
\n\n/update чтобы узнать, сколько уже подтвердило участие\
|
||||||
|
\n\n/end_random для завершения регистрации",
|
||||||
)
|
)
|
||||||
|
|
||||||
User.start_shuffle_reg()
|
User.start_shuffle_reg()
|
||||||
|
|
||||||
def monitor_participation():
|
return
|
||||||
while True:
|
|
||||||
participants = len(already_matched)
|
|
||||||
bot.send_message(
|
|
||||||
message.chat.id,
|
|
||||||
f"В данный момент подтвердило участие {participants} человек",
|
|
||||||
)
|
|
||||||
time.sleep(5)
|
|
||||||
|
|
||||||
thread = threading.Thread(
|
@bot.message_handler(commands=["update"])
|
||||||
target=monitor_participation, name="monitor_participation"
|
@admin_only
|
||||||
|
def update_random_command(message):
|
||||||
|
bot.send_message(
|
||||||
|
message.chat.id,
|
||||||
|
f"Подтвердило участие: {len(users_reg)} человек",
|
||||||
)
|
)
|
||||||
thread.start()
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@bot.message_handler(commands=["end_random", "random_again"])
|
@bot.message_handler(commands=["end_random", "random_again"])
|
||||||
@admin_only
|
@admin_only
|
||||||
def end_random_command(message):
|
def end_random_command(message):
|
||||||
for thread in threading.enumerate():
|
|
||||||
if thread.name == "monitor_participation":
|
|
||||||
thread.kill()
|
|
||||||
|
|
||||||
bot.send_message(message.chat.id, "Регистрация завершена. Ожидайте")
|
bot.send_message(message.chat.id, "Регистрация завершена. Ожидайте")
|
||||||
|
|
||||||
pairs = Shuffle()
|
pairs = Shuffle()
|
||||||
@@ -308,49 +305,63 @@ class Admin:
|
|||||||
if pair[1]:
|
if pair[1]:
|
||||||
bot.send_message(
|
bot.send_message(
|
||||||
pair[0].user_id,
|
pair[0].user_id,
|
||||||
f"Ваша пара: {pair[1].name}. Парта находится под номером: {pairs.index(pair) + 1})",
|
f"Твоя пара: {pair[1].name}\n\nНомер парты: {pairs.index(pair) + 1}\n\nХорошего знакомства 🥰",
|
||||||
)
|
)
|
||||||
bot.send_message(
|
bot.send_message(
|
||||||
pair[1].user_id,
|
pair[1].user_id,
|
||||||
f"Ваша пара: {pair[0].name}. Парта находится под номером: {pairs.index(pair) + 1})",
|
f"Твоя пара: {pair[0].name}\n\nНомер парты: {pairs.index(pair) + 1}\n\nХорошего знакомства 🥰",
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
bot.send_message(
|
bot.send_message(
|
||||||
pair[0].user_id,
|
pair[0].user_id,
|
||||||
"Подойди к организаторам мероприятия, они тебе подберут идеальную пару!",
|
(
|
||||||
|
"✨Счастливый билет✨"
|
||||||
|
"\n\nПодойди к организаторам мероприятия, они подберут идеальную пару для тебя!"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
with open("pairs.txt", "w") as f:
|
with open("pairs.txt", "w") as f:
|
||||||
str_pair = ""
|
|
||||||
for pair in pairs:
|
for pair in pairs:
|
||||||
str_pair += (
|
if pair[1]:
|
||||||
f"Парта {pairs.index(pair) + 1}: {pair[0].name} | {pair[1].name}\n"
|
f.write(
|
||||||
)
|
f"Парта {pairs.index(pair) + 1}: {pair[0].name} | {pair[1].name}\n"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
f.write(
|
||||||
|
f"Парта {pairs.index(pair) + 1}: {pair[0].name} | Нет пары\n"
|
||||||
|
)
|
||||||
|
|
||||||
f.write(str_pair)
|
for admin in Admin.get_all_admins():
|
||||||
|
with open("pairs.txt", "rb") as f:
|
||||||
with open("pairs.txt", "rb") as f:
|
|
||||||
for admin in Admin.get_all_admins():
|
|
||||||
bot.send_document(
|
bot.send_document(
|
||||||
admin["user_id"],
|
admin.user_id,
|
||||||
f,
|
f,
|
||||||
caption="Распредение по парам.",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
os.remove("pairs.txt")
|
os.remove("pairs.txt")
|
||||||
|
|
||||||
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\n"
|
||||||
"/remove_admin - удалить админа\n"
|
"/remove_admin - удалить админа\n\n"
|
||||||
"/generate_key - сгенерировать уникальный ключ (<code>admin_red</code> - чтобы админ добавился)\n"
|
"/generate_key - сгенерировать уникальный ключ (<code>admin_reg</code> - чтобы админ добавился)\n\n"
|
||||||
"/delete_user - удалить пользователя\n"
|
"/delete_user - удалить пользователя\n\n"
|
||||||
"/stats - статистика\n"
|
"/stats - статистика\n\n"
|
||||||
"/send_message - отправить всем сообщение\n"
|
"/send_message - отправить всем сообщение\n\n"
|
||||||
"/random - зарандомить людей для 1 тура\n"
|
"/random - зарандомить людей для 1 тура\n\n"
|
||||||
"/random_again - зарандомить людей без повторной регистрации\n"
|
"/random_again - зарандомить людей без повторной регистрации\n\n"
|
||||||
"<code>clear_all</code> - удаляет ВСЕХ пользователей для их повторной регистрации\n"
|
"<code>clear_all</code> - удаляет ВСЕХ пользователей для их повторной регистрации\n\n"
|
||||||
|
"/restart - перезапуск бота\n\n"
|
||||||
|
"/source - исходный код бота на Github"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,15 +14,21 @@ original_send_message = telebot.TeleBot.send_message
|
|||||||
|
|
||||||
|
|
||||||
def send_message_with_try_catch(self, chat_id, text, *args, **kwargs):
|
def send_message_with_try_catch(self, chat_id, text, *args, **kwargs):
|
||||||
|
print("test_msg")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return original_send_message(self, chat_id, text, *args, **kwargs)
|
return original_send_message(
|
||||||
|
self, chat_id, text, parse_mode="HTML", *args, **kwargs
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error sending message: {e}. Retrying in 5 seconds...")
|
print(f"Error sending message: {e}. Retrying in 5 seconds...")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
||||||
return original_send_message(self, chat_id, text, *args, **kwargs)
|
return original_send_message(
|
||||||
|
self, chat_id, text, parse_mode="HTML", *args, **kwargs
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Second attempt failed: {e}")
|
print(f"Second attempt failed: {e}")
|
||||||
|
|
||||||
@@ -32,6 +38,7 @@ telebot.TeleBot.send_message = send_message_with_try_catch
|
|||||||
bot = telebot.TeleBot(
|
bot = telebot.TeleBot(
|
||||||
config.API_TOKEN,
|
config.API_TOKEN,
|
||||||
colorful_logs=True,
|
colorful_logs=True,
|
||||||
|
parse_mode="HTML",
|
||||||
)
|
)
|
||||||
|
|
||||||
threading.Thread(
|
threading.Thread(
|
||||||
|
|||||||
@@ -6,18 +6,30 @@ from plugin.test import TestMessages
|
|||||||
from plugin.bot_instance import bot
|
from plugin.bot_instance import bot
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
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 +37,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)
|
||||||
@@ -60,33 +72,51 @@ def start_reg_group(message: types.Message):
|
|||||||
user = User(message.chat.id)
|
user = User(message.chat.id)
|
||||||
user.group = message.text
|
user.group = message.text
|
||||||
|
|
||||||
|
markup = types.InlineKeyboardMarkup()
|
||||||
|
markup.add(
|
||||||
|
types.InlineKeyboardButton("Согласен", callback_data="upload_agree"),
|
||||||
|
types.InlineKeyboardButton("Не согласен", callback_data="upload_skip"),
|
||||||
|
)
|
||||||
|
bot.send_message(message.chat.id, Messages.ENTER_AGREE_UPLOAD, reply_markup=markup)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@bot.callback_query_handler(func=lambda call: "upload" in call.data)
|
||||||
|
def start_agree_upload(call: types.CallbackQuery):
|
||||||
|
user = User(call.message.chat.id)
|
||||||
|
user.agree_upload = call.data.split("_")[-1] == "agree"
|
||||||
|
|
||||||
|
bot.edit_message_text(
|
||||||
|
(
|
||||||
|
"Согласен на сохранение данных в общую базу"
|
||||||
|
if user.agree_upload
|
||||||
|
else "Не согласен на сохранение данных в общую базу"
|
||||||
|
),
|
||||||
|
call.message.chat.id,
|
||||||
|
call.message.message_id,
|
||||||
|
reply_markup=None,
|
||||||
|
)
|
||||||
|
|
||||||
markup = types.InlineKeyboardMarkup()
|
markup = types.InlineKeyboardMarkup()
|
||||||
markup.add(
|
markup.add(
|
||||||
types.InlineKeyboardButton("Всё верно!", callback_data="registration_confirm"),
|
types.InlineKeyboardButton("Всё верно!", callback_data="registration_confirm"),
|
||||||
types.InlineKeyboardButton("Изменить", callback_data="registration_change"),
|
types.InlineKeyboardButton("Изменить", callback_data="registration_change"),
|
||||||
)
|
)
|
||||||
bot.send_message(
|
bot.send_message(
|
||||||
message.chat.id,
|
call.message.chat.id,
|
||||||
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,
|
||||||
|
"Да" if user.agree_upload else "Нет",
|
||||||
),
|
),
|
||||||
reply_markup=markup,
|
reply_markup=markup,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bot.callback_query_handler(func=lambda call: call.data == "registration_skip")
|
|
||||||
def start_skip_reg(call: types.CallbackQuery):
|
|
||||||
bot.edit_message_reply_markup(
|
|
||||||
call.message.chat.id, call.message.message_id, reply_markup=None
|
|
||||||
)
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
@bot.callback_query_handler(func=lambda call: call.data == "registration_change")
|
@bot.callback_query_handler(func=lambda call: call.data == "registration_change")
|
||||||
def start_reg_again(call: types.CallbackQuery):
|
def start_reg_again(call: types.CallbackQuery):
|
||||||
bot.edit_message_reply_markup(
|
bot.edit_message_reply_markup(
|
||||||
@@ -128,33 +158,102 @@ 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:
|
if call.data == "test_yes":
|
||||||
|
last_q = -1
|
||||||
|
else:
|
||||||
|
last_q = int(call.data.split("_")[1].split("#")[0])
|
||||||
|
previous_ans = int(call.data.split("#")[1])
|
||||||
|
for ans_type in TestMessages.TEST_QUESTIONS[last_q]["answers"][previous_ans][
|
||||||
|
"types"
|
||||||
|
]:
|
||||||
|
add_score = 3 if last_q == 0 else 2
|
||||||
|
user.vector_type[ans_type] = user.vector_type.get(ans_type, 0) + add_score
|
||||||
|
|
||||||
|
prev_answ = "\n\n".join(
|
||||||
|
[
|
||||||
|
f"{'✅ ' if i == previous_ans else ''}{i+1}. {ans['text']}"
|
||||||
|
for i, ans in enumerate(TestMessages.TEST_QUESTIONS[last_q]["answers"])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
prev_text = f"{TestMessages.TEST_QUESTIONS[last_q]['question']}\n\n{prev_answ}"
|
||||||
|
|
||||||
|
bot.edit_message_text(
|
||||||
|
prev_text,
|
||||||
|
call.message.chat.id,
|
||||||
|
call.message.message_id,
|
||||||
|
parse_mode="HTML",
|
||||||
|
)
|
||||||
|
|
||||||
|
if last_q == len(TestMessages.TEST_QUESTIONS) - 1:
|
||||||
|
max_value = max(user.vector_type.values())
|
||||||
|
max_types = [t for t, v in user.vector_type.items() if v == max_value]
|
||||||
|
user.type = random.choice(max_types)
|
||||||
|
|
||||||
show_result(call.message)
|
show_result(call.message)
|
||||||
return
|
return
|
||||||
|
|
||||||
if call.data != "test_yes":
|
question = TestMessages.TEST_QUESTIONS[last_q + 1]
|
||||||
user.type += call.data.split("_")[-1]
|
answ = "\n\n".join(
|
||||||
|
[f"{i+1}. {ans['text']}" for i, ans in enumerate(question["answers"])]
|
||||||
|
)
|
||||||
|
text = f"{question['question']}\n\n{answ}"
|
||||||
|
|
||||||
bot.edit_message_text(
|
|
||||||
call.message.text
|
|
||||||
+ "\n\n"
|
|
||||||
+ TestMessages.TEST_QUESTIONS[len(user.type) - 1]["answers"][
|
|
||||||
int(call.data[-1])
|
|
||||||
][0],
|
|
||||||
call.message.chat.id,
|
|
||||||
call.message.message_id,
|
|
||||||
) # упростить
|
|
||||||
|
|
||||||
question = TestMessages.TEST_QUESTIONS[len(user.type)]
|
|
||||||
markup = types.InlineKeyboardMarkup()
|
markup = types.InlineKeyboardMarkup()
|
||||||
for answer in question["answers"]:
|
for i in range(len(question["answers"])):
|
||||||
markup.add(
|
markup.add(
|
||||||
types.InlineKeyboardButton(answer[0], callback_data=f"test_{answer[1]}")
|
types.InlineKeyboardButton(
|
||||||
|
f"{question['answers'][i]['short']}",
|
||||||
|
callback_data=f"test_{last_q + 1}#{i}",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
bot.send_message(call.message.chat.id, text, reply_markup=markup, parse_mode="HTML")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# @bot.callback_query_handler(func=lambda call: "test" in call.data)
|
||||||
|
# def test_question(call: types.CallbackQuery):
|
||||||
|
# user = User(call.message.chat.id)
|
||||||
|
|
||||||
|
# bot.edit_message_reply_markup(
|
||||||
|
# call.message.chat.id, call.message.message_id, reply_markup=None
|
||||||
|
# )
|
||||||
|
|
||||||
|
# if call.data != "test_yes":
|
||||||
|
# user.type += TestMessages.TEST_QUESTIONS[len(user.type)]["answers"][
|
||||||
|
# int(call.data[-1])
|
||||||
|
# ][1]
|
||||||
|
|
||||||
|
# user_ans = int(call.data[-1])
|
||||||
|
# question_last = TestMessages.TEST_QUESTIONS[len(user.type) - 1]
|
||||||
|
# text_edit = f"{question_last['question']}\n\n{'✅ ' if user_ans == 0 else ''}1. {question_last['answers'][0][0]} \n\n{'✅ ' if user_ans == 1 else ''}2. {question_last['answers'][1][0]}"
|
||||||
|
|
||||||
|
# bot.edit_message_text(
|
||||||
|
# text_edit,
|
||||||
|
# call.message.chat.id,
|
||||||
|
# call.message.message_id,
|
||||||
|
# parse_mode="HTML",
|
||||||
|
# ) # упростить
|
||||||
|
|
||||||
|
# if len(user.type) == 4:
|
||||||
|
# show_result(call.message)
|
||||||
|
# return
|
||||||
|
|
||||||
|
# question = TestMessages.TEST_QUESTIONS[len(user.type)]
|
||||||
|
# text = f"{question['question']}\n\n1. {question['answers'][0][0]} \n\n2. {question['answers'][1][0]}"
|
||||||
|
# markup = types.InlineKeyboardMarkup()
|
||||||
|
# markup.add(
|
||||||
|
# types.InlineKeyboardButton("Первый вариант", callback_data=f"test_0"),
|
||||||
|
# types.InlineKeyboardButton("Второй вариант", callback_data=f"test_1"),
|
||||||
|
# )
|
||||||
|
|
||||||
|
# bot.send_message(call.message.chat.id, text, reply_markup=markup)
|
||||||
|
|
||||||
|
# return
|
||||||
|
|
||||||
|
|
||||||
def show_result(message: types.Message):
|
def show_result(message: types.Message):
|
||||||
user = User(message.chat.id)
|
user = User(message.chat.id)
|
||||||
text = TestMessages.TEST_RESULT.format(
|
text = TestMessages.TEST_RESULT.format(
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ def Shuffle() -> List[Tuple[User, User]]:
|
|||||||
pairs = []
|
pairs = []
|
||||||
|
|
||||||
if len(users) % 2 != 0:
|
if len(users) % 2 != 0:
|
||||||
pairs.append((users.pop(),))
|
pairs.append((users.pop(), None))
|
||||||
|
|
||||||
# Step 1: Match men with women by compatibility and age
|
# Step 1: Match men with women by compatibility and age
|
||||||
for user in users:
|
for user in users:
|
||||||
|
|||||||
@@ -1,124 +1,202 @@
|
|||||||
class TestMessages:
|
class TestMessages:
|
||||||
TEST_WELCOME = "Пройди следующий короткий тест, чтобы было легче подобрать тебе пару. А еще ты узнаешь, кто ты из героев советских мультфильмов."
|
TEST_WELCOME = "Пройди следующий короткий тест, чтобы было легче подобрать тебе пару. А еще ты узнаешь, кто ты из <b>героев славянских мифов.</b>"
|
||||||
TEST_RESULT = "Ты - {}!\n\n{}"
|
TEST_RESULT = "👉 Ты - {}!👈\n\n{}"
|
||||||
TEST_FINISH = "Поздравляем! Теперь вы зарегистрированы в системе."
|
TEST_FINISH = "🎉 Поздравляем! 🎉" "\nТеперь вы зарегистрированы в системе."
|
||||||
TEST_QUESTIONS = [
|
TEST_QUESTIONS = [
|
||||||
{
|
{
|
||||||
"question": "Когда вы оказываетесь в новой компании людей, вы, как правило:",
|
"question": "На кого из героев славянских мифов вы хотели бы быть похожи?",
|
||||||
"answers": [
|
"answers": [
|
||||||
(
|
{
|
||||||
"Легко заводите разговоры с разными людьми.",
|
"text": "<u><b>На Перуна — защищать порядок, брать ответственность и вести других за собой ✊🏻</b></u>.",
|
||||||
"E",
|
"types": ["ENTJ"],
|
||||||
),
|
"short": "Перун!",
|
||||||
(
|
},
|
||||||
"Предпочитаете сначала понаблюдать и только потом начать общаться с теми, кто вам интересен.",
|
{
|
||||||
"I",
|
"text": "<u><b>На Велеса — искать скрытые знания и понимать тайны мира 🔮</b></u>.",
|
||||||
),
|
"types": ["INTP"],
|
||||||
|
"short": "Велес!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Морену — видеть глубинные смыслы и управлять переменами 🪬</b></u>.",
|
||||||
|
"types": ["INFJ"],
|
||||||
|
"short": "Морена!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Стрибога — быть свободным, приносить новые идеи и перемены 😌</b></u>.",
|
||||||
|
"types": ["ENTP"],
|
||||||
|
"short": "Стрибог!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Ладу — создавать гармонию и помогать людям находить общий язык ☺️</b></u>.",
|
||||||
|
"types": ["ESFJ"],
|
||||||
|
"short": "Лада!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Макошь — заботиться о судьбах других и поддерживать близких 🫂</b></u>.",
|
||||||
|
"types": ["ISFJ"],
|
||||||
|
"short": "Макошь!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Ярило — жить ярко, действовать смело и наслаждаться моментом 😏</b></u>.",
|
||||||
|
"types": ["ESTP"],
|
||||||
|
"short": "Ярило!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Домового — защищать свой мир и сохранять стабильность 💪🏻</b></u>.",
|
||||||
|
"types": ["ISTJ"],
|
||||||
|
"short": "Домовой!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Чернобога — видеть стратегию и действовать по своему плану 😎</b></u>.",
|
||||||
|
"types": ["INTJ"],
|
||||||
|
"short": "Чернобог!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Купалу — вдохновлять других и приносить радость 🤩</b></u>.",
|
||||||
|
"types": ["ENFP"],
|
||||||
|
"short": "Купала!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Даждьбога — помогать людям расти и вести их к свету 🤗</b></u>.",
|
||||||
|
"types": ["ENFJ"],
|
||||||
|
"short": "Даждьбог!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Живу — жить в гармонии с собой и чувствовать мир 😇</b></u>.",
|
||||||
|
"types": ["ISFP"],
|
||||||
|
"short": "Жива!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Кощея — быть независимым и полагаться только на себя 😉</b></u>.",
|
||||||
|
"types": ["ISTP"],
|
||||||
|
"short": "Кощей!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Рода — создавать основы и поддерживать порядок мира 🙌🏻</b></u>.",
|
||||||
|
"types": ["ESTJ"],
|
||||||
|
"short": "Род!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Лелю — верить в добро и следовать своему сердцу 🫶🏻</b></u>.",
|
||||||
|
"types": ["INFP"],
|
||||||
|
"short": "Леля!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "<u><b>На Жар-птицу — зажигать сердца и превращать жизнь в яркое приключение 🔥</b></u>.",
|
||||||
|
"types": ["ESFP"],
|
||||||
|
"short": "Жар-птица!",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"question": "Вы пишете книгу или создаете проект. Какой подход вам ближе?",
|
"question": "На работе вам важнее всего:",
|
||||||
"answers": [
|
"answers": [
|
||||||
(
|
{
|
||||||
"Тщательно исследую тему, соберу всю доступную информацию и буду двигаться шаг за шагом, основываясь на фактах.",
|
"text": "Возможность творить и воплощать самые безумные идеи 😜.",
|
||||||
"S",
|
"types": ["ENFP", "ENTP", "INFP", "INTP"],
|
||||||
),
|
"short": "Творчество!",
|
||||||
(
|
},
|
||||||
"Сначала придумаю общую концепцию, представлю мир и героев (или цели проекта), и буду импровизировать, раскрывая детали по ходу дела.",
|
{
|
||||||
"N",
|
"text": "Профессиональный рост и постоянный апгрейд навыков 😌",
|
||||||
),
|
"types": ["ENTJ", "ESTJ", "ISTJ", "ISFJ"],
|
||||||
|
"short": "Карьера!",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"question": "Ваш друг совершил ошибку, которая имеет серьезные последствия. Как вы отреагируете?",
|
"question": "В дружбе вы цените больше всего:",
|
||||||
"answers": [
|
"answers": [
|
||||||
(
|
{
|
||||||
"Объективно проанализирую ситуацию, укажу на ошибки и предложу логичное решение проблемы.",
|
"text": "Позитивное мышление и фонтаны идей. Когда друг звонит ночью и предлагает сделать из картона ракету, чтобы улететь на Марс, я уже ищу скотч 👀",
|
||||||
"T",
|
"types": ["ENFP", "ENTP", "ESFP", "ESTP"],
|
||||||
),
|
"short": "Идеи!",
|
||||||
(
|
},
|
||||||
"Постараюсь понять его мотивы, проявить сочувствие и оказать эмоциональную поддержку, чтобы он справился с ситуацией.",
|
{
|
||||||
"F",
|
"text": "Искренность. Вы знаете о друге всё: почему он не любит лук, сколько хомяков загубил в детстве и какую песню пел на выпускном 🫶🏻",
|
||||||
),
|
"types": ["INFJ", "INFP", "ISFJ", "INTJ"],
|
||||||
|
"short": "Искренность!",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"question": "Представьте, что у вас есть свободный день. Что вы выберете?",
|
"question": "Что вас вдохновляет?",
|
||||||
"answers": [
|
"answers": [
|
||||||
(
|
{
|
||||||
"Заранее составлю план, чтобы максимально эффективно использовать время: посетить музей, заняться спортом, встретиться с друзьями.",
|
"text": "Галочка напротив выполненного дела и зачеркнутые пункты в плане ✅",
|
||||||
"J",
|
"types": ["ENTJ", "ESTJ", "ISTJ", "INTJ"],
|
||||||
),
|
"short": "Планирование!",
|
||||||
(
|
},
|
||||||
"Отложу все планы и позволю дню разворачиваться спонтанно: почитаю книгу, прогуляюсь по парку или просто буду наслаждаться моментом.",
|
{
|
||||||
"P",
|
"text": "Душевные разговоры, после которых хочется обнимать весь мир 🫂",
|
||||||
),
|
"types": ["ENFJ", "INFJ", "ISFP", "INFP"],
|
||||||
|
"short": "Душевность!",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
TEST_RESULTS = {
|
TEST_RESULTS = {
|
||||||
"INTJ": (
|
"INTJ": (
|
||||||
"Профессор Селезнёв",
|
"Чернобог",
|
||||||
"Ты умеешь воспринимать ситуацию глобально, а твои действия точны и эффективны. Ты, как и профессор Селезнев, привык к системному подходу и логическому анализу, эксперт в своей области",
|
"Ты стратег, как Чернобог. Умеешь видеть общую картину и планировать наперёд. Ты действуешь точно и уверенно, опираясь на разум.",
|
||||||
),
|
),
|
||||||
"INTP": (
|
"INTP": (
|
||||||
"Знайка",
|
"Велес",
|
||||||
"Знаешь всё про всё и даже больше. Предпочитаешь полагаться на свою голову. Любишь “покопаться” в каком-нибудь вопросе и не боишься выдвигать даже самые неожиданные гипотезы",
|
"Ты мудрый искатель истины, как Велес — хранитель тайных знаний. Ты стремишься понять мир глубже и видишь то, что скрыто от других. Твоя сила в интеллекте и наблюдательности.",
|
||||||
),
|
),
|
||||||
"INFJ": (
|
"INFJ": (
|
||||||
"Ёжик в тумане",
|
"Морена",
|
||||||
"Ты, как и Ежик, типичный интроверт, погруженный в свой внутренний мир. Ты глубоко чувствуешь окружающий мир и обладаешь богатым воображением. Хоть и бываешь застенчив и раним, но при этом ты отзывчив и добр.",
|
"Ты загадочная и глубокая личность, как Морена. Чувствуешь перемены и понимаешь истинную природу вещей. Твоя мудрость помогает тебе видеть то, что недоступно другим.",
|
||||||
),
|
),
|
||||||
"INFP": (
|
"INFP": (
|
||||||
"Кот Леопольд",
|
"Леля",
|
||||||
"«Ребята, давайте жить дружно!». Ты стремишься к гармонии во всех сферах жизни. Ты творческая личность, которая в принятии решений руководствуется своими ценностями и убеждениями",
|
"Ты чистая и искренняя душа, как Леля. Веришь в добро и следуешь своему сердцу. Твоя сила в чувствах и внутренней правде.",
|
||||||
),
|
),
|
||||||
"ISTJ": (
|
"ISTJ": (
|
||||||
"Кролик из Винни Пуха",
|
"Домовой",
|
||||||
"“-И это всё потому, что у кого-то очень узкие двери! -Нет! Это всё потому, что кто-то слишком много ест!” Ты, как и кролик, всегда логичен и прагматичен. Не тратишь слов попусту, но в ответ на критику за словом в карман не полезешь))",
|
"Ты надёжный защитник, как Домовой. Ценишь порядок, стабильность и безопасность. На тебя всегда можно положиться.",
|
||||||
),
|
),
|
||||||
"ISTP": (
|
"ISTP": (
|
||||||
"Буратино",
|
"Кощей",
|
||||||
"Ты стремишься узнать мир и найти свое место в жизни. Ты, как и Буратино, полон энергии и любопытства. Ты всегда готов исследовать новое и пробовать разные вещи",
|
"Ты независимый и сильный, как Кощей. Привык полагаться на себя, умеешь выживать и находить решения в любой ситуации.",
|
||||||
),
|
),
|
||||||
"ISFJ": (
|
"ISFJ": (
|
||||||
"Пятачок",
|
"Макошь",
|
||||||
"Ты добрый и заботливый (поросенок), всегда готов поддержать своих друзей. Любишь проявлять преданность и стремление заботиться о других, стараясь сделать их счастливыми. Как и Пятачок ты всегда готов прийти на помощь, даже если это требует смелости.",
|
"Ты хранитель судьбы, как Макошь. Заботишься о других и создаёшь стабильность. Люди доверяют тебе и чувствуют рядом с тобой безопасность.",
|
||||||
),
|
),
|
||||||
"ISFP": (
|
"ISFP": (
|
||||||
"Кот Матроскин",
|
"Жива",
|
||||||
"Ты гибкий, очаровательный артист, всегда готовый исследовать и испытать что-то новое. Ты творческая личность, тонкая, эмоциональные и чувствительные натура",
|
"Ты живёшь в гармонии, как богиня Жива. Тонко чувствуешь мир и ценишь красоту. Твоя сила — в искренности и внутреннем балансе.",
|
||||||
),
|
),
|
||||||
"ENTJ": (
|
"ENTJ": (
|
||||||
"Сыщик из бременских музыкантов",
|
"Перун",
|
||||||
"Оу ес! Ты решителен и успешен в любом деле. Можешь легко подстроиться под обстоятельства и наперёд просчитать свои действия, прямо как гениальный сыщик!",
|
"Ты прирождённый лидер, как Перун — бог грома и справедливости. Ты берёшь ответственность на себя и уверенно ведёшь других. Твоя сила в решительности, порядке и способности действовать без колебаний.",
|
||||||
),
|
),
|
||||||
"ENTP": (
|
"ENTP": (
|
||||||
"Карлсон",
|
"Стрибог",
|
||||||
"“В самом расцвете сил!” Ты экстравертен, обаятелен, остроумен, любишь привлекать внимание и постоянно придумывать новые затеи!",
|
"Ты свободный дух, как Стрибог — бог ветра. Ты приносишь новые идеи и перемены. Твоя энергия вдохновляет и открывает новые возможности.",
|
||||||
),
|
),
|
||||||
"ENFJ": (
|
"ENFJ": (
|
||||||
"Почтальон Печкин",
|
"Даждьбог",
|
||||||
"Своей яркой харизмой ты без усилий убеждаешь и увлекаешь других, наполняя пространство теплом и создавая отличную атмосферу для продуктивной работы.",
|
"Ты несёшь свет и развитие, как Даждьбог. Ты вдохновляешь других и помогаешь им становиться лучше. Твоя сила в поддержке и лидерстве.",
|
||||||
),
|
),
|
||||||
"ENFP": (
|
"ENFP": (
|
||||||
"Трубадур из бременских музыкантов",
|
"Купала",
|
||||||
"Ты энергичный, харизматичный и независимый человек. Ты не боишься перемен и всегда открыт к чему-то новому, легко находишь общий язык с людьми, а твое творческое мышление помогает находить нестандартные решения",
|
"Ты приносишь радость и вдохновение, как Купала. Любишь жизнь, новые эмоции и возможности. Люди тянутся к твоему свету.",
|
||||||
),
|
),
|
||||||
"ESTJ": (
|
"ESTJ": (
|
||||||
"Римма Трофимовна. Мама дядя Федора",
|
"Род",
|
||||||
"Ты являешься практичным и инициативным человеком, способным организовывать своё время и задачи. Высокие стандарты, которые ты установил для себя, делают тебя надежным и вдохновляющим примером для окружающих.",
|
"Ты создаёшь основы, как Род — создатель мира. Ты организованный и ответственный. Ты умеешь строить порядок и управлять процессами.",
|
||||||
),
|
),
|
||||||
"ESTP": (
|
"ESTP": (
|
||||||
"Волк из “Ну, погоди!”",
|
"Ярило",
|
||||||
"Ты энергичный, авантюрный и предприимчивый. Как Волк всегда стремишься достичь своей цели и, не останавливаясь, ищешь новых приключений!",
|
"Яркость и смелость, как у Ярило — бога солнца и жизни. Ты любишь действовать и не боишься риска. Ты живёшь настоящим моментом.",
|
||||||
),
|
),
|
||||||
"ESFJ": (
|
"ESFJ": (
|
||||||
"Дядя Федор",
|
"Лада",
|
||||||
"Как и Дядя Федор, ты надежный и ответственный, на тебя всегда можно положиться. Ты внимателен к потребностям и чувствам других людей и всегда готов прийти на помощь.",
|
"Ты создаёшь гармонию, как богиня Лада. Умеешь объединять людей и заботиться о них. Твоя сила в доброте, поддержке и способности создавать баланс.",
|
||||||
),
|
),
|
||||||
"ESFP": (
|
"ESFP": (
|
||||||
"Мышонок (“Какой чудесный день, какой чудесный пень…”)",
|
"Жар-птица",
|
||||||
"Заводила, запевала. Всегда в центре событий. Умеешь заставить улыбнуться людей",
|
"Ты — огонь праздника, как Жар-птица. Умеешь зажигать людей вокруг, любишь яркие впечатления и легко превращаешь обычный день в событие. Твоя сила в харизме, смелости и умении жить “здесь и сейчас”.",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from db import DB
|
|||||||
from plugin.bot_instance import bot
|
from plugin.bot_instance import bot
|
||||||
from config import Messages
|
from config import Messages
|
||||||
from telebot import types
|
from telebot import types
|
||||||
from typing import List, Tuple
|
from typing import List
|
||||||
|
|
||||||
users_reg: List["User"] = []
|
users_reg: List["User"] = []
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -18,11 +18,9 @@ class User:
|
|||||||
self._faculty: str = None
|
self._faculty: str = None
|
||||||
self._group: str = None
|
self._group: str = None
|
||||||
self._type: str = None
|
self._type: str = None
|
||||||
|
self._agree_upload: bool = None
|
||||||
|
self._vector_type: dict = None
|
||||||
|
|
||||||
self._save()
|
|
||||||
|
|
||||||
def __init__(self, user_id):
|
|
||||||
self.user_id: int = user_id
|
|
||||||
self._load()
|
self._load()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -91,6 +89,28 @@ class User:
|
|||||||
|
|
||||||
return self._type
|
return self._type
|
||||||
|
|
||||||
|
@property
|
||||||
|
def agree_upload(self):
|
||||||
|
return self._agree_upload
|
||||||
|
|
||||||
|
@agree_upload.setter
|
||||||
|
def agree_upload(self, value):
|
||||||
|
self._agree_upload = value
|
||||||
|
self.update_data()
|
||||||
|
|
||||||
|
return self._agree_upload
|
||||||
|
|
||||||
|
@property
|
||||||
|
def vector_type(self):
|
||||||
|
return self._vector_type
|
||||||
|
|
||||||
|
@vector_type.setter
|
||||||
|
def vector_type(self, value):
|
||||||
|
self._vector_type = value
|
||||||
|
self.update_data()
|
||||||
|
|
||||||
|
return self._vector_type
|
||||||
|
|
||||||
def _into_json(self):
|
def _into_json(self):
|
||||||
return {
|
return {
|
||||||
"_id": self.user_id,
|
"_id": self.user_id,
|
||||||
@@ -100,6 +120,8 @@ class User:
|
|||||||
"faculty": self._faculty,
|
"faculty": self._faculty,
|
||||||
"group": self._group,
|
"group": self._group,
|
||||||
"type": self._type,
|
"type": self._type,
|
||||||
|
"agree_upload": self._agree_upload,
|
||||||
|
"vector_type": self._vector_type,
|
||||||
}
|
}
|
||||||
|
|
||||||
def update_data(self):
|
def update_data(self):
|
||||||
@@ -121,7 +143,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"]
|
||||||
@@ -131,11 +154,13 @@ class User:
|
|||||||
self._faculty = data["faculty"]
|
self._faculty = data["faculty"]
|
||||||
self._group = data["group"]
|
self._group = data["group"]
|
||||||
self._type = data["type"]
|
self._type = data["type"]
|
||||||
|
self._agree_upload = data["agree_upload"]
|
||||||
|
self._vector_type = data["vector_type"]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def start_shuffle_reg():
|
def start_shuffle_reg():
|
||||||
users_reg.clear()
|
users_reg.clear()
|
||||||
users = [user for user in User.get_all() if user.type]
|
users = [user for user in User.get_all() if (user.type and len(user.type) == 4)]
|
||||||
|
|
||||||
markup = types.InlineKeyboardMarkup()
|
markup = types.InlineKeyboardMarkup()
|
||||||
markup.add(
|
markup.add(
|
||||||
@@ -145,19 +170,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
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,23 @@
|
|||||||
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 -u main.py"
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
mongodb:
|
mongodb:
|
||||||
image: mongo:latest
|
image: 'mongo:4.4.6'
|
||||||
# image: mongo:8.0-rc
|
|
||||||
container_name: mongodb
|
|
||||||
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 +25,4 @@ volumes:
|
|||||||
driver_opts:
|
driver_opts:
|
||||||
type: none
|
type: none
|
||||||
o: bind
|
o: bind
|
||||||
device: ./.data
|
device: ./.data
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
## Запуск
|
## Запуск
|
||||||
|
|
||||||
1. Создать [файл .env](#env) в директории `app`
|
1. Создать [файл .env](#env) в директории `app`
|
||||||
|
- Пример файла расположен в корне (`.env.example`)
|
||||||
2. Запустить контейнеры с помощью docker compose:
|
2. Запустить контейнеры с помощью docker compose:
|
||||||
- `docker-compose up -d`
|
- `docker-compose up -d`
|
||||||
|
|
||||||
@@ -46,6 +47,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>
|
||||||
|
|
||||||
@@ -56,7 +58,7 @@
|
|||||||
- `API_TOKEN` - токен для tg бота полученный у `@BotFather`
|
- `API_TOKEN` - токен для tg бота полученный у `@BotFather`
|
||||||
- `ADMIN_ID` - id **_главного админа_**
|
- `ADMIN_ID` - id **_главного админа_**
|
||||||
- `DB_PORT` порт для MongoDB, стандартно `27017`
|
- `DB_PORT` порт для MongoDB, стандартно `27017`
|
||||||
- `ENV` - если выставлен как `dev`:
|
- `ENV` - если выставлен как `DEV`:
|
||||||
- возможность подключаться к базе данных удалённо через SSH
|
- возможность подключаться к базе данных удалённо через SSH
|
||||||
- `SSH_HOST` - имя/ip хоста
|
- `SSH_HOST` - имя/ip хоста
|
||||||
- `SSH_USER` - имя пользователя
|
- `SSH_USER` - имя пользователя
|
||||||
|
|||||||