mycopunk-swag/cli/mycopunk/cli.py

214 lines
6.9 KiB
Python

"""
Main CLI entry point for mycopunk.
"""
import typer
from rich.console import Console
from rich.table import Table
from typing import Optional
from pathlib import Path
from . import __version__
app = typer.Typer(
name="mycopunk",
help="🍄 CLI tool for managing mycopunk merchandise and POD fulfillment",
add_completion=True,
)
console = Console()
# Sub-command groups
design_app = typer.Typer(help="Design management commands")
product_app = typer.Typer(help="POD product commands")
mockup_app = typer.Typer(help="Mockup generation commands")
catalog_app = typer.Typer(help="Catalog management commands")
batch_app = typer.Typer(help="Batch operations")
app.add_typer(design_app, name="design")
app.add_typer(product_app, name="product")
app.add_typer(mockup_app, name="mockup")
app.add_typer(catalog_app, name="catalog")
app.add_typer(batch_app, name="batch")
def version_callback(value: bool) -> None:
if value:
console.print(f"mycopunk version {__version__}")
raise typer.Exit()
@app.callback()
def main(
version: Optional[bool] = typer.Option(
None, "--version", "-v", callback=version_callback, is_eager=True,
help="Show version and exit"
),
) -> None:
"""
🍄 Mycopunk CLI - Merchandise management and POD fulfillment.
Manage designs, generate exports, and push products to print-on-demand
services like Printful and Prodigi.
"""
pass
# ============================================
# Design Commands
# ============================================
@design_app.command("new")
def design_new(
path: str = typer.Argument(..., help="Design path (e.g., stickers/my-design)"),
template: str = typer.Option(
"sticker-3x3", "--template", "-t",
help="Template to use (sticker-3x3, tshirt-front, etc.)"
),
) -> None:
"""Create a new design scaffold with metadata template."""
from .design import create_design
create_design(path, template)
@design_app.command("list")
def design_list(
status: Optional[str] = typer.Option(None, "--status", "-s", help="Filter by status"),
design_type: Optional[str] = typer.Option(None, "--type", "-t", help="Filter by type"),
) -> None:
"""List all designs in the repository."""
from .design import list_designs
list_designs(status, design_type)
@design_app.command("export")
def design_export(
path: str = typer.Argument(..., help="Design path to export"),
dpi: int = typer.Option(300, "--dpi", help="Export resolution"),
format: str = typer.Option("png", "--format", "-f", help="Export format (png, jpg)"),
) -> None:
"""Export design to print-ready files."""
from .export import export_design
export_design(path, dpi, format)
@design_app.command("validate")
def design_validate(
path: str = typer.Argument(..., help="Design path to validate"),
strict: bool = typer.Option(False, "--strict", help="Fail on warnings"),
) -> None:
"""Validate design meets POD requirements."""
from .design import validate_design
validate_design(path, strict)
# ============================================
# Product Commands
# ============================================
@product_app.command("create")
def product_create(
path: str = typer.Argument(..., help="Design path"),
provider: str = typer.Option("prodigi", "--provider", "-p", help="POD provider"),
sandbox: bool = typer.Option(False, "--sandbox", help="Use sandbox/test mode"),
) -> None:
"""Create product on POD service from design."""
from .catalog import create_product
create_product(path, provider, sandbox)
@product_app.command("push")
def product_push(
path: str = typer.Argument(..., help="Design path"),
provider: Optional[str] = typer.Option(None, "--provider", "-p", help="POD provider"),
) -> None:
"""Push design updates to POD product."""
from .catalog import push_product
push_product(path, provider)
@product_app.command("list")
def product_list(
provider: Optional[str] = typer.Option(None, "--provider", "-p", help="Filter by provider"),
) -> None:
"""List all products by provider."""
from .catalog import list_products
list_products(provider)
# ============================================
# Mockup Commands
# ============================================
@mockup_app.command("generate")
def mockup_generate(
path: str = typer.Argument(..., help="Design path"),
all_variants: bool = typer.Option(False, "--all", help="Generate all variants"),
color: Optional[str] = typer.Option(None, "--color", "-c", help="Product color"),
size: Optional[str] = typer.Option(None, "--size", "-s", help="Product size"),
) -> None:
"""Generate product mockups for a design."""
console.print(f"[yellow]Generating mockups for {path}...[/yellow]")
console.print("[dim]Mockup generation requires POD API access.[/dim]")
# TODO: Implement mockup generation
console.print("[red]Not yet implemented[/red]")
# ============================================
# Catalog Commands
# ============================================
@catalog_app.command("sync")
def catalog_sync(
provider: str = typer.Option("all", "--provider", "-p", help="Provider to sync"),
) -> None:
"""Sync product catalog from POD services."""
console.print(f"[yellow]Syncing catalog from {provider}...[/yellow]")
# TODO: Implement catalog sync
console.print("[red]Not yet implemented[/red]")
# ============================================
# Batch Commands
# ============================================
@batch_app.command("export")
def batch_export(
design_type: Optional[str] = typer.Option(None, "--type", "-t", help="Filter by type"),
status: str = typer.Option("active", "--status", "-s", help="Filter by status"),
) -> None:
"""Export all designs matching criteria."""
console.print(f"[yellow]Batch exporting designs (type={design_type}, status={status})...[/yellow]")
# TODO: Implement batch export
console.print("[red]Not yet implemented[/red]")
@batch_app.command("push")
def batch_push(
status: str = typer.Option("active", "--status", "-s", help="Filter by status"),
provider: Optional[str] = typer.Option(None, "--provider", "-p", help="POD provider"),
) -> None:
"""Push all designs to POD services."""
console.print(f"[yellow]Batch pushing designs (status={status})...[/yellow]")
# TODO: Implement batch push
console.print("[red]Not yet implemented[/red]")
# ============================================
# Report Commands
# ============================================
@app.command("report")
def report(
report_type: str = typer.Argument("pricing", help="Report type (pricing, inventory, orders)"),
output: Optional[Path] = typer.Option(None, "--output", "-o", help="Output file"),
) -> None:
"""Generate reports (pricing, inventory, orders)."""
console.print(f"[yellow]Generating {report_type} report...[/yellow]")
# TODO: Implement reports
console.print("[red]Not yet implemented[/red]")
if __name__ == "__main__":
app()