"""Configuration and common utilities for daily summary.""" import os from datetime import datetime, timedelta, timezone from pathlib import Path from typing import Optional def get_vault_path(cli_vault: Optional[str] = None) -> Path: """Resolve the Obsidian vault path from CLI arg, env var, or default locations.""" if cli_vault: vault = Path(cli_vault).expanduser().resolve() if not vault.exists(): raise FileNotFoundError(f"Vault path does not exist: {vault}") return vault env_vault = os.environ.get("OBSIDIAN_VAULT") if env_vault: vault = Path(env_vault).expanduser().resolve() if vault.exists(): return vault obsidian_dir = Path.home() / "Obsidian" if obsidian_dir.exists(): vaults = [d for d in obsidian_dir.iterdir() if d.is_dir()] if len(vaults) == 1: return vaults[0] elif len(vaults) > 1: raise RuntimeError( f"Multiple vaults found in {obsidian_dir}. " "Set OBSIDIAN_VAULT or use --vault." ) raise RuntimeError( "Could not determine Obsidian vault path. " "Use --vault or set OBSIDIAN_VAULT environment variable." ) def get_daily_notes_folder(vault_path: Path) -> Path: """Return the daily notes folder, defaulting to 'Daily Notes'.""" folder = os.environ.get("OBSIDIAN_DAILY_FOLDER", "Daily Notes") return vault_path / folder def date_range(dt: datetime) -> tuple[int, int]: """Return Unix timestamp range for the given datetime's date (start, end).""" start = datetime(dt.year, dt.month, dt.day, tzinfo=dt.tzinfo or timezone.utc) end = start + timedelta(days=1) return int(start.timestamp()), int(end.timestamp()) def format_duration(seconds: int) -> str: """Format seconds as 'Xh Ym' or 'Ym'.""" if seconds < 60: return f"{seconds}s" hours, remainder = divmod(seconds, 3600) minutes = remainder // 60 if hours: return f"{hours}h {minutes}m" return f"{minutes}m"