feat : Waybar Weekly commit module

This commit is contained in:
Ayush Dumasia 2025-06-07 12:51:17 +05:30
parent 43a1dc2442
commit df780e4c12
5 changed files with 413 additions and 0 deletions

1
waybar/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
scripts/.env

View file

@ -9,6 +9,7 @@
"modules-right": [
// "custom/cava",
"hyprland/window",
"custom/gh",
"temperature#gpu",
// "custom/update" ,
"custom/transparency",
@ -19,6 +20,12 @@
// "bluetooth",
"battery"
],
"custom/gh": {
"exec": "~/.config/waybar/scripts/weekly_commits",
"return-type": "json",
"interval": 3600, // Update every hour
"tooltip": true
},
"hyprland/window": {
"format": "{initialClass}",
"icon": true,

131
waybar/scripts/weekly_commits Executable file
View file

@ -0,0 +1,131 @@
#!/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'<span foreground="{color}">●</span>')
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))

261
waybar/styl.css Normal file
View file

@ -0,0 +1,261 @@
@import 'mocha.css';
* {
font-family: JetBrains Mono Nerd Font;
min-height: 12px;
font-size: 12px;
border-radius: 6px;
padding: 0;
margin: 0;
box-shadow: none;
text-shadow: none;
background-color: transparent;
}
window#waybar {
background: rgba(0, 0, 0, 0.65);
color: @beige;
border-radius: 6px;
padding: 2px;
box-shadow: none;
}
#window {
color: @text;
/* background: @raisin-black; */
padding: 6px;
margin: 0px 2px;
}
#custom-cava {
color: #cba6f7;
border-left: 0px;
border-right: 0px;
padding: 6px;
font-family: 'bargraph';
background: @raisin-black;
margin: 0px 2px;
}
#cpu {
color: @beige;
padding: 0px 8px 0px 15px;
/* background: @raisin-black; */
margin-left: 2px;
border-radius: 6px 0 0 6px;
}
#memory {
color: @beige;
padding: 0px 15px 0px 8px;
/* background: @raisin-black; */
margin-right: 1px;
border-radius: 0 6px 6px 0;
}
#temperature.gpu {
padding: 0px 12px;
margin-right: 2px;
color: @celadon;
/* background: @raisin-black; */
border-radius: 6px;
}
/* General Styling */
tooltip,
menu,
#workspaces,
#clock,
#pulseaudio,
#backlight,
#bluetooth,
#network,
#battery,
#custom-power {
/* background: @raisin-black; */
padding: 7px 8px;
margin: 0;
border-radius: 6px;
}
#workspaces {
/* background: @raisin-black; */
margin: 0;
margin-left: 3px;
padding: 0;
font-weight: bold;
font-style: normal;
opacity: 1;
font-size: 20px;
color: #1e1;
border-radius: 6px;
}
#workspaces button {
padding: 0px 5px;
margin: 3px;
border-radius: 6px;
border: none;
transition: all 0.3s ease-in-out;
opacity: 0.4;
}
#workspaces button.active {
color: #1e1e2e;
background: #cba6f7;
min-width: 20px;
opacity: 1;
}
#workspaces button:hover {
color: @cerise;
background: #1e1e2e;
opacity: 1;
animation: none;
}
#workspaces button:not(.active) {
color: #74c7ec;
}
#workspaces button:nth-child(1):not(.active) {
color: #f38ba8;
}
#workspaces button:nth-child(2):not(.active) {
color: #f9e2af;
}
#workspaces button:nth-child(3):not(.active) {
color: #a6e3a1;
}
#clock {
padding: 0 15px;
color: @beige;
border-radius: 6px;
}
#custom-launcher {
font-size: 18px;
transition: none;
padding: 0px 10px;
margin-right: 2px;
/* background: @raisin-black; */
color: rgba(137, 220, 235, 1);
border-radius: 0 6px 6px 0;
}
#custom-transparency {
font-size: 18px;
/* background: @raisin-black; */
color: #94e2d5;
padding: 0px 10px;
margin-right: 2px;
border-radius: 6px;
/* border-radius: 6px 0 0 6px; */
/* border-radius: 0 6px 6px 0; */
}
#custom-wallpaper {
font-size: 20px;
font-family: 'Font Awesome 5 Free';
padding: 0px 8px;
margin-right: 1px;
color: #f38ba8;
/* background: @raisin-black; */
/* border-radius: 0 6px 6px 0; */
border-radius: 6px;
}
#pulseaudio,
#backlight {
padding: 0 8px;
margin: 0 1px;
color: @beige;
border-radius: 6px 6px;
}
#bluetooth,
#network {
color: #cba6f7;
border-radius: 6px;
margin: 0 1px;
}
#custom-volume {
padding: 0 8px;
/* color: @beige; */
}
#network.speed {
/* background: @raisin-black; */
padding: 0px 6px;
min-width: 10px;
color: @beige;
border-radius: 6px;
}
#bluetooth {
min-width: 20px;
padding: 0 10px;
margin: 0 2px;
border-radius: 6px;
}
#network {
min-width: 30px;
padding: 0 7px 0 2px;
/* margin: 0 2px; */
border-radius: 6px;
/* border-radius: 0 6px 6px 0; */
}
#battery {
color: @mint;
min-width: 30px;
padding-left: 5px;
margin-left: 1px;
margin-right: 3px;
/* margin: 0 1px; */
padding-right: 5px;
border-radius: 6px;
}
#battery.charging {
color: #33ae18; /* Text */
/* background: @raisin-black; */
border-radius: 6px;
}
#battery.good:not(.charging) {
color: #f8d589;
/* background: @raisin-black; */
border-radius: 6px;
}
#battery.warning:not(.charging) {
color: #e0a858; /* Text */
/* background: @raisin-black; */
border-radius: 6px;
}
#battery.low:not(.charging) {
color: #d20f39; /* Text */
/* background: @raisin-black; */
border-radius: 6px;
}
#battery.critical:not(.charging) {
color: #d20f39; /* Text */
/* background: @raisin-black; */
animation-name: blink;
animation-duration: 0.75s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
border-radius: 6px;
}
@keyframes blink {
to {
color: #d20f39; /* Red */
background: #eff1f5; /* Text */
}
}

View file

@ -12,6 +12,19 @@
text-shadow: none;
background-color: transparent;
}
#custom-gh {
color: #39d353; /* Default color for contributions */
background: @raisin-black;
border-radius: 6px;
margin-right: 2px;
padding: 6px;
}
#custom-gh .empty {
color: #161b22; /* Color for no contributions */
}
window#waybar {
/* background: rgba(0, 0, 0, 0.45); */
/* color: @text; */