362
gitfiti.py
362
gitfiti.py
@ -1,7 +1,18 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os, sys, datetime, math, itertools, urllib2, json
|
"""
|
||||||
|
gitfiti
|
||||||
|
|
||||||
title='''
|
noun : Carefully crafted graffiti in a github commit history calendar
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import math
|
||||||
|
import itertools
|
||||||
|
import urllib2
|
||||||
|
import json
|
||||||
|
|
||||||
|
TITLE = '''
|
||||||
_ __ _____ __ _
|
_ __ _____ __ _
|
||||||
____ _(_) /_/ __(_) /_(_)
|
____ _(_) /_/ __(_) /_(_)
|
||||||
/ __ `/ / __/ /_/ / __/ /
|
/ __ `/ / __/ /_/ / __/ /
|
||||||
@ -10,7 +21,7 @@ title='''
|
|||||||
/____/
|
/____/
|
||||||
'''
|
'''
|
||||||
|
|
||||||
kitty=[
|
KITTY = [
|
||||||
[0,0,0,4,0,0,0,0,4,0,0,0],
|
[0,0,0,4,0,0,0,0,4,0,0,0],
|
||||||
[0,0,4,2,4,4,4,4,2,4,0,0],
|
[0,0,4,2,4,4,4,4,2,4,0,0],
|
||||||
[0,0,4,2,2,2,2,2,2,4,0,0],
|
[0,0,4,2,2,2,2,2,2,4,0,0],
|
||||||
@ -19,7 +30,7 @@ kitty=[
|
|||||||
[2,2,4,2,2,2,2,2,2,4,2,2],
|
[2,2,4,2,2,2,2,2,2,4,2,2],
|
||||||
[0,0,0,3,4,4,4,4,3,0,0,0]]
|
[0,0,0,3,4,4,4,4,3,0,0,0]]
|
||||||
|
|
||||||
oneup=[
|
ONEUP = [
|
||||||
[0,4,4,4,4,4,4,4,0],
|
[0,4,4,4,4,4,4,4,0],
|
||||||
[4,3,2,2,1,2,2,3,4],
|
[4,3,2,2,1,2,2,3,4],
|
||||||
[4,2,2,1,1,1,2,2,4],
|
[4,2,2,1,1,1,2,2,4],
|
||||||
@ -28,7 +39,7 @@ oneup=[
|
|||||||
[0,4,1,1,1,1,1,4,0],
|
[0,4,1,1,1,1,1,4,0],
|
||||||
[0,0,4,4,4,4,4,0,0]]
|
[0,0,4,4,4,4,4,0,0]]
|
||||||
|
|
||||||
oneup2=[
|
ONEUP2 = [
|
||||||
[0,0,4,4,4,4,4,4,4,0,0],
|
[0,0,4,4,4,4,4,4,4,0,0],
|
||||||
[0,4,2,2,1,1,1,2,2,4,0],
|
[0,4,2,2,1,1,1,2,2,4,0],
|
||||||
[4,3,2,2,1,1,1,2,2,3,4],
|
[4,3,2,2,1,1,1,2,2,3,4],
|
||||||
@ -37,7 +48,7 @@ oneup2=[
|
|||||||
[0,0,4,1,1,1,1,1,4,0,0],
|
[0,0,4,1,1,1,1,1,4,0,0],
|
||||||
[0,0,0,4,4,4,4,4,0,0,0]]
|
[0,0,0,4,4,4,4,4,0,0,0]]
|
||||||
|
|
||||||
hackerschool=[
|
HACKERSCHOOL = [
|
||||||
[4,4,4,4,4,4],
|
[4,4,4,4,4,4],
|
||||||
[4,3,3,3,3,4],
|
[4,3,3,3,3,4],
|
||||||
[4,1,3,3,1,4],
|
[4,1,3,3,1,4],
|
||||||
@ -46,7 +57,7 @@ hackerschool=[
|
|||||||
[0,0,4,4,0,0],
|
[0,0,4,4,0,0],
|
||||||
[4,4,4,4,4,4]]
|
[4,4,4,4,4,4]]
|
||||||
|
|
||||||
octocat=[
|
OCTOCAT = [
|
||||||
[0,0,0,4,0,0,0,4,0],
|
[0,0,0,4,0,0,0,4,0],
|
||||||
[0,0,4,4,4,4,4,4,4],
|
[0,0,4,4,4,4,4,4,4],
|
||||||
[0,0,4,1,3,3,3,1,4],
|
[0,0,4,1,3,3,3,1,4],
|
||||||
@ -55,7 +66,7 @@ octocat=[
|
|||||||
[0,0,4,4,4,4,4,4,4],
|
[0,0,4,4,4,4,4,4,4],
|
||||||
[0,0,4,0,4,0,4,0,4]]
|
[0,0,4,0,4,0,4,0,4]]
|
||||||
|
|
||||||
octocat2=[
|
OCTOCAT2 = [
|
||||||
[0,0,4,0,0,4,0],
|
[0,0,4,0,0,4,0],
|
||||||
[0,4,4,4,4,4,4],
|
[0,4,4,4,4,4,4],
|
||||||
[0,4,1,3,3,1,4],
|
[0,4,1,3,3,1,4],
|
||||||
@ -64,7 +75,7 @@ octocat2=[
|
|||||||
[0,4,4,4,4,4,0],
|
[0,4,4,4,4,4,0],
|
||||||
[0,0,0,4,4,4,0]]
|
[0,0,0,4,4,4,0]]
|
||||||
|
|
||||||
hello=[
|
HELLO = [
|
||||||
[0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,4],
|
[0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,4],
|
||||||
[0,2,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,4],
|
[0,2,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,4],
|
||||||
[0,3,3,3,0,2,3,3,0,3,0,3,0,1,3,1,0,3],
|
[0,3,3,3,0,2,3,3,0,3,0,3,0,1,3,1,0,3],
|
||||||
@ -73,7 +84,7 @@ hello=[
|
|||||||
[0,2,0,2,0,2,0,0,0,2,0,2,0,2,0,2,0,0],
|
[0,2,0,2,0,2,0,0,0,2,0,2,0,2,0,2,0,0],
|
||||||
[0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,4]]
|
[0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,4]]
|
||||||
|
|
||||||
hireme=[
|
HIREME = [
|
||||||
[1,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
[1,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||||
[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||||
[3,3,3,0,2,0,3,3,3,0,2,3,3,0,0,3,3,0,3,0,0,2,3,3],
|
[3,3,3,0,2,0,3,3,3,0,2,3,3,0,0,3,3,0,3,0,0,2,3,3],
|
||||||
@ -82,7 +93,7 @@ hireme=[
|
|||||||
[2,0,2,0,2,0,2,0,0,0,2,0,0,0,0,2,0,2,0,2,0,2,0,0],
|
[2,0,2,0,2,0,2,0,0,0,2,0,0,0,0,2,0,2,0,2,0,2,0,0],
|
||||||
[1,0,1,0,1,0,1,0,0,0,1,1,1,0,0,1,0,1,0,1,0,1,1,1]]
|
[1,0,1,0,1,0,1,0,0,0,1,1,1,0,0,1,0,1,0,1,0,1,1,1]]
|
||||||
|
|
||||||
ascii_to_number = {
|
ASCII_TO_NUMBER = {
|
||||||
'_': 0,
|
'_': 0,
|
||||||
'_': 1,
|
'_': 1,
|
||||||
'~': 2,
|
'~': 2,
|
||||||
@ -91,24 +102,21 @@ ascii_to_number = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def str_to_sprite(content):
|
def str_to_sprite(content):
|
||||||
# Break out lines and filter any excess
|
# Break out lines and filter any excess
|
||||||
lines = content.split('\n')
|
lines = content.split('\n')
|
||||||
def is_empty_line(line):
|
def is_empty_line(line):
|
||||||
return len(line) != 0
|
return len(line) != 0
|
||||||
lines = filter(is_empty_line, lines)
|
lines = filter(is_empty_line, lines)
|
||||||
|
# Break up lines into each character
|
||||||
|
split_lines = map(list, lines)
|
||||||
|
# Replace each character with its numeric equivalent
|
||||||
|
for line in split_lines:
|
||||||
|
for index, char in enumerate(line):
|
||||||
|
line[index] = ASCII_TO_NUMBER.get(char, 0)
|
||||||
|
# Return the formatted str
|
||||||
|
return split_lines
|
||||||
|
|
||||||
# Break up lines into each character
|
ONEUP_STR = str_to_sprite("""
|
||||||
split_lines = map(list, lines)
|
|
||||||
|
|
||||||
# Replace each character with its numeric equivalent
|
|
||||||
for line in split_lines:
|
|
||||||
for index, char in enumerate(line):
|
|
||||||
line[index] = ascii_to_number.get(char, 0)
|
|
||||||
|
|
||||||
# Return the formatted str
|
|
||||||
return split_lines
|
|
||||||
|
|
||||||
oneup_str = str_to_sprite("""
|
|
||||||
*******
|
*******
|
||||||
*=~~-~~=*
|
*=~~-~~=*
|
||||||
*~~---~~*
|
*~~---~~*
|
||||||
@ -118,164 +126,196 @@ oneup_str = str_to_sprite("""
|
|||||||
*****
|
*****
|
||||||
""")
|
""")
|
||||||
|
|
||||||
images={
|
IMAGES = {
|
||||||
'kitty':kitty,
|
'kitty': KITTY,
|
||||||
'oneup':oneup,
|
'oneup':ONEUP,
|
||||||
'oneup2':oneup2,
|
'oneup2':ONEUP2,
|
||||||
'hackerschool':hackerschool,
|
'hackerschool':HACKERSCHOOL,
|
||||||
'octocat':octocat,
|
'octocat':OCTOCAT,
|
||||||
'octocat2':octocat2,
|
'octocat2':OCTOCAT2,
|
||||||
'hello':hello,
|
'hello':HELLO,
|
||||||
'hireme':hireme,
|
'hireme':HIREME,
|
||||||
'oneup_str':oneup_str
|
'oneup_str':ONEUP_STR
|
||||||
}
|
}
|
||||||
|
|
||||||
def load_images(imgNames):
|
def load_images(img_names):
|
||||||
"""loads user images from given file(s)"""
|
"""loads user images from given file(s)"""
|
||||||
if imgNames[0]=='':
|
if img_names[0] == '':
|
||||||
return dict()
|
return dict()
|
||||||
for imageName in imgNames:
|
for image_name in img_names:
|
||||||
img = open(imageName)
|
img = open(image_name)
|
||||||
loadedImgs = {}
|
loaded_imgs = {}
|
||||||
imgList = ''
|
img_list = ''
|
||||||
imgLine = ' '
|
img_line = ' '
|
||||||
name = img.readline().replace('\n', '')
|
name = img.readline().replace('\n', '')
|
||||||
name = name[1:]
|
name = name[1:]
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
imgLine = img.readline()
|
img_line = img.readline()
|
||||||
if imgLine == '':
|
if img_line == '':
|
||||||
break
|
break
|
||||||
imgLine.replace('\n', '')
|
img_line.replace('\n', '')
|
||||||
if(imgLine[0] == ':'):
|
if(img_line[0] == ':'):
|
||||||
loadedImgs[name] = json.loads(imgList)
|
loaded_imgs[name] = json.loads(img_list)
|
||||||
name = imgLine[1:]
|
name = img_line[1:]
|
||||||
imgList = ''
|
img_list = ''
|
||||||
else:
|
else:
|
||||||
imgList += imgLine
|
img_list += img_line
|
||||||
loadedImgs[name] = json.loads(imgList)
|
loaded_imgs[name] = json.loads(img_list)
|
||||||
return loadedImgs
|
return loaded_imgs
|
||||||
|
|
||||||
def get_calendar(username):
|
def get_calendar(username, base_url='https://github.com/'):
|
||||||
"""retrieves the github commit calendar data for a username"""
|
"""retrieves the github commit calendar data for a username"""
|
||||||
BASEURL='https://github.com/'
|
url = base_url + 'users/' + username + '/contributions_calendar_data'
|
||||||
url = BASEURL + 'users/' + username + '/contributions_calendar_data'
|
try:
|
||||||
page = urllib2.urlopen(url)
|
page = urllib2.urlopen(url)
|
||||||
return json.load(page)
|
except (urllib2.HTTPError,urllib2.URLError) as e:
|
||||||
|
print "There was a problem fetching data from {0}".format(url)
|
||||||
|
print e
|
||||||
|
raise SystemExit
|
||||||
|
return json.load(page)
|
||||||
|
|
||||||
def max_commits(input):
|
def max_commits(input):
|
||||||
"""finds the highest number of commits in one day"""
|
"""finds the highest number of commits in one day"""
|
||||||
output = set()
|
output = set()
|
||||||
for i, j in enumerate(input):
|
for i, j in enumerate(input):
|
||||||
output.add(input[i][1])
|
output.add(input[i][1])
|
||||||
output = list(output)
|
output = list(output)
|
||||||
output.sort()
|
output.sort()
|
||||||
output.reverse()
|
output.reverse()
|
||||||
return output[0]
|
return output[0]
|
||||||
|
|
||||||
def multiplier(max_commits):
|
def multiplier(max_commits):
|
||||||
"""calculates a multiplier to scale github colors to commit history"""
|
"""calculates a multiplier to scale github colors to commit history"""
|
||||||
m = max_commits/4.0
|
m = max_commits/4.0
|
||||||
if m == 0: return 1
|
if m == 0: return 1
|
||||||
m = math.ceil(m)
|
m = math.ceil(m)
|
||||||
m = int(m)
|
m = int(m)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def get_start_date():
|
def get_start_date():
|
||||||
'''returns a datetime object for the first sunday after one year ago today at 12:00 noon'''
|
"""returns a datetime object for the first sunday after one year ago today
|
||||||
d = datetime.datetime.today()
|
at 12:00 noon"""
|
||||||
date = datetime.datetime(d.year-1, d.month, d.day, 12)
|
d = datetime.datetime.today()
|
||||||
weekday = datetime.datetime.weekday(date)
|
date = datetime.datetime(d.year-1, d.month, d.day, 12)
|
||||||
while weekday < 6:
|
weekday = datetime.datetime.weekday(date)
|
||||||
date = date + datetime.timedelta(1)
|
while weekday < 6:
|
||||||
weekday = datetime.datetime.weekday(date)
|
date = date + datetime.timedelta(1)
|
||||||
return date
|
weekday = datetime.datetime.weekday(date)
|
||||||
|
return date
|
||||||
|
|
||||||
def date_gen(start_date, offset=0):
|
def date_gen(start_date, offset=0):
|
||||||
'''generator that returns the next date, requires a datetime object as input. The offset is in weeks'''
|
"""generator that returns the next date, requires a datetime object as
|
||||||
start = offset * 7
|
input. The offset is in weeks"""
|
||||||
for i in itertools.count(start):
|
start = offset * 7
|
||||||
yield start_date + datetime.timedelta(i)
|
for i in itertools.count(start):
|
||||||
|
yield start_date + datetime.timedelta(i)
|
||||||
|
|
||||||
def values_in_date_order(image, multiplier=1):
|
def values_in_date_order(image, multiplier=1):
|
||||||
height = 7
|
height = 7
|
||||||
width = len(image[0])
|
width = len(image[0])
|
||||||
for w in range(width):
|
for w in range(width):
|
||||||
for h in range(height):
|
for h in range(height):
|
||||||
yield image[h][w]*multiplier
|
yield image[h][w]*multiplier
|
||||||
|
|
||||||
def commit(content, commitdate):
|
def commit(content, commitdate):
|
||||||
template = '''echo %s >> gitfiti\nGIT_AUTHOR_DATE=%s GIT_COMMITTER_DATE=%s git commit -a -m "gitfiti"\n'''
|
template = ("""echo {0} >> gitfiti\n"""
|
||||||
return template % (content, commitdate.isoformat(), commitdate.isoformat())
|
"""GIT_AUTHOR_DATE={1} GIT_COMMITTER_DATE={2} """
|
||||||
|
"""git commit -a -m "gitfiti" > /dev/null\n""")
|
||||||
|
return template.format(content, commitdate.isoformat(),
|
||||||
|
commitdate.isoformat())
|
||||||
|
|
||||||
def fake_it(image, start_date, username, repo, offset=0, multiplier=1):
|
def fake_it(image, start_date, username, repo, offset=0, multiplier=1,
|
||||||
template = ('#!/bin/bash\n'
|
git_url='git@github.com'):
|
||||||
'REPO=%s\n'
|
template = ('#!/bin/bash\n'
|
||||||
'git init $REPO\n'
|
'REPO={0}\n'
|
||||||
'cd $REPO\n'
|
'git init $REPO\n'
|
||||||
'touch README.md\n'
|
'cd $REPO\n'
|
||||||
'git add README.md\n'
|
'touch README.md\n'
|
||||||
'touch gitfiti\n'
|
'git add README.md\n'
|
||||||
'git add gitfiti\n'
|
'touch gitfiti\n'
|
||||||
'%s\n'
|
'git add gitfiti\n'
|
||||||
'git remote add origin git@github.com:%s/$REPO.git\n'
|
'{1}\n'
|
||||||
'git pull\n'
|
'git remote add origin {2}:{3}/$REPO.git\n'
|
||||||
'git push -u origin master\n')
|
'git pull\n'
|
||||||
strings = []
|
'git push -u origin master\n')
|
||||||
for value, date in zip(values_in_date_order(image, multiplier), date_gen(start_date, offset)):
|
strings = []
|
||||||
for i in range(value):
|
for value, date in zip(values_in_date_order(image, multiplier),
|
||||||
strings.append(commit(i, date))
|
date_gen(start_date, offset)):
|
||||||
return template % (repo, "".join(strings), username)
|
for i in range(value):
|
||||||
|
strings.append(commit(i, date))
|
||||||
|
return template.format(repo, "".join(strings), git_url, username)
|
||||||
|
|
||||||
def save(output, filename):
|
def save(output, filename):
|
||||||
"""Saves the list to a given filename"""
|
"""Saves the list to a given filename"""
|
||||||
f = open(filename, "w")
|
f = open(filename, "w")
|
||||||
f.write(output)
|
f.write(output)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global images
|
print TITLE
|
||||||
print title
|
print "Enter github url"
|
||||||
print 'Enter your github username:'
|
ghe = raw_input("Enter nothing for https://github.com/ to be used: ")
|
||||||
username = raw_input(">")
|
print 'Enter your github username:'
|
||||||
cal = get_calendar(username)
|
username = raw_input(">")
|
||||||
m = multiplier(max_commits(cal))
|
if ghe is None or ghe == "":
|
||||||
|
git_base = "https://github.com/"
|
||||||
|
cal = get_calendar(username)
|
||||||
|
else:
|
||||||
|
cal = get_calendar(username,base_url=ghe)
|
||||||
|
git_base = ghe
|
||||||
|
m = multiplier(max_commits(cal))
|
||||||
|
|
||||||
print 'Enter name of the repo to be used by gitfiti:'
|
print 'Enter name of the repo to be used by gitfiti:'
|
||||||
repo = raw_input(">")
|
repo = raw_input(">")
|
||||||
|
|
||||||
print 'Enter number of weeks to offset the image (from the left):'
|
print 'Enter number of weeks to offset the image (from the left):'
|
||||||
offset = raw_input(">")
|
offset = raw_input(">")
|
||||||
if offset == None: offset = 0
|
if offset == None:
|
||||||
else: offset = int(offset)
|
offset = 0
|
||||||
|
else:
|
||||||
|
offset = int(offset)
|
||||||
|
|
||||||
print ('By default gitfiti.py matches the darkest pixel to the highest\n'
|
print ('By default gitfiti.py matches the darkest pixel to the highest\n'
|
||||||
'number of commits found in your github commit/activity calendar,\n'
|
'number of commits found in your github commit/activity calendar,\n'
|
||||||
'\n'
|
'\n'
|
||||||
'Currently this is : %s commits\n'
|
'Currently this is : {0} commits\n'
|
||||||
'\n'
|
'\n'
|
||||||
'Enter the word "gitfiti" to exceed your max\n'
|
'Enter the word "gitfiti" to exceed your max\n'
|
||||||
'(this option generates WAY more commits)\n'
|
'(this option generates WAY more commits)\n'
|
||||||
'Any other input will cause the default matching behavior') % (max_commits(cal),)
|
'Any other input will cause the default matching behavior'
|
||||||
match = raw_input(">")
|
).format(max_commits(cal))
|
||||||
if match == "gitfiti": match = m
|
match = raw_input(">")
|
||||||
else: match = 1
|
if match == "gitfiti":
|
||||||
|
match = m
|
||||||
|
else:
|
||||||
|
match = 1
|
||||||
|
|
||||||
print 'enter file(s) to load images from (blank if not applicable)'
|
print 'enter file(s) to load images from (blank if not applicable)'
|
||||||
imgNames = raw_input(">").split(' ')
|
img_names = raw_input(">").split(' ')
|
||||||
images = dict(images, **load_images(imgNames))
|
images = dict(IMAGES, **load_images(img_names))
|
||||||
|
|
||||||
print 'enter the image name to gitfiti'
|
print 'enter the image name to gitfiti'
|
||||||
print 'images: ' + ", ".join(images.keys())
|
print 'images: ' + ", ".join(images.keys())
|
||||||
image = raw_input(">")
|
image = raw_input(">")
|
||||||
if image == None: image = images['kitty']
|
if image == None:
|
||||||
else:
|
image = IMAGES['kitty']
|
||||||
try: image = images[image]
|
else:
|
||||||
except: image = images['kitty']
|
try:
|
||||||
|
image = IMAGES[image]
|
||||||
|
except:
|
||||||
|
image = IMAGES['kitty']
|
||||||
|
if ghe is None or ghe == "":
|
||||||
|
output = fake_it(image, get_start_date(), username, repo, offset,
|
||||||
|
m*match)
|
||||||
|
else:
|
||||||
|
git_url = raw_input("Enter git url like git@site.github.com: ")
|
||||||
|
output = fake_it(image, get_start_date(), username, repo, offset,
|
||||||
|
m*match,git_url=git_url)
|
||||||
|
|
||||||
output = fake_it(image, get_start_date(), username, repo, offset, m*match)
|
save(output, 'gitfiti.sh')
|
||||||
save(output, 'gitfiti.sh')
|
print 'gitfiti.sh saved.'
|
||||||
print 'gitfiti.sh saved. Create a new(!) repo at: https://github.com/new and run it.'
|
print 'Create a new(!) repo at: {0}new and run it.'.format(git_base)
|
||||||
|
|
||||||
if __name__=='__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
Reference in New Issue
Block a user