Compare commits
3 Commits
c4a1387460
...
46d0b2009e
| Author | SHA1 | Date | |
|---|---|---|---|
| 46d0b2009e | |||
| 475ef1c7bf | |||
| 49baa96bcc |
@@ -124,4 +124,21 @@ class WordleDb:
|
|||||||
|
|
||||||
def bulk_update_scores(self, scores: typing.List[Score]):
|
def bulk_update_scores(self, scores: typing.List[Score]):
|
||||||
with db.atomic():
|
with db.atomic():
|
||||||
Score.bulk_update(scores, fields=[Score.score], batch_size=50)
|
for score in scores:
|
||||||
|
score.save()
|
||||||
|
|
||||||
|
def get_users_without_score(self, round_no, hole_no, tweetable=True):
|
||||||
|
hole = self.get_or_create_hole(round_no, hole_no)
|
||||||
|
query_str = """SELECT username
|
||||||
|
FROM user_tbl u
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT FROM score WHERE score.user_id = u.user_id AND score.hole_id = {}
|
||||||
|
)""".format(
|
||||||
|
hole.hole_id
|
||||||
|
)
|
||||||
|
|
||||||
|
if tweetable:
|
||||||
|
query_str += " AND u.check_twitter = true"
|
||||||
|
|
||||||
|
res = db.execute_sql(query_str)
|
||||||
|
return [r[0] for r in res]
|
||||||
|
|||||||
@@ -196,17 +196,28 @@ class TwitterClient(httpx.AsyncClient):
|
|||||||
async def get_wordlegolf_tweets(self):
|
async def get_wordlegolf_tweets(self):
|
||||||
return self._build_wordle_tweets(await self.search_tweets("#WordleGolf"))
|
return self._build_wordle_tweets(await self.search_tweets("#WordleGolf"))
|
||||||
|
|
||||||
def open_tweet(self, msg):
|
@classmethod
|
||||||
|
def open_tweet(cls, msg):
|
||||||
param = urllib.parse.urlencode({"text": msg})
|
param = urllib.parse.urlencode({"text": msg})
|
||||||
webbrowser.open(f"{self.TWEET_INTENT_URL}?{param}")
|
webbrowser.open(f"{cls.TWEET_INTENT_URL}?{param}")
|
||||||
|
|
||||||
async def notify_missing(self, names):
|
@classmethod
|
||||||
|
def full_notify_link(cls, names):
|
||||||
header = "Still missing a few #WordleGolf Players today!"
|
header = "Still missing a few #WordleGolf Players today!"
|
||||||
msg = header
|
msg = header
|
||||||
while names:
|
while names:
|
||||||
while len(msg) < self.MAX_TWEET_LENGTH and names:
|
msg += f" @{names.pop()}"
|
||||||
|
param = urllib.parse.urlencode({"text": msg})
|
||||||
|
return f"{cls.TWEET_INTENT_URL}?{param}"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def notify_missing(cls, names):
|
||||||
|
header = "Still missing a few #WordleGolf Players today!"
|
||||||
|
msg = header
|
||||||
|
while names:
|
||||||
|
while len(msg) < cls.MAX_TWEET_LENGTH and names:
|
||||||
msg += f" @{names.pop()}"
|
msg += f" @{names.pop()}"
|
||||||
self.open_tweet(msg)
|
cls.open_tweet(msg)
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
import collections
|
import collections
|
||||||
|
import datetime
|
||||||
import functools
|
import functools
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import dash
|
import dash
|
||||||
import dash.long_callback
|
import dash.long_callback
|
||||||
import diskcache
|
import diskcache
|
||||||
|
import flask
|
||||||
|
import flask.views
|
||||||
import plotly.graph_objs
|
import plotly.graph_objs
|
||||||
|
|
||||||
import wordlinator.db.pg as db
|
import wordlinator.db.pg as db
|
||||||
|
import wordlinator.twitter
|
||||||
import wordlinator.utils
|
import wordlinator.utils
|
||||||
|
|
||||||
###################
|
###################
|
||||||
@@ -29,7 +33,15 @@ long_callback_manager = dash.long_callback.DiskcacheLongCallbackManager(
|
|||||||
|
|
||||||
@functools.lru_cache()
|
@functools.lru_cache()
|
||||||
def _wordle_today(ttl_hash=None):
|
def _wordle_today(ttl_hash=None):
|
||||||
return wordlinator.utils.get_wordle_today()
|
today = wordlinator.utils.get_wordle_today()
|
||||||
|
if today.golf_hole:
|
||||||
|
return today
|
||||||
|
last_completed_round = [
|
||||||
|
dt for dt in wordlinator.utils.WORDLE_GOLF_ROUND_DATES[::-1] if dt <= today.date
|
||||||
|
]
|
||||||
|
last_round_start = last_completed_round[0]
|
||||||
|
last_round_end = last_round_start + datetime.timedelta(days=17)
|
||||||
|
return wordlinator.utils.WordleDay.from_date(last_round_end)
|
||||||
|
|
||||||
|
|
||||||
def wordle_today():
|
def wordle_today():
|
||||||
@@ -339,8 +351,23 @@ def get_stats_graph(_):
|
|||||||
server = app.server
|
server = app.server
|
||||||
|
|
||||||
|
|
||||||
|
class GetLinkView(flask.views.View):
|
||||||
|
methods = ["GET"]
|
||||||
|
|
||||||
|
def dispatch_request(self):
|
||||||
|
today = wordle_today()
|
||||||
|
missing_users = db.WordleDb().get_users_without_score(
|
||||||
|
today.golf_hole.game_no, today.golf_hole.hole_no
|
||||||
|
)
|
||||||
|
link = wordlinator.twitter.TwitterClient.full_notify_link(missing_users)
|
||||||
|
return flask.redirect(link)
|
||||||
|
|
||||||
|
|
||||||
|
server.add_url_rule("/tweet_link", view_func=GetLinkView.as_view("tweet_link"))
|
||||||
|
|
||||||
|
|
||||||
def serve(debug=True):
|
def serve(debug=True):
|
||||||
app.run_server(debug=debug)
|
app.run(debug=debug)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user