boardgames_tracker / src /sheets_backend.py
RandomCatLover's picture
Add saved-players/game-history tabs and persistent Drive access via Supabase
76b596f
Raw
History Blame
2.54 kB
import uuid
from datetime import datetime, timezone
import gspread
from google.oauth2.credentials import Credentials
_PLAYERS_HEADER = ["player_id", "name", "created_at"]
_GAMES_HEADER = ["timestamp", "game_name", "session_id", "round_number", "player_name", "score"]
_WORKBOOK_TITLE_PREFIX = "BoardGameTracker"
def _get_user_client(access_token: str) -> gspread.Client:
creds = Credentials(token=access_token)
return gspread.authorize(creds)
def get_or_create_user_workbook(access_token: str, email: str) -> gspread.Spreadsheet:
"""Returns the user's own Sheets workbook, creating it in their Drive on first use.
Uses the user's own OAuth access token (drive.file scope), so the file is
owned by them directly -- no service account or shared storage involved.
"""
client = _get_user_client(access_token)
title = f"{_WORKBOOK_TITLE_PREFIX} - {email}"
existing = client.list_spreadsheet_files(title=title)
if existing:
return client.open_by_key(existing[0]["id"])
sh = client.create(title)
players_ws = sh.sheet1
players_ws.update_title("players")
players_ws.append_row(_PLAYERS_HEADER)
games_ws = sh.add_worksheet(title="games_played", rows=1, cols=len(_GAMES_HEADER))
games_ws.append_row(_GAMES_HEADER)
return sh
def list_players(wb: gspread.Spreadsheet) -> list[dict]:
ws = wb.worksheet("players")
return ws.get_all_records()
def list_game_names(wb: gspread.Spreadsheet) -> list[str]:
"""Distinct game names played, most-recently-used first."""
ws = wb.worksheet("games_played")
names = [row["game_name"] for row in ws.get_all_records() if row.get("game_name")]
return list(dict.fromkeys(reversed(names)))
def add_player(wb: gspread.Spreadsheet, name: str) -> str:
ws = wb.worksheet("players")
existing = ws.get_all_records()
for row in existing:
if row.get("name", "").strip().lower() == name.strip().lower():
return row["player_id"]
player_id = uuid.uuid4().hex
ws.append_row([player_id, name, datetime.now(timezone.utc).isoformat()])
return player_id
def record_round(
wb: gspread.Spreadsheet,
*,
game_name: str,
session_id: str,
round_number: int,
player_name: str,
score: int,
) -> None:
ws = wb.worksheet("games_played")
ws.append_row(
[
datetime.now(timezone.utc).isoformat(),
game_name,
session_id,
round_number,
player_name,
score,
]
)