Client and logic improvements all around
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import argparse
|
||||
import asyncio
|
||||
import datetime
|
||||
|
||||
@@ -7,12 +8,12 @@ import rich.table
|
||||
import wordlinator.sheets
|
||||
import wordlinator.twitter
|
||||
|
||||
WORDLE_DAY_ONE = datetime.date(2021, 6, 20)
|
||||
WORDLE_TODAY_NUMBER = (datetime.date.today() - WORDLE_DAY_ONE).days
|
||||
WORDLE_DAY_ZERO = datetime.date(2021, 6, 19)
|
||||
WORDLE_TODAY_NUMBER = (datetime.date.today() - WORDLE_DAY_ZERO).days
|
||||
|
||||
|
||||
async def get_scores(wordle_day=WORDLE_TODAY_NUMBER):
|
||||
users = wordlinator.sheets.get_wordlegolf_users()
|
||||
users = wordlinator.sheets.SheetsClient().get_users()
|
||||
|
||||
twitter_client = wordlinator.twitter.TwitterClient()
|
||||
|
||||
@@ -26,8 +27,7 @@ async def get_scores(wordle_day=WORDLE_TODAY_NUMBER):
|
||||
return scores
|
||||
|
||||
|
||||
async def main():
|
||||
wordle_day = WORDLE_TODAY_NUMBER # - 1
|
||||
async def main(wordle_day=None):
|
||||
scores = await get_scores(wordle_day)
|
||||
|
||||
table = rich.table.Table(
|
||||
@@ -44,11 +44,11 @@ async def main():
|
||||
if raw_score < 4:
|
||||
color = "green"
|
||||
elif raw_score == 4:
|
||||
color = "white"
|
||||
color = "orange3"
|
||||
elif raw_score > 6:
|
||||
color = "red"
|
||||
else:
|
||||
color = "blue"
|
||||
color = "yellow"
|
||||
|
||||
score_args = [raw_score, score.score, score.score_name]
|
||||
args += [f"[{color}]{arg}" for arg in score_args]
|
||||
@@ -58,8 +58,25 @@ async def main():
|
||||
rich.print(table)
|
||||
|
||||
|
||||
def _get_day():
|
||||
parser = argparse.ArgumentParser("wordlinator")
|
||||
days = parser.add_mutually_exclusive_group()
|
||||
days.add_argument(
|
||||
"--days-ago", type=int, help="The number of days back to pull a score report."
|
||||
)
|
||||
days.add_argument(
|
||||
"--wordle-day", type=int, help="The wordle day number for the score report."
|
||||
)
|
||||
args = parser.parse_args()
|
||||
wordle_day = args.wordle_day or WORDLE_TODAY_NUMBER
|
||||
if args.days_ago:
|
||||
wordle_day = WORDLE_TODAY_NUMBER - args.days_ago
|
||||
return wordle_day
|
||||
|
||||
|
||||
def sync_main():
|
||||
asyncio.run(main())
|
||||
wordle_day = _get_day()
|
||||
asyncio.run(main(wordle_day=wordle_day))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -4,34 +4,33 @@ import googleapiclient.discovery
|
||||
import rich
|
||||
import rich.table
|
||||
|
||||
WORDLEGOLF_SPREADSHEET_ID = "1POoklzvD643pvdMAleFxrecN50IMv2NdQBs9h43Hw8E"
|
||||
WORDLEGOLF_RANGE_NAME = "Round 1!A2:A100"
|
||||
SPREADSHEET_ID = "1POoklzvD643pvdMAleFxrecN50IMv2NdQBs9h43Hw8E"
|
||||
SHEET_NAME = "Round 1"
|
||||
USER_RANGE = "A2:A1000"
|
||||
|
||||
|
||||
def _get_sheets_client():
|
||||
return googleapiclient.discovery.build(
|
||||
"sheets", "v4", developerKey=os.getenv("SHEET_API_KEY")
|
||||
)
|
||||
class SheetsClient:
|
||||
def __init__(
|
||||
self, sheet_id=SPREADSHEET_ID, sheet_name=SHEET_NAME, user_range=USER_RANGE
|
||||
):
|
||||
creds = {"developerKey": os.getenv("SHEET_API_KEY")}
|
||||
self.client = googleapiclient.discovery.build("sheets", "v4", **creds)
|
||||
self.sheet_id = sheet_id
|
||||
self.sheet_name = sheet_name
|
||||
self.user_range = user_range
|
||||
|
||||
def _get_sheet_values(self, range):
|
||||
sheets = self.client.spreadsheets()
|
||||
result = sheets.values().get(spreadsheetId=self.sheet_id, range=range).execute()
|
||||
return result.get("values", [])
|
||||
|
||||
def _get_sheet_values(client, range):
|
||||
sheet = client.spreadsheets()
|
||||
result = (
|
||||
sheet.values()
|
||||
.get(spreadsheetId=WORDLEGOLF_SPREADSHEET_ID, range=range)
|
||||
.execute()
|
||||
)
|
||||
return result.get("values", [])
|
||||
|
||||
|
||||
def get_wordlegolf_users():
|
||||
client = _get_sheets_client()
|
||||
res = _get_sheet_values(client, WORDLEGOLF_RANGE_NAME)
|
||||
return [row[0] for row in res]
|
||||
def get_users(self):
|
||||
rows = self._get_sheet_values(f"{self.sheet_name}!{self.user_range}")
|
||||
return list(filter(None, [row[0] for row in rows]))
|
||||
|
||||
|
||||
def main():
|
||||
users = get_wordlegolf_users()
|
||||
users = SheetsClient().get_users()
|
||||
table = rich.table.Table("Username", title="WordleGolf Players")
|
||||
for user in users:
|
||||
table.add_row(user)
|
||||
|
||||
@@ -5,15 +5,28 @@ import enum
|
||||
import os
|
||||
import re
|
||||
|
||||
import authlib.integrations.httpx_client
|
||||
import dateutil.parser
|
||||
import httpx
|
||||
import rich
|
||||
|
||||
BASE_URL = "https://api.twitter.com/2"
|
||||
WORDLE_RE = re.compile(r"Wordle (?P<number>\d+) (?P<score>[X\d])/6")
|
||||
WORDLE_RE = re.compile(r"Wordle(\w+)? (?P<number>\d+) (?P<score>[X\d])/6")
|
||||
TOKEN = os.getenv("TWITTER_TOKEN")
|
||||
|
||||
|
||||
def _get_oauth_creds():
|
||||
creds = {
|
||||
"client_id": os.getenv("TWITTER_API_KEY"),
|
||||
"client_secret": os.getenv("TWITTER_API_KEY_SECRET"),
|
||||
"token": os.getenv("TWITTER_USER_TOKEN"),
|
||||
"token_secret": os.getenv("TWITTER_USER_TOKEN_SECRET"),
|
||||
}
|
||||
if not all(creds.values()):
|
||||
return None
|
||||
return creds
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class TwitterUser:
|
||||
name: str
|
||||
@@ -76,8 +89,13 @@ class TwitterClient(httpx.AsyncClient):
|
||||
SEARCH_PATH = "tweets/search/recent"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
oauth_creds = _get_oauth_creds()
|
||||
if oauth_creds:
|
||||
auth = authlib.integrations.httpx_client.OAuth1Auth(**oauth_creds)
|
||||
kwargs["auth"] = auth
|
||||
super().__init__(base_url=BASE_URL, **kwargs)
|
||||
self.headers["Authorization"] = f"Bearer {TOKEN}"
|
||||
if not oauth_creds:
|
||||
self.headers["Authorization"] = f"Bearer {TOKEN}"
|
||||
|
||||
async def search_tweets(self, search_str):
|
||||
return await self.get(
|
||||
@@ -102,7 +120,7 @@ class TwitterClient(httpx.AsyncClient):
|
||||
|
||||
async def get_user_wordles(self, username):
|
||||
return self._build_wordle_tweets(
|
||||
await self.search_tweets(f"from:{username} wordle")
|
||||
await self.search_tweets(f"from:{username} (wordle OR #WordleGolf)")
|
||||
)
|
||||
|
||||
async def get_wordlegolf_tweets(self):
|
||||
|
||||
Reference in New Issue
Block a user