"""Filename generation with collision avoidance. Pattern: YYYY-MM-DD-slugified-title.md Slug: lowercase alphanumeric + hyphens only. Appends numeric suffix (-2, -3, ...) if file already exists. """ import logging from datetime import datetime, timezone from pathlib import Path from slugify import slugify logger = logging.getLogger(__name__) def generate_filename(title: str, date: str | None = None) -> str: """Generate a filename from title and optional date. Args: title: The note title to slugify. date: Optional date string (YYYY-MM-DD). Uses today if not provided. Returns: Filename in format YYYY-MM-DD-slugified-title.md """ if date is None: date = datetime.now(timezone.utc).strftime("%Y-%m-%d") # Ensure date is just the date portion (handle ISO datetime strings) date_part = date[:10] if len(date) >= 10 else date slug = slugify(title, max_length=80) if not slug: slug = "untitled" return f"{date_part}-{slug}.md" def resolve_collision(target_dir: Path, filename: str) -> Path: """Resolve filename collisions by appending numeric suffix. Args: target_dir: Directory where the file will be written. filename: Desired filename (e.g., 2024-03-15-meeting-notes.md). Returns: Full path with unique filename (appends -2, -3, etc. if needed). """ target = Path(target_dir) / filename if not target.exists(): return target # Split filename to insert suffix before .md stem = filename.rsplit(".md", 1)[0] suffix_num = 2 while True: new_filename = f"{stem}-{suffix_num}.md" new_target = Path(target_dir) / new_filename if not new_target.exists(): logger.debug("Collision resolved: %s → %s", filename, new_filename) return new_target suffix_num += 1