Compare commits
3 Commits
cefa490f5f
...
326934ca9b
| Author | SHA1 | Date | |
|---|---|---|---|
| 326934ca9b | |||
| 077dc25a5d | |||
| 69fe72512c |
@@ -216,12 +216,16 @@ class WordleDb:
|
|||||||
Score.select(
|
Score.select(
|
||||||
Score,
|
Score,
|
||||||
Hole.hole,
|
Hole.hole,
|
||||||
|
Hole.hole_id,
|
||||||
|
Game.game_id,
|
||||||
User.username,
|
User.username,
|
||||||
|
User.user_id,
|
||||||
Player.game_id,
|
Player.game_id,
|
||||||
)
|
)
|
||||||
.join(Player, on=(Score.user_id == Player.user_id))
|
.join(Player, on=(Score.user_id == Player.user_id))
|
||||||
.switch(Score)
|
.switch(Score)
|
||||||
.join(Hole, on=(Score.hole_id == Hole.hole_id))
|
.join(Hole, on=(Score.hole_id == Hole.hole_id))
|
||||||
|
.join(Game, on=(Hole.game_id == Game.game_id))
|
||||||
.switch(Score)
|
.switch(Score)
|
||||||
.join(User, on=(Score.user_id == User.user_id))
|
.join(User, on=(Score.user_id == User.user_id))
|
||||||
.filter(Player.game_id == round.game_id)
|
.filter(Player.game_id == round.game_id)
|
||||||
@@ -235,9 +239,18 @@ class WordleDb:
|
|||||||
Score.insert_many(batch).execute()
|
Score.insert_many(batch).execute()
|
||||||
|
|
||||||
def bulk_update_scores(self, scores: typing.List[Score]):
|
def bulk_update_scores(self, scores: typing.List[Score]):
|
||||||
with db.atomic():
|
query_str = """UPDATE score
|
||||||
for score in scores:
|
SET score = {score}, tweet_id = {tweet_id}
|
||||||
score.save()
|
WHERE user_id = {user_id} AND game_id = {game_id} AND hole_id = {hole_id}"""
|
||||||
|
for score in scores:
|
||||||
|
query = query_str.format(
|
||||||
|
score=score.score,
|
||||||
|
tweet_id=score.tweet_id or "NULL",
|
||||||
|
user_id=score.user_id.user_id,
|
||||||
|
game_id=score.game_id.game_id,
|
||||||
|
hole_id=score.hole_id.hole_id,
|
||||||
|
)
|
||||||
|
db.execute_sql(query)
|
||||||
|
|
||||||
def get_users_without_score(self, round_no, hole_no, tweetable=True):
|
def get_users_without_score(self, round_no, hole_no, tweetable=True):
|
||||||
hole = self.get_or_create_hole(round_no, hole_no)
|
hole = self.get_or_create_hole(round_no, hole_no)
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ class TwitterClient(httpx.AsyncClient):
|
|||||||
user_id = await self.get_user_twitter_id(username)
|
user_id = await self.get_user_twitter_id(username)
|
||||||
if user_id:
|
if user_id:
|
||||||
self.db.add_user(username, user_id)
|
self.db.add_user(username, user_id)
|
||||||
|
self.db.add_user_to_round(username, self.wordle_day.golf_hole.game_no)
|
||||||
return user_id
|
return user_id
|
||||||
|
|
||||||
def _start_timestamp(self):
|
def _start_timestamp(self):
|
||||||
|
|||||||
@@ -154,9 +154,12 @@ class UserRow(ScoreRow):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
saved_score = score_match[0]
|
saved_score = score_match[0]
|
||||||
if saved_score.score != score or saved_score.tweet_id != tweet_id:
|
if saved_score.score != score or (
|
||||||
|
tweet_id and saved_score.tweet_id != tweet_id
|
||||||
|
):
|
||||||
saved_score.score = score
|
saved_score.score = score
|
||||||
saved_score.tweet_id = tweet_id
|
if tweet_id:
|
||||||
|
saved_score.tweet_id = tweet_id
|
||||||
results["update"].append(saved_score)
|
results["update"].append(saved_score)
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import collections
|
import collections
|
||||||
import functools
|
import functools
|
||||||
|
import math
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import re
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import dash
|
import dash
|
||||||
@@ -19,6 +21,7 @@ import wordlinator.utils.web
|
|||||||
|
|
||||||
TTL_TIME = 30 if os.getenv("DEBUG") else 90
|
TTL_TIME = 30 if os.getenv("DEBUG") else 90
|
||||||
LEADERBOARD_COUNT = 20
|
LEADERBOARD_COUNT = 20
|
||||||
|
VALUE_RE = re.compile(r"\[(?P<value>-?\d+)\]")
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# Setup Functions #
|
# Setup Functions #
|
||||||
@@ -26,7 +29,10 @@ LEADERBOARD_COUNT = 20
|
|||||||
|
|
||||||
assets_dir = pathlib.Path(__file__).parent / "assets"
|
assets_dir = pathlib.Path(__file__).parent / "assets"
|
||||||
app = dash.Dash(
|
app = dash.Dash(
|
||||||
name="WordleGolf", title="#WordleGolf", assets_folder=str(assets_dir.resolve())
|
name="WordleGolf",
|
||||||
|
title="#WordleGolf",
|
||||||
|
assets_folder=str(assets_dir.resolve()),
|
||||||
|
suppress_callback_exceptions=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -114,10 +120,16 @@ def get_leaderboard(round_id):
|
|||||||
#################
|
#################
|
||||||
|
|
||||||
|
|
||||||
def get_scores(round_id):
|
def _get_scores(round_id):
|
||||||
score_matrix = scores_from_db(round_id)
|
score_matrix = scores_from_db(round_id)
|
||||||
round_day = round_wordle_day(round_id)
|
round_day = round_wordle_day(round_id)
|
||||||
table_rows = score_matrix.user_rows(round_day)
|
table_rows = score_matrix.user_rows(round_day)
|
||||||
|
return table_rows
|
||||||
|
|
||||||
|
|
||||||
|
def get_scores(round_id):
|
||||||
|
round_day = round_wordle_day(round_id)
|
||||||
|
table_rows = _get_scores(round_id)
|
||||||
|
|
||||||
hole_columns = [
|
hole_columns = [
|
||||||
{"name": f"{i}", "id": f"{i}", "type": "text", "presentation": "markdown"}
|
{"name": f"{i}", "id": f"{i}", "type": "text", "presentation": "markdown"}
|
||||||
@@ -150,6 +162,7 @@ def get_scores(round_id):
|
|||||||
return dash.dash_table.DataTable(
|
return dash.dash_table.DataTable(
|
||||||
table_rows,
|
table_rows,
|
||||||
columns,
|
columns,
|
||||||
|
id="user-scores-table",
|
||||||
style_table={
|
style_table={
|
||||||
"width": "80%",
|
"width": "80%",
|
||||||
"margin": "auto",
|
"margin": "auto",
|
||||||
@@ -163,7 +176,9 @@ def get_scores(round_id):
|
|||||||
style_data={"width": "10%"},
|
style_data={"width": "10%"},
|
||||||
style_as_list_view=True,
|
style_as_list_view=True,
|
||||||
style_data_conditional=formatting,
|
style_data_conditional=formatting,
|
||||||
sort_action="native",
|
sort_action="custom",
|
||||||
|
sort_mode="single",
|
||||||
|
sort_by=[{"column_id": "Name", "direction": "asc"}],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -399,6 +414,32 @@ def render_tab(tab, round_id):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@app.callback(
|
||||||
|
dash.dependencies.Output("user-scores-table", "data"),
|
||||||
|
dash.dependencies.Input("user-scores-table", "sort_by"),
|
||||||
|
dash.dependencies.State("user-scores-table", "data"),
|
||||||
|
)
|
||||||
|
def sort_scores(sort_by, data):
|
||||||
|
if not sort_by:
|
||||||
|
return data
|
||||||
|
sort_by = sort_by[0]
|
||||||
|
|
||||||
|
def _sort_val(entry):
|
||||||
|
col_id = sort_by["column_id"]
|
||||||
|
raw_val = entry.get(col_id)
|
||||||
|
if raw_val is None or raw_val == "":
|
||||||
|
return math.inf
|
||||||
|
if col_id == "Name":
|
||||||
|
return raw_val
|
||||||
|
if isinstance(raw_val, int) or raw_val.isdigit():
|
||||||
|
return int(raw_val)
|
||||||
|
match = VALUE_RE.match(raw_val).groupdict()["value"]
|
||||||
|
return int(match)
|
||||||
|
|
||||||
|
data = sorted(data, key=_sort_val, reverse=sort_by["direction"] == "desc")
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
server = app.server
|
server = app.server
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user