""" Catalog and product management for POD services. """ from pathlib import Path from typing import Optional import yaml from rich.console import Console from rich.table import Table console = Console() def get_project_root() -> Path: """Find the project root.""" current = Path.cwd() while current != current.parent: if (current / "designs").is_dir(): return current current = current.parent return Path.cwd() DESIGNS_DIR = get_project_root() / "designs" CONFIG_DIR = get_project_root() / "config" def create_product(path: str, provider: str, sandbox: bool = False) -> None: """Create a product on a POD service.""" design_dir = DESIGNS_DIR / path if not design_dir.exists(): console.print(f"[red]Error: Design not found at {design_dir}[/red]") raise SystemExit(1) metadata_path = design_dir / "metadata.yaml" if not metadata_path.exists(): console.print("[red]Error: metadata.yaml not found[/red]") raise SystemExit(1) with open(metadata_path) as f: metadata = yaml.safe_load(f) products = metadata.get("products", []) matching_products = [p for p in products if p.get("provider") == provider] if not matching_products: console.print(f"[yellow]No products configured for provider '{provider}'[/yellow]") console.print("Add products to metadata.yaml first.") raise SystemExit(1) mode = "SANDBOX" if sandbox else "PRODUCTION" console.print(f"\n[bold]Creating products on {provider} ({mode})[/bold]\n") for product in matching_products: product_type = product.get("type", "unknown") sku = product.get("sku", "N/A") price = product.get("retail_price", 0) console.print(f" Product: {product_type}") console.print(f" SKU: {sku}") console.print(f" Price: ${price:.2f}") if provider == "printful": _create_printful_product(design_dir, metadata, product, sandbox) elif provider == "prodigi": _create_prodigi_product(design_dir, metadata, product, sandbox) else: console.print(f"[red] Unknown provider: {provider}[/red]") console.print() def _create_printful_product( design_dir: Path, metadata: dict, product: dict, sandbox: bool ) -> None: """Create product on Printful.""" console.print("[yellow] → Printful API integration not yet implemented[/yellow]") console.print("[dim] Would create product with Printful API[/dim]") # TODO: Implement Printful API call # 1. Upload design file to Printful # 2. Create sync product # 3. Add sync variants # 4. Store Printful product ID in metadata def _create_prodigi_product( design_dir: Path, metadata: dict, product: dict, sandbox: bool ) -> None: """Create product on Prodigi.""" console.print("[yellow] → Prodigi API integration not yet implemented[/yellow]") console.print("[dim] Would create product with Prodigi API[/dim]") # TODO: Implement Prodigi API call # 1. Upload design file to Prodigi # 2. Create product template # 3. Store Prodigi template ID in metadata def push_product(path: str, provider: Optional[str] = None) -> None: """Push design updates to POD product.""" design_dir = DESIGNS_DIR / path if not design_dir.exists(): console.print(f"[red]Error: Design not found at {design_dir}[/red]") raise SystemExit(1) metadata_path = design_dir / "metadata.yaml" if not metadata_path.exists(): console.print("[red]Error: metadata.yaml not found[/red]") raise SystemExit(1) with open(metadata_path) as f: metadata = yaml.safe_load(f) products = metadata.get("products", []) if provider: products = [p for p in products if p.get("provider") == provider] if not products: console.print("[yellow]No products to push[/yellow]") raise SystemExit(1) console.print(f"\n[bold]Pushing updates for: {metadata.get('name', path)}[/bold]\n") for product in products: prod_provider = product.get("provider", "unknown") product_type = product.get("type", "unknown") console.print(f" Pushing {product_type} to {prod_provider}...") console.print("[yellow] → API integration not yet implemented[/yellow]") # TODO: Implement push logic # 1. Check if product exists on provider # 2. Upload updated design file # 3. Sync any metadata changes def list_products(provider: Optional[str] = None) -> None: """List all products across designs.""" table = Table(title="🍄 Mycopunk Products") table.add_column("Design", style="cyan") table.add_column("Type", style="green") table.add_column("Provider", style="yellow") table.add_column("SKU", style="blue") table.add_column("Price", style="magenta", justify="right") table.add_column("Status", style="dim") products_found = 0 for category_dir in DESIGNS_DIR.iterdir(): if not category_dir.is_dir(): continue for design_dir in category_dir.iterdir(): if not design_dir.is_dir(): continue metadata_path = design_dir / "metadata.yaml" if not metadata_path.exists(): continue try: with open(metadata_path) as f: metadata = yaml.safe_load(f) except Exception: continue design_path = f"{category_dir.name}/{design_dir.name}" design_status = metadata.get("status", "unknown") products = metadata.get("products", []) for product in products: prod_provider = product.get("provider", "unknown") if provider and prod_provider != provider: continue products_found += 1 table.add_row( design_path, product.get("type", "unknown"), prod_provider, product.get("sku", "N/A"), f"${product.get('retail_price', 0):.2f}", design_status, ) if products_found == 0: console.print("[yellow]No products found.[/yellow]") else: console.print(table) console.print(f"\n[dim]Total: {products_found} product(s)[/dim]")