init commit

This commit is contained in:
2025-11-12 20:57:36 +09:00
commit e0075d91b6
40 changed files with 8544 additions and 0 deletions

116
winner_display.py Normal file
View File

@@ -0,0 +1,116 @@
"""
Утилиты для отображения информации о победителях в зависимости от настроек розыгрыша
"""
from typing import Dict, Any, Optional
from models import User, Lottery
from account_utils import mask_account_number
def format_winner_display(user: User, lottery: Lottery, show_sensitive_data: bool = False) -> str:
"""
Форматирует отображение победителя в зависимости от настроек розыгрыша
Args:
user: Пользователь-победитель
lottery: Розыгрыш
show_sensitive_data: Показывать ли чувствительные данные (для админов)
Returns:
str: Отформатированная строка для отображения победителя
"""
display_type = getattr(lottery, 'winner_display_type', 'username')
if display_type == 'username':
# Отображаем username или имя
if user.username:
return f"@{user.username}"
else:
return user.first_name or f"Пользователь {user.id}"
elif display_type == 'chat_id':
# Отображаем Telegram ID
return f"ID: {user.telegram_id}"
elif display_type == 'account_number':
# Отображаем номер клиентского счета
if not user.account_number:
return "Счёт не указан"
if show_sensitive_data:
# Для админов показываем полный номер
return f"Счёт: {user.account_number}"
else:
# Для публичного показа маскируем номер
masked = mask_account_number(user.account_number, show_last_digits=4)
return f"Счёт: {masked}"
else:
# Fallback к username/имени
if user.username:
return f"@{user.username}"
else:
return user.first_name or f"Пользователь {user.id}"
def format_winner_info(winner_data: Dict[str, Any], show_sensitive_data: bool = False) -> str:
"""
Форматирует информацию о победителе из данных розыгрыша
Args:
winner_data: Словарь с данными о победителе
show_sensitive_data: Показывать ли чувствительные данные
Returns:
str: Отформатированная строка для отображения
"""
user = winner_data.get('user')
place = winner_data.get('place', 1)
prize = winner_data.get('prize', f'Приз {place} места')
if not user:
return f"{place}. Победитель не определен"
# Пробуем получить lottery из winner_data, если есть
lottery = winner_data.get('lottery')
if lottery:
winner_display = format_winner_display(user, lottery, show_sensitive_data)
else:
# Fallback если нет данных о розыгрыше
if user.username:
winner_display = f"@{user.username}"
else:
winner_display = user.first_name or f"Пользователь {user.id}"
return f"{place}. {winner_display}"
def get_display_type_name(display_type: str) -> str:
"""
Получить человекочитаемое название типа отображения
Args:
display_type: Тип отображения
Returns:
str: Название типа
"""
types = {
'username': 'Username/Имя',
'chat_id': 'Telegram ID',
'account_number': 'Номер счёта'
}
return types.get(display_type, 'Неизвестно')
def validate_display_type(display_type: str) -> bool:
"""
Проверяет корректность типа отображения
Args:
display_type: Тип отображения для проверки
Returns:
bool: True если тип корректен
"""
return display_type in ['username', 'chat_id', 'account_number']