Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider existing commits of target profile #100

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 42 additions & 29 deletions gitfiti.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
"""

from datetime import datetime, timedelta
from collections import defaultdict
import itertools
import json
import math
import os
import re
try:
# Python 3+
from urllib.error import HTTPError, URLError
Expand Down Expand Up @@ -193,6 +195,23 @@
}


def get_start_date():
"""returns a datetime object for the first sunday after one year ago today
at 12:00 noon"""
today = datetime.today()
date = datetime(today.year - 1, today.month, today.day, 12)
weekday = datetime.weekday(date)

while weekday < 6:
date = date + timedelta(1)
weekday = datetime.weekday(date)

return date


# get start date only once, in case program run between two days
start_date = get_start_date()

def str_to_sprite(content):
# Break out lines and filter any excess
lines = content.split('\n')
Expand Down Expand Up @@ -293,19 +312,24 @@ def retrieve_contributions_calendar(username, base_url):


def parse_contributions_calendar(contributions_calendar):
"""Yield daily counts extracted from the contributions SVG."""
for line in contributions_calendar.splitlines():
for day in line.split():
if 'data-count=' in day:
commit = day.split('=')[1]
commit = commit.strip('"')
yield int(commit)
"""convert XML of contributions calendar to a dict {date: nubmer of commits}"""
data_count_pattern = re.compile('data-count="([\d]+)"')
data_date_pattern = re.compile('data-date="([-\d]+)"')
elements = re.findall("<rect[^>]+>", contributions_calendar)
result = defaultdict(lambda: 0)
for element in elements:
try:
data_count = int(data_count_pattern.search(element).group(1))
data_date = data_date_pattern.search(element).group(1)
result[data_date] = data_count
except:
pass
return result


def find_max_daily_commits(contributions_calendar):
"""finds the highest number of commits in one day"""
daily_counts = parse_contributions_calendar(contributions_calendar)
return max(daily_counts)
return max(contributions_calendar.values())


def calculate_multiplier(max_commits):
Expand All @@ -320,20 +344,6 @@ def calculate_multiplier(max_commits):
return m


def get_start_date():
"""returns a datetime object for the first sunday after one year ago today
at 12:00 noon"""
today = datetime.today()
date = datetime(today.year - 1, today.month, today.day, 12)
weekday = datetime.weekday(date)

while weekday < 6:
date = date + timedelta(1)
weekday = datetime.weekday(date)

return date


def generate_next_dates(start_date, offset=0):
"""generator that returns the next date, requires a datetime object as
input. The offset is in weeks"""
Expand Down Expand Up @@ -367,8 +377,9 @@ def commit(commitdate, shell):
return template.format(commitdate.isoformat(), commitdate.isoformat())


def fake_it(image, start_date, username, repo, git_url, shell, offset=0, multiplier=1):
template_bash = (
def fake_it(image, start_date, username, repo, git_url, shell, offset=0, multiplier=1,
contributions_calendar=defaultdict(lambda: 0)):
template = (
'#!/usr/bin/env bash\n'
'REPO={0}\n'
'git init $REPO\n'
Expand Down Expand Up @@ -403,9 +414,10 @@ def fake_it(image, start_date, username, repo, git_url, shell, offset=0, multipl
template = template_bash if shell == 'bash' else template_powershell

strings = []
for value, date in zip(generate_values_in_date_order(image, multiplier),
for commits_need, date in zip(generate_values_in_date_order(image, multiplier),
generate_next_dates(start_date, offset)):
for _ in range(value):
commits_now = contributions_calendar[date.strftime('%Y-%m-%d')]
for _ in range(commits_need - commits_now):
strings.append(commit(date, shell))

return template.format(repo, ''.join(strings), git_url, username)
Expand Down Expand Up @@ -435,6 +447,8 @@ def main():

contributions_calendar = retrieve_contributions_calendar(username, git_base)

contributions_calendar = parse_contributions_calendar(contributions_calendar)

max_daily_commits = find_max_daily_commits(contributions_calendar)

m = calculate_multiplier(max_daily_commits)
Expand Down Expand Up @@ -481,7 +495,6 @@ def main():
except:
image = IMAGES[image_name_fallback]

start_date = get_start_date()
fake_it_multiplier = m * match

if not ghe:
Expand All @@ -495,7 +508,7 @@ def main():
'Enter the target shell ({}): '.format(' or '.join(SHELLS.keys())))

output = fake_it(image, start_date, username, repo, git_url, shell, offset,
fake_it_multiplier)
fake_it_multiplier, contributions_calendar)

output_filename = 'gitfiti.{}'.format(SHELLS[shell])
save(output, output_filename)
Expand Down
48 changes: 39 additions & 9 deletions tests/test_find_max_daily_commits.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,48 @@


def test_parse_contributions_calendar():
expected = [
0, 0, 0, 0, 6, 0, 0,
0, 0, 0, 0, 0, 0, 6,
84, 16, 4, 8, 0, 0, 0,
0, 25, 66, 20, 10, 0, 0,
33, 9, 0, 0, 7,
]
expected = {
"2016-05-08": 0,
"2016-05-09": 0,
"2016-05-10": 0,
"2016-05-11": 0,
"2016-05-12": 6,
"2016-05-13": 0,
"2016-05-14": 0,
"2016-05-15": 0,
"2016-05-16": 0,
"2016-05-17": 0,
"2016-05-18": 0,
"2016-05-19": 0,
"2016-05-20": 0,
"2016-05-21": 6,
"2016-05-22": 84,
"2016-05-23": 16,
"2016-05-24": 4,
"2016-05-25": 8,
"2016-05-26": 0,
"2016-05-27": 0,
"2016-05-28": 0,
"2016-05-29": 0,
"2016-05-30": 25,
"2016-05-31": 66,
"2016-06-01": 20,
"2016-06-02": 10,
"2016-06-03": 0,
"2016-06-04": 0,
"2016-06-05": 33,
"2016-06-06": 9,
"2016-06-07": 0,
"2016-06-08": 0,
"2016-06-09": 7,
}

actual = parse_contributions_calendar(CONTRIBUTIONS_CALENDAR_SVG)

assert list(actual) == expected
assert sorted(actual.keys()) == sorted(expected.keys())
assert all(actual[k] == expected[k] for k in actual.keys())


def test_find_max_daily_commits():
assert find_max_daily_commits(CONTRIBUTIONS_CALENDAR_SVG) == 84
contributions_calendar = parse_contributions_calendar(CONTRIBUTIONS_CALENDAR_SVG)
assert find_max_daily_commits(contributions_calendar) == 84