Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,10 @@ LOG_LEVEL="INFO"
WEBHOOK_HOST="https://yourdomain.com"

SSL_ENABLED=True
SSL_KEY_PATH=''
SSL_CERT_PATH=''
SSL_KEY_PATH=""
SSL_CERT_PATH=""

# Параметры для Nextcloud
NC_URL="https://yourdomain"
NC_LOGIN=""
NC_PASSWORD=""
5 changes: 5 additions & 0 deletions config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ class Settings(BaseSettings):
# Настройки вебхука (опционально для продакшена)
WEBHOOK_HOST: Optional[str] = Field(None, description="Публичный URL для вебхука")

# Настройки NextCloud
NC_URL: Optional[str] = Field(None, description="Адрес Nextcloud")
NC_LOGIN: Optional[str] = Field(None, description="Логин Nextcloud")
NC_PASSWORD: Optional[str] = Field(None, description="Пароль Nextcloud")

# Настройки логирования
LOG_LEVEL: str = Field("INFO", description="Уровень логирования")

Expand Down
18 changes: 18 additions & 0 deletions handlers/bot_routes/nc_deck_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from aiogram import Router, types
from aiogram.filters import Command

from handlers.handler_logging import logger
from handlers.handler_nc_deck import get_decks_in_workspace
from models.model_board import ModelBoard

nc_deck_router = Router()


@nc_deck_router.message(Command("decks"))
async def get_decks(message: types.Message):
logger.info(f"Запрошен список карточек пользователем {message.from_user.id}")
decks_json = await get_decks_in_workspace()
decks = [ModelBoard.model_validate(deck) for deck in decks_json]
await message.answer(
f"Доступные списки: {', '.join([deck.title for deck in decks])}" # TODO: Дебаг
)
2 changes: 2 additions & 0 deletions handlers/handler_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from config.settings import settings
from handlers.bot_routes.base_routes import base_router
from handlers.bot_routes.nc_deck_routes import nc_deck_router
from handlers.handler_logging import logger

# Инициализация бота
Expand All @@ -13,6 +14,7 @@

# Регистрируем роутеры бота
dispatcher.include_router(base_router)
dispatcher.include_router(nc_deck_router)

logger.info("Бот инициализирован")

Expand Down
43 changes: 43 additions & 0 deletions handlers/handler_nc_deck.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import asyncio
from httpx import (
AsyncClient,
BasicAuth,
HTTPStatusError,
ConnectError,
ConnectTimeout,
ReadTimeout,
NetworkError,
)
from config.settings import settings
from handlers.handler_logging import logger


headers = {
"OCS-APIRequest": "true",
"accept": "application/json",
}

auth = BasicAuth(username=settings.NC_LOGIN, password=settings.NC_PASSWORD)

DECK_ENDPOINT = "/apps/deck/api/v1.0"


async def get_decks_in_workspace():
BOARD_ENDPOINT = f"{settings.NC_URL}{DECK_ENDPOINT}/boards"
async with AsyncClient(auth=auth, headers=headers) as client:
try:
response = await client.get(url=BOARD_ENDPOINT)
response.raise_for_status()
except HTTPStatusError as err:
logger.error(f"Ошибка статуса: {err}")
except ConnectError:
logger.error(
f"Не удалось установить соединение с сервером {settings.NC_URL}"
)
except ConnectTimeout:
logger.error(f"Таймаут от сервера {settings.NC_URL}")
except ReadTimeout:
logger.error(f"Таймаут при чтении ответа {settings.NC_URL}")
except NetworkError as err:
logger.error(f"Ошибка сети: {err}")
return response.json()
62 changes: 62 additions & 0 deletions models/model_board.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from pydantic import BaseModel
from typing import Dict, List, Optional, Union

# TODO: Референсные данные - удалить после тестов
# "title": "Board title",
# "owner": {
# "primaryKey": "admin",
# "uid": "admin",
# "displayname": "Administrator"
# },
# "color": "ff0000",
# "archived": false,
# "labels": [],
# "acl": [],
# "permissions": {
# "PERMISSION_READ": true,
# "PERMISSION_EDIT": true,
# "PERMISSION_MANAGE": true,
# "PERMISSION_SHARE": true
# },
# "users": [],
# "shared": 0,
# "deletedAt": 0,
# "id": 10,
# "lastModified": 1586269585,
# "settings": {
# "notify-due": "off",
# "calendar": true


class Owner(BaseModel):
primaryKey: str
uid: str
displayname: str


class Permissions(BaseModel):
PERMISSION_READ: bool
PERMISSION_EDIT: bool
PERMISSION_MANAGE: bool
PERMISSION_SHARE: bool


class Settings(BaseModel):
notify_due: str
calendar: bool


class ModelBoard(BaseModel):
title: str
owner: Owner
color: str
archived: bool
labels: List[str]
acl: List[Dict]
permissions: Permissions
users: List[Dict]
shared: int
deletedAt: int
id: int
lastModified: int
settings: Optional[Union[Settings, List]] = None
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
aiogram==3.22.0
fastapi==0.120.0
fastapi==0.120.1
httpx==0.28.1
loguru==0.7.3
pydantic==2.11.4
pydantic_settings==2.11.0
Expand Down
Loading