90 lines
2.9 KiB
Python
90 lines
2.9 KiB
Python
"""Сервис пользователей."""
|
||
|
||
from __future__ import annotations
|
||
|
||
from aiogram.types import ChatMemberUpdated, Message, User
|
||
|
||
from bot.services.economy import ACTION_USER_DELETED
|
||
from common.analytics import EventType, record
|
||
from common.models import NickEntry, UserInfo
|
||
from common.repositories import economy_repo, users_repo
|
||
|
||
|
||
def _user_fields(user: User) -> tuple[int, str, str, str]:
|
||
return (
|
||
int(user.id),
|
||
user.username or "",
|
||
user.first_name or "",
|
||
user.last_name or "",
|
||
)
|
||
|
||
|
||
async def register_from_message(message: Message) -> None:
|
||
"""Зарегистрировать/обновить автора сообщения."""
|
||
user = message.from_user
|
||
if user is None or user.is_bot:
|
||
return
|
||
await users_repo.add_user(*_user_fields(user))
|
||
|
||
|
||
async def register_from_event(event: ChatMemberUpdated) -> None:
|
||
"""Зарегистрировать/обновить участника, вошедшего в чат."""
|
||
user = event.new_chat_member.user
|
||
if user.is_bot:
|
||
return
|
||
await users_repo.add_user(*_user_fields(user))
|
||
record(
|
||
EventType.JOIN,
|
||
user_id=user.id,
|
||
username=user.username,
|
||
chat_id=event.chat.id,
|
||
payload={"chat_title": event.chat.title or ""},
|
||
)
|
||
|
||
|
||
async def set_nick(id_user: int, nick: str) -> None:
|
||
await users_repo.set_nick_with_history(id_user, nick, editor_id=id_user, source="user")
|
||
record(EventType.NICK_SET, user_id=id_user, payload={"nick": nick})
|
||
|
||
|
||
async def delete_user(id_user: int) -> None:
|
||
"""Удалить пользователя и зафиксировать обнуление баланса.
|
||
|
||
Баланс читается **до** удаления: ``bot.del_user_by_id`` обнуляет его записью
|
||
в журнал ``money``.
|
||
"""
|
||
balance = await economy_repo.get_money(id_user)
|
||
await users_repo.del_user_by_id(id_user)
|
||
if balance:
|
||
record(
|
||
EventType.MONEY_SPEND,
|
||
user_id=id_user,
|
||
payload={"amount": abs(balance), "reason": "user_deleted", "action_id": ACTION_USER_DELETED},
|
||
)
|
||
|
||
|
||
async def list_nicks() -> list[NickEntry]:
|
||
rows = await users_repo.get_nick_list()
|
||
return [NickEntry(username=row.get("username"), nick=row.get("nick")) for row in rows]
|
||
|
||
|
||
async def list_subscribers() -> list[dict]:
|
||
return await users_repo.get_nick_list_subscribe()
|
||
|
||
|
||
async def get_user_info(id_user: int) -> UserInfo | None:
|
||
row = await users_repo.get_info_by_id(id_user)
|
||
if not row:
|
||
return None
|
||
return UserInfo(
|
||
username=row.get("username"),
|
||
nick=row.get("nick"),
|
||
title=row.get("title"),
|
||
lvl=int(row.get("lvl") or 0),
|
||
exp=int(row.get("expr") or 0),
|
||
money=int(row.get("mny") or 0),
|
||
dt=row.get("dt") or "",
|
||
msg_count=int(row.get("msg_count") or 0),
|
||
eggs=int(row.get("eggs_count") or 0),
|
||
)
|