Add cmd line app
This commit is contained in:
parent
68ad80e435
commit
8306fb4c3e
@ -23,5 +23,7 @@ use `--input` and `--output` to specify input and output files respectively.
|
||||
|
||||
There's some handy test data in the `tests/data` directory. For example:
|
||||
```bash
|
||||
gzip -dc tests/data/fdb_list_compact.gz| qubed --from=fdblist
|
||||
gzip -dc tests/data/fdb_list_compact.gz| qubed convert --from=fdb --to=text --output=qube.txt
|
||||
gzip -dc tests/data/fdb_list_porcelain.gz| qubed convert --from=fdb --to=json --output=qube.json
|
||||
gzip -dc tests/data/fdb_list_compact.gz | qubed convert --from=fdb --to=html --output=qube.html
|
||||
```
|
||||
|
@ -18,6 +18,9 @@ requires-python = ">= 3.11"
|
||||
dynamic = ["version"]
|
||||
dependencies = [
|
||||
"frozendict",
|
||||
"rich",
|
||||
"numpy",
|
||||
"click",
|
||||
]
|
||||
|
||||
# Because this is a mixed rust/python project the structure is src/python/qubed rather than the more typical src/qubed
|
||||
|
@ -1,82 +1,114 @@
|
||||
import argparse
|
||||
import sys
|
||||
import time
|
||||
|
||||
import click
|
||||
import psutil
|
||||
from rich.console import Console
|
||||
from rich.layout import Layout
|
||||
from rich.live import Live
|
||||
from rich.panel import Panel
|
||||
from rich.spinner import Spinner
|
||||
from rich.text import Text
|
||||
|
||||
from qubed import Qube
|
||||
from qubed.convert import parse_fdb_list
|
||||
|
||||
console = Console(stderr=True)
|
||||
process = psutil.Process()
|
||||
|
||||
PRINT_INTERVAL = 0.25
|
||||
|
||||
|
||||
@click.group()
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate a compressed tree from various inputs."
|
||||
)
|
||||
|
||||
subparsers = parser.add_subparsers(title="subcommands", required=True)
|
||||
parser_convert = subparsers.add_parser(
|
||||
"convert", help="Convert trees from one format to another."
|
||||
)
|
||||
# parser_another = subparsers.add_parser(
|
||||
# "another_subcommand", help="Does something else"
|
||||
# )
|
||||
|
||||
parser_convert.add_argument(
|
||||
"--input",
|
||||
type=argparse.FileType("r"),
|
||||
default=sys.stdin,
|
||||
help="Specify the input file (default: standard input).",
|
||||
)
|
||||
parser_convert.add_argument(
|
||||
"--output",
|
||||
type=argparse.FileType("w"),
|
||||
default=sys.stdout,
|
||||
help="Specify the output file (default: standard output).",
|
||||
)
|
||||
|
||||
parser_convert.add_argument(
|
||||
"--input_format",
|
||||
choices=["fdb", "mars"],
|
||||
default="fdb",
|
||||
help="""Specify the input format:
|
||||
fdb: the output of fdb list --porcelain
|
||||
mars: the output of mars list
|
||||
""",
|
||||
)
|
||||
|
||||
parser_convert.add_argument(
|
||||
"--output_format",
|
||||
choices=["text", "html"],
|
||||
default="text",
|
||||
help="Specify the output format (text or html).",
|
||||
)
|
||||
parser_convert.set_defaults(func=convert)
|
||||
|
||||
args = parser.parse_args()
|
||||
args.func(args)
|
||||
"""Command-line tool for working with trees."""
|
||||
pass
|
||||
|
||||
|
||||
def convert(args):
|
||||
@main.command()
|
||||
@click.option(
|
||||
"--input",
|
||||
type=click.File("r"),
|
||||
default="-",
|
||||
help="Specify the input file (default: standard input).",
|
||||
)
|
||||
@click.option(
|
||||
"--output",
|
||||
type=click.File("w"),
|
||||
default="-",
|
||||
help="Specify the output file (default: standard output).",
|
||||
)
|
||||
@click.option(
|
||||
"--from",
|
||||
"from_format",
|
||||
type=click.Choice(["fdb", "mars"]),
|
||||
default="fdb",
|
||||
help="Specify the input format: fdb (fdb list --porcelain) or mars (mars list).",
|
||||
)
|
||||
@click.option(
|
||||
"--to",
|
||||
"to_format",
|
||||
type=click.Choice(["text", "html", "json"]),
|
||||
default="text",
|
||||
help="Specify the output format: text, html, json.",
|
||||
)
|
||||
def convert(input, output, from_format, to_format):
|
||||
"""Convert trees from one format to another."""
|
||||
q = Qube.empty()
|
||||
for datacube in parse_fdb_list(args.input):
|
||||
new_branch = Qube.from_datacube(datacube)
|
||||
q = q | Qube.from_datacube(datacube)
|
||||
t = time.time()
|
||||
i0 = 0
|
||||
n0 = 0
|
||||
depth = 5
|
||||
log = Text()
|
||||
summary = Layout()
|
||||
summary.split_column(
|
||||
Layout(name="upper"),
|
||||
Layout(name="qube"),
|
||||
)
|
||||
summary["upper"].split_row(
|
||||
Layout(name="performance"),
|
||||
Layout(log, name="log"),
|
||||
)
|
||||
spinner = Spinner("aesthetic", text="Performance", speed=0.3)
|
||||
|
||||
# output = match args.output_format:
|
||||
# case "text":
|
||||
# str(q)
|
||||
# case "html":
|
||||
# q.html()
|
||||
output = "fw"
|
||||
with Live(summary, auto_refresh=False, transient=True, console=console) as live:
|
||||
for i, datacube in enumerate(parse_fdb_list(input)):
|
||||
new_branch = Qube.from_datacube(datacube)
|
||||
q = q | new_branch
|
||||
|
||||
with open(args.output, "w") as f:
|
||||
f.write(output)
|
||||
if time.time() - t > PRINT_INTERVAL:
|
||||
tree = q.__str__(depth=depth)
|
||||
if tree.count("\n") > 20:
|
||||
depth -= 1
|
||||
if tree.count("\n") < 5:
|
||||
depth += 1
|
||||
|
||||
console.print([1, 2, 3])
|
||||
console.print("[blue underline]Looks like a link")
|
||||
console.print(locals())
|
||||
console.print("FOO", style="white on blue")
|
||||
summary["performance"].update(
|
||||
Panel(
|
||||
Text.assemble(
|
||||
f"The Qube has {q.n_leaves} leaves and {q.n_nodes} internal nodes so far.\n",
|
||||
f"{(i - i0) / (time.time() - t) / PRINT_INTERVAL:.0f} lines per second. ",
|
||||
f"{(q.n_leaves - n0) / (time.time() - t):.0f} leaves per second.\n",
|
||||
f"Memory usage: {process.memory_info().rss / 1024 / 1024:.0f} MB\n",
|
||||
),
|
||||
title=spinner.render(time.time()),
|
||||
border_style="blue",
|
||||
)
|
||||
)
|
||||
summary["qube"].update(
|
||||
Panel(tree, title=f"Qube (depth {depth})", border_style="blue")
|
||||
)
|
||||
summary["log"].update(
|
||||
Panel(
|
||||
f"{datacube}", border_style="blue", title="Last Datacube Added"
|
||||
)
|
||||
)
|
||||
live.refresh()
|
||||
i0 = i
|
||||
n0 = q.n_leaves
|
||||
t = time.time()
|
||||
|
||||
output_content = str(q) if to_format == "text" else q.html().html
|
||||
output.write(output_content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Loading…
x
Reference in New Issue
Block a user