Merge pull request 'add make command make reformat' (#1) from lundberg_add_black into master
Reviewed-on: #1
This commit is contained in:
commit
13dac398c5
3 changed files with 82 additions and 58 deletions
2
Makefile
Normal file
2
Makefile
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
reformat:
|
||||||
|
black *py
|
||||||
40
db.py
40
db.py
|
|
@ -3,13 +3,15 @@ from typing import Dict
|
||||||
|
|
||||||
DB_FILE = "dereth.db"
|
DB_FILE = "dereth.db"
|
||||||
|
|
||||||
|
|
||||||
def init_db() -> None:
|
def init_db() -> None:
|
||||||
"""Create tables if they do not exist (extended with kills_per_hour and onlinetime)."""
|
"""Create tables if they do not exist (extended with kills_per_hour and onlinetime)."""
|
||||||
conn = sqlite3.connect(DB_FILE)
|
conn = sqlite3.connect(DB_FILE)
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
|
|
||||||
# History log
|
# History log
|
||||||
c.execute("""
|
c.execute(
|
||||||
|
"""
|
||||||
CREATE TABLE IF NOT EXISTS telemetry_log (
|
CREATE TABLE IF NOT EXISTS telemetry_log (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
character_name TEXT NOT NULL,
|
character_name TEXT NOT NULL,
|
||||||
|
|
@ -27,10 +29,12 @@ def init_db() -> None:
|
||||||
prismatic_taper_count INTEGER,
|
prismatic_taper_count INTEGER,
|
||||||
vt_state TEXT
|
vt_state TEXT
|
||||||
)
|
)
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
# Live snapshot (upsert)
|
# Live snapshot (upsert)
|
||||||
c.execute("""
|
c.execute(
|
||||||
|
"""
|
||||||
CREATE TABLE IF NOT EXISTS live_state (
|
CREATE TABLE IF NOT EXISTS live_state (
|
||||||
character_name TEXT PRIMARY KEY,
|
character_name TEXT PRIMARY KEY,
|
||||||
char_tag TEXT,
|
char_tag TEXT,
|
||||||
|
|
@ -47,30 +51,36 @@ def init_db() -> None:
|
||||||
prismatic_taper_count INTEGER,
|
prismatic_taper_count INTEGER,
|
||||||
vt_state TEXT
|
vt_state TEXT
|
||||||
)
|
)
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
def save_snapshot(data: Dict) -> None:
|
def save_snapshot(data: Dict) -> None:
|
||||||
"""Insert snapshot into history and upsert into live_state (with new fields)."""
|
"""Insert snapshot into history and upsert into live_state (with new fields)."""
|
||||||
conn = sqlite3.connect(DB_FILE)
|
conn = sqlite3.connect(DB_FILE)
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
|
|
||||||
# Insert full history row
|
# Insert full history row
|
||||||
c.execute("""
|
c.execute(
|
||||||
|
"""
|
||||||
INSERT INTO telemetry_log (
|
INSERT INTO telemetry_log (
|
||||||
character_name, char_tag, session_id, timestamp,
|
character_name, char_tag, session_id, timestamp,
|
||||||
ew, ns, z,
|
ew, ns, z,
|
||||||
kills, kills_per_hour, onlinetime,
|
kills, kills_per_hour, onlinetime,
|
||||||
deaths, rares_found, prismatic_taper_count, vt_state
|
deaths, rares_found, prismatic_taper_count, vt_state
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
""", (
|
""",
|
||||||
|
(
|
||||||
data["character_name"],
|
data["character_name"],
|
||||||
data.get("char_tag", ""),
|
data.get("char_tag", ""),
|
||||||
data["session_id"],
|
data["session_id"],
|
||||||
data["timestamp"],
|
data["timestamp"],
|
||||||
data["ew"], data["ns"], data.get("z", 0.0),
|
data["ew"],
|
||||||
|
data["ns"],
|
||||||
|
data.get("z", 0.0),
|
||||||
data["kills"],
|
data["kills"],
|
||||||
data.get("kills_per_hour", ""),
|
data.get("kills_per_hour", ""),
|
||||||
data.get("onlinetime", ""),
|
data.get("onlinetime", ""),
|
||||||
|
|
@ -78,10 +88,12 @@ def save_snapshot(data: Dict) -> None:
|
||||||
data.get("rares_found", 0),
|
data.get("rares_found", 0),
|
||||||
data.get("prismatic_taper_count", 0),
|
data.get("prismatic_taper_count", 0),
|
||||||
data.get("vt_state", "Unknown"),
|
data.get("vt_state", "Unknown"),
|
||||||
))
|
),
|
||||||
|
)
|
||||||
|
|
||||||
# Upsert into live_state
|
# Upsert into live_state
|
||||||
c.execute("""
|
c.execute(
|
||||||
|
"""
|
||||||
INSERT INTO live_state (
|
INSERT INTO live_state (
|
||||||
character_name, char_tag, session_id, timestamp,
|
character_name, char_tag, session_id, timestamp,
|
||||||
ew, ns, z,
|
ew, ns, z,
|
||||||
|
|
@ -102,12 +114,15 @@ def save_snapshot(data: Dict) -> None:
|
||||||
rares_found = excluded.rares_found,
|
rares_found = excluded.rares_found,
|
||||||
prismatic_taper_count = excluded.prismatic_taper_count,
|
prismatic_taper_count = excluded.prismatic_taper_count,
|
||||||
vt_state = excluded.vt_state
|
vt_state = excluded.vt_state
|
||||||
""", (
|
""",
|
||||||
|
(
|
||||||
data["character_name"],
|
data["character_name"],
|
||||||
data.get("char_tag", ""),
|
data.get("char_tag", ""),
|
||||||
data["session_id"],
|
data["session_id"],
|
||||||
data["timestamp"],
|
data["timestamp"],
|
||||||
data["ew"], data["ns"], data.get("z", 0.0),
|
data["ew"],
|
||||||
|
data["ns"],
|
||||||
|
data.get("z", 0.0),
|
||||||
data["kills"],
|
data["kills"],
|
||||||
data.get("kills_per_hour", ""),
|
data.get("kills_per_hour", ""),
|
||||||
data.get("onlinetime", ""),
|
data.get("onlinetime", ""),
|
||||||
|
|
@ -115,7 +130,8 @@ def save_snapshot(data: Dict) -> None:
|
||||||
data.get("rares_found", 0),
|
data.get("rares_found", 0),
|
||||||
data.get("prismatic_taper_count", 0),
|
data.get("prismatic_taper_count", 0),
|
||||||
data.get("vt_state", "Unknown"),
|
data.get("vt_state", "Unknown"),
|
||||||
))
|
),
|
||||||
|
)
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
|
||||||
30
main.py
30
main.py
|
|
@ -19,10 +19,11 @@ app = FastAPI()
|
||||||
live_snapshots: Dict[str, dict] = {}
|
live_snapshots: Dict[str, dict] = {}
|
||||||
|
|
||||||
SHARED_SECRET = "your_shared_secret"
|
SHARED_SECRET = "your_shared_secret"
|
||||||
#LOG_FILE = "telemetry_log.jsonl"
|
# LOG_FILE = "telemetry_log.jsonl"
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
ACTIVE_WINDOW = timedelta(seconds=30) # player is “online” if seen in last 30 s
|
ACTIVE_WINDOW = timedelta(seconds=30) # player is “online” if seen in last 30 s
|
||||||
|
|
||||||
|
|
||||||
class TelemetrySnapshot(BaseModel):
|
class TelemetrySnapshot(BaseModel):
|
||||||
character_name: str
|
character_name: str
|
||||||
char_tag: str
|
char_tag: str
|
||||||
|
|
@ -51,8 +52,7 @@ def on_startup():
|
||||||
@app.post("/position")
|
@app.post("/position")
|
||||||
@app.post("/position/")
|
@app.post("/position/")
|
||||||
async def receive_snapshot(
|
async def receive_snapshot(
|
||||||
snapshot: TelemetrySnapshot,
|
snapshot: TelemetrySnapshot, x_plugin_secret: str = Header(None)
|
||||||
x_plugin_secret: str = Header(None)
|
|
||||||
):
|
):
|
||||||
if x_plugin_secret != SHARED_SECRET:
|
if x_plugin_secret != SHARED_SECRET:
|
||||||
raise HTTPException(status_code=401, detail="Unauthorized")
|
raise HTTPException(status_code=401, detail="Unauthorized")
|
||||||
|
|
@ -64,10 +64,12 @@ async def receive_snapshot(
|
||||||
save_snapshot(snapshot.dict())
|
save_snapshot(snapshot.dict())
|
||||||
|
|
||||||
# optional log-file append
|
# optional log-file append
|
||||||
#with open(LOG_FILE, "a") as f:
|
# with open(LOG_FILE, "a") as f:
|
||||||
# f.write(json.dumps(snapshot.dict(), default=str) + "\n")
|
# f.write(json.dumps(snapshot.dict(), default=str) + "\n")
|
||||||
|
|
||||||
print(f"[{datetime.now()}] {snapshot.character_name} @ NS={snapshot.ns:+.2f}, EW={snapshot.ew:+.2f}")
|
print(
|
||||||
|
f"[{datetime.now()}] {snapshot.character_name} @ NS={snapshot.ns:+.2f}, EW={snapshot.ew:+.2f}"
|
||||||
|
)
|
||||||
|
|
||||||
return {"status": "ok"}
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
|
@ -90,13 +92,14 @@ def get_live_players():
|
||||||
cutoff = datetime.utcnow().replace(tzinfo=timezone.utc) - ACTIVE_WINDOW
|
cutoff = datetime.utcnow().replace(tzinfo=timezone.utc) - ACTIVE_WINDOW
|
||||||
|
|
||||||
players = [
|
players = [
|
||||||
dict(r) for r in rows
|
dict(r)
|
||||||
if datetime.fromisoformat(
|
for r in rows
|
||||||
r["timestamp"].replace('Z', '+00:00')
|
if datetime.fromisoformat(r["timestamp"].replace("Z", "+00:00")) > cutoff
|
||||||
) > cutoff
|
|
||||||
]
|
]
|
||||||
|
|
||||||
return JSONResponse(content={"players": players})
|
return JSONResponse(content={"players": players})
|
||||||
|
|
||||||
|
|
||||||
@app.get("/history/")
|
@app.get("/history/")
|
||||||
@app.get("/history")
|
@app.get("/history")
|
||||||
def get_history(
|
def get_history(
|
||||||
|
|
@ -143,7 +146,7 @@ def get_history(
|
||||||
data = [
|
data = [
|
||||||
{
|
{
|
||||||
"timestamp": row["timestamp"],
|
"timestamp": row["timestamp"],
|
||||||
"character_name":row["character_name"],
|
"character_name": row["character_name"],
|
||||||
"kills": row["kills"],
|
"kills": row["kills"],
|
||||||
"kph": row["kph"],
|
"kph": row["kph"],
|
||||||
}
|
}
|
||||||
|
|
@ -151,6 +154,7 @@ def get_history(
|
||||||
]
|
]
|
||||||
return JSONResponse(content={"data": data})
|
return JSONResponse(content={"data": data})
|
||||||
|
|
||||||
|
|
||||||
# ------------------------ GET Trails ---------------------------------
|
# ------------------------ GET Trails ---------------------------------
|
||||||
@app.get("/trails")
|
@app.get("/trails")
|
||||||
@app.get("/trails/")
|
@app.get("/trails/")
|
||||||
|
|
@ -162,7 +166,9 @@ def get_trails(
|
||||||
for the past `seconds` seconds.
|
for the past `seconds` seconds.
|
||||||
"""
|
"""
|
||||||
# match the same string format as stored timestamps (via str(datetime))
|
# match the same string format as stored timestamps (via str(datetime))
|
||||||
cutoff_dt = datetime.utcnow().replace(tzinfo=timezone.utc) - timedelta(seconds=seconds)
|
cutoff_dt = datetime.utcnow().replace(tzinfo=timezone.utc) - timedelta(
|
||||||
|
seconds=seconds
|
||||||
|
)
|
||||||
cutoff = str(cutoff_dt)
|
cutoff = str(cutoff_dt)
|
||||||
conn = sqlite3.connect(DB_FILE)
|
conn = sqlite3.connect(DB_FILE)
|
||||||
conn.row_factory = sqlite3.Row
|
conn.row_factory = sqlite3.Row
|
||||||
|
|
@ -173,7 +179,7 @@ def get_trails(
|
||||||
WHERE timestamp >= ?
|
WHERE timestamp >= ?
|
||||||
ORDER BY character_name, timestamp
|
ORDER BY character_name, timestamp
|
||||||
""",
|
""",
|
||||||
(cutoff,)
|
(cutoff,),
|
||||||
).fetchall()
|
).fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
trails = [
|
trails = [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue