Skip to content

Instantly share code, notes, and snippets.

@randerzander
Last active November 26, 2022 13:42
Show Gist options
  • Save randerzander/97bf2030f284d74feb67fa071dde7135 to your computer and use it in GitHub Desktop.
Save randerzander/97bf2030f284d74feb67fa071dde7135 to your computer and use it in GitHub Desktop.
Terminal UI for displaying live college or nfl game status
Game {
height: 3;
width: 50%;
}
from time import monotonic
from textual.app import App, ComposeResult
from textual.containers import Container
from textual.reactive import reactive
from textual.widgets import Button, Header, Footer, Static
import requests, json
class Game(Static):
def __init__(self, game) -> None:
t1 = game["competitors"][0]
t2 = game["competitors"][1]
title = f"{game['name'].replace(' at ', ' @ ')}: "
title = title + f"{game['fullStatus']['type']['detail']}"
# map team UID to team name for xreferincing who has the ball
possession = {
t1["uid"].split(":")[-1]: t1["name"],
t2["uid"].split(":")[-1]: t2["name"],
}
# ugly logic for prepending team name w/ "<>" if they have possession of the ball
t1_has_ball = ""
t2_has_ball = ""
has_ball = ""
if "possession" in game["situation"]:
pos = game["situation"]["possession"]
has_ball = possession[pos]
if t1["name"] == has_ball:
t1_has_ball = "<> "
elif t2["name"] == has_ball:
t2_has_ball = "<> "
desc = f"{t1_has_ball}{t1['abbreviation']}: {t1['score']}, "
desc = desc + f"{t2_has_ball}{t2['abbreviation']}: {t2['score']}\n"
self._title = title
self._desc = desc
super().__init__()
def compose(self) -> ComposeResult:
yield Static(self._title, id="title")
yield Static(self._desc, id="desc")
class FootballApp(App):
CSS_PATH = "football.css"
BINDINGS = [("u", "update_games", "Update")]
def action_update_games(self) -> None:
self.load_games()
def compose(self) -> ComposeResult:
yield Container(id="games")
def load_games(self):
league = "college-football"
url = "https://site.web.api.espn.com/apis/v2/scoreboard/header?sport=football&league=LEAGUE&region=us&lang=en&contentorigin=espn&buyWindow=1m&showAirings=buy%2Clive%2Creplay&showZipLookup=true&tz=America%2FNew_York"
doc = json.loads(requests.get(url.replace("LEAGUE", league)).text)
games = doc["sports"][0]["leagues"][0]["events"]
# remove existing displayed game entries
[game.remove() for game in self.query("Game")]
# filter for only active games
for game in [game for game in games if game["status"] == "in"]:
self.query_one("#games", Container).mount(Game(game))
print(f"Loaded {len(games)}")
if __name__ == "__main__":
app = FootballApp()
app.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment