Changing logic

This commit is contained in:
Mikan
2026-03-12 19:41:29 +03:00
parent 1afa6f71ca
commit 0f8a86e536
2 changed files with 126 additions and 11 deletions

View File

@@ -38,6 +38,7 @@ class Application:
self._tracking_thread: Optional[threading.Thread] = None
self._running = True
self.session_start_time: Optional[float] = None
self.idle_start_time: Optional[float] = None
# Загружаем задачу
if self.config.current_task_id:
@@ -91,6 +92,7 @@ class Application:
with self._lock:
if not self.tracking_enabled or not self.current_task:
self.session_start_time = None
self.idle_start_time = None
return
current_time = time.time()
@@ -99,24 +101,106 @@ class Application:
is_blocked = self._is_group_blocked(group_name)
was_idle = self.is_idle
current_idle = (current_time - self.last_activity > self.config.idle_threshold_seconds) or is_blocked
if current_time - self.last_activity > 60 or is_blocked:
# === СЛУЧАЙ 1: Переход в бездействие ===
if not was_idle and current_idle:
self.is_idle = True
self.idle_start_time = current_time
self.last_window_group = None
self.session_start_time = None
else:
self.maybe_save_task()
return
# === СЛУЧАЙ 2: Выход из бездействия ===
if was_idle and not current_idle:
self.is_idle = False
idle_duration = current_time - self.idle_start_time if self.idle_start_time else 0
self.idle_start_time = None
# Решаем, создавать ли НОВУЮ сессию
create_new_session = False
reasons = []
# Причина 1: Длительное бездействие (>10 минут)
if idle_duration > self.config.new_session_after_idle_seconds:
create_new_session = True
reasons.append(f"бездействие {idle_duration / 60:.1f} мин")
# Причина 2: Смена календарного дня
if self.current_task.sessions:
last_session_date = self.current_task.sessions[-1].end_time.date()
current_date = datetime.now().date()
if last_session_date < current_date:
create_new_session = True
reasons.append(f"смена дня ({last_session_date}{current_date})")
# Причина 3: Первая сессия для задачи
if not self.current_task.sessions:
create_new_session = True
reasons.append("первая сессия задачи")
# Создаём новую сессию при необходимости
if create_new_session:
new_session = WorkSession(
start_time=datetime.now(),
end_time=datetime.now(),
details=[],
synchronized=False
)
self.current_task.sessions.append(new_session)
logger.info(
f"Новая сессия для {self.current_task.task_id}: "
f"{', '.join(reasons)}"
)
# Начинаем отслеживание
self.session_start_time = current_time
self.last_window_group = group_name
self._add_work_detail_to_session(group_name, 5.0)
return
# === СЛУЧАЙ 3: Продолжение активной работы ===
if not current_idle:
self.is_idle = False
if self.last_window_group != group_name:
self.last_window_group = group_name
self._add_work_detail(group_name, 5.0)
# Начинаем/продолжаем сессию
# Гарантируем наличие сессии (на случай редких состояний)
if not self.current_task.sessions:
self.current_task.sessions.append(WorkSession(
start_time=datetime.now(),
end_time=datetime.now(),
details=[],
synchronized=False
))
self._add_work_detail_to_session(group_name, 5.0)
if self.session_start_time is None:
self.session_start_time = current_time
return
# === СЛУЧАЙ 4: Продолжение бездействия ===
self.is_idle = True
def _add_work_detail_to_session(self, group_name: str, seconds: float):
"""Добавляет запись ТОЛЬКО в последнюю сессию (не создаёт новые)"""
if not self.current_task or not self.current_task.sessions:
logger.warning("Нет активной сессии для добавления времени")
return
session = self.current_task.sessions[-1]
# Объединяем записи одной группы
for detail in session.details:
if detail.group_name == group_name:
detail.duration_seconds += seconds
break
else:
session.details.append(WorkDetail(group_name=group_name, duration_seconds=seconds))
session.end_time = datetime.now()
# Сохраняем при переходе в бездействие
if not was_idle and self.is_idle:
self.maybe_save_task()
def _match_window_to_policy(self, window_info) -> str:
title = window_info.title.lower()
@@ -183,9 +267,17 @@ class Application:
self.config.tracking_enabled = self.tracking_enabled
self._save_config(self.config)
# Сохраняем при переходе в паузу
if was_enabled and not self.tracking_enabled:
# Переход в паузу → сохраняем и сбрасываем состояние
self.maybe_save_task()
self.is_idle = True
self.idle_start_time = time.time()
self.session_start_time = None
elif not was_enabled and self.tracking_enabled:
# Возобновление → сбрасываем состояние бездействия
self.is_idle = False
self.idle_start_time = None
self.session_start_time = time.time()
def create_task(self, task_id: str, project_id: Optional[str], estimated_minutes: Optional[float]):
with self._lock:
@@ -226,9 +318,30 @@ class Application:
with self._lock:
if not self.current_task:
return
seconds = abs(minutes) * 60
sign = 1 if minutes >= 0 else -1
self._add_work_detail("Manual", sign * seconds)
if minutes == 0:
return
# Создаём ОТДЕЛЬНУЮ сессию для ручного времени
new_session = WorkSession(
start_time=datetime.now(),
end_time=datetime.now(),
details=[WorkDetail(
group_name="Manual Adjustment",
duration_seconds=abs(minutes) * 60
)],
synchronized=False,
description=f"Manual: {minutes:+.1f} min"
)
self.current_task.sessions.append(new_session)
logger.info(f"Добавлена ручная сессия: {minutes:+.1f} мин для {self.current_task.task_id}")
# Сохраняем и синхронизируем
self.save_task(self.current_task)
try:
self.sync_with_youtrack()
except Exception as e:
logger.error(f"Ошибка синхронизации после ручного добавления: {e}")
def get_display_status(self) -> str:
with self._lock: