Initial commit

This commit is contained in:
Evgeniy L.
2025-03-15 10:10:55 +05:00
commit 1ef9dc18bb
9 changed files with 313 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
__pycache__/
.env
.venv/
.idea/
.vscode/
+57
View File
@@ -0,0 +1,57 @@
import asyncio
import aiohttp
from bs4 import BeautifulSoup
import random
import logging
URL = 'https://nekdo.ru/random/'
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
}
JOKES_list = [
'''— Доктор, у меня проблема: я всё время забываю, что хотел сказать.
— Сколько это уже продолжается?
— Что «это»?''',
'''— Почему вы опоздали на работу?
— Проспал.
— И что, до 16:00 спали?
— Нет, до 15:55.''',
'''— Папа, а кто такой пессимист?
— Это человек, который, когда ему дают выбор между двумя злами, выбирает оба.''',
]
def findInSoup(soup: BeautifulSoup):
element = soup.find('div', id=True, class_=True)
return element
async def getAnecdote() -> str:
logging.info("Запрашиваю анекдот с сайта.")
async with aiohttp.ClientSession(headers=HEADERS) as session:
try:
async with session.get(URL) as response:
if response.status == 200:
logging.info("Успешно получен ответ от сервера.")
html = await response.text()
soup = BeautifulSoup(html, 'html.parser')
element = findInSoup(soup)
if element:
logging.info("Анекдот успешно найден на странице.")
return element.text.strip()
logging.warning(f"Получен неудачный статус ответа: {response.status}. Использую локальный анекдот.")
return random.choice(JOKES_list)
except Exception as e:
logging.error(f"Ошибка при запросе: {e}. Использую локальный анекдот.")
return random.choice(JOKES_list)
if __name__ == "__main__":
async def main():
text = await getAnecdote()
print(text)
asyncio.run(main())
+73
View File
@@ -0,0 +1,73 @@
# Telegram Бот для Проекта SRSP
Телеграм-бот для предоставления информации о команде разработчиков, документации и презентации проекта.
## Описание
Этот бот предоставляет удобный интерфейс для доступа к информации о команде разработчиков, технической документации и презентации проекта. Бот разработан с использованием библиотеки aiogram 3.x.
## Функциональность
- `/start` - Начать работу с ботом и отобразить основную клавиатуру.
- В ответном сообщение отправляется случайный анекдот с сайта nekdo.ru
- `/team_members` - Показать информацию о членах команды разработчиков
- `/documentation` - Скачать техническую документацию проекта
- `/presentation` - Скачать презентацию проекта
- `/help` - Показать список доступных команд
## Установка и запуск
### Предварительные требования
- Python 3.8 или выше
- pip (менеджер пакетов Python)
### Шаги по установке
1. Клонировать репозиторий:
```bash
git clone https://github.com/ArtzSU/SRSP-bot
cd tgbotsrsp
```
2. Создать и активировать виртуальное окружение:
```bash
python -m venv .venv
# Для Windows
.venv\Scripts\activate
# Для macOS/Linux
source .venv/bin/activate
```
3. Установить зависимости:
```bash
pip install -r requirements.txt
```
4. Создать файл `.env` в корневой директории проекта и добавить токен бота:
```
BOT_TOKEN=ваш_токен_бота
```
### Запуск бота
```bash
python main.py
```
## Структура проекта
- `main.py` - Основной файл с логикой бота
- `config.py` - Конфигурационный файл с константами и настройками
- `keyboard.py` - Файл с определениями клавиатур для бота
- `assets/` - Директория с ресурсами (документация, презентация)
- `Modules/` - Директория с модулями
- `Modules/getAnecdote.py` - Модуль запроса случайного анекдота
- `requirements.txt` - Список зависимостей проекта
## Команда разработчиков
- Лукьянов Е. - @artzsu
- Серик Т. - @tam_serik
- Скрипченко В. - @Sunny_Vls
- Исламберди А. - @Y191900
Binary file not shown.
Binary file not shown.
+19
View File
@@ -0,0 +1,19 @@
import os
from dotenv import load_dotenv
if not load_dotenv():
raise FileNotFoundError('.env file does not exist')
TOKEN = os.environ.get('BOT_TOKEN')
if not TOKEN:
raise ValueError("BOT_TOKEN is not set in the environment variables")
DEBUG = os.environ.get('DEBUG', 'False').lower() in ('true', '1', 'yes', 'on')
TEAM_MEMBERS_STR = """
Team:
- Lukyanov E. - @queue_qq
- Serik T. - @tam_serik
- Skripchenko V. - @Sunny_Vls
- Islamberdi A. - @Y191900
"""
+22
View File
@@ -0,0 +1,22 @@
from aiogram.types import (
KeyboardButton,
ReplyKeyboardMarkup,
)
# REPLY_KEYBOARDS
main_kb = ReplyKeyboardMarkup(
keyboard = [
[
KeyboardButton(text="/team_members")
],
[
KeyboardButton(text="/documentation"),
KeyboardButton(text="/presentation"),
],
[
KeyboardButton(text="/help")
]
],
resize_keyboard=True,
input_field_placeholder="Choose one option",
)
+133
View File
@@ -0,0 +1,133 @@
import asyncio
import logging
from aiogram.filters import Command
from aiogram.enums import ParseMode, ChatType
from aiogram.client.default import DefaultBotProperties
from aiogram import (
F,
Bot,
html,
Dispatcher,
)
from aiogram.types import (
Message,
FSInputFile,
BotCommand,
)
from Modules.getAnecdote import getAnecdote
import config
from keyboard import main_kb
logger = logging.getLogger(__name__)
logging.basicConfig(
level=logging.DEBUG if config.DEBUG else logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
dp = Dispatcher()
bot = Bot(
token=config.TOKEN,
default=DefaultBotProperties(
parse_mode=ParseMode.HTML
)
)
async def set_commands(service: Bot):
"""
Регистрация команд бота в меню команд Telegram
"""
commands = [
BotCommand(command="start", description="Start the bot"),
BotCommand(command="help", description="Help"),
BotCommand(command="team_members", description="Show members of development team"),
BotCommand(command="documentation", description="Show documentation"),
BotCommand(command="presentation", description="Show presentation"),
]
await service.set_my_commands(commands)
logger.info("Команды бота успешно зарегистрированы")
@dp.message(Command("start"))
async def command_start_handler(message: Message) -> None:
"""
Handler for the `/start` command
"""
await message.reply(
text=f"Hello, {html.bold(message.from_user.full_name)}! {await getAnecdote()}",
reply_markup=main_kb
)
@dp.message(Command("team_members"))
async def command_of_devers(message: Message):
"""
Handler for the `/team_members` command
"""
await message.reply(text=config.TEAM_MEMBERS_STR)
@dp.message(Command("help"))
async def cmd_help(message: Message):
"""
Handler for the `/help` command
"""
await message.reply(
text = """Вот список команд:
/start - начать работу
/help - вывести это сообщение
/documentation - отправляет отчет проделанной работы
/presentation - отправляет презентацию о боте"""
)
@dp.message(Command("documentation"))
async def cmd_doc(message: Message):
"""
Handler for the `/documentation` command
"""
await message.reply_document(
document=FSInputFile(path="assets/tech_doc.docx", filename="техническая документация.docx")
)
@dp.message(Command("presentation"))
async def cmd_presentation(message: Message):
"""
Handler for the `/presentation` command
"""
await message.reply_document(
document=FSInputFile(path="assets/pressetation.pptx", filename="презентация.pptx")
)
async def main() -> None:
"""
Main function to start the bot
"""
logging.info("Starting bot")
dp.message.filter(F.chat.type == ChatType.PRIVATE)
dp.callback_query.filter(F.message.chat.type == ChatType.PRIVATE)
await set_commands(bot)
await bot.delete_webhook(drop_pending_updates=True)
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
+4
View File
@@ -0,0 +1,4 @@
aiogram~=3.18.0
python-dotenv~=1.0.1
beautifulsoup4~=4.13.3
requests~=2.32.3