Rozsirenie analytiky: login event, prepinac vsetci/prihlaseni, plny nazov krajiny
Pageview beacony uz neposielaju player_id z klienta (nedovereny vstup na neautentifikovanom endpointe) -- prihlasenie sa eviduje server-side ako event "login" (aj z registracie), s player_id skutocneho uctu. Admin dashboard dostal prepinac scope vsetci/prihlaseni, ktory konzistentne pocita grafy aj tabulky (kazdy login samostatne, navstevnicky den pre anonymnu navstevnost). PageView.country teraz uklada cely anglicky nazov krajiny namiesto ISO kodu (potrebna zmena schemy). Pridane sledovanie klikov na "Pravidla hry" aj z GameList. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+21
-1
@@ -6,6 +6,7 @@ import time
|
||||
import uuid
|
||||
from collections import defaultdict
|
||||
from json import JSONEncoder
|
||||
from urllib.parse import parse_qs
|
||||
|
||||
import socketio
|
||||
|
||||
@@ -103,6 +104,9 @@ async def _handle_track(scope, receive, send):
|
||||
data = {}
|
||||
headers = dict(scope.get("headers") or [])
|
||||
user_agent = headers.get(b"user-agent", b"").decode("utf-8", "ignore")[:300]
|
||||
# player_id sa sem nikdy nedava z klienta (nedovereny/spoofovatelny vstup na
|
||||
# neautentifikovanom endpointe) -- pripaja sa len server-side na evente
|
||||
# "login" (pozri handler @sio.on("login")).
|
||||
await stats_module.record_pageview(
|
||||
path=str(data.get("path", ""))[:200],
|
||||
referrer=str(data.get("referrer", ""))[:300],
|
||||
@@ -120,7 +124,9 @@ async def _handle_admin_stats(scope, send):
|
||||
if not _admin_authorized(scope):
|
||||
_register_admin_failure(ip)
|
||||
return await _send_text(send, 403, b"forbidden")
|
||||
data = await stats_module.get_daily_stats()
|
||||
query = parse_qs((scope.get("query_string") or b"").decode("utf-8", "ignore"))
|
||||
logged_in_only = query.get("logged_in", ["0"])[0] == "1"
|
||||
data = await stats_module.get_daily_stats(logged_in_only=logged_in_only)
|
||||
await _send_text(send, 200, json.dumps(data).encode(), b"application/json")
|
||||
|
||||
|
||||
@@ -382,6 +388,18 @@ async def register_account(sid, username):
|
||||
await sio.emit("register_account", data, to=sid)
|
||||
|
||||
|
||||
async def _record_login_event(sid: str, player_id: int) -> None:
|
||||
scope = (sio.get_environ(sid) or {}).get("asgi.scope", {})
|
||||
headers = dict(scope.get("headers") or [])
|
||||
await stats_module.record_pageview(
|
||||
path="login",
|
||||
referrer="",
|
||||
user_agent=headers.get(b"user-agent", b"").decode("utf-8", "ignore")[:300],
|
||||
ip=_client_ip(scope),
|
||||
player_id=player_id,
|
||||
)
|
||||
|
||||
|
||||
@sio.on("confirm_account")
|
||||
async def confirm_account(sid, username, code):
|
||||
try:
|
||||
@@ -389,6 +407,7 @@ async def confirm_account(sid, username, code):
|
||||
except AuthError as exc:
|
||||
return await send_error(sid, str(exc))
|
||||
accounts[sid] = {"player_id": identity["player_id"], "username": identity["username"]}
|
||||
await _record_login_event(sid, identity["player_id"])
|
||||
await sio.emit("login", {"player": accounts[sid], "token": identity["token"]}, to=sid)
|
||||
|
||||
|
||||
@@ -399,6 +418,7 @@ async def login(sid, username, code):
|
||||
except AuthError as exc:
|
||||
return await send_error(sid, str(exc))
|
||||
accounts[sid] = {"player_id": identity["player_id"], "username": identity["username"]}
|
||||
await _record_login_event(sid, identity["player_id"])
|
||||
await sio.emit("login", {"player": accounts[sid], "token": identity["token"]}, to=sid)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user