Skip to content

Instantly share code, notes, and snippets.

@dynamic-entropy
Created May 18, 2024 09:37
Show Gist options
  • Save dynamic-entropy/a276bf0d2493d4c5e907b0931e71a341 to your computer and use it in GitHub Desktop.
Save dynamic-entropy/a276bf0d2493d4c5e907b0931e71a341 to your computer and use it in GitHub Desktop.
import calendar
import argparse
from datetime import datetime, timedelta
from PIL import Image, ImageDraw, ImageFont
def generate_calendar(year, filename):
# Determine the start and end dates of the year
start_date = datetime(year, 1, 1)
end_date = datetime(year, 12, 31)
# Determine the number of days in the year
days_in_year = (end_date - start_date).days + 1
# Create an image
cell_size = 20
gap = 2
margin = 40
weeks_in_year = (days_in_year + start_date.weekday()) // 7 + 1
img_width = cell_size * weeks_in_year + \
margin * 2 + gap * (weeks_in_year - 1)
img_height = cell_size * 7 + margin * 2
image = Image.new("RGB", (img_width, img_height), "white")
draw = ImageDraw.Draw(image)
# Load a font
try:
font = ImageFont.truetype("arial.ttf", 12)
except IOError:
font = ImageFont.load_default()
# Draw month labels
month_starts = {}
for month in range(1, 13):
month_start = datetime(year, month, 1)
month_start_week = (month_start - start_date).days // 7
month_starts[month] = month_start_week
for month, week in month_starts.items():
month_name = calendar.month_abbr[month]
x_pos = margin + week * (cell_size + gap)
draw.text((x_pos, margin - 20), month_name, fill="black", font=font)
# Draw day labels
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
for i, day in enumerate(days):
y_pos = margin + i * (cell_size + gap)
draw.text((margin - 30, y_pos + cell_size // 4),
day, fill="black", font=font)
# Fill the calendar with cells
for day in range(days_in_year):
current_date = start_date + timedelta(days=day)
week = (day + start_date.weekday()) // 7
day_of_week = current_date.weekday()
x = margin + week * (cell_size + gap)
y = margin + day_of_week * (cell_size + gap)
# Draw a rounded rectangle as a cell
draw.rounded_rectangle([x, y, x + cell_size - 1, y + cell_size - 1],
3, fill="white", outline="black")
# Save the image
image.save(filename)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("year", type=int, help="The year for the tracker")
parser.add_argument("--filename", type=str,
help="The output filename", default="tracker.png")
args = parser.parse_args()
generate_calendar(args.year, args.filename)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment