drowzeys's picture
Upload folder using huggingface_hub
676f5d4 verified
Raw
History Blame Contribute Delete
3.89 kB
from __future__ import annotations
import argparse
import json
import shutil
import sys
from pathlib import Path
from app.camera import aim, snapshot
from app.config import load_settings
from app.db import get_receipt, list_line_items, list_receipts, open_db
from app.pipeline import process_file
from app.schemas import ProcessResult
def _print_result(result: ProcessResult) -> None:
payload = result.model_dump(mode="json")
json.dump(payload, sys.stdout, indent=2)
sys.stdout.write("\n")
def cmd_scan(args: argparse.Namespace) -> int:
settings = load_settings()
if getattr(args, "aim_down", False) and not args.image:
aim(settings, "down")
if args.image:
image = Path(args.image)
else:
image = snapshot(settings)
if args.inbox:
dest = settings.inbox_dir / image.name
shutil.copy2(image, dest)
image = dest
result = process_file(image, settings)
_print_result(result)
return 0 if result.status.value not in {"failed"} else 1
def cmd_query(args: argparse.Namespace) -> int:
settings = load_settings()
con = open_db(settings)
try:
rows = list_receipts(con, status=args.status, limit=args.limit)
out = []
for row in rows:
item = dict(row)
if args.category and item.get("category") != args.category:
continue
if args.vendor and (item.get("vendor") or "").lower().find(args.vendor.lower()) < 0:
continue
item["line_items"] = [dict(x) for x in list_line_items(con, int(row["id"]))]
out.append(item)
json.dump(out, sys.stdout, indent=2, default=str)
sys.stdout.write("\n")
finally:
con.close()
return 0
def cmd_show(args: argparse.Namespace) -> int:
settings = load_settings()
con = open_db(settings)
try:
row = get_receipt(con, args.id)
if row is None:
print(f"not found: {args.id}", file=sys.stderr)
return 1
payload = dict(row)
payload["line_items"] = [dict(x) for x in list_line_items(con, args.id)]
json.dump(payload, sys.stdout, indent=2, default=str)
sys.stdout.write("\n")
finally:
con.close()
return 0
def cmd_snapshot(_args: argparse.Namespace) -> int:
settings = load_settings()
path = snapshot(settings)
print(path)
return 0
def cmd_ui(_args: argparse.Namespace) -> int:
from app.ui import main
main()
return 0
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(prog="keys-scan")
sub = parser.add_subparsers(dest="cmd", required=True)
scan = sub.add_parser("scan", help="process one image (Lamp camera if omitted)")
scan.add_argument("--image", help="path to jpeg/png/pdf; omit to snapshot Lamp camera")
scan.add_argument("--inbox", action="store_true", help="copy into inbox/ first")
scan.add_argument("--aim-down", action="store_true", help="HAL servo down before snapshot")
scan.set_defaults(func=cmd_scan)
query = sub.add_parser("query", help="list stored receipts")
query.add_argument("--status")
query.add_argument("--category")
query.add_argument("--vendor")
query.add_argument("--limit", type=int, default=50)
query.set_defaults(func=cmd_query)
show = sub.add_parser("show", help="show one receipt")
show.add_argument("id", type=int)
show.set_defaults(func=cmd_show)
snap = sub.add_parser("snapshot", help="HAL camera snapshot only")
snap.set_defaults(func=cmd_snapshot)
ui = sub.add_parser("ui", help="Gradio review UI")
ui.set_defaults(func=cmd_ui)
return parser
def main(argv: list[str] | None = None) -> None:
parser = build_parser()
args = parser.parse_args(argv)
raise SystemExit(args.func(args))
if __name__ == "__main__":
main()