DispelEvilBot/bot/services/users.py

90 lines
2.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Сервис пользователей."""
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),
)