Last active
February 27, 2023 04:00
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### 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