Ryanhub - file viewer
filename: scripts/new_lead.py
branch: main
back to repo
#!/usr/bin/env python3
"""Create a lead markdown file with the next available ID."""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))

from common import (  # noqa: E402
    LEADS_DIR,
    LEAD_STATUSES,
    MATCH_VALUES,
    load_entities,
    next_id,
    normalize_name,
    run_sync_indexes,
    slugify,
    today_str,
    write_markdown,
    find_company_by_name,
    parse_frontmatter,
    REPO_ROOT,
    die,
)


def build_body(title: str, company: str) -> str:
    return "\n".join(
        [
            f"# {title} @ {company}",
            "",
            "# Summary",
            "",
            "# Why it fits",
            "",
            "# Concerns",
            "",
            "# Next action",
            "",
        ]
    )


def ensure_company(company_name: str) -> str:
    existing = find_company_by_name(company_name)
    if existing:
        _, meta, _ = existing
        return str(meta["id"])

    from new_company import main as new_company_main

    argv = [
        "new_company.py",
        "--name",
        company_name,
    ]
    old_argv = sys.argv
    try:
        sys.argv = argv
        new_company_main()
    finally:
        sys.argv = old_argv

    created = find_company_by_name(company_name)
    if not created:
        die(f"Failed to create company: {company_name}")
    _, meta, _ = created
    return str(meta["id"])


def add_lead_to_company(company_id: str, lead_id: str) -> None:
    for path in LEADS_DIR.parent.joinpath("companies").glob("*.md"):
        meta, body = parse_frontmatter(path)
        if meta.get("id") != company_id:
            continue
        leads = list(meta.get("leads") or [])
        if lead_id not in leads:
            leads.append(lead_id)
            meta["leads"] = leads
            meta["date_updated"] = today_str()
            write_markdown(path, meta, body)
        return


def duplicate_url(url: str) -> bool:
    for path in LEADS_DIR.glob("*.md"):
        if path.name.startswith("_"):
            continue
        meta, _ = parse_frontmatter(path)
        if str(meta.get("url", "")).strip() == url.strip():
            return True
    return False


def main() -> None:
    parser = argparse.ArgumentParser(description="Create a new lead file.")
    parser.add_argument("--title", required=True, help="Job title")
    parser.add_argument("--company", required=True, help="Company name")
    parser.add_argument("--url", required=True, help="Job posting URL")
    parser.add_argument("--source", required=True, help="Where the lead was found")
    parser.add_argument("--location", default="", help="Job location")
    parser.add_argument(
        "--remote",
        action="store_true",
        help="Mark role as remote",
    )
    parser.add_argument("--employment-type", default="", help="Employment type")
    parser.add_argument(
        "--status",
        default="found",
        choices=sorted(LEAD_STATUSES),
        help="Lead status",
    )
    parser.add_argument(
        "--match",
        default="moderate",
        choices=sorted(MATCH_VALUES),
        help="Fit match level",
    )
    parser.add_argument("--priority", type=int, default=3, help="Priority 1-5")
    args = parser.parse_args()

    if not (1 <= args.priority <= 5):
        die("priority must be between 1 and 5")

    url = args.url.strip()
    if duplicate_url(url):
        die(f"Duplicate lead URL: {url}")

    company_id = ensure_company(args.company)
    leads = load_entities(LEADS_DIR)
    lead_id = next_id("L", 4, leads)
    slug = slugify(f"{args.company}-{args.title}")
    path = LEADS_DIR / f"{lead_id}-{slug}.md"
    if path.exists():
        die(f"File already exists: {path}")

    today = today_str()
    meta = {
        "id": lead_id,
        "title": args.title,
        "company": args.company,
        "company_id": company_id,
        "url": url,
        "source": args.source,
        "location": args.location,
        "remote": args.remote,
        "employment_type": args.employment_type,
        "status": args.status,
        "match": args.match,
        "priority": args.priority,
        "date_found": today,
        "date_updated": today,
        "apply_by": "",
        "contacts": [],
        "outputs": {
            "resume": "",
            "cover_note": "",
            "outreach": "",
        },
        "notes": "",
    }
    write_markdown(path, meta, build_body(args.title, args.company))
    add_lead_to_company(company_id, lead_id)
    print(f"Created {path.relative_to(REPO_ROOT)}")
    run_sync_indexes()


if __name__ == "__main__":
    main()