#!/usr/bin/env python3 import requests import datetime import json from collections import OrderedDict import os from dotenv import load_dotenv load_dotenv() GITHUB_USERNAME = os.getenv("GITHUB_USERNAME") GITHUB_PAT = os.getenv("GITHUB_PAT") today = datetime.date.today() start_of_week = today - datetime.timedelta(days=today.weekday()) from_date = start_of_week.isoformat() + "T00:00:00Z" to_date = today.isoformat() + "T23:59:59Z" query = """ query($user: String!, $from: DateTime!, $to: DateTime!) { user(login: $user) { contributionsCollection(from: $from, to: $to) { contributionCalendar { weeks { contributionDays { date contributionCount weekday } } } } } } """ variables = { "user": GITHUB_USERNAME, "from": from_date, "to": to_date } headers = { "Authorization": f"Bearer {GITHUB_PAT}", "Accept": "application/vnd.github.v4.idl" } COLOR_SCHEME = { 0: "#ebedf0", # No contributions (light gray) 1: "#9be9a8", # 1-3 commits (light green) 2: "#40c463", # 4-6 commits (medium green) 3: "#30a14e", # 7-9 commits (dark green) 4: "#216e39" # 10+ commits (darkest green) } def get_color(count): """Get GitHub-like color based on contribution count""" if count == 0: return COLOR_SCHEME[0] elif 1 <= count <= 3: return COLOR_SCHEME[1] elif 4 <= count <= 6: return COLOR_SCHEME[2] elif 7 <= count <= 9: return COLOR_SCHEME[3] else: return COLOR_SCHEME[4] def get_weekday_name(weekday): """Convert weekday number (0-6) to abbreviated name""" return ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"][weekday] try: response = requests.post( "https://api.github.com/graphql", json={"query": query, "variables": variables}, headers=headers, timeout=10 ) response.raise_for_status() data = response.json() weeks = data["data"]["user"]["contributionsCollection"]["contributionCalendar"]["weeks"] contributions = OrderedDict() for i in range(7): day = start_of_week + datetime.timedelta(days=i) contributions[day] = 0 for week in weeks: for day in week["contributionDays"]: date = datetime.date.fromisoformat(day["date"]) if start_of_week <= date <= today: contributions[date] = day["contributionCount"] dots = [] tooltip_lines = [] total_contributions = 0 for date, count in contributions.items(): color = get_color(count) dots.append(f'') weekday = get_weekday_name(date.weekday()) tooltip_lines.append(f"{weekday}: {count} contribution{'s' if count != 1 else ''}") total_contributions += count output = { "text": " ".join(dots), "tooltip": "\n".join([f"GitHub Contributions ({start_of_week} to {today})", f"Total: {total_contributions}"] + tooltip_lines), "class": "github-contributions", "alt": "GitHub Contributions" } except requests.exceptions.RequestException as e: output = { "text": "⚠", "tooltip": f"GitHub API error: {str(e)}", "class": "error", "alt": "GitHub Error" } except Exception as e: output = { "text": "⚠", "tooltip": f"Error: {str(e)}", "class": "error", "alt": "Error" } print(json.dumps(output))