Skip to content

Commit

Permalink
Add chat repo
Browse files Browse the repository at this point in the history
  • Loading branch information
Lamroy95 committed Nov 14, 2023
1 parent 9fce1d8 commit 19e280d
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 2 deletions.
Empty file.
94 changes: 94 additions & 0 deletions app/infrastructure/database/repo/chat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from collections import namedtuple

from tortoise import BaseDBAsyncClient
from tortoise.exceptions import DoesNotExist

from app.infrastructure.database.models import UserKarma
from app.infrastructure.database.models.chat import Chat
from app.infrastructure.database.models.user import User
from app.models.db.db import karma_filters
from app.utils.exceptions import NotHaveNeighbours

TopResultEntry = namedtuple("TopResult", ("user", "karma"))
Neighbours = namedtuple("Neighbours", ("prev_id", "next_id"))


class ChatRepo:
def __init__(self, session: BaseDBAsyncClient | None = None):
self.session = session

async def create_from_tg_chat(self, chat) -> Chat:
chat = await Chat.create(
chat_id=chat.id,
type_=chat.type,
title=chat.title,
username=chat.username,
using_db=self.session,
)
return chat

async def get_or_create_from_tg_chat(self, chat) -> Chat:
try:
chat = await Chat.get(chat_id=chat.id)
except DoesNotExist:
chat = await self.create_from_tg_chat(chat=chat)
return chat

async def get_top_karma_list(
self, chat: Chat, limit: int = 15
) -> list[TopResultEntry]:
await chat.fetch_related("user_karma", using_db=self.session)
users_karmas = (
await chat.user_karma.order_by(*karma_filters)
.limit(limit)
.prefetch_related("user")
.all()
)
rez = []
for user_karma in users_karmas:
user = user_karma.user
karma = user_karma.karma_round
rez.append(TopResultEntry(user, karma))

return rez

async def get_neighbours(
self, user: User, chat: Chat
) -> tuple[UserKarma, UserKarma, UserKarma]:
prev_id, next_id = await self.get_neighbours_id(chat.chat_id, user.id)
uk = (
await chat.user_karma.filter(user_id__in=(prev_id, next_id))
.prefetch_related("user")
.order_by(*karma_filters)
.all()
)

user_uk = (
await chat.user_karma.filter(user=user).prefetch_related("user").first()
)
return uk[0], user_uk, uk[1]

async def get_neighbours_id(self, chat_id, user_id) -> Neighbours:
neighbours = await self.session.execute_query(
query="""
SELECT prev_user_id, next_user_id
FROM (
SELECT
user_id,
LAG(user_id) OVER(ORDER BY karma) prev_user_id,
LEAD(user_id) OVER(ORDER BY karma) next_user_id
FROM user_karma
WHERE chat_id = ?
)
WHERE user_id = ?""",
values=[chat_id, user_id],
)
try:
rez = dict(neighbours[1][0])
except IndexError:
raise NotHaveNeighbours
try:
rez = int(rez["prev_user_id"]), int(rez["next_user_id"])
except TypeError:
raise NotHaveNeighbours
return rez
9 changes: 7 additions & 2 deletions app/middlewares/db_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
from aiogram.dispatcher.event.bases import CancelHandler
from aiogram.types import TelegramObject

from app.infrastructure.database.models import Chat, User
from app.infrastructure.database.models import User
from app.infrastructure.database.repo.chat import ChatRepo
from app.services.settings import get_chat_settings
from app.utils.lock_factory import LockFactory
from app.utils.log import Logger
Expand Down Expand Up @@ -36,15 +37,19 @@ async def setup_chat(
self, data: dict, user: types.User, chat: Optional[types.Chat] = None
):
try:
chat_repo = ChatRepo()

async with self.lock_factory.get_lock(user.id):
user = await User.get_or_create_from_tg_user(user)

if chat and chat.type != "private":
async with self.lock_factory.get_lock(chat.id):
chat = await Chat.get_or_create_from_tg_chat(chat)
chat = await chat_repo.get_or_create_from_tg_chat(chat)
data["chat_settings"] = await get_chat_settings(chat=chat)

except Exception as e:
logger.exception("troubles with db", exc_info=e)
raise e
data["user"] = user
data["chat"] = chat
data["chat_repo"] = chat_repo

0 comments on commit 19e280d

Please sign in to comment.