Files
boker/storage.py
T

122 lines
2.9 KiB
Python

#!/usr/bin/env python3
from __future__ import annotations
import csv
import uuid
from datetime import datetime, timezone
from pathlib import Path
from typing import TypedDict
CSV_HEADERS = [
"id",
"created_at",
"session_id",
"session_date",
"player_name",
"event_type",
"amount_cents",
"note",
"actor",
]
class EventRow(TypedDict):
id: str
created_at: str
session_id: str
session_date: str
player_name: str
event_type: str
amount_cents: int
note: str
actor: str
VALID_EVENT_TYPES = {
"buyin",
"front",
"front_writeoff",
"cashout",
"paid",
"rollover_in",
"rollover_out",
"note",
"session_open",
"session_close",
}
def ensure_data_file(csv_path: Path) -> None:
csv_path.parent.mkdir(parents=True, exist_ok=True)
if csv_path.exists():
return
with csv_path.open("w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=CSV_HEADERS)
writer.writeheader()
def load_events(csv_path: Path) -> list[EventRow]:
ensure_data_file(csv_path)
events: list[EventRow] = []
with csv_path.open("r", newline="", encoding="utf-8") as file:
reader = csv.DictReader(file)
for row in reader:
events.append(
EventRow(
id=row["id"],
created_at=row["created_at"],
session_id=row["session_id"],
session_date=row["session_date"],
player_name=row["player_name"],
event_type=row["event_type"],
amount_cents=int(row["amount_cents"] or 0),
note=row.get("note", ""),
actor=row.get("actor", ""),
)
)
events.sort(
key=lambda event: (event["session_date"], event["created_at"], event["id"])
)
return events
def append_event(
csv_path: Path,
session_id: str,
session_date: str,
player_name: str,
event_type: str,
amount_cents: int,
note: str,
actor: str,
) -> EventRow:
ensure_data_file(csv_path)
normalized_type = event_type.strip().lower()
if normalized_type not in VALID_EVENT_TYPES:
raise ValueError(f"Unsupported event type: {event_type}")
if normalized_type in {"note", "session_open", "session_close"}:
amount_cents = 0
event = EventRow(
id=str(uuid.uuid4()),
created_at=datetime.now(timezone.utc).isoformat(),
session_id=session_id.strip(),
session_date=session_date.strip(),
player_name=player_name.strip(),
event_type=normalized_type,
amount_cents=amount_cents,
note=note.strip(),
actor=actor.strip(),
)
with csv_path.open("a", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=CSV_HEADERS)
writer.writerow(event)
return event