diff --git a/action.yml b/action.yml index a646f82..0a91b88 100644 --- a/action.yml +++ b/action.yml @@ -52,6 +52,15 @@ inputs: description: "Show the Total Lines of code written Badge till date" default: "False" + SHOW_LANGUAGE_PER_REPO: + required: false + description: "" + default: "True" + + SHOW_LOC_CHART: + required: false + description: "" + default: "True" diff --git a/loc.py b/loc.py index 170c0a7..a92da4b 100644 --- a/loc.py +++ b/loc.py @@ -6,7 +6,7 @@ from github import Github import datetime from string import Template import matplotlib.pyplot as plt -from io import StringIO,BytesIO +from io import StringIO, BytesIO from dotenv import load_dotenv import time @@ -15,70 +15,70 @@ from make_bar_graph import BarGraph class LinesOfCode: - def __init__(self,id,username,ghtoken, repositoryData): - self.id=id - self.username=username + def __init__(self, id, username, ghtoken, repositoryData): + self.id = id + self.username = username - self.g = Github(ghtoken) - self.headers = {"Authorization": "Bearer " + ghtoken} - self.repositoryData=repositoryData + self.g = Github(ghtoken) + self.headers = {"Authorization": "Bearer " + ghtoken} + self.repositoryData = repositoryData def calculateLoc(self): - result=self.repositoryData - yearly_data={} + result = self.repositoryData + yearly_data = {} for repo in result['data']['user']['repositories']['edges']: - print(repo) - self.getCommitStat(repo['node'],yearly_data) - time.sleep(0.7) + print(repo) + self.getCommitStat(repo['node'], yearly_data) + time.sleep(0.7) print("\n\n") print(yearly_data) - graph=BarGraph(yearly_data) - graph_file=graph.build_graph() + print("here") + graph = BarGraph(yearly_data) + graph_file = graph.build_graph() self.pushChart() - def run_query_v3(self,nameWithOwner): - endPoint='https://api.github.com/repos/'+nameWithOwner+'/stats/code_frequency' + def run_query_v3(self, nameWithOwner): + endPoint = 'https://api.github.com/repos/' + nameWithOwner + '/stats/code_frequency' # print(endPoint) request = requests.get(endPoint, headers=self.headers) if request.status_code == 401: - raise Exception("Invalid token {}. {}".format(request.status_code, nameWithOwner)) + raise Exception("Invalid token {}. {}".format(request.status_code, nameWithOwner)) return request.json() - def getQuarter(self,timeStamp): - month=datetime.datetime.fromtimestamp(timeStamp).month - if month>=1 and month<=4: - return 1 - elif month>=5 and month<=8: - return 2 - elif month>=9 and month<=12: - return 3 - + def getQuarter(self, timeStamp): + month = datetime.datetime.fromtimestamp(timeStamp).month + if month >= 1 and month <= 4: + return 1 + elif month >= 5 and month <= 8: + return 2 + elif month >= 9 and month <= 12: + return 3 - def getCommitStat(self,repoDetails,yearly_data): - result= self.run_query_v3(repoDetails['nameWithOwner']) - this_year=datetime.datetime.utcnow().year + def getCommitStat(self, repoDetails, yearly_data): + result = self.run_query_v3(repoDetails['nameWithOwner']) + this_year = datetime.datetime.utcnow().year for i in range(len(result)): - curr_year=datetime.datetime.fromtimestamp(result[i][0]).year - # if curr_year != this_year: - quarter=self.getQuarter(result[i][0]) - if repoDetails['primaryLanguage'] is not None: + curr_year = datetime.datetime.fromtimestamp(result[i][0]).year + # if curr_year != this_year: + quarter = self.getQuarter(result[i][0]) + if repoDetails['primaryLanguage'] is not None: - if curr_year not in yearly_data: - yearly_data[curr_year]={} - if quarter not in yearly_data[curr_year]: - yearly_data[curr_year][quarter]={} - if repoDetails['primaryLanguage']['name'] not in yearly_data[curr_year][quarter]: - yearly_data[curr_year][quarter][repoDetails['primaryLanguage']['name']]=0 - yearly_data[curr_year][quarter][repoDetails['primaryLanguage']['name']]+=(result[i][1]+result[i][2]) + if curr_year not in yearly_data: + yearly_data[curr_year] = {} + if quarter not in yearly_data[curr_year]: + yearly_data[curr_year][quarter] = {} + if repoDetails['primaryLanguage']['name'] not in yearly_data[curr_year][quarter]: + yearly_data[curr_year][quarter][repoDetails['primaryLanguage']['name']] = 0 + yearly_data[curr_year][quarter][repoDetails['primaryLanguage']['name']] += (result[i][1] + result[i][2]) - #to find total + # to find total - # if 'total' not in yearly_data[curr_year]: - # yearly_data[curr_year]['total']={} - # if repoDetails['primaryLanguage']['name'] not in yearly_data[curr_year]['total']: - # yearly_data[curr_year]['total'][repoDetails['primaryLanguage']['name']]=0 - # yearly_data[curr_year]['total'][repoDetails['primaryLanguage']['name']]+=(result[i][1]+result[i][2]) + # if 'total' not in yearly_data[curr_year]: + # yearly_data[curr_year]['total']={} + # if repoDetails['primaryLanguage']['name'] not in yearly_data[curr_year]['total']: + # yearly_data[curr_year]['total'][repoDetails['primaryLanguage']['name']]=0 + # yearly_data[curr_year]['total'][repoDetails['primaryLanguage']['name']]+=(result[i][1]+result[i][2]) def pushChart(self): repo = self.g.get_repo(f"{self.username}/{self.username}") @@ -88,13 +88,9 @@ class LinesOfCode: contents = repo.get_contents("charts/bar_graph.png") repo.update_file(contents.path, "Charts Added", data, contents.sha) except Exception as e: - repo.create_file("charts/bar_graph.png", "Initial Commit",data) + repo.create_file("charts/bar_graph.png", "Initial Commit", data) print("pushed") - - - - # if __name__ == '__main__': # try: # g = Github(ghtoken) @@ -103,7 +99,7 @@ class LinesOfCode: # username = user_data["data"]["viewer"]["login"] # id = user_data["data"]["viewer"]["id"] # print("user {} id {}".format(username, id)) - + # getLoc() # # repo = g.get_repo(f"{username}/{username}") @@ -117,4 +113,4 @@ class LinesOfCode: # # content=new_readme, sha=contents.sha, branch='master') # # print("Readme updated") # except Exception as e: -# print("Exception Occurred" + str(e)) \ No newline at end of file +# print("Exception Occurred" + str(e)) diff --git a/main.py b/main.py index ffa6189..27111c7 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,7 @@ ''' Readme Development Metrics With waka time progress ''' - +import locale import re import os import base64 @@ -12,8 +12,6 @@ import requests from github import Github, GithubException import datetime from string import Template -import matplotlib.pyplot as plt -from io import StringIO,BytesIO from dotenv import load_dotenv from loc import LinesOfCode @@ -33,9 +31,10 @@ showOs = os.getenv('INPUT_SHOW_OS') showCommit = os.getenv('INPUT_SHOW_COMMIT') showLanguage = os.getenv('INPUT_SHOW_LANGUAGE') show_loc = os.getenv('INPUT_SHOW_LINES_OF_CODE') -showLanguagePerRepo= os.getenv('INPUT_LANGUAGE_PER_REPO') -showLocChart='y' if (os.getenv('LOC_CHART') is None) else os.getenv('LOC_CHART') -show_waka_stats='n' if waka_key is None else 'y' + +showLanguagePerRepo = os.getenv('INPUT_SHOW_LANGUAGE_PER_REPO') +showLocChart = os.getenv('INPUT_SHOW_LOC_CHART') +show_waka_stats = 'y' # The GraphQL query to get commit data. userInfoQuery = """ { @@ -90,10 +89,11 @@ def run_v3_api(query): raise Exception( "Query failed to run by returning code of {}. {},... {}".format(request.status_code, query, request.json())) + repositoryListQuery = Template(""" { user(login: "$username") { - repositories(orderBy: {field: CREATED_AT, direction: ASC}, last: 100, affiliations: [OWNER, COLLABORATOR, ORGANIZATION_MEMBER], isFork: false) { + repositories(orderBy: {field: CREATED_AT, direction: ASC}, last: 5, affiliations: [OWNER, COLLABORATOR, ORGANIZATION_MEMBER], isFork: false) { totalCount edges { node { @@ -132,6 +132,7 @@ repositoryListQuery = Template(""" } """) + def run_query(query): request = requests.post('https://api.github.com/graphql', json={'query': query}, headers=headers) if request.status_code == 200: @@ -278,11 +279,11 @@ def generate_commit_list(tz): string = string + '**' + title + '** \n\n' + '```text\n' + make_commit_list(one_day) + '\n\n```\n' string = string + '📅 **' + days_title + '** \n\n' + '```text\n' + make_commit_list(dayOfWeek) + '\n\n```\n' + def get_waka_time_stats(): - stats='' - try: - request = requests.get( - f"https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key={waka_key}") + stats = '' + request = requests.get( + f"https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key={waka_key}") if request.status_code != 401: data = request.json() @@ -366,9 +367,6 @@ def get_stats(): '''Gets API data and returns markdown progress''' stats = '' - if showCommit.lower() in ['true', '1', 't', 'y', 'yes']: - stats = stats + generate_commit_list() + '\n\n' - repositoryList = run_query(repositoryListQuery.substitute(username=username, id=id)) if showLanguagePerRepo.lower() in ['true', '1', 't', 'y', 'yes']: @@ -386,6 +384,7 @@ def get_stats(): return stats + def decode_readme(data: str): '''Decode the contets of old readme''' decoded_bytes = base64.b64decode(data) @@ -420,4 +419,3 @@ if __name__ == '__main__': print("Readme updated") except Exception as e: print("Exception Occurred" + str(e)) - diff --git a/make_bar_graph.py b/make_bar_graph.py index daf8721..d87fa21 100644 --- a/make_bar_graph.py +++ b/make_bar_graph.py @@ -2,106 +2,111 @@ import pandas as pd import numpy as np import altair as alt import json + +alt.data_transformers.enable('data_server_proxied') + + # npm install vega-lite vega-cli canvas class BarGraph: - def __init__(self, yearly_data): - self.yearly_data=yearly_data + def __init__(self, yearly_data): + self.yearly_data = yearly_data - def build_graph(self): + def build_graph(self): - with open('colors.json') as f: - colors = json.load(f) - allColorsValues=[] + with open('colors.json') as f: + colors = json.load(f) + allColorsValues = [] - #filter data - max_languages=5 - top_languages={} - for year in self.yearly_data.keys(): - for quarter in self.yearly_data[year].keys(): - for language in sorted(list(self.yearly_data[year][quarter].keys()), key=lambda lang:self.yearly_data[year][quarter][lang], reverse=True)[0:max_languages]: - if 'top' not in self.yearly_data[year][quarter]: - self.yearly_data[year][quarter]['top']={} - if self.yearly_data[year][quarter][language]!=0: - self.yearly_data[year][quarter]['top'][language]=self.yearly_data[year][quarter][language] - - if language not in top_languages: - top_languages[language] =1 - top_languages[language]+=1 + # filter data + max_languages = 5 + top_languages = {} + for year in self.yearly_data.keys(): + for quarter in self.yearly_data[year].keys(): + for language in sorted(list(self.yearly_data[year][quarter].keys()), + key=lambda lang: self.yearly_data[year][quarter][lang], reverse=True)[ + 0:max_languages]: + if 'top' not in self.yearly_data[year][quarter]: + self.yearly_data[year][quarter]['top'] = {} + if self.yearly_data[year][quarter][language] != 0: + self.yearly_data[year][quarter]['top'][language] = self.yearly_data[year][quarter][language] - # print(self.yearly_data) + if language not in top_languages: + top_languages[language] = 1 + top_languages[language] += 1 - all_languages=list(top_languages.keys()) + print("here") + print(self.yearly_data) - for language in all_languages: - if colors[language]['color'] is not None: - allColorsValues.append(colors[language]['color']) + all_languages = list(top_languages.keys()) - languages_all_loc={} + for language in all_languages: + if colors[language]['color'] is not None: + allColorsValues.append(colors[language]['color']) - for language in all_languages: - language_year=[] - for year in self.yearly_data.keys(): - language_quarter=[0,0,0] - for quarter in self.yearly_data[year].keys(): - if language in self.yearly_data[year][quarter]['top']: - language_quarter[quarter-1]=self.yearly_data[year][quarter]['top'][language] - else: - language_quarter[quarter-1]=0 - language_year.append(language_quarter) - languages_all_loc[language]=language_year + languages_all_loc = {} - print(languages_all_loc) + for language in all_languages: + language_year = [] + for year in self.yearly_data.keys(): + language_quarter = [0, 0, 0] + for quarter in self.yearly_data[year].keys(): + if language in self.yearly_data[year][quarter]['top']: + language_quarter[quarter - 1] = self.yearly_data[year][quarter]['top'][language] + else: + language_quarter[quarter - 1] = 0 + language_year.append(language_quarter) + languages_all_loc[language] = language_year - language_df={} + print("here 2") + print(languages_all_loc) - def prep_df(df, name): - df = df.stack().reset_index() - df.columns = ['c1', 'c2', 'values'] - df['Language'] = name - return df + language_df = {} - for language in languages_all_loc.keys(): - language_df[language]=pd.DataFrame(languages_all_loc[language],index=list(self.yearly_data.keys()),columns=["Q1","Q2","Q3"]) + def prep_df(df, name): + df = df.stack().reset_index() + df.columns = ['c1', 'c2', 'values'] + df['Language'] = name + return df - for language in language_df.keys(): - language_df[language]=prep_df(language_df[language], language) + for language in languages_all_loc.keys(): + language_df[language] = pd.DataFrame(languages_all_loc[language], index=list(self.yearly_data.keys()), + columns=["Q1", "Q2", "Q3"]) + for language in language_df.keys(): + language_df[language] = prep_df(language_df[language], language) + df = pd.concat(list(language_df.values())) - df=pd.concat(list(language_df.values())) + # print(df) + chart = alt.Chart(df).mark_bar().encode( - # print(df) + # tell Altair which field to group columns on + x=alt.X('c2:N', title=None), + # tell Altair which field to use as Y values and how to calculate + y=alt.Y('sum(values):Q', + axis=alt.Axis( + grid=False, + title='LOC added')), - chart=alt.Chart(df).mark_bar().encode( + # tell Altair which field to use to use as the set of columns to be represented in each group + column=alt.Column('c1:N', title=None), - # tell Altair which field to group columns on - x=alt.X('c2:N', title=None), - - # tell Altair which field to use as Y values and how to calculate - y=alt.Y('sum(values):Q', - axis=alt.Axis( - grid=False, - title='LOC added')), - - # tell Altair which field to use to use as the set of columns to be represented in each group - column=alt.Column('c1:N', title=None), - - # tell Altair which field to use for color segmentation - color=alt.Color('Language:N', - scale=alt.Scale( - domain=all_languages, - # make it look pretty with an enjoyable color pallet - range=allColorsValues, - ), - ))\ - .configure_view( - # remove grid lines around column clusters - strokeOpacity=0 - ) - chart.save('bar_graph.png') - return 'bar_graph.png' \ No newline at end of file + # tell Altair which field to use for color segmentation + color=alt.Color('Language:N', + scale=alt.Scale( + domain=all_languages, + # make it look pretty with an enjoyable color pallet + range=allColorsValues, + ), + )) \ + .configure_view( + # remove grid lines around column clusters + strokeOpacity=0 + ) + chart.save('bar_graph.png') + return 'bar_graph.png'