Compare commits

...

5 Commits

14 changed files with 1341 additions and 2 deletions

1
.gitignore vendored
View File

@ -159,4 +159,3 @@ cython_debug/
# 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/

50
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,50 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.2.0
hooks:
- id: trailing-whitespace # убирает лишние пробелы
- id: check-added-large-files # проверяет тяжелые файлы на изменения
- id: check-yaml # проверяет синтаксис .yaml файлов
- id: check-json # проверяет синтаксис .json файлов
exclude: launch.json
- id: check-case-conflict # проверяет файлы, которые могут конфликтовать в файловых системах без учета регистра.
- id: check-merge-conflict # проверяет файлы, содержащие конфликтные строки слияния.
- id: double-quote-string-fixer # заменяет " на '
- id: end-of-file-fixer # добавляет пустую строку в конце файла
# Отсортировывает импорты в проекте
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
exclude: __init__.py
args: [ --profile, black, --filter-files ]
# Обновляет синтаксис Python кода в соответствии с последними версиями
- repo: https://github.com/asottile/pyupgrade
rev: v2.31.1
hooks:
- id: pyupgrade
args: [--py310-plus]
# Форматирует код под PEP8
- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v2.0.1
hooks:
- id: autopep8
args: [--max-line-length=120, --in-place]
# Сканер стилистических ошибок, нарушающие договоренности PEP8
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8
exclude: "__init__.py"
args: ["--ignore=E501,F821", "--max-line-length=120"]
# Проверка статических типов с помощью mypy
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.991
hooks:
- id: mypy
exclude: 'migrations'

15
Dockerfile Normal file
View File

@ -0,0 +1,15 @@
FROM python:3.10-slim
RUN pip install poetry
RUN poetry config virtualenvs.create false
RUN mkdir -p /usr/src/tg_bot
WORKDIR /usr/src/tg_bot
COPY ./poetry.lock .
COPY ./pyproject.toml .
RUN poetry install --no-root

View File

@ -1,3 +1,3 @@
# tg_bot
Бот написанный по учебе в качестве домашних заданий.
Бот написанный по учебе в качестве домашних заданий.

15
docker-compose.yml Normal file
View File

@ -0,0 +1,15 @@
version: "3.8"
services:
app:
container_name: tg_demo_bot
build:
context: .
env_file:
- .env
volumes:
- .:/usr/src/tg_bot
command: /bin/bash -c 'poetry run bot'

1082
poetry.lock generated Normal file

File diff suppressed because it is too large Load Diff

25
pyproject.toml Normal file
View File

@ -0,0 +1,25 @@
[tool.poetry]
name = "tg-bot"
version = "0.1.0"
description = ""
authors = ["pi3c <pi3c@yandex.ru>"]
license = "MIT"
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10"
aiogram = "^3.3.0"
requests = "^2.31.0"
types-requests = "^2.31.0.20240125"
mypy = "^1.8.0"
[tool.poetry.group.dev.dependencies]
pre-commit = "^3.6.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.scripts]
bot = "tg_bot.app:main"

0
tg_bot/__init__.py Normal file
View File

36
tg_bot/app.py Normal file
View File

@ -0,0 +1,36 @@
import asyncio
import logging
import sys
from os import getenv
from aiogram import Bot, Dispatcher
from aiogram.enums import ParseMode
from aiogram.filters import CommandStart
from aiogram.types import Message
from aiogram.utils.markdown import hbold
from tg_bot.handlers.lesson_four import router as router_one
TOKEN: str = getenv('BOT_TOKEN') or 'Your TG_BOT token'
dp = Dispatcher()
dp.include_routers(router_one)
@dp.message(CommandStart())
async def command_start_handler(message: Message) -> None:
await message.answer(f'Hello, {hbold(message.from_user.first_name)}!')
async def run_bot() -> None:
bot = Bot(TOKEN, parse_mode=ParseMode.HTML)
await dp.start_polling(bot)
def main():
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
asyncio.run(run_bot())
if __name__ == '__main__':
main()

View File

View File

@ -0,0 +1,46 @@
import json
import requests # type: ignore
from aiogram import F, Router
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import Message
router = Router()
class OrderAsk(StatesGroup):
string = State()
@router.message(Command('ask'))
async def reverse_request(message: Message, state: FSMContext):
await state.set_state(OrderAsk.string)
await message.answer(
text='Введите вопрос',
)
@router.message(OrderAsk.string, F.text)
async def reversing(message: Message, state: FSMContext):
string = message.text
if string is not None:
pass
data = {'question_raw': [string]}
response = requests.post(
url='https://7012.deeppavlov.ai/model', data=json.dumps(data)
)
if response.status_code == 200:
response = response.json()
answer = response[0][0]
accuracy = round(response[0][1], 2)
if not answer:
await message.answer(text='На этот вопрос я не могу дать ответ')
else:
await message.answer(text=f'Ответ: {answer}\nТочность: {accuracy}')
else:
await message.answer(f'Request error: status code is {response.status_code}')
await state.clear()

View File

@ -0,0 +1,20 @@
from random import randint
from aiogram import F, Router, types
from aiogram.filters import Command
router = Router()
@router.message(Command('rand'))
async def rand_handler(message: types.Message):
await message.answer(f'Держи свое случайное число: {randint(0, 100)}')
@router.message(F.text)
async def echo_handler(message: types.Message) -> None:
"""Эхо ответ"""
try:
await message.send_copy(chat_id=message.chat.id)
except TypeError:
await message.answer('Nice try!')

View File

@ -0,0 +1,13 @@
from aiogram import Bot, F, Router
from aiogram.types import FSInputFile, Message
router = Router()
@router.message(F.video)
async def greating(message: Message, bot: Bot):
await bot.download(message.video, destination='./video.mp4')
await bot.send_video_note(
chat_id=message.chat.id, video_note=FSInputFile('video.mp4')
)

View File

@ -0,0 +1,38 @@
from aiogram import F, Router
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import Message
from aiogram.utils.markdown import hbold
router = Router()
greatings = ['привет', 'добрый день', 'добрый вечер', 'доброе утро', 'здравствуйте']
class OrderReverse(StatesGroup):
string = State()
@router.message(Command('reverse'))
async def reverse_request(message: Message, state: FSMContext):
await state.set_state(OrderReverse.string)
await message.answer(
text='Введите строку для разворота',
)
@router.message(OrderReverse.string, F.text)
async def reversing(message: Message, state: FSMContext):
string = message.text
if string is not None:
string = string[::-1]
await message.answer(
text=f'Ваша строка наоборот:\n{string}',
)
await state.clear()
@router.message(F.text.func(lambda m: m.lower() in greatings))
async def greating(message: Message):
await message.answer(f'Здравствуй, {hbold(message.from_user.first_name)}')