File size: 4,805 Bytes
8bf595d 9b98acb 8bf595d |
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 |
from __future__ import annotations
#%%
import os
# os.environ.setdefault("GRADIO_SERVER_PORT", "1080")
# os.environ.setdefault("TEXTGAMES_SHOW_HIDDEN_LEVEL", "1")
os.environ.setdefault("TEXTGAMES_LOADGAME_DIR", "problemsets")
os.environ.setdefault("TEXTGAMES_LOADGAME_ID", "42")
os.environ.setdefault("TEXTGAMES_MOCKUSER", "")
os.environ.setdefault("TEXTGAMES_OUTPUT_DIR", "user_outputs")
favicon_path = "textgames-scrabble-black2-ss.png"
#%%
from play_helper import css, declare_components, start_new_game, check_played_game, download_from_drive, upload_to_drive, _leaderboards
import pandas as pd
import gradio as gr
import random
import json
from textgames import GAME_NAMES
#%%
os.makedirs(os.getenv('TEXTGAMES_OUTPUT_DIR', '.'), exist_ok=True)
#%%
def generate_sid(fp):
rand_int = random.randint(0, 1000)
with open(fp, "w", encoding="utf8") as f:
f.write(f"session_{rand_int:04}\n")
upload_to_drive(fp, mime_type="text/plain", update=True)
#%%
def get_sid(uid, force_generate_sid=False):
fp = f"{os.getenv('TEXTGAMES_OUTPUT_DIR')}/{uid}_sid.txt"
if force_generate_sid:
generate_sid(fp)
if not os.path.exists(fp):
download_from_drive(fp, mime_type="text/plain", compare_checksum=False)
if not os.path.exists(fp):
generate_sid(fp)
with open(fp, "r", encoding="utf8") as f:
sid = [_ for _ in f][-1]
return sid.strip()
#%%
def greet(request: gr.OAuthProfile | None):
user = {'email': os.getenv('TEXTGAMES_MOCKUSER', ''), 'name': ""}
if request is not None:
user = {'email': request.username, 'name': request.name, 'sid': get_sid(request.username)}
return f"""
Welcome to TextGames, {user['name'] or 'please login'}!
""", user, user['email']
#%%
with gr.Blocks(title="TextGames", css=css, delete_cache=(3600, 3600)) as demo:
((m, logout_btn, solved_games_df, game_radio, level_radio, new_game_btn, render_toggle, reset_sid_btn),
(session_state, is_solved, solved_games, user_state, uid_state),
) = declare_components(demo, greet, use_login_button=True)
logout_btn.activate()
reset_sid_checkbox = gr.Checkbox(False, visible=False, interactive=False)
reset_sid_btn.click(
lambda: [gr.update(interactive=False)]*2, None, [reset_sid_btn, new_game_btn]
).then(
lambda x: x, [reset_sid_checkbox], [reset_sid_checkbox],
js="(x) => confirm('Reset Progress? (cannot be undone)')"
).then(
lambda: [gr.update(interactive=True)]*2, None, [reset_sid_btn, new_game_btn]
)
def _resetting(confirmed, user):
uid = user.get('email', None) if isinstance(user, dict) else None
if not uid:
gr.Warning("You need to log in first!")
elif confirmed:
user['sid'] = get_sid(uid, force_generate_sid=True)
return user, False
reset_sid_checkbox.change(
lambda: [gr.update(interactive=False)]*3, None, [logout_btn, reset_sid_btn, new_game_btn]
).then(
_resetting, [reset_sid_checkbox, user_state], [user_state, reset_sid_checkbox]
).then(
check_played_game, [solved_games, user_state], [solved_games, solved_games_df]
).then(
lambda: [gr.update(interactive=True)]*3, None, [logout_btn, reset_sid_btn, new_game_btn]
)
@gr.render(inputs=[game_radio, level_radio, user_state, session_state, uid_state], triggers=[render_toggle.change])
def _start_new_game(game_name, level, user, _session_state, _uid_state):
if _session_state in [1, 2]:
start_new_game(game_name, level, session_state, is_solved, solved_games, user=user, uid=_uid_state)
#%%
with demo.route("Leaderboards", "/leaderboard") as demo_leaderboard:
gr.Markdown("Under Construction. Will be available soon.")
leaderboards = []
for tab in ["π
Easy", "π Medium", "πΈ Hard"]:
with gr.Tab(tab):
leaderboards.append(gr.DataFrame(label="Rankings"))
# if os.path.exists(_leaderboards):
# datas = []
# with open(_leaderboards, "r", encoding="utf8") as f:
# for line in f:
# datas.append(json.loads(line))
# concat = [{'Level': d['difficulty_level'], 'User': d['uid'], 'Game': d['game_name'].split('\t', 1)[0], 'Attempts': d['turns'],
# "Time": d['ed'] - d['st']} for d in datas]
# else:
def add_dummies():
return pd.DataFrame({
'User': ['dummy'],
'Solved': [' '.join([g.split('\t', 1)[0] for g in GAME_NAMES])],
'Attempts': [8],
'Time': [7200.8],
})
for l in leaderboards:
demo_leaderboard.load(add_dummies, None, [l])
#%%
# demo.launch()
demo.launch(
favicon_path=favicon_path if os.path.exists(favicon_path) else None,
show_api=False,
)
|