Add quote bot

This commit is contained in:
LeoR156
2026-09-12 09:46:55 +05:00
commit 44410c3e56
18 changed files with 542 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
import logging
from telebot import TeleBot
from telebot.types import Message
from .config import TOKEN, ADMIN_IDS
from .quotes import get_random_quote, add_quote, count_quotes
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
)
bot = TeleBot(TOKEN)
# ─── Хэндлеры ────────────────────────────────────────────────────────────────
@bot.message_handler(commands=["start"])
def cmd_start(message: Message):
name = message.from_user.first_name
bot.reply_to(
message,
f"Привет, {name}! 👋\n\n"
"Я бот с цитатами. Вот что я умею:\n"
"/quote — случайная цитата\n"
"/stats — сколько цитат в базе\n"
"/add <текст> — добавить цитату (только для администратора)",
)
logging.info(
f"[/start] user_id={message.from_user.id} ({message.from_user.first_name})"
)
@bot.message_handler(commands=["quote"])
def cmd_quote(message: Message):
quote = get_random_quote()
if quote is None:
bot.reply_to(
message,
"😔 Цитат пока нет. Попросите администратора добавить хотя бы одну!",
)
else:
bot.reply_to(message, f"💬 {quote}")
logging.info(f"[/quote] user_id={message.from_user.id}")
@bot.message_handler(commands=["stats"])
def cmd_stats(message: Message):
total = count_quotes()
bot.reply_to(message, f"📚 В базе {total} цитат.")
logging.info(f"[/stats] user_id={message.from_user.id}, total={total}")
@bot.message_handler(commands=["add"])
def cmd_add(message: Message):
# Проверяем права
if message.from_user.id not in ADMIN_IDS:
bot.reply_to(message, "🚫 У вас нет прав для добавления цитат.")
logging.warning(
f"[/add] Unauthorized attempt by user_id={message.from_user.id}")
return
# Извлекаем текст после команды /add
parts = message.text.split(maxsplit=1)
if len(parts) < 2 or not parts[1].strip():
bot.reply_to(
message, "✏️ Укажите текст цитаты. Пример:\n/add Жизнь прекрасна!")
return
quote_text = parts[1].strip()
added = add_quote(quote_text)
if added:
bot.reply_to(message, f"✅ Цитата добавлена:\n\n💬 {quote_text}")
logging.info(
f"[/add] Added new quote by user_id={message.from_user.id}")
else:
bot.reply_to(message, "⚠️ Такая цитата уже есть в базе.")
# ─── Точка входа ─────────────────────────────────────────────────────────────
def main():
logging.info("Бот запущен в режиме polling...")
bot.infinity_polling()
if __name__ == "__main__":
main()
+8
View File
@@ -0,0 +1,8 @@
import os
TOKEN = os.environ.get("TOKEN")
if not TOKEN:
raise ValueError("Переменная окружения TOKEN не задана!")
admin_ids_raw = os.environ.get("ADMIN_IDS", "")
ADMIN_IDS = {int(i) for i in admin_ids_raw.split(",") if i.strip()}
+39
View File
@@ -0,0 +1,39 @@
import random
from pathlib import Path
DATA_FILE = Path(__file__).parent.parent / "data" / "quotes.txt"
def _read_all() -> list[str]:
"""Читает все цитаты из файла. Возвращает пустой список, если файл пуст или не существует."""
if not DATA_FILE.exists():
return []
lines = DATA_FILE.read_text(encoding="utf-8").splitlines()
return [line for line in lines if line.strip()]
def get_random_quote() -> str | None:
"""Возвращает случайную цитату или None, если их нет."""
quotes = _read_all()
if not quotes:
return None
return random.choice(quotes) # nosec
def add_quote(text: str) -> bool:
"""
Добавляет новую цитату в файл.
Возвращает False, если такая цитата уже существует, иначе True.
"""
quotes = _read_all()
if text in quotes:
return False
DATA_FILE.parent.mkdir(parents=True, exist_ok=True)
with DATA_FILE.open("a", encoding="utf-8") as f:
f.write(text + "\n")
return True
def count_quotes() -> int:
"""Возвращает количество цитат в базе."""
return len(_read_all())