- Added `ca-certificates` installation to Dockerfile for improved network security. - Updated health check command in Dockerfile to include better timeout handling. - Refactored `run_helper.py` to implement proper signal handling and logging during shutdown. - Transitioned database operations to an asynchronous model in `async_db.py`, improving performance and responsiveness. - Updated database schema to support new foreign key relationships and optimized indexing for better query performance. - Enhanced various bot handlers to utilize async database methods, improving overall efficiency and user experience. - Removed obsolete database and fix scripts to streamline the project structure.
100 lines
4.2 KiB
Python
100 lines
4.2 KiB
Python
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
|
||
|
||
|
||
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'<b>Последнее сообщение было записано {word_minute_escaped} назад</b>'
|
||
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'<b>Последнее сообщение было записано {word_hour_escaped} назад</b>'
|
||
elif much_hour_ago > 24:
|
||
word_day = plural_time(3, much_days_ago)
|
||
# Экранируем потенциально проблемные символы
|
||
word_day_escaped = html.escape(word_day)
|
||
message_with_date = f'<b>Последнее сообщение было записано {word_day_escaped} назад</b>'
|
||
|
||
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]
|
||
|
||
|
||
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'
|
||
|
||
|
||
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 "😊"
|