Add storage layer with FileStorage, MarkdownReader, and MarkdownWriter classes. Add data models (Project, Session, Note, Change).
68 lines
2.0 KiB
Python
68 lines
2.0 KiB
Python
"""Session service for active session management."""
|
|
|
|
import json
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
from ..models import Session
|
|
|
|
|
|
_ACTIVE_SESSION_FILE = ".active_session.json"
|
|
|
|
|
|
def get_active_session_path() -> Path:
|
|
"""Return the path to the active session file in projects/ directory."""
|
|
return Path("projects") / _ACTIVE_SESSION_FILE
|
|
|
|
|
|
def get_active_session() -> Optional[Session]:
|
|
"""Load and return the currently active session, or None if none exists."""
|
|
path = get_active_session_path()
|
|
if not path.exists():
|
|
return None
|
|
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
|
|
# Convert started_at string back to datetime
|
|
data["started_at"] = datetime.fromisoformat(data["started_at"])
|
|
if data.get("ended_at"):
|
|
data["ended_at"] = datetime.fromisoformat(data["ended_at"])
|
|
|
|
return Session(**data)
|
|
|
|
|
|
def set_active_session(session: Session) -> None:
|
|
"""Save the given session as the active session."""
|
|
path = get_active_session_path()
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
data = session.model_dump(mode="json")
|
|
# Serialize datetime objects to ISO format
|
|
data["started_at"] = session.started_at.isoformat()
|
|
if session.ended_at:
|
|
data["ended_at"] = session.ended_at.isoformat()
|
|
|
|
with open(path, "w", encoding="utf-8") as f:
|
|
json.dump(data, f, indent=2, ensure_ascii=False)
|
|
|
|
|
|
def clear_active_session() -> None:
|
|
"""Remove the active session file."""
|
|
path = get_active_session_path()
|
|
if path.exists():
|
|
path.unlink()
|
|
|
|
|
|
def validate_no_other_active_session(project_slug: str) -> bool:
|
|
"""
|
|
Check if there is an active session for a different project.
|
|
Returns True if no conflict exists (i.e., either no active session
|
|
or the active session belongs to the same project).
|
|
"""
|
|
active = get_active_session()
|
|
if active is None:
|
|
return True
|
|
return active.project_slug == project_slug
|