This commit is contained in:
2026-02-27 15:59:37 +03:00
commit a57a5278d6
29 changed files with 1084 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
def main() -> None:
print("Hello from dutylog!")
View File
+34
View File
@@ -0,0 +1,34 @@
import asyncio
import logging
from aiogram import Bot, Dispatcher
from aiogram.client.default import DefaultBotProperties
from aiogram.enums import ParseMode
from aiogram_dialog import setup_dialogs
from src.dutylog.application.bot.user_handlers import router as user_router
from src.dutylog.application.bot.user_dialogs import main_menu_dialog
from src.dutylog.infrastructure.utils.config import load_config
async def main():
logging.basicConfig(level=logging.INFO)
config = load_config()
bot = Bot(
token=config.bot_token,
default=DefaultBotProperties(parse_mode=ParseMode.HTML)
)
dp = Dispatcher()
dp.include_router(user_router)
dp.include_router(main_menu_dialog)
setup_dialogs(dp)
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,3 @@
from src.dutylog.application.bot.user_dialogs.main_menu_dialog import main_menu_dialog
__all__ = ["main_menu_dialog"]
@@ -0,0 +1,11 @@
from aiogram_dialog import Dialog, Window
from aiogram_dialog.widgets.text import Const
from src.dutylog.application.bot.user_dialogs.states import MainMenuSG
main_menu_dialog = Dialog(
Window(
Const("Главное меню"),
state=MainMenuSG.main,
),
)
@@ -0,0 +1,5 @@
from aiogram.fsm.state import State, StatesGroup
class MainMenuSG(StatesGroup):
main = State()
@@ -0,0 +1,13 @@
from aiogram import Router
from aiogram.filters import CommandStart
from aiogram.types import Message
from aiogram_dialog import DialogManager, StartMode
from src.dutylog.application.bot.user_dialogs.states import MainMenuSG
router = Router()
@router.message(CommandStart())
async def start_handler(message: Message, dialog_manager: DialogManager):
await dialog_manager.start(MainMenuSG.main, mode=StartMode.RESET_STACK)
View File
+7
View File
@@ -0,0 +1,7 @@
from dataclasses import dataclass
@dataclass
class User:
id: int
username: str | None
@@ -0,0 +1,9 @@
from sqlalchemy.ext.asyncio import AsyncEngine, async_sessionmaker, create_async_engine
def create_engine(database_url: str) -> AsyncEngine:
return create_async_engine(database_url, echo=False)
def create_session_maker(engine: AsyncEngine) -> async_sessionmaker:
return async_sessionmaker(engine, expire_on_commit=False)
@@ -0,0 +1,21 @@
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from src.dutylog.infrastructure.database.models.user import User
class UsersDAO:
def __init__(self, session: AsyncSession):
self.session = session
async def get_user(self, user_id: int) -> User | None:
result = await self.session.execute(
select(User).where(User.id == user_id)
)
return result.scalar_one_or_none()
async def create_user(self, user_id: int, username: str | None) -> User:
user = User(id=user_id, username=username)
self.session.add(user)
await self.session.commit()
return user
@@ -0,0 +1,5 @@
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
pass
@@ -0,0 +1,11 @@
from sqlalchemy import BigInteger, String
from sqlalchemy.orm import Mapped, mapped_column
from src.dutylog.infrastructure.database.models.base import Base
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
username: Mapped[str | None] = mapped_column(String(255), nullable=True)
@@ -0,0 +1,15 @@
from dataclasses import dataclass
from os import getenv
@dataclass
class Config:
bot_token: str
database_url: str
def load_config() -> Config:
return Config(
bot_token=getenv("BOT_TOKEN", ""),
database_url=getenv("DATABASE_URL", "sqlite+aiosqlite:///./db.sqlite3"),
)
+7
View File
@@ -0,0 +1,7 @@
from sqlalchemy.ext.asyncio import AsyncSession
from src.dutylog.infrastructure.database.dao.users_dao import UsersDAO
def get_users_dao(session: AsyncSession) -> UsersDAO:
return UsersDAO(session)