Добавлены новые методы для получения статистики постов пользователей, информации о последних постах и количестве банов. Обновлены запросы в репозиториях для сортировки пользователей по дате бана. Исправлены вызовы функций форматирования сообщений для администраторов. Обновлены тесты для проверки новых функциональностей.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
from typing import Optional
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from database.base import DatabaseConnection
|
||||
from database.models import BlacklistHistoryRecord
|
||||
@@ -120,3 +120,55 @@ class BlacklistHistoryRepository(DatabaseConnection):
|
||||
f"Ошибка обновления даты разбана в истории для user_id={user_id}: {str(e)}"
|
||||
)
|
||||
return False
|
||||
|
||||
async def get_ban_count(self, user_id: int) -> int:
|
||||
"""
|
||||
Получает количество банов пользователя за все время.
|
||||
|
||||
Args:
|
||||
user_id: ID пользователя
|
||||
|
||||
Returns:
|
||||
Количество банов
|
||||
"""
|
||||
query = "SELECT COUNT(*) FROM blacklist_history WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
count = row[0] if row else 0
|
||||
self.logger.info(f"Количество банов для user_id={user_id}: {count}")
|
||||
return count
|
||||
|
||||
async def get_last_ban_info(
|
||||
self, user_id: int
|
||||
) -> Optional[Tuple[int, str, Optional[int]]]:
|
||||
"""
|
||||
Получает информацию о последнем бане пользователя.
|
||||
|
||||
Args:
|
||||
user_id: ID пользователя
|
||||
|
||||
Returns:
|
||||
Tuple (date_ban, reason, date_unban) или None, если банов не было
|
||||
"""
|
||||
query = """
|
||||
SELECT date_ban, reason, date_unban FROM blacklist_history
|
||||
WHERE user_id = ?
|
||||
ORDER BY date_ban DESC
|
||||
LIMIT 1
|
||||
"""
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
if row:
|
||||
date_ban = row[0]
|
||||
reason = row[1]
|
||||
date_unban = row[2]
|
||||
self.logger.info(
|
||||
f"Последний бан для user_id={user_id}: "
|
||||
f"date_ban={date_ban}, reason={reason}, date_unban={date_unban}"
|
||||
)
|
||||
return (date_ban, reason, date_unban)
|
||||
|
||||
self.logger.info(f"Банов для user_id={user_id} не найдено")
|
||||
return None
|
||||
|
||||
@@ -87,13 +87,14 @@ class BlacklistRepository(DatabaseConnection):
|
||||
async def get_all_users(
|
||||
self, offset: int = 0, limit: int = 10
|
||||
) -> List[BlacklistUser]:
|
||||
"""Возвращает список пользователей в черном списке."""
|
||||
"""Возвращает список пользователей в черном списке, отсортированных по дате бана (новые первые)."""
|
||||
query = """
|
||||
SELECT user_id, message_for_user, date_to_unban, created_at, ban_author
|
||||
FROM blacklist
|
||||
LIMIT ?, ?
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ? OFFSET ?
|
||||
"""
|
||||
rows = await self._execute_query_with_result(query, (offset, limit))
|
||||
rows = await self._execute_query_with_result(query, (limit, offset))
|
||||
|
||||
users = []
|
||||
for row in rows:
|
||||
@@ -113,10 +114,11 @@ class BlacklistRepository(DatabaseConnection):
|
||||
return users
|
||||
|
||||
async def get_all_users_no_limit(self) -> List[BlacklistUser]:
|
||||
"""Возвращает список всех пользователей в черном списке без лимитов."""
|
||||
"""Возвращает список всех пользователей в черном списке без лимитов, отсортированных по дате бана (новые первые)."""
|
||||
query = """
|
||||
SELECT user_id, message_for_user, date_to_unban, created_at, ban_author
|
||||
FROM blacklist
|
||||
ORDER BY created_at DESC
|
||||
"""
|
||||
rows = await self._execute_query_with_result(query)
|
||||
|
||||
|
||||
@@ -545,3 +545,67 @@ class PostRepository(DatabaseConnection):
|
||||
texts = [row[0] for row in rows if row[0]]
|
||||
self.logger.info(f"Получено {len(texts)} отклоненных постов для обучения")
|
||||
return texts
|
||||
|
||||
async def get_user_posts_stats(self, user_id: int) -> Tuple[int, int, int]:
|
||||
"""
|
||||
Получает статистику постов пользователя.
|
||||
|
||||
Args:
|
||||
user_id: ID пользователя
|
||||
|
||||
Returns:
|
||||
Tuple (approved_count, declined_count, suggest_count)
|
||||
"""
|
||||
query = """
|
||||
SELECT
|
||||
SUM(CASE WHEN status = 'approved' THEN 1 ELSE 0 END) as approved,
|
||||
SUM(CASE WHEN status = 'declined' THEN 1 ELSE 0 END) as declined,
|
||||
SUM(CASE WHEN status = 'suggest' THEN 1 ELSE 0 END) as suggest
|
||||
FROM post_from_telegram_suggest
|
||||
WHERE author_id = ? AND text != '^'
|
||||
"""
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
if row:
|
||||
approved = row[0] or 0
|
||||
declined = row[1] or 0
|
||||
suggest = row[2] or 0
|
||||
self.logger.info(
|
||||
f"Статистика постов для user_id={user_id}: "
|
||||
f"approved={approved}, declined={declined}, suggest={suggest}"
|
||||
)
|
||||
return (approved, declined, suggest)
|
||||
|
||||
return (0, 0, 0)
|
||||
|
||||
async def get_last_post_by_author(self, user_id: int) -> Optional[str]:
|
||||
"""
|
||||
Получает текст последнего поста пользователя.
|
||||
|
||||
Args:
|
||||
user_id: ID пользователя
|
||||
|
||||
Returns:
|
||||
Текст последнего поста или None, если постов нет
|
||||
"""
|
||||
query = """
|
||||
SELECT text FROM post_from_telegram_suggest
|
||||
WHERE author_id = ? AND text IS NOT NULL AND text != '' AND text != '^'
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 1
|
||||
"""
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
if row:
|
||||
text = row[0]
|
||||
self.logger.info(
|
||||
f"Последний пост для user_id={user_id}: '{text[:50]}...'"
|
||||
if len(text) > 50
|
||||
else f"Последний пост для user_id={user_id}: '{text}'"
|
||||
)
|
||||
return text
|
||||
|
||||
self.logger.info(f"Постов для user_id={user_id} не найдено")
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user