pokerbots-dev 0.1.2__tar.gz → 0.1.3__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.
Files changed (27) hide show
  1. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/PKG-INFO +1 -1
  2. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/pyproject.toml +1 -1
  3. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/commands/account.py +15 -6
  4. pokerbots_dev-0.1.3/src/pokerbots_cli/fmt.py +55 -0
  5. pokerbots_dev-0.1.2/src/pokerbots_cli/fmt.py +0 -23
  6. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/.gitignore +0 -0
  7. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/README.md +0 -0
  8. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/__init__.py +0 -0
  9. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/agent.py +0 -0
  10. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/api.py +0 -0
  11. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/auth.py +0 -0
  12. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/cards.py +0 -0
  13. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/commands/__init__.py +0 -0
  14. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/commands/admin.py +0 -0
  15. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/commands/local.py +0 -0
  16. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/commands/money.py +0 -0
  17. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/docs.md +0 -0
  18. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/engine.py +0 -0
  19. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/house.py +0 -0
  20. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/main.py +0 -0
  21. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/template/bot.py +0 -0
  22. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/src/pokerbots_cli/wallet.py +0 -0
  23. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/tests/test_agent.py +0 -0
  24. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/tests/test_cards.py +0 -0
  25. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/tests/test_cli.py +0 -0
  26. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/tests/test_engine.py +0 -0
  27. {pokerbots_dev-0.1.2 → pokerbots_dev-0.1.3}/tests/test_wallet.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pokerbots-dev
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: pb: command-line client for pokerbots.dev
5
5
  Project-URL: Homepage, https://pokerbots.dev
6
6
  Project-URL: Source, https://github.com/pokerbots-dev/pokerbots
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pokerbots-dev"
7
- version = "0.1.2"
7
+ version = "0.1.3"
8
8
  description = "pb: command-line client for pokerbots.dev"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -6,7 +6,7 @@ from pathlib import Path
6
6
 
7
7
  from .. import auth
8
8
  from ..api import call
9
- from ..fmt import money, place, table
9
+ from ..fmt import INK, PAPER, colored, money, place, signed, table, when
10
10
 
11
11
  MAX_UPLOAD = 1 << 20
12
12
  WATCH_SECONDS = 5
@@ -63,12 +63,16 @@ def report():
63
63
  d = me["deployments"].get(mode)
64
64
  rows.append([mode, f"v{d['version']} rating {d['rating']:.0f} games {d['games']} today {d['today']}" if d else "-"])
65
65
  rows += [["balance", money(me["balance"])], ["wallet", me["wallet"] or "-"]]
66
- text = table(rows)
66
+ text = table(rows, labels=True)
67
67
  games = call("GET", "/games")
68
68
  if games:
69
- text += "\n\n" + table([["game", "mode", "place", "hands"]] + [
70
- [g["created_at"], g["mode"], place(g["place"]), g["hands"] or "-"] for g in games
71
- ])
69
+ live = any(g["mode"] == "live" for g in games)
70
+ head = ["game", "mode", "place", "hands", "rating"] + (["won"] if live else [])
71
+ text += "\n\n" + table([head] + [
72
+ [when(g["created_at"]), g["mode"], place(g["place"]), g["hands"] or "-", signed(g.get("rating_delta"))]
73
+ + ([signed(g.get("net"), "money")] if live else [])
74
+ for g in games
75
+ ], header=True)
72
76
  return text
73
77
 
74
78
 
@@ -77,13 +81,18 @@ def status(args):
77
81
 
78
82
 
79
83
  def watch(args):
84
+ paint = f"\x1b[48;2;{INK}m\x1b[38;2;{PAPER}m" if colored() else ""
85
+ sys.stdout.write("\x1b[?1049h\x1b[?25l" + paint + "\x1b[2J")
80
86
  try:
81
87
  while True:
