/ vidolib / scripts / generate-star-history.py
dichbang Update scripts/generate-star-history.py · 7/24/2026
a2df494
78 lines · 2.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
"""
Fetches stargazer history for the current repo and renders a static
star-history chart to assets/star-history.svg.

Run inside GitHub Actions where GH_TOKEN and REPO are set automatically
(see .github/workflows/star-history.yml). Can also be run locally:

    GH_TOKEN=<personal-access-token> REPO=owner/name python generate-star-history.py
"""

import os
import requests
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime

TOKEN = os.environ["GH_TOKEN"]
REPO = os.environ["REPO"]  # e.g. "swadhinbiswas/VidoLib"

HEADERS = {
    "Authorization": f"Bearer {TOKEN}",
    # This custom media type makes GitHub include a "starred_at" timestamp
    # on each stargazer record, which is not present in the default response.
    "Accept": "application/vnd.github.star+json",
}


def fetch_stargazers():
    stars = []
    page = 1
    while True:
        resp = requests.get(
            f"https://api.github.com/repos/{REPO}/stargazers",
            headers=HEADERS,
            params={"per_page": 100, "page": page},
            timeout=(10, 30),
        )
        resp.raise_for_status()
        data = resp.json()
        if not data:
            break
        stars.extend(data)
        page += 1
    return stars


def main():
    stars = fetch_stargazers()
    dates = sorted(
        datetime.strptime(s["starred_at"], "%Y-%m-%dT%H:%M:%SZ") for s in stars
    )

    if not dates:
        print("No stargazers yet, skipping chart.")
        return

    counts = list(range(1, len(dates) + 1))

    fig, ax = plt.subplots(figsize=(8, 4))
    ax.plot(dates, counts, color="#2f81f7", linewidth=2)
    ax.fill_between(dates, counts, color="#2f81f7", alpha=0.1)
    ax.set_title(f"Star History — {REPO}")
    ax.set_xlabel("Date")
    ax.set_ylabel("Stars")
    ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m"))
    fig.autofmt_xdate()
    ax.grid(alpha=0.3)

    os.makedirs("assets", exist_ok=True)
    fig.savefig("assets/star-history.svg", format="svg", bbox_inches="tight")
    print(f"Saved chart with {len(dates)} stars.")


if __name__ == "__main__":
    main()