From 87aa6b18fae10deb35bcc63ef1e3cb5e9505f33a Mon Sep 17 00:00:00 2001 From: NSPC911 <87571998+NSPC911@users.noreply.github.com> Date: Sat, 26 Jul 2025 11:28:47 +0800 Subject: [PATCH] feat: Add a script to update showcased projects' stars --- src/textual/demo/_project_data.py | 107 +++++++++++++++ .../demo/_project_stargazer_updater.py | 50 +++++++ src/textual/demo/_project_stars.py | 15 ++ src/textual/demo/projects.py | 129 ++---------------- 4 files changed, 184 insertions(+), 117 deletions(-) create mode 100644 src/textual/demo/_project_data.py create mode 100644 src/textual/demo/_project_stargazer_updater.py create mode 100644 src/textual/demo/_project_stars.py diff --git a/src/textual/demo/_project_data.py b/src/textual/demo/_project_data.py new file mode 100644 index 0000000000..6dcb00c8f7 --- /dev/null +++ b/src/textual/demo/_project_data.py @@ -0,0 +1,107 @@ +from dataclasses import dataclass + + +@dataclass +class ProjectInfo: + """Dataclass for storing project information.""" + + title: str + author: str + url: str + description: str + repo_url_part: str + + +PROJECTS = [ + ProjectInfo( + "Posting", + "Darren Burns", + "https://posting.sh/", + "Posting is an HTTP client, not unlike Postman and Insomnia. As a TUI application, it can be used over SSH and enables efficient keyboard-centric workflows. ", + "darrenburns/posting", + ), + ProjectInfo( + "Memray", + "Bloomberg", + "https://github.com/bloomberg/memray", + "Memray is a memory profiler for Python. It can track memory allocations in Python code, in native extension modules, and in the Python interpreter itself.", + "bloomberg/memray", + ), + ProjectInfo( + "Toolong", + "Will McGugan", + "https://github.com/Textualize/toolong", + "A terminal application to view, tail, merge, and search log files (plus JSONL).", + "Textualize/toolong", + ), + ProjectInfo( + "Dolphie", + "Charles Thompson", + "https://github.com/charles-001/dolphie", + "Your single pane of glass for real-time analytics into MySQL/MariaDB & ProxySQL", + "charles-001/dolphie", + ), + ProjectInfo( + "Harlequin", + "Ted Conbeer", + "https://harlequin.sh/", + "Portable, powerful, colorful. An easy, fast, and beautiful database client for the terminal.", + "tconbeer/harlequin", + ), + ProjectInfo( + "Elia", + "Darren Burns", + "https://github.com/darrenburns/elia", + "A snappy, keyboard-centric terminal user interface for interacting with large language models.", + "darrenburns/elia", + ), + ProjectInfo( + "Trogon", + "Textualize", + "https://github.com/Textualize/trogon", + "Auto-generate friendly terminal user interfaces for command line apps.", + "Textualize/trogon", + ), + ProjectInfo( + "TFTUI - The Terraform textual UI", + "Ido Avraham", + "https://github.com/idoavrah/terraform-tui", + "TFTUI is a powerful textual UI that empowers users to effortlessly view and interact with their Terraform state.", + "idoavrah/terraform-tui", + ), + ProjectInfo( + "RecoverPy", + "Pablo Lecolinet", + "https://github.com/PabloLec/RecoverPy", + "RecoverPy is a powerful tool that leverages your system capabilities to recover lost files.", + "PabloLec/RecoverPy", + ), + ProjectInfo( + "Frogmouth", + "Dave Pearson", + "https://github.com/Textualize/frogmouth", + "Frogmouth is a Markdown viewer / browser for your terminal, built with Textual.", + "Textualize/frogmouth", + ), + ProjectInfo( + "oterm", + "Yiorgis Gozadinos", + "https://github.com/ggozad/oterm", + "The text-based terminal client for Ollama.", + "ggozad/oterm", + ), + ProjectInfo( + "logmerger", + "Paul McGuire", + "https://github.com/ptmcg/logmerger", + "logmerger is a TUI for viewing a merged display of multiple log files, merged by timestamp.", + "ptmcg/logmerger", + ), + ProjectInfo( + "doit", + "Murli Tawari", + "https://github.com/dooit-org/dooit", + "A todo manager that you didn't ask for, but needed!", + "dooit-org/dooit", + ), +] diff --git a/src/textual/demo/_project_stargazer_updater.py b/src/textual/demo/_project_stargazer_updater.py new file mode 100644 index 0000000000..ab2d0f0c92 --- /dev/null +++ b/src/textual/demo/_project_stargazer_updater.py @@ -0,0 +1,50 @@ +import httpx +import os +import json +from rich.console import Console + +# Not using the Absolute reference because +# I can't get python to run it. +from _project_data import PROJECTS + +console = Console() +error_console = Console(stderr=True, style="bold red") + + +def main() -> None: + STARS = {} + + for project in PROJECTS: + # get each repo + console.log(f"Checking {project.repo_url_part}") + response = httpx.get(f"https://api.github.com/repos/{project.repo_url_part}") + if response.status_code == 200: + # get stargazers + stargazers = response.json()["stargazers_count"] + if stargazers // 1000 != 0: + # humanize them + stargazers = f"{stargazers / 1000:.1f}k" + else: + stargazers = str(stargazers) + STARS[project.title] = stargazers + elif response.status_code == 403: + # gh api rate limited + error_console.log( + "GitHub has received too many requests and started rate limiting." + ) + exit(1) + else: + # any other reason + print( + f"GET https://api.github.com/repos/{project.repo_url_part} returned status code {response.status_code}" + ) + # replace + with open( + os.path.join(os.path.dirname(__file__), "_project_stars.py"), "w" + ) as file: + file.write("STARS = " + json.dumps(STARS, indent=4)) + console.log("Done!") + + +if __name__ == "__main__": + main() diff --git a/src/textual/demo/_project_stars.py b/src/textual/demo/_project_stars.py new file mode 100644 index 0000000000..3a19e8edc3 --- /dev/null +++ b/src/textual/demo/_project_stars.py @@ -0,0 +1,15 @@ +STARS = { + "Posting": "9.5k", + "Memray": "14.2k", + "Toolong": "3.5k", + "Dolphie": 857, + "Harlequin": "4.8k", + "Elia": "2.2k", + "Trogon": "2.6k", + "TFTUI - The Terraform textual UI": "1.1k", + "RecoverPy": "1.5k", + "Frogmouth": "2.8k", + "oterm": "2.0k", + "logmerger": 194, + "doit": "2.6k", +} diff --git a/src/textual/demo/projects.py b/src/textual/demo/projects.py index e264fd7143..dbf40eade6 100644 --- a/src/textual/demo/projects.py +++ b/src/textual/demo/projects.py @@ -8,18 +8,8 @@ from textual.containers import Center, Horizontal, ItemGrid, Vertical, VerticalScroll from textual.demo.page import PageScreen from textual.widgets import Footer, Label, Link, Markdown, Static - - -@dataclass -class ProjectInfo: - """Dataclass for storing project information.""" - - title: str - author: str - url: str - description: str - stars: str - +from textual.demo._project_stars import STARS +from textual.demo._project_data import PROJECTS, ProjectInfo PROJECTS_MD = """\ # Projects @@ -30,101 +20,6 @@ class ProjectInfo: See below for a small selection! """ -PROJECTS = [ - ProjectInfo( - "Posting", - "Darren Burns", - "https://posting.sh/", - """Posting is an HTTP client, not unlike Postman and Insomnia. As a TUI application, it can be used over SSH and enables efficient keyboard-centric workflows. """, - "6.0k", - ), - ProjectInfo( - "Memray", - "Bloomberg", - "https://github.com/bloomberg/memray", - """Memray is a memory profiler for Python. It can track memory allocations in Python code, in native extension modules, and in the Python interpreter itself.""", - "13.3k", - ), - ProjectInfo( - "Toolong", - "Will McGugan", - "https://github.com/Textualize/toolong", - """A terminal application to view, tail, merge, and search log files (plus JSONL).""", - "3.2k", - ), - ProjectInfo( - "Dolphie", - "Charles Thompson", - "https://github.com/charles-001/dolphie", - "Your single pane of glass for real-time analytics into MySQL/MariaDB & ProxySQL", - "649", - ), - ProjectInfo( - "Harlequin", - "Ted Conbeer", - "https://harlequin.sh/", - """Portable, powerful, colorful. An easy, fast, and beautiful database client for the terminal.""", - "3.7k", - ), - ProjectInfo( - "Elia", - "Darren Burns", - "https://github.com/darrenburns/elia", - """A snappy, keyboard-centric terminal user interface for interacting with large language models. -Chat with Claude 3, ChatGPT, and local models like Llama 3, Phi 3, Mistral and Gemma.""", - "1.8k", - ), - ProjectInfo( - "Trogon", - "Textualize", - "https://github.com/Textualize/trogon", - "Auto-generate friendly terminal user interfaces for command line apps.", - "2.5k", - ), - ProjectInfo( - "TFTUI - The Terraform textual UI", - "Ido Avraham", - "https://github.com/idoavrah/terraform-tui", - "TFTUI is a powerful textual UI that empowers users to effortlessly view and interact with their Terraform state.", - "1k", - ), - ProjectInfo( - "RecoverPy", - "Pablo Lecolinet", - "https://github.com/PabloLec/RecoverPy", - """RecoverPy is a powerful tool that leverages your system capabilities to recover lost files.""", - "1.3k", - ), - ProjectInfo( - "Frogmouth", - "Dave Pearson", - "https://github.com/Textualize/frogmouth", - """Frogmouth is a Markdown viewer / browser for your terminal, built with Textual.""", - "2.5k", - ), - ProjectInfo( - "oterm", - "Yiorgis Gozadinos", - "https://github.com/ggozad/oterm", - "The text-based terminal client for Ollama.", - "1k", - ), - ProjectInfo( - "logmerger", - "Paul McGuire", - "https://github.com/ptmcg/logmerger", - "logmerger is a TUI for viewing a merged display of multiple log files, merged by timestamp.", - "162", - ), - ProjectInfo( - "doit", - "Murli Tawari", - "https://github.com/kraanzu/dooit", - "A todo manager that you didn't ask for, but needed!", - "2.1k", - ), -] - class Project(Vertical, can_focus=True, can_focus_children=False): """Display project information and open repo links.""" @@ -133,16 +28,16 @@ class Project(Vertical, can_focus=True, can_focus_children=False): DEFAULT_CSS = """ Project { width: 1fr; - height: auto; + height: auto; padding: 0 1; border: tall transparent; box-sizing: border-box; - &:focus { + &:focus { border: tall $text-primary; background: $primary 20%; &.link { color: red !important; - } + } } #title { text-style: bold; width: 1fr; } #author { text-style: italic; } @@ -179,7 +74,7 @@ def compose(self) -> ComposeResult: info = self.project_info with Horizontal(classes="header"): yield Label(info.title, id="title") - yield Label(f"★ {info.stars}", classes="stars") + yield Label(f"★ {STARS[info.title]}", classes="stars") yield Label(info.author, id="author") yield Link(info.url, tooltip="Click to open project repository") yield Static(info.description, classes="description") @@ -197,18 +92,18 @@ def action_open_repository(self) -> None: class ProjectsScreen(PageScreen): AUTO_FOCUS = None CSS = """ - ProjectsScreen { - align-horizontal: center; + ProjectsScreen { + align-horizontal: center; ItemGrid { margin: 2 4; padding: 1 2; background: $boost; width: 1fr; - height: auto; + height: auto; grid-gutter: 1 1; - grid-rows: auto; - keyline:thin $foreground 30%; - } + grid-rows: auto; + keyline:thin $foreground 30%; + } Markdown { margin: 0; padding: 0 2; max-width: 100; background: transparent; } } """