domovoy_bot/services/thanks.py
Admin ba4676b0af v1.0 MVP - Инициализация проекта 🏠
 Регистрация и верификация жильцов
 Рейтинг активности (уровни)
 Детект шпионов (Score 0-100)
 Анти-мат система (3 предупреждения → бан)
 Админ-панель с рассылкой
 Учёт квартир (несколько жильцов)
 Телефоны экстренных служб и мастеров
 Еженедельный экспорт JSON
 Прокси (socks5) для обхода РКН

Бекап: backups/versions/v1.0_mvp_2026-02-26/

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-02-27 10:54:16 +00:00

166 lines
5.4 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.

"""
Thanks Service — система благодарностей пользователей
"""
import logging
from datetime import datetime
from typing import Dict, List, Optional
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
logger = logging.getLogger(__name__)
class ThanksService:
"""Сервис благодарностей"""
def __init__(self, session: AsyncSession):
self.session = session
async def give_thank(self, from_user_id: int, to_user_id: int, message: str = None) -> bool:
"""
Отправить благодарность
Returns: True если успешно
"""
from database.models import Thank
# Нельзя поблагодарить самого себя
if from_user_id == to_user_id:
return False
# Создаём благодарность
thank = Thank(
from_user_id=from_user_id,
to_user_id=to_user_id,
message=message
)
self.session.add(thank)
await self.session.commit()
logger.info(f"Благодарность от {from_user_id} к {to_user_id}")
return True
async def get_user_thanks(self, user_id: int) -> Dict:
"""
Получить статистику благодарностей пользователя
Returns: dict со статистикой
"""
from database.models import Thank
# Полученные благодарности
stmt_received = (
select(func.count(Thank.id))
.where(Thank.to_user_id == user_id)
)
result = await self.session.execute(stmt_received)
received_count = result.scalar() or 0
# Отправленные благодарности
stmt_given = (
select(func.count(Thank.id))
.where(Thank.from_user_id == user_id)
)
result = await self.session.execute(stmt_given)
given_count = result.scalar() or 0
# Последние полученные
stmt_last = (
select(Thank)
.where(Thank.to_user_id == user_id)
.order_by(Thank.created_at.desc())
.limit(5)
)
result = await self.session.execute(stmt_last)
last_received = list(result.scalars().all())
return {
'received': received_count,
'given': given_count,
'last_received': [
{
'from': t.from_user_id,
'message': t.message,
'created_at': t.created_at.isoformat()
}
for t in last_received
]
}
async def get_leaderboard(self, limit: int = 10) -> List[Dict]:
"""
Получить топ пользователей по благодарностям
Returns: список пользователей с количеством благодарностей
"""
from database.models import Thank, User
stmt = (
select(
User.user_id,
User.full_name,
User.apartment,
func.count(Thank.id).label('thanks_count')
)
.join(Thank, User.user_id == Thank.to_user_id, isouter=True)
.group_by(User.user_id)
.order_by(func.count(Thank.id).desc())
.limit(limit)
)
result = await self.session.execute(stmt)
rows = list(result.all())
return [
{
'user_id': row.user_id,
'name': row.full_name or f'user{row.user_id}',
'apartment': row.apartment or '?',
'thanks': row.thanks_count
}
for row in rows
]
async def get_thanks_history(self, user_id: int, limit: int = 20) -> List[Dict]:
"""
Получить историю благодарностей пользователя
Returns: список благодарностей
"""
from database.models import Thank
stmt = (
select(Thank)
.where((Thank.from_user_id == user_id) | (Thank.to_user_id == user_id))
.order_by(Thank.created_at.desc())
.limit(limit)
)
result = await self.session.execute(stmt)
thanks = list(result.scalars().all())
return [
{
'from': t.from_user_id,
'to': t.to_user_id,
'message': t.message,
'created_at': t.created_at.isoformat(),
'is_received': t.to_user_id == user_id
}
for t in thanks
]
async def has_thanked_today(self, from_user_id: int, to_user_id: int) -> bool:
"""
Проверить, благодарил ли уже пользователь сегодня
Returns: True если уже благодарил
"""
from database.models import Thank
from datetime import timedelta
today = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0)
stmt = (
select(func.count(Thank.id))
.where(Thank.from_user_id == from_user_id)
.where(Thank.to_user_id == to_user_id)
.where(Thank.created_at >= today)
)
result = await self.session.execute(stmt)
count = result.scalar() or 0
return count > 0