# session_manager.py import time import logging import threading from datetime import datetime class SessionManager: """Класс для управления сессией голосового помощника""" def __init__(self, timeout_seconds=30): """ Инициализация менеджера сессий Args: timeout_seconds (int): Время таймаута сессии в секундах """ self.logger = logging.getLogger('VADApp') self.timeout_seconds = timeout_seconds self.session_active = False self.session_paused = False self.pause_start_time = None self.session_start_time = None self.session_end_time = None self.last_reset_time = None self.timer = None self.lock = threading.Lock() self.logger.info(f"SessionManager инициализирован с таймаутом {timeout_seconds} секунд") def start_session(self): """Начать новую сессию""" with self.lock: if self.session_active: self.logger.info("Сессия уже активна, сбрасываем таймер") self.last_reset_time = datetime.now() self._reset_timer() else: self.session_active = True self.session_start_time = datetime.now() self.last_reset_time = self.session_start_time self.session_end_time = None self._start_timer() self.logger.info(f"Сессия начата в {self.session_start_time}") def end_session(self): """Завершить текущую сессию""" with self.lock: if self.session_active: self.session_active = False self.session_paused = False self.pause_start_time = None self.session_end_time = datetime.now() if self.timer: self.timer.cancel() self.timer = None self.logger.info(f"Сессия завершена в {self.session_end_time}") return True return False def pause_session(self): """Поставить текущую сессию на паузу""" with self.lock: if self.session_active and not self.session_paused: self.session_paused = True self.pause_start_time = datetime.now() # Останавливаем таймер на время паузы if self.timer: self.timer.cancel() self.timer = None self.logger.info(f"Сессия поставлена на паузу в {self.pause_start_time}") return True return False def resume_session(self): """Возобновить сессию после паузы""" with self.lock: if self.session_active and self.session_paused: pause_duration = 0 if self.pause_start_time: # Вычисляем длительность паузы pause_duration = (datetime.now() - self.pause_start_time).total_seconds() # Обновляем время последнего сброса с учетом паузы if self.last_reset_time: self.last_reset_time = datetime.now() self.session_paused = False self.pause_start_time = None # Запускаем таймер заново self._start_timer() self.logger.info(f"Сессия возобновлена после паузы длительностью {pause_duration:.1f} секунд") return True return False def reset_timer(self): """Сбросить таймер сессии""" with self.lock: if self.session_active: self.last_reset_time = datetime.now() self._reset_timer() self.logger.info("Таймер сессии сброшен") return True return False def _start_timer(self): """Запустить таймер сессии""" if self.timer: self.timer.cancel() self.timer = None self.timer = threading.Timer(self.timeout_seconds, self._timeout_callback) self.timer.daemon = True self.timer.start() def _reset_timer(self): """Сбросить и перезапустить таймер сессии""" self._start_timer() def _timeout_callback(self): """Обработчик истечения таймера сессии""" with self.lock: if self.session_active: self.session_active = False self.session_end_time = datetime.now() self.logger.info(f"Сессия завершена по таймауту в {self.session_end_time}") def is_session_active(self): """Проверить, активна ли сессия""" with self.lock: return self.session_active def get_session_status(self): """Получить статус сессии""" with self.lock: if not self.session_active: return { "active": False, "paused": False, "time_left": 0, "start_time": self.session_start_time.isoformat() if self.session_start_time else None, "end_time": self.session_end_time.isoformat() if self.session_end_time else None } # Вычисляем оставшееся время # Используем время последнего сброса таймера, если оно есть reference_time = self.last_reset_time if self.last_reset_time else self.session_start_time # Если сессия на паузе, не вычисляем оставшееся время if self.session_paused: time_left = self.timeout_seconds if reference_time and self.pause_start_time: # Вычисляем время, прошедшее до паузы elapsed_before_pause = (self.pause_start_time - reference_time).total_seconds() time_left = max(0, self.timeout_seconds - elapsed_before_pause) else: if reference_time: elapsed = (datetime.now() - reference_time).total_seconds() time_left = max(0, self.timeout_seconds - elapsed) else: time_left = 0 return { "active": True, "paused": self.session_paused, "time_left": time_left, "start_time": self.session_start_time.isoformat() if self.session_start_time else None, "pause_time": self.pause_start_time.isoformat() if self.pause_start_time else None, "end_time": None }