81 lines
2.2 KiB
Python
81 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Gitea Language Stats
|
|
Calculates the percentage of every programming language used
|
|
in all repositories of a given account and prints a markdown
|
|
table to stdout, delimited by the
|
|
markers <!--LANG_STATS_START--> … <!--LANG_STATS_END-->.
|
|
|
|
Required environment variables
|
|
--------------------------------
|
|
GITEA_BASE_URL e.g. https://gitea.example.com
|
|
GITEA_TOKEN personal access-token with `repo` scope
|
|
GITEA_USERNAME the account to analyse
|
|
"""
|
|
import os
|
|
import sys
|
|
import requests
|
|
from collections import defaultdict
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
BASE_URL = os.getenv("GITEA_BASE_URL", "").rstrip("/")
|
|
TOKEN = os.getenv("GITEA_TOKEN")
|
|
USERNAME = os.getenv("GITEA_USERNAME")
|
|
|
|
if not BASE_URL or not TOKEN or not USERNAME:
|
|
sys.exit("GITEA_BASE_URL, GITEA_TOKEN and GITEA_USERNAME must be set")
|
|
|
|
session = requests.Session()
|
|
session.headers["Authorization"] = f"token {TOKEN}"
|
|
|
|
# ---------- collect repositories ----------
|
|
page = 1
|
|
repos = []
|
|
while True:
|
|
resp = session.get(
|
|
f"{BASE_URL}/api/v1/users/{USERNAME}/repos",
|
|
params={"page": page, "limit": 50},
|
|
timeout=30,
|
|
)
|
|
resp.raise_for_status()
|
|
batch = resp.json()
|
|
if not batch:
|
|
break
|
|
repos.extend(batch)
|
|
page += 1
|
|
|
|
# ---------- aggregate language bytes ----------
|
|
totals: dict[str, int] = defaultdict(int)
|
|
|
|
for repo in repos:
|
|
langs = session.get(
|
|
f"{BASE_URL}/api/v1/repos/{USERNAME}/{repo['name']}/languages",
|
|
timeout=30,
|
|
).json()
|
|
for lang, bytes_ in langs.items():
|
|
totals[lang] += bytes_
|
|
|
|
total_bytes = sum(totals.values())
|
|
if total_bytes == 0:
|
|
sys.exit("No language data returned from API.")
|
|
|
|
# ---------- build markdown table ----------
|
|
pairs = sorted(totals.items(), key=lambda x: x[1], reverse=True)
|
|
|
|
lines = [
|
|
"## 📊 Language Usage\n",
|
|
"| Language | Percent |\n",
|
|
"|----------|---------|\n",
|
|
]
|
|
for lang, nbytes in pairs:
|
|
pct = nbytes * 100 / total_bytes
|
|
bar = "█" * int(pct / 2) # up to 50 chars
|
|
lines.append(f"| {lang} | {pct:5.1f}% {bar} |\n")
|
|
|
|
block = "<!--LANG_STATS_START-->\n" + "".join(lines) + "<!--LANG_STATS_END-->\n"
|
|
|
|
# ---------- output markdown block ----------
|
|
print(block)
|