import json import sys from rich.console import Console from rich.table import Table from rich import box console = Console() STATUS_COLORS = { "registered": "green", "filed": "yellow", "pending": "yellow", "expired": "red", "refused": "red", "withdrawn": "dim", } TYPE_ABBREV = { "WORD": "Word", "FIGURATIVE": "Fig.", "COMBINED": "Combined", "3D": "3D", "COLOUR": "Colour", "SOUND": "Sound", "OTHER": "Other", } def _status_markup(status): key = (status or "").lower() color = STATUS_COLORS.get(key, "white") return f"[{color}]{status or '—'}[/{color}]" def _truncate(text, width): text = text or "—" if len(text) > width: return text[: width - 1] + "…" return text def _format_fetched(iso: str) -> str: if not iso: return "—" # Compact: "2026-02-24 10:30 UTC" try: ts = iso.replace("T", " ").replace("Z", "") return f"[dim]{ts} UTC[/dim]" except Exception: return f"[dim]{iso}[/dim]" def print_table(result, query, verbose=False, image_path=None): trademarks = result["trademarks"] total = result["total"] page = result["page"] fetched_at = result.get("fetched_at", "") if image_path: from pathlib import Path header = f'Similar logos to "{Path(image_path).name}" — {total:,} result{"s" if total != 1 else ""} (page {page})' else: header = f'Trademark Search: "{query}" — {total:,} result{"s" if total != 1 else ""} (page {page})' console.print(f"\n[bold]{header}[/bold]\n") if not trademarks: console.print(f'[yellow]No trademarks found for "{query}"[/yellow]') return table = Table(box=box.ROUNDED, show_lines=False, highlight=False) table.add_column("Origin", width=12, no_wrap=True) table.add_column("Name", width=30) table.add_column("Status", width=14, no_wrap=True) table.add_column("Type", width=10, no_wrap=True) table.add_column("Owner", width=28) table.add_column("Classes", width=12, no_wrap=True) table.add_column("Applied", width=12, no_wrap=True) table.add_column("App #", width=14, no_wrap=True) if verbose: table.add_column("Fetched", width=20, no_wrap=True) fetched_cell = _format_fetched(fetched_at) for tm in trademarks: code = tm.get("office", "") name_label = tm.get("office_name", code) or code origin = f"[bold]{code}[/bold] {name_label}" if code else "—" tm_name = f"[cyan]{_truncate(tm.get('name'), 29)}[/cyan]" status = _status_markup(tm.get("status")) tm_type = TYPE_ABBREV.get((tm.get("type") or "").upper(), tm.get("type") or "—") owner = _truncate(tm.get("owner"), 27) classes_raw = tm.get("classes") or [] classes = ", ".join(str(c) for c in classes_raw) if classes_raw else "—" applied = tm.get("application_date") or "—" app_num = tm.get("application_number") or "—" row = [origin, tm_name, status, tm_type, owner, classes, applied, app_num] if verbose: row.append(fetched_cell) table.add_row(*row) console.print(table) def print_json(result): json.dump(result["trademarks"], sys.stdout, indent=2, default=str) sys.stdout.write("\n")