82
- sys.stdout.write("\x1b[H\x1b[2J" + report() + "\n\nctrl-c to quit\n")
88
+ lines = ["", *(" " + line for line in report().split("\n")), "", " " + "ctrl-c to quit"]
89
+ sys.stdout.write("\x1b[H" + "".join(line + "\x1b[K\n" for line in lines) + "\x1b[J")
83
90
  sys.stdout.flush()
84
91
  time.sleep(WATCH_SECONDS)
85
92
  except KeyboardInterrupt:
86
93
  pass
94
+ finally:
95
+ sys.stdout.write("\x1b[0m\x1b[?25h\x1b[?1049l")
87
96
 
88
97
 
89
98
  def register(sub):
@@ -0,0 +1,55 @@
1
+ import os
2
+ import sys
3
+ from datetime import datetime, timezone
4
+
5
+ MICRO = 1_000_000
6
+ INK, PAPER = "17;17;17", "244;243;239"
7
+
8
+
9
+ def colored():
10
+ return sys.stdout.isatty() and not os.environ.get("NO_COLOR")
11
+
12
+
13
+ def bold(text):
14
+ return f"\x1b[1m{text}\x1b[22m" if colored() else text
15
+
16
+
17
+ def table(rows, labels=False, header=False):
18
+ """Aligned columns; bold the first column (labels) or first row (header)."""
19
+ rows = [[str(c) for c in row] for row in rows]
20
+ widths = [max(len(r[i]) for r in rows if i < len(r)) for i in range(max(map(len, rows)))]
21
+ lines = []
22
+ for n, r in enumerate(rows):
23
+ cells = [c.ljust(w) for c, w in zip(r, widths)]
24
+ if header and n == 0:
25
+ cells = [bold(c) for c in cells]
26
+ elif labels:
27
+ cells[0] = bold(cells[0])
28
+ lines.append(" ".join(cells).rstrip())
29
+ return "\n".join(lines)
30
+
31
+
32
+ def money(micro):
33
+ cents = round(micro / 10_000)
34
+ return f"{cents}¢" if abs(cents) < 100 else f"${cents / 100:,.2f}"
35
+
36
+
37
+ def signed(value, unit=""):
38
+ if value is None:
39
+ return "-"
40
+ return ("+" if value > 0 else "") + (money(value) if unit == "money" else f"{value:.0f}")
41
+
42
+
43
+ def when(utc):
44
+ return datetime.fromisoformat(utc).replace(tzinfo=timezone.utc).astimezone().strftime("%m-%d %H:%M")
45
+
46
+
47
+ def parse_money(text):
48
+ value = round(float(text.lstrip("$")) * MICRO)
49
+ if value <= 0:
50
+ raise ValueError("amount must be positive")
51
+ return value
52
+
53
+
54
+ def place(n):
55
+ return {1: "1st", 2: "2nd", 3: "3rd"}.get(n, f"{n}th") if n else "-"
@@ -1,23 +0,0 @@
1
- MICRO = 1_000_000
2
-
3
-
4
- def table(rows):
5
- rows = [[str(c) for c in row] for row in rows]
6
- widths = [max(len(r[i]) for r in rows if i < len(r)) for i in range(max(map(len, rows)))]
7
- return "\n".join(" ".join(c.ljust(w) for c, w in zip(r, widths)).rstrip() for r in rows)
8
-
9
-
10
- def money(micro):
11
- cents = round(micro / 10_000)
12
- return f"{cents}¢" if abs(cents) < 100 else f"${cents / 100:,.2f}"
13
-
14
-
15
- def parse_money(text):
16
- value = round(float(text.lstrip("$")) * MICRO)
17
- if value <= 0:
18
- raise ValueError("amount must be positive")
19
- return value
20
-
21
-
22
- def place(n):
23
- return {1: "1st", 2: "2nd", 3: "3rd"}.get(n, f"{n}th") if n else "-"
File without changes
File without changes