import time import html from datetime import datetime from typing import Optional from helper_bot.handlers.voice.exceptions import DatabaseError from logs.custom_logger import logger from helper_bot.utils.metrics import ( track_time, track_errors, db_query_time ) def format_time_ago(date_from_db: str) -> Optional[str]: """Форматировать время с момента последней записи""" try: if date_from_db is None: return None parse_date = datetime.strptime(date_from_db, "%Y-%m-%d %H:%M:%S") last_voice_time_timestamp = time.mktime(parse_date.timetuple()) time_now_timestamp = time.time() date_difference = time_now_timestamp - last_voice_time_timestamp # Считаем минуты, часы, дни much_minutes_ago = round(date_difference / 60, 0) much_hour_ago = round(date_difference / 3600, 0) much_days_ago = int(round(much_hour_ago / 24, 0)) message_with_date = '' if much_minutes_ago <= 60: word_minute = plural_time(1, much_minutes_ago) # Экранируем потенциально проблемные символы word_minute_escaped = html.escape(word_minute) message_with_date = f'Последнее сообщение было записано {word_minute_escaped} назад' elif much_minutes_ago > 60 and much_hour_ago <= 24: word_hour = plural_time(2, much_hour_ago) # Экранируем потенциально проблемные символы word_hour_escaped = html.escape(word_hour) message_with_date = f'Последнее сообщение было записано {word_hour_escaped} назад' elif much_hour_ago > 24: word_day = plural_time(3, much_days_ago) # Экранируем потенциально проблемные символы word_day_escaped = html.escape(word_day) message_with_date = f'Последнее сообщение было записано {word_day_escaped} назад' return message_with_date except Exception as e: logger.error(f"Ошибка при форматировании времени: {e}") return None def plural_time(type: int, n: float) -> str: """Форматировать множественное число для времени""" word = [] if type == 1: word = ['минуту', 'минуты', 'минут'] elif type == 2: word = ['час', 'часа', 'часов'] elif type == 3: word = ['день', 'дня', 'дней'] else: return str(int(n)) if n % 10 == 1 and n % 100 != 11: p = 0 elif 2 <= n % 10 <= 4 and (n % 100 < 10 or n % 100 >= 20): p = 1 else: p = 2 new_number = int(n) return str(new_number) + ' ' + word[p] @track_time("get_last_message_text", "voice_utils") @track_errors("voice_utils", "get_last_message_text") @db_query_time("get_last_message_text", "voice", "select") async def get_last_message_text(bot_db) -> Optional[str]: """Получить текст сообщения о времени последней записи""" try: date_from_db = await bot_db.last_date_audio() if date_from_db is None: return None # Преобразуем UNIX timestamp в строку для format_time_ago date_string = datetime.fromtimestamp(date_from_db).strftime("%Y-%m-%d %H:%M:%S") return format_time_ago(date_string) except Exception as e: logger.error(f"Не удалось получить дату последнего сообщения - {e}") return None async def validate_voice_message(message) -> bool: """Проверить валидность голосового сообщения""" return message.content_type == 'voice' @track_time("get_user_emoji_safe", "voice_utils") @track_errors("voice_utils", "get_user_emoji_safe") @db_query_time("get_user_emoji_safe", "voice", "select") async def get_user_emoji_safe(bot_db, user_id: int) -> str: """Безопасно получить эмодзи пользователя""" try: user_emoji = await bot_db.get_user_emoji(user_id) return user_emoji if user_emoji and user_emoji != "Смайл еще не определен" else "😊" except Exception as e: logger.error(f"Ошибка при получении эмодзи пользователя {user_id}: {e}") return "😊"