from textual.app import App, ComposeResult from textual.widgets import Footer, Label, ListItem, ListView,DataTable, ProgressBar import httpx from datetime import datetime, timezone from zoneinfo import ZoneInfo from textual.containers import Container class MyApp(App): CSS_PATH = "proj.tcss" async def on_mount(self) -> None: self.set_interval(3600, self.load_data_groceries) self.set_interval(3600, self.load_data_Tasks) self.set_interval(3600, self.load_data_inter) self.set_interval(3600, self.load_data_pfc) await self.load_data_Tasks() await self.load_data_groceries() await self.load_data_inter(6684) await self.load_data_pfc(1045) def compose(self) -> ComposeResult: with Container(id="Lists"): self.list_Groceries = ListView() yield self.list_Groceries self.list_ToDo = ListView() yield self.list_ToDo with Container(id="Football"): self.Intertable = DataTable() yield self.Intertable self.PFCtable = DataTable() yield self.PFCtable with Container(id="Printer"): self.PB = ProgressBar(total=100) yield self.PB async def load_data_pfc(self,id): async with httpx.AsyncClient() as client: response = await client.get( f"http://100.124.129.93:19837/device-info", ) result = response.json() self.PB.update(progress=int(result["percentage"])) async def load_data_pfc(self,id): async with httpx.AsyncClient() as client: response = await client.get( f"https://api.football-data.org/v4/teams/{id}/matches", headers={"X-Auth-Token": "1535f68086e542528841b5e276f50b45"} ) result = response.json() now = datetime.now(timezone.utc) # Separate finished matches and future matches relative to now finished_matches = [m for m in result["matches"] if m["status"] == "FINISHED" and datetime.fromisoformat(m["utcDate"].replace("Z", "+00:00")) <= now] upcoming_matches = [m for m in result["matches"] if datetime.fromisoformat(m["utcDate"].replace("Z", "+00:00")) > now] # Sort finished matches by date descending (most recent first) finished_matches.sort(key=lambda m: m["utcDate"], reverse=True) # Sort upcoming matches by date ascending (soonest first) upcoming_matches.sort(key=lambda m: m["utcDate"]) # Get last 2 finished and next 2 upcoming last_two = finished_matches[:2] next_two = upcoming_matches[:2] HEADERS = ["Domicile", "Score", "Extérieur", "Date"] self.PFCtable.add_columns(*HEADERS) rows = [] for match in list(reversed(next_two)) + last_two : home_team = match["homeTeam"]["name"] away_team = match["awayTeam"]["name"] utc_time = datetime.fromisoformat(match["utcDate"].replace("Z", "+00:00")) paris_time = utc_time.astimezone(ZoneInfo("Europe/Paris")) match_date_paris = paris_time.strftime("%H:%M %d-%m-%Y ") status = match["status"] score = match.get("score", {}).get("fullTime") if status == "FINISHED" else None if score: score_str = f"{score.get('home', '?')} - {score.get('away', '?')}" rows.append((home_team, score_str ,away_team ,match_date_paris)) else: rows.append((home_team, status ,away_team ,match_date_paris)) self.PFCtable.add_rows(rows) async def load_data_inter(self,id): async with httpx.AsyncClient() as client: response = await client.get( f"https://api.football-data.org/v4/teams/{id}/matches", headers={"X-Auth-Token": "1535f68086e542528841b5e276f50b45"} ) result = response.json() now = datetime.now(timezone.utc) # Separate finished matches and future matches relative to now finished_matches = [m for m in result["matches"] if m["status"] == "FINISHED" and datetime.fromisoformat(m["utcDate"].replace("Z", "+00:00")) <= now] upcoming_matches = [m for m in result["matches"] if datetime.fromisoformat(m["utcDate"].replace("Z", "+00:00")) > now] # Sort finished matches by date descending (most recent first) finished_matches.sort(key=lambda m: m["utcDate"], reverse=True) # Sort upcoming matches by date ascending (soonest first) upcoming_matches.sort(key=lambda m: m["utcDate"]) # Get last 2 finished and next 2 upcoming last_two = finished_matches[:2] next_two = upcoming_matches[:2] HEADERS = ["Domicile", "Score", "Extérieur", "Date"] self.Intertable.add_columns(*HEADERS) rows = [] for match in list(reversed(next_two)) + last_two : home_team = match["homeTeam"]["name"] away_team = match["awayTeam"]["name"] utc_time = datetime.fromisoformat(match["utcDate"].replace("Z", "+00:00")) paris_time = utc_time.astimezone(ZoneInfo("Europe/Paris")) match_date_paris = paris_time.strftime("%H:%M %d-%m-%Y ") status = match["status"] score = match.get("score", {}).get("fullTime") if status == "FINISHED" else None if score: score_str = f"{score.get('home', '?')} - {score.get('away', '?')}" rows.append((home_team, score_str ,away_team ,match_date_paris)) else: rows.append((home_team, status ,away_team ,match_date_paris)) self.Intertable.add_rows(rows) async def load_data_Tasks(self): async with httpx.AsyncClient() as client: response = await client.get("https://tasktrove.couraud.xyz/api/v1/tasks") print(response) items = response.json()["tasks"] self.list_ToDo.clear() for item in items: if not item.get("completed"): if (item.get("priority") in [1, 2]): self.list_ToDo.append(ListItem(Label(item["title"]))) elif item.get("dueDate"): due_date = datetime.fromisoformat(item["dueDate"]) if due_date.date() <= datetime.now().date(): self.list_ToDo.append(ListItem(Label(item["title"]))) async def load_data_groceries(self): async with httpx.AsyncClient() as client: response = await client.get( "https://memos.couraud.xyz/api/v1/memos?page=1&perPage=1", headers={ "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJuYW1lIjoiZ3JvY2VyaWVzIiwiaXNzIjoibWVtb3MiLCJzdWIiOiIyIiwiYXVkIjpbInVzZXIuYWNjZXNzLXRva2VuIl0sImlhdCI6MTc2MDI3NzQwMX0.H8m6LSaav7cuiQgt_rrzB7Fx4UM7Un11M2S0L5JJfPc" } ) result = response.json()["memos"][0]["content"] lines = result.splitlines() # Split by newline to get each line as an item self.list_Groceries.clear() for line in lines: line = line.strip() # Remove markdown checkbox syntax like "- [ ] " or "- [x] " if line.startswith("- [ ] "): line = line[6:] elif line.startswith("- [x] "): line = line[6:] if line: self.list_Groceries.append(ListItem(Label(line))) if __name__ == "__main__": MyApp().run()