91 lines
3.1 KiB
Python
91 lines
3.1 KiB
Python
from sqlalchemy import select
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.db.models import PomodoroCycle
|
|
|
|
PHASE_WORK = "work"
|
|
PHASE_SHORT_BREAK = "short_break"
|
|
PHASE_LONG_BREAK = "long_break"
|
|
|
|
|
|
class CycleManager:
|
|
def __init__(self, db: Session, user_id: int):
|
|
self.db = db
|
|
self.user_id = user_id
|
|
|
|
def get(self) -> PomodoroCycle:
|
|
cycle = self.db.scalar(select(PomodoroCycle).where(PomodoroCycle.user_id == self.user_id).limit(1))
|
|
if not cycle:
|
|
cycle = PomodoroCycle(user_id=self.user_id)
|
|
self.db.add(cycle)
|
|
self.db.commit()
|
|
self.db.refresh(cycle)
|
|
return cycle
|
|
|
|
def to_dict(self, cycle: PomodoroCycle | None = None) -> dict:
|
|
c = cycle or self.get()
|
|
return {
|
|
"completed_work_sessions": c.completed_work_sessions,
|
|
"sessions_until_long_break": c.sessions_until_long_break,
|
|
"task_note": c.task_note,
|
|
"work_duration_min": c.work_duration_min,
|
|
"short_break_min": c.short_break_min,
|
|
"long_break_min": c.long_break_min,
|
|
"auto_advance": c.auto_advance,
|
|
"chat_notify_seq": c.chat_notify_seq,
|
|
}
|
|
|
|
def reset(self, clear_task: bool = False) -> dict:
|
|
cycle = self.get()
|
|
cycle.completed_work_sessions = 0
|
|
if clear_task:
|
|
cycle.task_note = ""
|
|
self.db.commit()
|
|
self.db.refresh(cycle)
|
|
return self.to_dict(cycle)
|
|
|
|
def bump_notify_seq(self) -> int:
|
|
cycle = self.get()
|
|
cycle.chat_notify_seq += 1
|
|
self.db.commit()
|
|
self.db.refresh(cycle)
|
|
return cycle.chat_notify_seq
|
|
|
|
def on_work_completed(self) -> str:
|
|
"""Returns next phase: short_break or long_break."""
|
|
cycle = self.get()
|
|
cycle.completed_work_sessions += 1
|
|
if cycle.completed_work_sessions >= cycle.sessions_until_long_break:
|
|
next_phase = PHASE_LONG_BREAK
|
|
else:
|
|
next_phase = PHASE_SHORT_BREAK
|
|
self.db.commit()
|
|
return next_phase
|
|
|
|
def on_long_break_completed(self) -> None:
|
|
cycle = self.get()
|
|
cycle.completed_work_sessions = 0
|
|
self.db.commit()
|
|
|
|
def duration_for_phase(self, phase: str, cycle: PomodoroCycle | None = None) -> int:
|
|
c = cycle or self.get()
|
|
if phase == PHASE_WORK:
|
|
return c.work_duration_min
|
|
if phase == PHASE_SHORT_BREAK:
|
|
return c.short_break_min
|
|
if phase == PHASE_LONG_BREAK:
|
|
return c.long_break_min
|
|
return c.work_duration_min
|
|
|
|
def next_phase_after(self, completed_phase: str) -> str | None:
|
|
if completed_phase == PHASE_WORK:
|
|
cycle = self.get()
|
|
if cycle.completed_work_sessions >= cycle.sessions_until_long_break:
|
|
return PHASE_LONG_BREAK
|
|
return PHASE_SHORT_BREAK
|
|
if completed_phase == PHASE_SHORT_BREAK:
|
|
return PHASE_WORK
|
|
if completed_phase == PHASE_LONG_BREAK:
|
|
return None
|
|
return None
|