mirror of
https://github.com/okhsunrog/vpnhide.git
synced 2026-04-28 06:31:27 +00:00
Repo had ~1800 lines of Python (kmod/build.py, scripts/*, zygisk/build.py,
portshide/build-zip.py) with no formatter or linter. Long-lived scripts
like scripts/release.py and scripts/codegen-interfaces.py benefit from
catching unused-import / undefined-name / outdated-syntax issues early.
pyproject.toml — ruff config, target-py312, line-length 100,
rules E F W I B UP SIM. Excludes zygisk/third_party,
target/, .claude/.
ci.yml — astral-sh/ruff-action@v4 for `format --check` and `check`,
ahead of the slow Rust/Gradle steps so it fails fast.
docs/development.md — add `uvx ruff …` to the local-lint snippet.
Cleanup applied (`ruff format` + `ruff check --fix`):
- reformat: kmod/build.py, scripts/{changelog_lib,codegen-interfaces,
release,stats}.py, zygisk/build.py
- I001: split multi-name imports onto separate lines after the
sys.path.insert prelude (kmod/build.py, zygisk/build.py)
- E501 manual: wrap one console.print line in scripts/release.py
Stdlib-only invariant from scripts/build_lib.py is preserved — ruff is
a dev/CI tool, not imported at runtime.
70 lines
2 KiB
Python
Executable file
70 lines
2 KiB
Python
Executable file
#!/usr/bin/env -S uv run --script
|
|
#
|
|
# /// script
|
|
# requires-python = ">=3.12"
|
|
# dependencies = [
|
|
# "httpx",
|
|
# "rich",
|
|
# ]
|
|
# ///
|
|
|
|
import os
|
|
import subprocess
|
|
|
|
import httpx
|
|
from rich.console import Console
|
|
from rich.table import Table
|
|
|
|
console = Console()
|
|
|
|
|
|
def github_token() -> str | None:
|
|
if token := os.environ.get("GITHUB_TOKEN"):
|
|
return token
|
|
try:
|
|
out = subprocess.run(["gh", "auth", "token"], capture_output=True, text=True, check=True)
|
|
return out.stdout.strip() or None
|
|
except (FileNotFoundError, subprocess.CalledProcessError):
|
|
return None
|
|
|
|
|
|
headers = {"Accept": "application/vnd.github+json"}
|
|
if token := github_token():
|
|
headers["Authorization"] = f"Bearer {token}"
|
|
|
|
resp = httpx.get("https://api.github.com/repos/okhsunrog/vpnhide/releases", headers=headers)
|
|
resp.raise_for_status()
|
|
releases = resp.json()
|
|
|
|
all_assets = [a for r in releases for a in r["assets"]]
|
|
max_count = max((a["download_count"] for a in all_assets), default=1) or 1
|
|
name_w = max((len(a["name"]) for a in all_assets), default=0)
|
|
count_w = max((len(str(a["download_count"])) for a in all_assets), default=1)
|
|
# padding=(0, 1) on 3 columns => 6 chars of horizontal padding, no borders (box=None)
|
|
bar_w = max(10, console.width - name_w - count_w - 6)
|
|
|
|
grand_total = 0
|
|
for release in releases:
|
|
assets = release["assets"]
|
|
total = sum(a["download_count"] for a in assets)
|
|
grand_total += total
|
|
|
|
table = Table(
|
|
title=f"{release['tag_name']} ({total} downloads)",
|
|
title_style="bold",
|
|
show_header=False,
|
|
box=None,
|
|
padding=(0, 1),
|
|
)
|
|
table.add_column("Asset", style="cyan")
|
|
table.add_column("Count", justify="right", style="yellow")
|
|
table.add_column("Bar", style="green", no_wrap=True)
|
|
|
|
for a in assets:
|
|
bar = "█" * max(1, a["download_count"] * bar_w // max_count)
|
|
table.add_row(a["name"], str(a["download_count"]), bar)
|
|
|
|
console.print()
|
|
console.print(table)
|
|
|
|
console.print(f"\n[bold green]Total: {grand_total} downloads[/bold green]")
|