Skip to content

Instantly share code, notes, and snippets.

@conor-f
Last active February 27, 2023 04:00
Show Gist options
  • Save conor-f/93221bb74fb522d0e98029c48417eac0 to your computer and use it in GitHub Desktop.
Save conor-f/93221bb74fb522d0e98029c48417eac0 to your computer and use it in GitHub Desktop.
This script will let you write short phrases on your Github contributions heatmap on your profile for a particular year.
### github_heatmap_writer.py
#
# Overview:
# This script will let you write short phrases on your Github contributions
# heatmap on your profile for a particular year. It does this by modifying the
# commit date/time.
#
# Usage:
# - Make a Github repo (public or private) and clone it locally.
# - Modify this script to specify what year you want to display on and what
# you want to show.
# - Run this script from within the Github repo.
#
# Tested on python3.8, for an example output, see the following:
# https://github.com/conor-f?tab=overview&from=1970-12-01&to=1970-12-31
import datetime
import os
LETTER_WIDTH = 3
INTER_LETTER_SPACE_WIDTH = 1
LETTERS = {
'a': [
(0, 0), (1, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (1, 2), (2, 2),
(0, 3), (2, 3),
(0, 4), (2, 4),
],
'b': [
(0, 0), (1, 0),
(0, 1), (2, 1),
(0, 2), (1, 2),
(0, 3), (2, 3),
(0, 4), (1, 4),
],
'c': [
(0, 0), (1, 0), (2, 0),
(0, 1),
(0, 2),
(0, 3),
(0, 4), (1, 4), (2, 4),
],
'd': [
(0, 0), (1, 0),
(0, 1), (2, 1),
(0, 2), (2, 2),
(0, 3), (2, 3),
(0, 4), (1, 4),
],
'e': [
(0, 0), (1, 0), (2, 0),
(0, 1),
(0, 2), (1, 2), (2, 2),
(0, 3),
(0, 4), (1, 4), (2, 4),
],
'f': [
(0, 0), (1, 0), (2, 0),
(0, 1),
(0, 2), (1, 2),
(0, 3),
(0, 4),
],
'g': [
(0, 0), (1, 0), (2, 0),
(0, 1),
(0, 2),
(0, 3), (2, 3),
(0, 4), (1, 4), (2, 4),
],
'h': [
(0, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (1, 2), (2, 2),
(0, 3), (2, 3),
(0, 4), (2, 4),
],
'i': [
(1, 0),
(1, 1),
(1, 2),
(1, 3),
(1, 4),
],
'j': [
(0, 0), (1, 0), (2, 0),
(1, 1),
(1, 2),
(1, 3),
(0, 4), (1, 4),
],
'k': [
(0, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (1, 2),
(0, 3), (2, 3),
(0, 4), (2, 4),
],
'l': [
(0, 0),
(0, 1),
(0, 2),
(0, 3),
(0, 4), (1, 4), (2, 4),
],
'm': [
(0, 0), (2, 0),
(0, 1), (1, 1), (2, 1),
(0, 2), (2, 2),
(0, 3), (2, 3),
(0, 4), (2, 4),
],
'n': [
(0, 0), (1, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (2, 2),
(0, 3), (2, 3),
(0, 4), (2, 4),
],
'o': [
(0, 0), (1, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (2, 2),
(0, 3), (2, 3),
(0, 4), (1, 4), (2, 4),
],
'p': [
(0, 0), (1, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (1, 2), (2, 2),
(0, 3),
(0, 4),
],
'q': [
(0, 0), (1, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (2, 2),
(0, 3), (1, 3),
(2, 4),
],
'r': [
(0, 0), (1, 0),
(0, 1), (2, 1),
(0, 2), (1, 2),
(0, 3), (2, 3),
(0, 4), (2, 4),
],
's': [
(0, 0), (1, 0), (2, 0),
(0, 1),
(0, 2), (1, 2), (2, 2),
(2, 3),
(0, 4), (1, 4), (2, 4),
],
't': [
(0, 0), (1, 0), (2, 0),
(1, 1),
(1, 2),
(1, 3),
(1, 4),
],
'u': [
(0, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (2, 2),
(0, 3), (2, 3),
(0, 4), (1, 4), (2, 4),
],
'v': [
(0, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (2, 2),
(0, 3), (2, 3),
(1, 4),
],
'w': [
(0, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (1, 2), (2, 2),
(0, 3), (1, 3), (2, 3),
(0, 4), (1, 4), (2, 4),
],
'x': [
(0, 0), (2, 0),
(0, 1), (2, 1),
(1, 2),
(0, 3), (2, 3),
(0, 4), (2, 4),
],
'y': [
(0, 0), (2, 0),
(0, 1), (2, 1),
(1, 2),
(1, 3),
(1, 4),
],
'z': [
(0, 0), (1, 0), (2, 0),
(2, 1),
(1, 2),
(0, 3),
(0, 4), (1, 4), (2, 4),
],
'?': [
(0, 0), (1, 0), (2, 0),
(0, 1), (2, 1),
(2, 2),
(1, 3), (2, 3),
(1, 4),
],
'!': [
(1, 0),
(1, 1),
(1, 2),
(1, 4),
],
'-': [
(0, 2), (1, 2), (2, 2),
],
',': [
(1, 3),
(0, 4), (1, 4),
],
'1': [
(1, 0),
(0, 1), (1, 1),
(1, 2),
(1, 3),
(0, 4), (1, 4), (2, 4),
],
'2': [
(0, 0), (1, 0), (2, 0),
(2, 1),
(0, 2), (1, 2), (2, 2),
(0, 3),
(0, 4), (1, 4), (2, 4),
],
'3': [
(0, 0), (1, 0), (2, 0),
(2, 1),
(0, 2), (1, 2), (2, 2),
(2, 3),
(0, 4), (1, 4), (2, 4),
],
'4': [
(0, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (1, 2), (2, 2),
(2, 3),
(2, 4),
],
'5': [
(0, 0), (1, 0), (2, 0),
(0, 1),
(0, 2), (1, 2), (2, 2),
(2, 3),
(0, 4), (1, 4), (2, 4),
],
'6': [
(0, 0), (1, 0),
(0, 1),
(0, 2), (1, 2), (2, 2),
(0, 3), (2, 3),
(0, 4), (1, 4), (2, 4),
],
'7': [
(0, 0), (1, 0), (2, 0),
(2, 1),
(1, 2), (2, 2),
(2, 3),
(2, 4),
],
'8': [
(0, 0), (1, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (1, 2), (2, 2),
(0, 3), (2, 3),
(0, 4), (1, 4), (2, 4),
],
'9': [
(0, 0), (1, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (1, 2), (2, 2),
(2, 3),
(2, 4),
],
'0': [
(0, 0), (1, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (2, 2),
(0, 3), (2, 3),
(0, 4), (1, 4), (2, 4),
],
' ': []
}
def modify_file(filename):
"""
Horrendous code. Just use path...
"""
if len(filename.split("/")) > 1:
os.system(f"mkdir -p {'/'.join(filename.split('/')[:-1])}")
os.system(f"touch {filename}")
os.system(f"echo '1' >> {filename}")
def git_add_file(filename):
os.system(f"git add {filename} >/dev/null 2>&1")
def git_push():
os.system(f"git push >/dev/null 2>&1")
def git_commit_file_on_date(filename, datetime_obj):
"""
"""
date_string = datetime_obj.ctime()
command_str = f"LC_ALL=C GIT_COMMITTER_DATE='{date_string}' "
command_str += f"git commit {filename} -m'{date_string}' "
command_str += f"--no-edit --date '{date_string}'"
os.system(f"{command_str} >/dev/null 2>&1")
def get_origin_datetime(year):
"""
Returns the datetime of (0,0) on the contributions heatmap.
This is horrific code.
"""
d = datetime.datetime(year, 1, 1, 12)
while d.weekday() != 6:
d += datetime.timedelta(1)
return d
def xy_to_datetime(year, x, y):
return get_origin_datetime(year) + datetime.timedelta((7 * x) + y)
def commit_on_xy(year, x, y):
"""
Given a year and an x/y position, make a commit corresponding to that
location on the contributions heatmap.
"""
filename = f"{year}/{x}/{y}"
datetime_obj = xy_to_datetime(year, x, y)
modify_file(filename)
git_add_file(filename)
git_commit_file_on_date(filename, datetime_obj)
def draw_letter(year, letter, letter_number):
"""
The letter_number is to calculate the offset to apply in the grid.
"""
x_offset = letter_number * (LETTER_WIDTH + INTER_LETTER_SPACE_WIDTH)
# This centres the letter vertically
y_offset = 1
for coord in LETTERS[letter]:
commit_on_xy(year, x_offset + coord[0], y_offset + coord[1])
def draw_word(year, word):
word = word.lower()
for i in range(len(word)):
draw_letter(year, word[i], i)
git_push()
draw_word(1970, "Hello, World!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment