File size: 2,794 Bytes
e197abb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import argparse
import json
import logging
import sys
from typing import Any, Optional

logger = logging.getLogger(__name__)


def _json(data: Any) -> None:
    print(json.dumps(data, indent=2, default=str))


def _table(rows: list[dict], cols: Optional[list[str]] = None) -> None:
    if not rows:
        print("(empty)")
        return
    cols = cols or list(rows[0].keys())
    widths = {c: max(len(c), max(len(str(r.get(c, ""))) for r in rows))
              for c in cols}
    sep = "  "
    print(sep.join(c.ljust(widths[c]) for c in cols))
    print("-" * (sum(widths.values()) + len(sep) * (len(cols) - 1)))
    for row in rows:
        print(sep.join(str(row.get(c, "")).ljust(widths[c]) for c in cols))


def cmd_list(args: argparse.Namespace) -> int:
    logger.debug("list: %s", vars(args))
    print(f"Listing (page={args.page} size={args.size})")
    return 0


def cmd_add(args: argparse.Namespace) -> int:
    logger.debug("add: name=%s", args.name)
    print(f"Added: {args.name!r}")
    return 0


def cmd_delete(args: argparse.Namespace) -> int:
    logger.debug("delete: id=%s", args.id)
    print(f"Deleted: {args.id}")
    return 0


def cmd_show(args: argparse.Namespace) -> int:
    logger.debug("show: id=%s", args.id)
    print(f"Record: {args.id}")
    return 0


def cmd_export(args: argparse.Namespace) -> int:
    logger.debug("export: fmt=%s", args.format)
    print(f"Exported as {args.format}")
    return 0


def build_parser() -> argparse.ArgumentParser:
    p = argparse.ArgumentParser(prog="app",
                                formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    p.add_argument("--json", dest="as_json", action="store_true")
    sub = p.add_subparsers(dest="cmd", required=True)

    ls = sub.add_parser("list")
    ls.add_argument("--page", type=int, default=1)
    ls.add_argument("--size", type=int, default=20)
    ls.set_defaults(func=cmd_list)

    add = sub.add_parser("add")
    add.add_argument("name")
    add.add_argument("--tag", action="append", dest="tags", default=[])
    add.set_defaults(func=cmd_add)

    rm = sub.add_parser("delete")
    rm.add_argument("id")
    rm.add_argument("-y", "--yes", action="store_true")
    rm.set_defaults(func=cmd_delete)

    show = sub.add_parser("show")
    show.add_argument("id")
    show.set_defaults(func=cmd_show)

    exp = sub.add_parser("export")
    exp.add_argument("--format", choices=["csv", "json", "text"], default="text")
    exp.add_argument("--output", "-o", default="-")
    exp.set_defaults(func=cmd_export)

    return p


def run_cli() -> int:
    args = build_parser().parse_args()
    try:
        return args.func(args)
    except Exception as exc:
        logger.error("%s", exc)
        return 1


if __name__ == "__main__":
    sys.exit(run_cli())