mirror of
https://github.com/BillyOutlast/flash-attention-prebuild-wheels-rocm.git
synced 2026-06-29 22:13:37 -04:00
1bc47b39f2
- Rename docs/ to doc/ (contains packages.md, release_history.md, etc.) - Rename pages/ to docs/ (contains search page index.html) - Update all references in README.md, workflows, and Python scripts GitHub Pages only supports / or /docs as the source directory.
194 lines
5.3 KiB
Python
194 lines
5.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Fetch GitHub release download statistics and generate a graph.
|
|
|
|
This script fetches download counts from GitHub API, stores historical data,
|
|
and generates a graph showing download trends over time.
|
|
"""
|
|
|
|
import json
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
|
|
import matplotlib.pyplot as plt
|
|
import requests
|
|
|
|
|
|
def fetch_download_stats(owner: str, repo: str) -> dict:
|
|
"""
|
|
Fetch download statistics from GitHub API.
|
|
|
|
Args:
|
|
owner: Repository owner
|
|
repo: Repository name
|
|
|
|
Returns:
|
|
dict: Dictionary containing total downloads and timestamp
|
|
"""
|
|
url = f"https://api.github.com/repos/{owner}/{repo}/releases"
|
|
headers = {}
|
|
|
|
# Fetch all releases with pagination
|
|
all_releases = []
|
|
page = 1
|
|
per_page = 100 # Maximum per page allowed by GitHub API
|
|
|
|
while True:
|
|
params = {"page": page, "per_page": per_page}
|
|
response = requests.get(url, headers=headers, params=params)
|
|
response.raise_for_status()
|
|
|
|
releases = response.json()
|
|
if not releases:
|
|
break
|
|
|
|
all_releases.extend(releases)
|
|
page += 1
|
|
|
|
# Check if there are more pages
|
|
if len(releases) < per_page:
|
|
break
|
|
|
|
print(f"Fetched {len(all_releases)} releases")
|
|
|
|
total_downloads = 0
|
|
release_data = []
|
|
|
|
for release in all_releases:
|
|
release_downloads = 0
|
|
for asset in release.get("assets", []):
|
|
release_downloads += asset.get("download_count", 0)
|
|
|
|
total_downloads += release_downloads
|
|
release_data.append(
|
|
{
|
|
"tag": release["tag_name"],
|
|
"name": release["name"],
|
|
"downloads": release_downloads,
|
|
"created_at": release["created_at"],
|
|
}
|
|
)
|
|
|
|
return {
|
|
"total_downloads": total_downloads,
|
|
"releases": release_data,
|
|
}
|
|
|
|
|
|
def load_history(filepath: Path) -> list:
|
|
"""
|
|
Load historical download statistics from JSON file.
|
|
|
|
Args:
|
|
filepath: Path to the history JSON file
|
|
|
|
Returns:
|
|
list: List of historical data points
|
|
"""
|
|
if not filepath.exists():
|
|
return []
|
|
|
|
with open(filepath, "r") as f:
|
|
return json.load(f)
|
|
|
|
|
|
def save_history(filepath: Path, history: list) -> None:
|
|
"""
|
|
Save historical download statistics to JSON file.
|
|
|
|
Args:
|
|
filepath: Path to the history JSON file
|
|
history: List of historical data points
|
|
"""
|
|
filepath.parent.mkdir(parents=True, exist_ok=True)
|
|
with open(filepath, "w") as f:
|
|
json.dump(history, f, indent=2)
|
|
|
|
|
|
def generate_graph(history: list, output_path: Path, label: str = "") -> None:
|
|
"""
|
|
Generate a download statistics graph in Star History (XKCD) style.
|
|
"""
|
|
if len(history) < 2:
|
|
print("Not enough data to generate a graph (need at least 2 data points)")
|
|
return
|
|
|
|
dates = [datetime.fromisoformat(entry["timestamp"]) for entry in history]
|
|
downloads = [entry["total_downloads"] for entry in history]
|
|
|
|
# --- XKCD Style Context ---
|
|
# これにより手書き風のエフェクト(歪んだ線、手書きフォント)が適用されます
|
|
with plt.xkcd():
|
|
fig, ax = plt.subplots(figsize=(8, 6))
|
|
|
|
# Star History風の色(オレンジ/赤系)
|
|
line_color = "#f05133"
|
|
|
|
# プロット
|
|
ax.plot(
|
|
dates,
|
|
downloads,
|
|
color=line_color,
|
|
linewidth=3,
|
|
label=label if label else "Downloads",
|
|
)
|
|
|
|
if label:
|
|
legend = ax.legend(loc="upper left", frameon=True, fontsize=10)
|
|
legend.get_frame().set_edgecolor("black")
|
|
legend.get_frame().set_linewidth(1.5)
|
|
|
|
ax.spines["right"].set_color("none")
|
|
ax.spines["top"].set_color("none")
|
|
|
|
ax.spines["bottom"].set_linewidth(1.5)
|
|
ax.spines["left"].set_linewidth(1.5)
|
|
|
|
plt.title("Download History", fontsize=16, y=1.05)
|
|
plt.xlabel("Date", fontsize=12)
|
|
plt.ylabel("Total Downloads", fontsize=12)
|
|
|
|
ax.set_ylim(bottom=0)
|
|
|
|
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f"{int(x):,}"))
|
|
|
|
fig.autofmt_xdate(rotation=0, ha="center")
|
|
|
|
plt.tight_layout()
|
|
|
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
plt.savefig(output_path, dpi=150, bbox_inches="tight", facecolor="white")
|
|
print(f"Graph saved to {output_path}")
|
|
|
|
|
|
def main():
|
|
"""Main function to update download statistics and generate graph."""
|
|
owner = "mjun0812"
|
|
repo = "flash-attention-prebuild-wheels"
|
|
history_file = Path("doc/data/download_history.json")
|
|
graph_output = Path("doc/data/download_graph.png")
|
|
|
|
# Fetch current stats
|
|
print("Fetching download statistics from GitHub API...")
|
|
current_stats = fetch_download_stats(owner, repo)
|
|
print(f"Total downloads: {current_stats['total_downloads']}")
|
|
|
|
# Load and update history
|
|
history = load_history(history_file)
|
|
history.append(
|
|
{
|
|
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
"total_downloads": current_stats["total_downloads"],
|
|
}
|
|
)
|
|
|
|
# Save updated history
|
|
save_history(history_file, history)
|
|
print(f"History saved to {history_file}")
|
|
|
|
generate_graph(history, graph_output, f"{owner}/{repo}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|