Spaces:
Running
on
Zero
Running
on
Zero
File size: 6,463 Bytes
a303b0f 02817fd 6648256 a303b0f add3bed 4a0d2aa add3bed 4a0d2aa add3bed a303b0f 4a0d2aa add3bed 4a0d2aa add3bed 4a0d2aa a303b0f add3bed 02817fd 4a0d2aa add3bed 3e464ec a303b0f add3bed a303b0f add3bed a303b0f 02817fd 4a0d2aa add3bed b2cc102 add3bed 3e464ec b2cc102 add3bed 4a0d2aa b2cc102 add3bed a303b0f add3bed a303b0f add3bed a303b0f add3bed a303b0f add3bed 4a0d2aa add3bed 4a0d2aa |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
import os
import json
import tempfile
from datetime import datetime, timezone
from huggingface_hub import hf_hub_download, upload_file
from huggingface_hub.utils import HfHubHTTPError
# Constant for the dataset repository, configurable via environment variable
DATASET_REPO = os.getenv("HF_DATASET_REPO", "Jofthomas/geoguessr_game_of_the_day")
BLOCK_MULTIPLE_GAMES = os.getenv("Block_Multiple_games", "False") == "true"
def get_todays_records_path() -> str:
"""Gets the path for today's game records file, e.g., 'records/2025-10-03.json'."""
date_str = datetime.now(timezone.utc).strftime('%Y-%m-%d')
return f"records/{date_str}.json"
def get_todays_games(token: str) -> list:
"""
Downloads and reads the game records for the current day from the HF Hub.
Returns an empty list if the file for today doesn't exist yet.
"""
filepath = get_todays_records_path()
try:
# Use the provided token for read access
local_path = hf_hub_download(
repo_id=DATASET_REPO,
filename=filepath,
repo_type="dataset",
token=token,
)
with open(local_path, "r", encoding="utf-8") as f:
return json.load(f)
except HfHubHTTPError as e:
if e.response.status_code == 404:
return [] # No games played today yet, which is normal.
else:
print(f"Error downloading daily records: {e}")
raise # Re-raise other HTTP errors
except Exception as e:
print(f"An unexpected error occurred while getting today's games: {e}")
return []
def has_user_played_today(username: str, todays_games: list) -> bool:
"""Checks if a user has completed a game today."""
today_date = datetime.now(timezone.utc).date().isoformat()
for game in todays_games:
if game.get("username") == username and game.get("completed", False):
# Additional check: ensure the game's timestamp is from today
game_timestamp = game.get("timestamp", "")
if game_timestamp:
try:
game_date = datetime.fromisoformat(game_timestamp.replace('Z', '+00:00')).date().isoformat()
if game_date == today_date:
return True
except:
# If we can't parse the timestamp, assume it's from today (since it's in todays_games)
return True
else:
# If no timestamp, assume it's from today (since it's in todays_games)
return True
return False
def get_user_game_today(username: str, todays_games: list, game_id: str = None) -> dict:
"""
Gets the user's game record for today, if it exists.
If game_id is provided, returns the specific game with that ID.
Otherwise, returns the first game found for the user.
"""
for game in todays_games:
if game.get("username") == username:
if game_id and game.get("game_id") == game_id:
return game
elif not game_id:
return game
return None
def update_game_record(username: str, game_id: str, round_data: dict = None, final_score: float = None, final_ai_score: float = None):
"""
Updates or creates a game record for a user after each round.
This ensures data is recorded incrementally and prevents abuse.
Args:
username: The player's username
game_id: Unique identifier for this game session
round_data: Single round details to append to the record
final_score: Final total human score (only set when game is complete)
final_ai_score: Final total AI score (only set when game is complete)
"""
write_token = os.getenv("HF_TOKEN", "")
if not write_token:
print("Warning: Server HF_TOKEN not set. Cannot record game data.")
return
try:
# Fetch the latest records
todays_games = get_todays_games(token=write_token)
# Find existing game record for this user today with this specific game_id
existing_game = get_user_game_today(username, todays_games, game_id)
if existing_game:
# Update existing record
if round_data:
if "rounds" not in existing_game:
existing_game["rounds"] = []
existing_game["rounds"].append(round_data)
if final_score is not None:
existing_game["human_score"] = float(round(final_score))
existing_game["completed"] = True
if final_ai_score is not None:
existing_game["ai_score"] = float(round(final_ai_score))
else:
# Create new game record
game_record = {
"username": username,
"game_id": game_id,
"human_score": 0.0, # Will be updated when game completes
"ai_score": 0.0, # Will be updated when game completes
"timestamp": datetime.now(timezone.utc).isoformat(),
"rounds": [round_data] if round_data else [],
"completed": False
}
todays_games.append(game_record)
filepath_in_repo = get_todays_records_path()
with tempfile.NamedTemporaryFile(mode="w+", delete=False, suffix=".json", encoding="utf-8") as tmp_file:
json.dump(todays_games, tmp_file, indent=2)
tmp_file_path = tmp_file.name
upload_file(
path_or_fileobj=tmp_file_path,
path_in_repo=filepath_in_repo,
repo_id=DATASET_REPO,
repo_type="dataset",
token=write_token,
commit_message=f"Update game for {username}"
)
print(f"Successfully updated game record for {username}")
except Exception as e:
print(f"Error updating game record for {username}: {e}")
finally:
if 'tmp_file_path' in locals() and os.path.exists(tmp_file_path):
os.remove(tmp_file_path)
def record_game(username: str, score: float, rounds_data: list = None, ai_score: float = None, game_id: str = None):
"""
Legacy function - now just calls update_game_record with final score.
Kept for backwards compatibility.
"""
if not game_id:
import uuid
game_id = str(uuid.uuid4())
update_game_record(username, game_id, final_score=score, final_ai_score=ai_score)
|