Files
TSSBOT/web/api/db.py
T
NotSoToothless 24335a2677 Auto merge dev → main (#1353)
* feat(gateway): hashed key store with grant + hot reload

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(gateway): channel registry + aiohttp app (keyed auth, whoami, per-channel ws/proxy)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(gateway): manage_keys CLI (add/list/revoke)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(gateway): retire srebot_external, run relay-gateway under PM2

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(gateway): point ecosystem + README at relay-gateway

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss): replay outbox producer for relay gateway

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss): forward processed games to relay outbox

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss-api): db helpers, app skeleton, info endpoint, fixtures

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss-api): player, games, history, search endpoints

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss-api): live, match, scoreboard, matches-search, maps

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss-api): filter-required leaderboards (players/vehicles/stats)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss-api): tournament list/detail/standings/matches

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: wire tss upstream through gateway + tssbot-api PM2 app

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 03:38:20 -07:00

48 lines
1.3 KiB
Python

from __future__ import annotations
import os
import sqlite3
import sys
from pathlib import Path
from typing import Any
import aiosqlite
# Make TSSBOT root importable for BOT.storage defaults.
_TSSBOT_ROOT = Path(__file__).resolve().parents[2]
if str(_TSSBOT_ROOT) not in sys.path:
sys.path.insert(0, str(_TSSBOT_ROOT))
def battles_path() -> Path:
override = os.getenv("TSS_API_BATTLES_DB", "").strip()
if override:
return Path(override)
from BOT.storage import TSS_BATTLES_DB_PATH
return TSS_BATTLES_DB_PATH
def tournaments_path() -> Path:
override = os.getenv("TSS_API_TOURNAMENTS_DB", "").strip()
if override:
return Path(override)
from BOT.storage import STORAGE_DIR
return STORAGE_DIR / "tss_tournaments.db"
def _ro_uri(path: Path) -> str:
return f"file:{path}?mode=ro"
async def query(path: Path, sql: str, params: tuple[Any, ...] = ()) -> list[dict]:
async with aiosqlite.connect(_ro_uri(path), uri=True) as conn:
conn.row_factory = sqlite3.Row
async with conn.execute(sql, params) as cur:
rows = await cur.fetchall()
return [dict(r) for r in rows]
async def query_one(path: Path, sql: str, params: tuple[Any, ...] = ()) -> dict | None:
rows = await query(path, sql, params)
return rows[0] if rows else None