fix: исправлен парсинг счетов и добавлены уведомления победителям

Исправления:
1. Парсинг счетов (parse_accounts_from_message):
   - Исправлено дублирование счетов при формате 'КАРТА СЧЕТ'
   - Добавлены негативные lookbehind для корректного разбора
   - Теперь '2521 11-22-33-44-55-66-77' парсится только 1 раз

2. Уведомления победителям:
   - Создан новый модуль src/utils/notifications.py
   - Добавлена функция notify_winners_async()
   - Уведомления отправляются автоматически после розыгрыша
   - Поддержка счетов и обычных пользователей
   - Включает кнопки подтверждения для победителей по счетам
This commit is contained in:
2025-11-17 08:32:11 +09:00
parent 2d03c3e14c
commit 712577e694
4 changed files with 161 additions and 10 deletions

View File

@@ -113,9 +113,11 @@ def parse_accounts_from_message(text: str) -> List[str]:
return []
accounts = []
found_accounts_only = set() # Для отслеживания уже найденных счетов
# Паттерн 1: номер карты (4 цифры) + пробел + счет (7 пар цифр)
pattern_with_card = r'\b(\d{4})\s+(\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2})\b'
# Используем негативный lookbehind чтобы не ловить цифры перед картой
pattern_with_card = r'(?<!\d)(\d{4})\s+(\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2})(?!\d)'
matches_with_card = re.findall(pattern_with_card, text)
for card, account in matches_with_card:
@@ -124,19 +126,17 @@ def parse_accounts_from_message(text: str) -> List[str]:
full_account = f"{card} {formatted}"
if full_account not in accounts:
accounts.append(full_account)
found_accounts_only.add(formatted) # Запоминаем этот счет
# Паттерн 2: только счет (7 пар цифр) - для обратной совместимости
pattern_only_account = r'\b\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}\b'
# Паттерн 2: только счет (7 пар цифр) БЕЗ карты перед ним
# Негативный lookbehind для проверки что перед счетом нет "4 цифры + пробел"
pattern_only_account = r'(?<!\d{4}\s)(?<!\d)\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}(?!\d)'
matches_only = re.findall(pattern_only_account, text)
for match in matches_only:
# Проверяем, что этот счет еще не был добавлен как часть "карта + счет"
formatted = format_account_number(match)
if formatted:
# Проверяем, нет ли уже этого счета с картой
already_added = any(formatted in acc for acc in accounts)
if not already_added and formatted not in accounts:
accounts.append(formatted)
if formatted and formatted not in found_accounts_only and formatted not in accounts:
accounts.append(formatted)
return accounts