214 lines
6.9 KiB
Python
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()
|