fablazing-cli 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/PKG-INFO +1 -1
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/pyproject.toml +1 -1
- fablazing_cli-0.1.1/src/fablazing_cli/__init__.py +1 -0
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/commands/hero.py +2 -2
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/commands/matchup.py +2 -2
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/config.py +1 -1
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/main.py +26 -1
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/resolve.py +17 -0
- fablazing_cli-0.1.0/src/fablazing_cli/__init__.py +0 -1
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/.gitignore +0 -0
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/README.md +0 -0
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/client.py +0 -0
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/commands/__init__.py +0 -0
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/commands/auth.py +0 -0
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/commands/card.py +0 -0
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/commands/meta.py +0 -0
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/commands/tournaments.py +0 -0
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/output.py +0 -0
- {fablazing_cli-0.1.0 → fablazing_cli-0.1.1}/src/fablazing_cli/reference.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "fablazing-cli"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.1"
|
|
8
8
|
description = "Fablazing analytics from your terminal - Flesh and Blood matchups, meta, cards, and tournaments."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.1"
|
|
@@ -25,7 +25,7 @@ def list_heroes(
|
|
|
25
25
|
|
|
26
26
|
@app.command()
|
|
27
27
|
def show(
|
|
28
|
-
hero: str = typer.Argument(..., help="Hero id or name"),
|
|
28
|
+
hero: str = typer.Argument(..., help="Hero id or name", autocompletion=resolve.complete_hero),
|
|
29
29
|
json_: bool = typer.Option(False, "--json"),
|
|
30
30
|
csv_: bool = typer.Option(False, "--csv"),
|
|
31
31
|
):
|
|
@@ -44,7 +44,7 @@ def show(
|
|
|
44
44
|
|
|
45
45
|
@app.command()
|
|
46
46
|
def aggregate(
|
|
47
|
-
hero: str = typer.Argument(..., help="Hero id or name"),
|
|
47
|
+
hero: str = typer.Argument(..., help="Hero id or name", autocompletion=resolve.complete_hero),
|
|
48
48
|
format_type: str = typer.Option("cc", "--format"),
|
|
49
49
|
source: str = typer.Option("online", "--source", help="online | paper"),
|
|
50
50
|
period: str = typer.Option("14d", "--period", help="7d | 14d | 30d"),
|
|
@@ -8,8 +8,8 @@ from ..output import emit, pct, set_mode
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def matchup(
|
|
11
|
-
hero1: str = typer.Argument(..., help="Deck 1 hero (id or name)"),
|
|
12
|
-
hero2: str = typer.Argument(..., help="Deck 2 hero (id or name)"),
|
|
11
|
+
hero1: str = typer.Argument(..., help="Deck 1 hero (id or name)", autocompletion=resolve.complete_hero),
|
|
12
|
+
hero2: str = typer.Argument(..., help="Deck 2 hero (id or name)", autocompletion=resolve.complete_hero),
|
|
13
13
|
format_type: str = typer.Option("cc", "--format"),
|
|
14
14
|
days: int = typer.Option(30, "--days", min=1, max=365),
|
|
15
15
|
start_date: str = typer.Option(None, "--start", help="YYYY-MM-DD (overrides --days)"),
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"""Fablazing CLI entry point. `fablazing` and `fabz` both land here."""
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
2
5
|
import typer
|
|
3
6
|
|
|
4
7
|
from . import __version__
|
|
5
8
|
from .commands import auth, card, hero, meta, tournaments
|
|
6
9
|
from .commands.matchup import matchup
|
|
7
|
-
from .
|
|
10
|
+
from .config import load_config, save_config
|
|
11
|
+
from .output import console, err_console
|
|
8
12
|
from .reference import REFERENCE
|
|
9
13
|
|
|
10
14
|
app = typer.Typer(
|
|
@@ -17,6 +21,27 @@ app = typer.Typer(
|
|
|
17
21
|
context_settings={"help_option_names": ["-h", "--help"]},
|
|
18
22
|
)
|
|
19
23
|
|
|
24
|
+
@app.callback()
|
|
25
|
+
def _main():
|
|
26
|
+
_completion_tip()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _completion_tip():
|
|
30
|
+
"""One-time hint about tab completion. Skipped during shell completion
|
|
31
|
+
itself and when not on a terminal."""
|
|
32
|
+
if any(k.endswith("_COMPLETE") for k in os.environ):
|
|
33
|
+
return
|
|
34
|
+
cfg = load_config()
|
|
35
|
+
if cfg.get("completion_tip_shown") or not sys.stderr.isatty():
|
|
36
|
+
return
|
|
37
|
+
err_console.print(
|
|
38
|
+
"[dim]tip: run `fablazing --install-completion` once to enable tab "
|
|
39
|
+
"completion (takes effect in a new terminal)[/dim]"
|
|
40
|
+
)
|
|
41
|
+
cfg["completion_tip_shown"] = True
|
|
42
|
+
save_config(cfg)
|
|
43
|
+
|
|
44
|
+
|
|
20
45
|
app.add_typer(auth.app, name="auth")
|
|
21
46
|
app.add_typer(hero.app, name="hero")
|
|
22
47
|
app.add_typer(meta.app, name="meta")
|
|
@@ -61,6 +61,23 @@ def hero_id(text: str) -> str:
|
|
|
61
61
|
fail(f"ambiguous hero '{text}' - did you mean: {options}", 2)
|
|
62
62
|
|
|
63
63
|
|
|
64
|
+
def complete_hero(incomplete: str):
|
|
65
|
+
"""Tab completion for hero arguments. Reads the local cache only; a
|
|
66
|
+
completer must never hit the network or it makes TAB feel broken."""
|
|
67
|
+
path = cache_path(_HEROES_CACHE_FILE)
|
|
68
|
+
try:
|
|
69
|
+
heroes = json.loads(path.read_text(encoding="utf-8"))["heroes"]
|
|
70
|
+
except (OSError, ValueError, KeyError):
|
|
71
|
+
return
|
|
72
|
+
query = incomplete.lower()
|
|
73
|
+
for h in heroes:
|
|
74
|
+
name = h.get("hero_name", "")
|
|
75
|
+
if name.lower().startswith(query):
|
|
76
|
+
yield (name, h["hero_id"])
|
|
77
|
+
elif h["hero_id"].lower().startswith(query):
|
|
78
|
+
yield (h["hero_id"], name)
|
|
79
|
+
|
|
80
|
+
|
|
64
81
|
def card_id(text: str, allow_spec: bool = False) -> str:
|
|
65
82
|
"""Resolve a card name or id; optionally preserve a :gte2-style suffix."""
|
|
66
83
|
candidate = text.strip()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|