New structure

This commit is contained in:
2025-04-21 13:50:51 +02:00
parent 1eba79cc5a
commit abe0cbb173
45 changed files with 10 additions and 50 deletions

View File

@@ -0,0 +1,12 @@
from enum import StrEnum
from pydantic import BaseModel
class OAuthProvider(StrEnum):
TWITCH = "twitch"
class OAuthData(BaseModel):
id: str
email: str | None

View File

@@ -0,0 +1,41 @@
from pydantic import BaseModel
class TwitchConfig(BaseModel):
id: int
name: str
class NotificationsConfig(BaseModel):
start_stream: str
change_category: str | None = None
redemption_reward: str | None = None
class GamesListConfig(BaseModel):
channel_id: int
message_id: int
class DiscordConfig(BaseModel):
guild_id: int
notifications_channel_id: int
games_list: GamesListConfig | None = None
roles: dict[str, int] | None = None
class TelegramConfig(BaseModel):
notifications_channel_id: int
class IntegrationsConfig(BaseModel):
discord: DiscordConfig | None = None
telegram: TelegramConfig | None = None
class StreamerConfig(BaseModel):
twitch: TwitchConfig
notifications: NotificationsConfig
integrations: IntegrationsConfig
chatbot_in_chats: list[int] | None = None

View File

@@ -0,0 +1,17 @@
from pydantic import BaseModel
from domain.auth import OAuthProvider, OAuthData
class User(BaseModel):
id: str
oauths: dict[OAuthProvider, OAuthData]
is_admin: bool
class CreateUser(BaseModel):
oauths: dict[OAuthProvider, OAuthData]
is_admin: bool = False

View File

@@ -0,0 +1,18 @@
import abc
from contextlib import asynccontextmanager
from core.mongo import mongo_manager
class BaseRepository(abc.ABC):
COLLECTION_NAME: str
@classmethod
@asynccontextmanager
async def connect(cls):
async with mongo_manager.connect() as client:
db = client.get_default_database()
collection = db[cls.COLLECTION_NAME]
yield collection

View File

@@ -0,0 +1,45 @@
from domain.streamers import StreamerConfig
from .base import BaseRepository
class StreamerConfigRepository(BaseRepository):
COLLECTION_NAME = "streamers"
@classmethod
async def get_by_twitch_id(cls, twitch_id: int) -> StreamerConfig:
async with cls.connect() as collection:
doc = await collection.find_one({"twitch.id": twitch_id})
if doc is None:
raise ValueError(f"Streamer with twitch id {twitch_id} not found")
return StreamerConfig(**doc)
@classmethod
async def find_one(
cls,
integration_discord_guild_id: int | None = None,
integration_discord_games_list_channel_id: int | None = None,
) -> StreamerConfig | None:
filters = {}
if integration_discord_guild_id is not None:
filters["integrations.discord.guild_id"] = integration_discord_guild_id
if integration_discord_games_list_channel_id is not None:
filters[
"integrations.discord.games_list.channel_id"
] = integration_discord_games_list_channel_id
async with cls.connect() as collection:
doc = await collection.find_one(filters)
if doc is None:
return None
return StreamerConfig(**doc)
@classmethod
async def all(cls) -> list[StreamerConfig]:
async with cls.connect() as collection:
cursor = await collection.find()
return [StreamerConfig(**doc) async for doc in cursor]

View File

@@ -0,0 +1,44 @@
from domain.users import CreateUser, User
from .base import BaseRepository
class UserRepository(BaseRepository):
COLLECTION_NAME = "users"
@classmethod
async def get(cls, user_id: str) -> User:
async with cls.connect() as collection:
user = await collection.find_one({"_id": user_id})
return User(
id=str(user["_id"]),
oauths=user["oauths"],
is_admin=user["is_admin"],
)
@classmethod
async def get_or_create_user(cls, new_user: CreateUser) -> User:
filter_data = {}
for provider, data in new_user.oauths.items():
filter_data[f"oauths.{provider}.id"] = data.id
async with cls.connect() as collection:
await collection.update_one(
filter_data,
{
"$setOnInsert": {
**new_user.model_dump(),
}
},
upsert=True,
)
user = await collection.find_one(filter_data)
return User(
id=str(user["_id"]),
oauths=user["oauths"],
is_admin=user["is_admin"],
)