diff --git a/.env.example b/.env.example index 23d0d27..c273a36 100644 --- a/.env.example +++ b/.env.example @@ -1,22 +1,22 @@ -INPUT_WAKATIME_API_KEY="" -INPUT_PUSH_BRANCH_NAME="main" -INPUT_SECTION_NAME="waka" -INPUT_SHOW_TIMEZONE="True" -INPUT_SHOW_PROJECTS="False" -INPUT_SHOW_EDITORS="False" -INPUT_SHOW_OS="False" -INPUT_SHOW_LANGUAGE="False" -INPUT_GH_TOKEN="" -INPUT_SYMBOL_VERSION="1" -INPUT_SHOW_LINES_OF_CODE="False" -INPUT_SHOW_LOC_CHART="False" -INPUT_SHOW_PROFILE_VIEWS="False" -INPUT_SHOW_TOTAL_CODE_TIME="True" -INPUT_SHOW_SHORT_INFO="False" -INPUT_SHOW_COMMIT="False" -INPUT_SHOW_DAYS_OF_WEEK="True" -INPUT_SHOW_LANGUAGE_PER_REPO="True" -INPUT_SHOW_UPDATED_DATE="True" -INPUT_UPDATED_DATE_FORMAT="%d/%m/%Y %H:%M:%S" -INPUT_COMMIT_BY_ME="False" -INPUT_COMMIT_MESSAGE="Updated with Dev Metrics" \ No newline at end of file +INPUT_WAKATIME_API_KEY=YOUR_WAKATIME_API_KEY +INPUT_PUSH_BRANCH_NAME=main +INPUT_SECTION_NAME=waka +INPUT_SHOW_TIMEZONE=True +INPUT_SHOW_PROJECTS=True +INPUT_SHOW_EDITORS=True +INPUT_SHOW_OS=True +INPUT_SHOW_LANGUAGE=True +INPUT_GH_TOKEN=YOUR_GITHUB_TOKEN_KEY +INPUT_SYMBOL_VERSION=1 +INPUT_SHOW_LINES_OF_CODE=True +INPUT_SHOW_LOC_CHART=True +INPUT_SHOW_PROFILE_VIEWS=True +INPUT_SHOW_TOTAL_CODE_TIME=True +INPUT_SHOW_SHORT_INFO=True +INPUT_SHOW_COMMIT=True +INPUT_SHOW_DAYS_OF_WEEK=True +INPUT_SHOW_LANGUAGE_PER_REPO=True +INPUT_SHOW_UPDATED_DATE=True +INPUT_UPDATED_DATE_FORMAT=%d/%m/%Y %H:%M:%S +INPUT_COMMIT_BY_ME=False +INPUT_COMMIT_MESSAGE=Updated with Dev Metrics diff --git a/.github/workflows/build_image.yml b/.github/workflows/build_image.yml new file mode 100644 index 0000000..4ae01df --- /dev/null +++ b/.github/workflows/build_image.yml @@ -0,0 +1,37 @@ +name: PUBLISH_IMAGE + +on: + push: + +jobs: + publish-server-image: + name: Publish 'waka-readme-stats' image + runs-on: ubuntu-latest + + steps: + - name: Checkout 🛎️ + uses: actions/checkout@v3 + + - name: Log in to the container registry 🚪 + uses: docker/login-action@v2 + with: + username: wakareadmestats + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker 🏋️ + id: meta + uses: docker/metadata-action@v4 + with: + images: wakareadmestats/waka-readme-stats + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Build and push Docker image 🏗️ + uses: docker/build-push-action@v3 + with: + push: ${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/releases') }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore index fd76478..082302f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,20 @@ +# Environment files: *.env + +# Generated graph images: *.png + +# Library roots: node_modules/ +venv/ + +# Python caches: __pycache__/ +# Package manager configuration files: +package.json +package-lock.json + +# IDE configuration files: .vscode +.idea diff --git a/Dockerfile b/Dockerfile index c5ff795..1800aab 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,14 @@ FROM nikolaik/python-nodejs:python3.9-nodejs16 -ADD requirements.txt /requirements.txt -ADD main.py /main.py -ADD loc.py /loc.py -ADD make_bar_graph.py /make_bar_graph.py -ADD translation.json /translation.json -ADD download_manager.py /download_manager.py +ENV PYTHONUNBUFFERED 1 +ENV PYTHONDONTWRITEBYTECODE 1 -ENV PATH "$PATH:/home/root/.npm-global/bin" +WORKDIR /waka-readme-stats -RUN python -m pip install --upgrade pip wheel setuptools -RUN pip install -r requirements.txt -RUN npm -g config set user root -RUN npm i -g npm@next-8 -RUN npm i -g vega vega-lite vega-cli canvas +ADD requirements.txt ./requirements.txt +RUN pip install --upgrade pip && pip install -r requirements.txt +RUN npm i npm@next-8 && npm i vega vega-lite vega-cli canvas -ENTRYPOINT ["python", "/main.py"] +ADD sources/* ./ + +ENTRYPOINT python3 /waka-readme-stats/main.py diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fcec175 --- /dev/null +++ b/Makefile @@ -0,0 +1,49 @@ +.ONESHELL: +.DEFAULT_GOAL = help +SHELL = /bin/bash + +PATH := venv/bin:node_modules/.bin:$(PATH) + + +help: + @ # Print help commands + echo "Welcome to 'waka-readme-stats' GitHub Actions!" + echo "The action can be tested locally with: 'make run'." + echo "NB! For local testing Python version 3.6+ and NodeJS version between 14 and 16 are required." + echo "The action image can be built locally with: 'make container'." + echo "NB! For local container building Docker version 20+ is required." + echo "The action directory and image can be cleaned with: 'make clean'." +.PHONY: help + +venv: + @ # Install Python virtual environment and dependencies + python3 -m venv venv + pip install --upgrade pip + pip install -r requirements.txt + +node_modules: + @ # Install NodeJS dependencies + npm i npm@next-8 + npm i vega vega-lite vega-cli canvas + + +run-locally: venv node_modules + @ # Run action locally + source <(cat .env.example | sed 's/=/=/' | sed 's/^/export /') && python3 ./sources/main.py +.PHONY: run-locally + +run-container: + @ # Run action in container + docker build -t waka-readme-stats -f Dockerfile . + docker run --env-file .env.example waka-readme-stats +.PHONY: run-container + + +clean: + @ # Clean all build files, including: libraries, package manager configs, docker images and containers + rm -rf venv + rm -rf node_modules + rm -f package*.json + docker rm -f waka-readme-stats 2>/dev/null || true + docker rmi $(docker images | grep "waka-readme-stats") 2> /dev/null || true +.PHONY: clean diff --git a/action.yml b/action.yml index 3643eb2..2e42fc5 100644 --- a/action.yml +++ b/action.yml @@ -11,7 +11,7 @@ inputs: WAKATIME_API_KEY: description: 'Your Wakatime API Key' required: true - + SECTION_NAME: description: 'Name used in readme to scope the updated section' required: false @@ -134,7 +134,7 @@ inputs: runs: using: 'docker' - image: 'Dockerfile' + image: 'docker://wakareadmestats/waka-readme-stats:master' branding: icon: 'activity' diff --git a/requirements.txt b/requirements.txt index b756a36..dfbea0d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,35 +1,11 @@ -altair==4.1.0 -altair-data-server==0.4.1 -altair-saver==0.5.0 -altair-viewer==0.3.0 -attrs==20.3.0 -certifi==2020.12.5 -cycler==0.10.0 -Deprecated==1.2.12 -entrypoints==0.3 -httpx==0.23.3 -humanize==3.3.0 -idna==2.10 -Jinja2==2.11.3 -jsonschema==3.2.0 -kiwisolver==1.3.1 -MarkupSafe==1.1.1 -matplotlib==3.4.1 -numpy==1.20.2 -pandas==1.2.3 -Pillow==8.2.0 -portpicker==1.3.1 PyGithub==1.54.1 -PyJWT==1.7.1 -PyYAML==6.0 -pyparsing==2.4.7 -pyrsistent==0.17.3 -python-dateutil==2.8.1 +matplotlib==3.4.1 python-dotenv==0.17.0 +numpy==1.24.1 +pandas==1.2.3 +altair==4.1.0 +altair-saver==0.5.0 pytz==2021.1 -selenium==3.141.0 -six==1.15.0 -toolz==0.11.1 -tornado==6.1 -urllib3==1.26.5 -wrapt==1.12.1 +humanize==3.3.0 +httpx==0.23.3 +PyYAML==6.0 diff --git a/sources/colors.json b/sources/colors.json new file mode 100644 index 0000000..e69de29 diff --git a/download_manager.py b/sources/download_manager.py similarity index 100% rename from download_manager.py rename to sources/download_manager.py diff --git a/loc.py b/sources/loc.py similarity index 93% rename from loc.py rename to sources/loc.py index d05f871..10c3010 100644 --- a/loc.py +++ b/sources/loc.py @@ -1,84 +1,77 @@ -import re -import os -import base64 -from asyncio import sleep - -from github import Github, InputGitAuthor, AuthenticatedUser -import datetime -from string import Template -import matplotlib.pyplot as plt -from io import StringIO, BytesIO -from dotenv import load_dotenv -import time - -from download_manager import DownloadManager -from make_bar_graph import BarGraph - - -class LinesOfCode: - - def __init__(self, user: AuthenticatedUser, ghtoken, repositoryData, ignored_repos): - self.g = Github(ghtoken) - self.user = user - self.repositoryData = repositoryData - self.ignored_repos = ignored_repos - - async def calculateLoc(self): - result = self.repositoryData - yearly_data = {} - total = len(result['data']['user']['repositories']['edges']) - for ind, repo in enumerate(result['data']['user']['repositories']['edges']): - if repo['node']['name'] not in self.ignored_repos: - print(f"{ind}/{total}", "Retrieving repo:", repo['node']["owner"]["login"], repo['node']['name']) - await self.getCommitStat(repo['node'], yearly_data) - await sleep(0.7) - return yearly_data - - async def plotLoc(self, yearly_data): - graph = BarGraph(yearly_data) - await graph.build_graph() - self.pushChart() - - def getQuarter(self, timeStamp): - month = datetime.datetime.fromisoformat(timeStamp).month - if month >= 1 and month <= 3: - return 1 - elif month >= 4 and month <= 6: - return 2 - elif month >= 7 and month <= 9: - return 3 - elif month >= 10 and month <= 12: - return 4 - - async def getCommitStat(self, repoDetails, yearly_data): - commit_data = await DownloadManager.get_remote_graphql("repository_commit_list", owner=repoDetails["owner"]["login"], name=repoDetails['name'], id=self.user.node_id) - - if commit_data["data"]["repository"] is None: - print("\tSkipping:", repoDetails['name']) - return - - for commit in [commit["node"] for branch in commit_data["data"]["repository"]["refs"]["edges"] for commit in branch["node"]["target"]["history"]["edges"]]: - date = re.search(r'\d+-\d+-\d+', commit["committedDate"]).group(0) - curr_year = datetime.datetime.fromisoformat(date).year - quarter = self.getQuarter(date) - - 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']] += (commit["additions"] - commit["deletions"]) - - - def pushChart(self): - repo = self.g.get_repo(f"{self.user.login}/{self.user.login}") - committer = InputGitAuthor('readme-bot', '41898282+github-actions[bot]@users.noreply.github.com') - with open('bar_graph.png', 'rb') as input_file: - data = input_file.read() - try: - contents = repo.get_contents("charts/bar_graph.png") - repo.update_file(contents.path, "Charts Updated", data, contents.sha, committer=committer) - except Exception as e: - repo.create_file("charts/bar_graph.png", "Charts Added", data, committer=committer) +import re +from asyncio import sleep + +from github import Github, InputGitAuthor, AuthenticatedUser +import datetime + +from download_manager import DownloadManager +from make_bar_graph import BarGraph + + +class LinesOfCode: + + def __init__(self, user: AuthenticatedUser, ghtoken, repositoryData, ignored_repos): + self.g = Github(ghtoken) + self.user = user + self.repositoryData = repositoryData + self.ignored_repos = ignored_repos + + async def calculateLoc(self): + result = self.repositoryData + yearly_data = {} + total = len(result['data']['user']['repositories']['edges']) + for ind, repo in enumerate(result['data']['user']['repositories']['edges']): + if repo['node']['name'] not in self.ignored_repos: + print(f"{ind}/{total}", "Retrieving repo:", repo['node']["owner"]["login"], repo['node']['name']) + await self.getCommitStat(repo['node'], yearly_data) + await sleep(0.7) + return yearly_data + + async def plotLoc(self, yearly_data): + graph = BarGraph(yearly_data) + await graph.build_graph() + self.pushChart() + + def getQuarter(self, timeStamp): + month = datetime.datetime.fromisoformat(timeStamp).month + if month >= 1 and month <= 3: + return 1 + elif month >= 4 and month <= 6: + return 2 + elif month >= 7 and month <= 9: + return 3 + elif month >= 10 and month <= 12: + return 4 + + async def getCommitStat(self, repoDetails, yearly_data): + commit_data = await DownloadManager.get_remote_graphql("repository_commit_list", owner=repoDetails["owner"]["login"], name=repoDetails['name'], id=self.user.node_id) + + if commit_data["data"]["repository"] is None: + print("\tSkipping:", repoDetails['name']) + return + + for commit in [commit["node"] for branch in commit_data["data"]["repository"]["refs"]["edges"] for commit in branch["node"]["target"]["history"]["edges"]]: + date = re.search(r'\d+-\d+-\d+', commit["committedDate"]).group(0) + curr_year = datetime.datetime.fromisoformat(date).year + quarter = self.getQuarter(date) + + 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']] += (commit["additions"] - commit["deletions"]) + + + def pushChart(self): + repo = self.g.get_repo(f"{self.user.login}/{self.user.login}") + committer = InputGitAuthor('readme-bot', '41898282+github-actions[bot]@users.noreply.github.com') + with open('bar_graph.png', 'rb') as input_file: + data = input_file.read() + try: + contents = repo.get_contents("charts/bar_graph.png") + repo.update_file(contents.path, "Charts Updated", data, contents.sha, committer=committer) + except Exception as e: + repo.create_file("charts/bar_graph.png", "Charts Added", data, committer=committer) diff --git a/main.py b/sources/main.py similarity index 96% rename from main.py rename to sources/main.py index a85a4cf..cbc802c 100644 --- a/main.py +++ b/sources/main.py @@ -1,462 +1,457 @@ -''' -Readme Development Metrics With waka time progress -''' -import re -import os -import base64 -from asyncio import run -from typing import Dict - -from pytz import timezone -import pytz -from github import Github, GithubException, InputGitAuthor, AuthenticatedUser -import datetime -from string import Template - -from download_manager import init_download_manager, DownloadManager -from loc import LinesOfCode -import time -import traceback -import humanize -from urllib.parse import quote -import json -import sys -from datetime import date -import math - -from dotenv import load_dotenv - -load_dotenv() - -START_COMMENT = f'' -END_COMMENT = f'' -listReg = f"{START_COMMENT}[\\s\\S]+{END_COMMENT}" - -waka_key = os.getenv('INPUT_WAKATIME_API_KEY') -ghtoken = os.getenv('INPUT_GH_TOKEN') -branchName = os.getenv('INPUT_PUSH_BRANCH_NAME') -showTimeZone = os.getenv('INPUT_SHOW_TIMEZONE') -showProjects = os.getenv('INPUT_SHOW_PROJECTS') -showEditors = os.getenv('INPUT_SHOW_EDITORS') -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') -show_days_of_week = os.getenv('INPUT_SHOW_DAYS_OF_WEEK') -showLanguagePerRepo = os.getenv('INPUT_SHOW_LANGUAGE_PER_REPO') -showLocChart = os.getenv('INPUT_SHOW_LOC_CHART') -show_profile_view = os.getenv('INPUT_SHOW_PROFILE_VIEWS') -show_short_info = os.getenv('INPUT_SHOW_SHORT_INFO') -locale = os.getenv('INPUT_LOCALE') -commit_by_me = os.getenv('INPUT_COMMIT_BY_ME') -ignored_repos_name = str(os.getenv('INPUT_IGNORED_REPOS') or '').replace(' ', '').split(',') -show_updated_date = os.getenv('INPUT_SHOW_UPDATED_DATE') -updated_date_format = os.getenv('INPUT_UPDATED_DATE_FORMAT') -commit_message = os.getenv('INPUT_COMMIT_MESSAGE') -commit_username = os.getenv('INPUT_COMMIT_USERNAME') -commit_email = os.getenv('INPUT_COMMIT_EMAIL') -show_total_code_time = os.getenv('INPUT_SHOW_TOTAL_CODE_TIME') -symbol_version = os.getenv('INPUT_SYMBOL_VERSION').strip() -show_waka_stats = 'y' - -truthy = ['true', '1', 't', 'y', 'yes'] - -translate: Dict[str, str] -user: AuthenticatedUser - - -def millify(n): - millnames = ['', ' Thousand', ' Million', ' Billion', ' Trillion'] - n = float(n) - millidx = max(0, min(len(millnames) - 1, - int(math.floor(0 - if n == 0 - else math.log10(abs(n)) / 3)))) - - return '{:.0f}{}'.format(n / 10 ** (3 * millidx), millnames[millidx]) - - -def make_graph(percent: float): - '''Make progress graph from API graph''' - if (symbol_version == '1'): # version 1 - done_block = '█' - empty_block = '░' - elif (symbol_version == '2'): # version 2 - done_block = '⣿' - empty_block = '⣀' - elif (symbol_version == '3'): # version 3 - done_block = '⬛' - empty_block = '⬜' - else: - done_block = '█' # default is version 1 - empty_block = '░' - - pc_rnd = round(percent) - return f"{done_block * int(pc_rnd / 4)}{empty_block * int(25 - int(pc_rnd / 4))}" - - -def make_list(data: list): - '''Make List''' - data_list = [] - for l in data[:5]: - ln = len(l['name']) - ln_text = len(l['text']) - percent = "{:05.2f}".format(float(l['percent'])) - op = f"{l['name'][:25]}{' ' * (25 - ln)}{l['text']}{' ' * (20 - ln_text)}{make_graph(l['percent'])} {percent} % " - data_list.append(op) - return '\n'.join(data_list) - - -def make_commit_list(data: list): - '''Make List''' - data_list = [] - for l in data[:7]: - ln = len(l['name']) - ln_text = len(l['text']) - percent = "{:05.2f}".format(float(l['percent'])) - op = f"{l['name']}{' ' * ((15 - ln) + (11 - ln_text))}{l['text']}{' ' * (7)}{make_graph(l['percent'])} {percent} % " - data_list.append(op) - return '\n'.join(data_list) - - -async def generate_commit_list(tz): - string = '' - - result = await DownloadManager.get_remote_graphql("repositories_contributed_to", username=user.login) - nodes = result["data"]["user"]["repositoriesContributedTo"]["nodes"] - repos = [d for d in nodes if d['isFork'] is False] - - morning = 0 # 6 - 12 - daytime = 0 # 12 - 18 - evening = 0 # 18 - 24 - night = 0 # 0 - 6 - - Monday = 0 - Tuesday = 0 - Wednesday = 0 - Thursday = 0 - Friday = 0 - Saturday = 0 - Sunday = 0 - - for repository in repos: - result = await DownloadManager.get_remote_graphql("repository_committed_dates", owner=repository["owner"]["login"], name=repository["name"], id=user.node_id) - committed_dates = result["data"]["repository"]["defaultBranchRef"]["target"]["history"]["edges"] - for committedDate in committed_dates: - date = datetime.datetime.strptime(committedDate["node"]["committedDate"], "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=pytz.utc).astimezone(timezone(tz)) - hour = date.hour - weekday = date.strftime('%A') - if 6 <= hour < 12: - morning += 1 - if 12 <= hour < 18: - daytime += 1 - if 18 <= hour < 24: - evening += 1 - if 0 <= hour < 6: - night += 1 - - if weekday == "Monday": - Monday += 1 - if weekday == "Tuesday": - Tuesday += 1 - if weekday == "Wednesday": - Wednesday += 1 - if weekday == "Thursday": - Thursday += 1 - if weekday == "Friday": - Friday += 1 - if weekday == "Saturday": - Saturday += 1 - if weekday == "Sunday": - Sunday += 1 - - sumAll = morning + daytime + evening + night - sum_week = Sunday + Monday + Tuesday + Friday + Saturday + Wednesday + Thursday - title = translate['I am an Early'] if morning + daytime >= evening + night else translate['I am a Night'] - one_day = [ - {"name": "🌞 " + translate['Morning'], "text": str(morning) + " commits", - "percent": round((morning / sumAll) * 100, 2)}, - {"name": "🌆 " + translate['Daytime'], "text": str(daytime) + " commits", - "percent": round((daytime / sumAll) * 100, 2)}, - {"name": "🌃 " + translate['Evening'], "text": str(evening) + " commits", - "percent": round((evening / sumAll) * 100, 2)}, - {"name": "🌙 " + translate['Night'], "text": str(night) + " commits", - "percent": round((night / sumAll) * 100, 2)}, - ] - dayOfWeek = [ - {"name": translate['Monday'], "text": str(Monday) + " commits", "percent": round((Monday / sum_week) * 100, 2)}, - {"name": translate['Tuesday'], "text": str(Tuesday) + " commits", - "percent": round((Tuesday / sum_week) * 100, 2)}, - {"name": translate['Wednesday'], "text": str(Wednesday) + " commits", - "percent": round((Wednesday / sum_week) * 100, 2)}, - {"name": translate['Thursday'], "text": str(Thursday) + " commits", - "percent": round((Thursday / sum_week) * 100, 2)}, - {"name": translate['Friday'], "text": str(Friday) + " commits", "percent": round((Friday / sum_week) * 100, 2)}, - {"name": translate['Saturday'], "text": str(Saturday) + " commits", - "percent": round((Saturday / sum_week) * 100, 2)}, - {"name": translate['Sunday'], "text": str(Sunday) + " commits", "percent": round((Sunday / sum_week) * 100, 2)}, - ] - - string = string + '**' + title + '** \n\n' + '```text\n' + make_commit_list(one_day) + '\n\n```\n' - - if show_days_of_week.lower() in truthy: - max_element = { - 'percent': 0 - } - - for day in dayOfWeek: - if day['percent'] > max_element['percent']: - max_element = day - days_title = translate['I am Most Productive on'] % max_element['name'] - string = string + '📅 **' + days_title + '** \n\n' + '```text\n' + make_commit_list(dayOfWeek) + '\n\n```\n' - - return string - - -async def get_waka_time_stats(): - stats = '' - no_activity = translate["No Activity Tracked This Week"] - - data = await DownloadManager.get_remote_json("waka_latest") - if showCommit.lower() in truthy: - stats = stats + await generate_commit_list(data['data']['timezone']) + '\n\n' - - if showTimeZone.lower() in truthy or showLanguage.lower() in truthy or showEditors.lower() in truthy or showProjects.lower() in truthy or showOs.lower() in truthy: - stats += '📊 **' + translate['This Week I Spend My Time On'] + '** \n\n' - stats += '```text\n' - - if showTimeZone.lower() in truthy: - tzone = data['data']['timezone'] - stats = stats + '⌚︎ ' + translate['Timezone'] + ': ' + tzone + '\n\n' - - if showLanguage.lower() in truthy: - if len(data['data']['languages']) == 0: - lang_list = no_activity - else: - lang_list = make_list(data['data']['languages']) - stats = stats + '💬 ' + translate['Languages'] + ': \n' + lang_list + '\n\n' - - if showEditors.lower() in truthy: - if len(data['data']['editors']) == 0: - edit_list = no_activity - else: - edit_list = make_list(data['data']['editors']) - stats = stats + '🔥 ' + translate['Editors'] + ': \n' + edit_list + '\n\n' - - if showProjects.lower() in truthy: - if len(data['data']['projects']) == 0: - project_list = no_activity - else: - # Re-order the project list by percentage - data['data']['projects'] = sorted(data['data']['projects'], key=lambda x: x["percent"], - reverse=True) - project_list = make_list(data['data']['projects']) - stats = stats + '🐱‍💻 ' + translate['Projects'] + ': \n' + project_list + '\n\n' - - if showOs.lower() in truthy: - if len(data['data']['operating_systems']) == 0: - os_list = no_activity - else: - os_list = make_list(data['data']['operating_systems']) - stats = stats + '💻 ' + translate['operating system'] + ': \n' + os_list + '\n\n' - - stats += '```\n\n' - - return stats - - -def generate_language_per_repo(result): - language_count = {} - total = 0 - for repo in result['data']['user']['repositories']['edges']: - if repo['node']['primaryLanguage'] is None: - continue - language = repo['node']['primaryLanguage']['name'] - total += 1 - if language not in language_count.keys(): - language_count[language] = {} - language_count[language]['count'] = 1 - else: - language_count[language]['count'] = language_count[language]['count'] + 1 - data = [] - sorted_labels = list(language_count.keys()) - sorted_labels.sort(key=lambda x: language_count[x]['count'], reverse=True) - most_language_repo = sorted_labels[0] - for label in sorted_labels: - percent = round(language_count[label]['count'] / total * 100, 2) - extension = " repos" - if language_count[label]['count'] == 1: - extension = " repo" - data.append({ - "name": label, - "text": str(language_count[label]['count']) + extension, - "percent": percent - }) - - title = translate['I Mostly Code in'] % most_language_repo - return '**' + title + '** \n\n' + '```text\n' + make_list(data) + '\n\n```\n' - - -async def get_yearly_data(): - repository_list = await DownloadManager.get_remote_graphql("user_repository_list", username=user.login, id=user.node_id) - loc = LinesOfCode(user, ghtoken, repository_list, ignored_repos_name) - yearly_data = await loc.calculateLoc() - if showLocChart.lower() in truthy: - await loc.plotLoc(yearly_data) - return yearly_data - - -async def get_line_of_code() -> str: - repositoryList = await DownloadManager.get_remote_graphql("user_repository_list", username=user.login, id=user.node_id) - loc = LinesOfCode(user, ghtoken, repositoryList, ignored_repos_name) - yearly_data = await loc.calculateLoc() - total_loc = sum( - [yearly_data[year][quarter][lang] for year in yearly_data for quarter in yearly_data[year] for lang in - yearly_data[year][quarter]]) - return millify(int(total_loc)) - - -async def get_short_info(): - string = '**🐱 ' + translate['My GitHub Data'] + '** \n\n' - if user.disk_usage is None: - disk_usage = humanize.naturalsize(0) - print("Please add new github personal access token with user permission") - else: - disk_usage = humanize.naturalsize(user.disk_usage) - data = await DownloadManager.get_remote_json("github_stats") - if len(data['years']) > 0: - this_year_data = data['years'][0] - total = this_year_data['total'] - year = this_year_data['year'] - string += '> 🏆 ' + translate['Contributions in the year'] % (humanize.intcomma(total), year) + '\n > \n' - - string += '> 📦 ' + translate["Used in GitHub's Storage"] % disk_usage + ' \n > \n' - is_hireable = user.hireable - public_repo = user.public_repos - private_repo = user.owned_private_repos - if private_repo is None: - private_repo = 0 - if is_hireable: - string += "> 💼 " + translate["Opted to Hire"] + "\n > \n" - else: - string += "> 🚫 " + translate["Not Opted to Hire"] + "\n > \n" - - string += '> 📜 ' - string += translate['public repositories'] % public_repo + " " + '\n > \n' if public_repo != 1 else translate[ - 'public repository'] % public_repo + " " + '\n > \n' - string += '> 🔑 ' - string += translate['private repositories'] % private_repo + " " + ' \n > \n' if private_repo != 1 else translate[ - 'private repository'] % private_repo + " " + '\n > \n' - - return string - - -async def get_stats(github) -> str: - '''Gets API data and returns markdown progress''' - - stats = '' - repositoryList = await DownloadManager.get_remote_graphql("user_repository_list", username=user.login, id=user.node_id) - - if show_loc.lower() in truthy or showLocChart.lower() in truthy: - # This condition is written to calculate the lines of code because it is heavy process soo needs to be calculate once this will reduce the execution time - await get_yearly_data() - - if show_total_code_time.lower() in truthy: - data = await DownloadManager.get_remote_json("waka_all") - stats += '![Code Time](http://img.shields.io/badge/' + quote( - str("Code Time")) + '-' + quote(str( - data['data']['text'])) + '-blue)\n\n' - - if show_profile_view.lower() in truthy: - data = github.get_repo(f"{user.login}/{user.login}").get_views_traffic(per="week") - stats += '![Profile Views](http://img.shields.io/badge/' + quote(str(translate['Profile Views'])) + '-' + str( - data['count']) + '-blue)\n\n' - - if show_loc.lower() in truthy: - stats += '![Lines of code](https://img.shields.io/badge/' + quote( - str(translate['From Hello World I have written'])) + '-' + quote( - str(await get_line_of_code())) + '%20' + quote(str(translate['Lines of code'])) + '-blue)\n\n' - - if show_short_info.lower() in truthy: - stats += await get_short_info() - - if show_waka_stats.lower() in truthy: - stats += await get_waka_time_stats() - - if showLanguagePerRepo.lower() in truthy: - stats = stats + generate_language_per_repo(repositoryList) + '\n\n' - - if showLocChart.lower() in truthy: - stats += '**' + translate['Timeline'] + '**\n\n' - branch_name = github.get_repo(f'{user.login}/{user.login}').default_branch - stats = stats + '![Chart not found](https://raw.githubusercontent.com/' + user.login + '/' + user.login + '/' + branch_name + '/charts/bar_graph.png) \n\n' - - if show_updated_date.lower() in truthy: - now = datetime.datetime.utcnow() - d1 = now.strftime(updated_date_format) - stats = stats + "\n Last Updated on " + d1 + " UTC" - - return stats - - -def decode_readme(data: str): - '''Decode the contents of old readme''' - decoded_bytes = base64.b64decode(data) - return str(decoded_bytes, 'utf-8') - - -def generate_new_readme(stats: str, readme: str): - '''Generate a new Readme.md''' - stats_in_readme = f"{START_COMMENT}\n{stats}\n{END_COMMENT}" - return re.sub(listReg, stats_in_readme, readme) - - -async def main(): - global translate, user - - if ghtoken is None: - raise Exception('Token not available') - user = Github(ghtoken).get_user() - print(f"Current user: {user.login}") - await init_download_manager(waka_key, ghtoken, user) - - try: - with open(os.path.join(os.path.dirname(__file__), 'translation.json'), encoding='utf-8') as config_file: - data = json.load(config_file) - translate = data[locale] - except Exception as e: - print("Cannot find the Locale choosing default to english") - translate = data['en'] - - g = Github(ghtoken) - waka_stats = await get_stats(g) - - repo = g.get_repo(f"{user.login}/{user.login}") - contents = repo.get_readme() - rdmd = decode_readme(contents.content) - new_readme = generate_new_readme(stats=waka_stats, readme=rdmd) - - if commit_by_me.lower() in truthy: - committer = InputGitAuthor(user.login or commit_username, user.email or commit_email) - else: - committer = InputGitAuthor( - commit_username or 'readme-bot', - commit_email or '41898282+github-actions[bot]@users.noreply.github.com' - ) - if new_readme != rdmd: - try: - repo.update_file(path=contents.path, message=commit_message, - content=new_readme, sha=contents.sha, branch=branchName, - committer=committer) - except: - repo.update_file(path=contents.path, message=commit_message, - content=new_readme, sha=contents.sha, branch='main', - committer=committer) - print("Readme updated") - - -if __name__ == '__main__': - start_time = datetime.datetime.now().timestamp() * 1000 - run(main()) - end_time = datetime.datetime.now().timestamp() * 1000 - print(f"Program processed in {round(end_time - start_time, 0)} miliseconds.") +''' +Readme Development Metrics With waka time progress +''' +import re +import os +import base64 +from asyncio import run +from typing import Dict + +from pytz import timezone +import pytz +from github import Github, InputGitAuthor, AuthenticatedUser +import datetime + +from download_manager import init_download_manager, DownloadManager +from loc import LinesOfCode +import humanize +from urllib.parse import quote +import json +import math + +from dotenv import load_dotenv + +load_dotenv() + +START_COMMENT = f'' +END_COMMENT = f'' +listReg = f"{START_COMMENT}[\\s\\S]+{END_COMMENT}" + +waka_key = os.getenv('INPUT_WAKATIME_API_KEY') +ghtoken = os.getenv('INPUT_GH_TOKEN') +branchName = os.getenv('INPUT_PUSH_BRANCH_NAME') +showTimeZone = os.getenv('INPUT_SHOW_TIMEZONE') +showProjects = os.getenv('INPUT_SHOW_PROJECTS') +showEditors = os.getenv('INPUT_SHOW_EDITORS') +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') +show_days_of_week = os.getenv('INPUT_SHOW_DAYS_OF_WEEK') +showLanguagePerRepo = os.getenv('INPUT_SHOW_LANGUAGE_PER_REPO') +showLocChart = os.getenv('INPUT_SHOW_LOC_CHART') +show_profile_view = os.getenv('INPUT_SHOW_PROFILE_VIEWS') +show_short_info = os.getenv('INPUT_SHOW_SHORT_INFO') +locale = os.getenv('INPUT_LOCALE') +commit_by_me = os.getenv('INPUT_COMMIT_BY_ME') +ignored_repos_name = str(os.getenv('INPUT_IGNORED_REPOS') or '').replace(' ', '').split(',') +show_updated_date = os.getenv('INPUT_SHOW_UPDATED_DATE') +updated_date_format = os.getenv('INPUT_UPDATED_DATE_FORMAT') +commit_message = os.getenv('INPUT_COMMIT_MESSAGE') +commit_username = os.getenv('INPUT_COMMIT_USERNAME') +commit_email = os.getenv('INPUT_COMMIT_EMAIL') +show_total_code_time = os.getenv('INPUT_SHOW_TOTAL_CODE_TIME') +symbol_version = os.getenv('INPUT_SYMBOL_VERSION').strip() +show_waka_stats = 'y' + +truthy = ['true', '1', 't', 'y', 'yes'] + +translate: Dict[str, str] +user: AuthenticatedUser + + +def millify(n): + millnames = ['', ' Thousand', ' Million', ' Billion', ' Trillion'] + n = float(n) + millidx = max(0, min(len(millnames) - 1, + int(math.floor(0 + if n == 0 + else math.log10(abs(n)) / 3)))) + + return '{:.0f}{}'.format(n / 10 ** (3 * millidx), millnames[millidx]) + + +def make_graph(percent: float): + '''Make progress graph from API graph''' + if (symbol_version == '1'): # version 1 + done_block = '█' + empty_block = '░' + elif (symbol_version == '2'): # version 2 + done_block = '⣿' + empty_block = '⣀' + elif (symbol_version == '3'): # version 3 + done_block = '⬛' + empty_block = '⬜' + else: + done_block = '█' # default is version 1 + empty_block = '░' + + pc_rnd = round(percent) + return f"{done_block * int(pc_rnd / 4)}{empty_block * int(25 - int(pc_rnd / 4))}" + + +def make_list(data: list): + '''Make List''' + data_list = [] + for l in data[:5]: + ln = len(l['name']) + ln_text = len(l['text']) + percent = "{:05.2f}".format(float(l['percent'])) + op = f"{l['name'][:25]}{' ' * (25 - ln)}{l['text']}{' ' * (20 - ln_text)}{make_graph(l['percent'])} {percent} % " + data_list.append(op) + return '\n'.join(data_list) + + +def make_commit_list(data: list): + '''Make List''' + data_list = [] + for l in data[:7]: + ln = len(l['name']) + ln_text = len(l['text']) + percent = "{:05.2f}".format(float(l['percent'])) + op = f"{l['name']}{' ' * ((15 - ln) + (11 - ln_text))}{l['text']}{' ' * (7)}{make_graph(l['percent'])} {percent} % " + data_list.append(op) + return '\n'.join(data_list) + + +async def generate_commit_list(tz): + string = '' + + result = await DownloadManager.get_remote_graphql("repositories_contributed_to", username=user.login) + nodes = result["data"]["user"]["repositoriesContributedTo"]["nodes"] + repos = [d for d in nodes if d['isFork'] is False] + + morning = 0 # 6 - 12 + daytime = 0 # 12 - 18 + evening = 0 # 18 - 24 + night = 0 # 0 - 6 + + Monday = 0 + Tuesday = 0 + Wednesday = 0 + Thursday = 0 + Friday = 0 + Saturday = 0 + Sunday = 0 + + for repository in repos: + result = await DownloadManager.get_remote_graphql("repository_committed_dates", owner=repository["owner"]["login"], name=repository["name"], id=user.node_id) + committed_dates = result["data"]["repository"]["defaultBranchRef"]["target"]["history"]["edges"] + for committedDate in committed_dates: + date = datetime.datetime.strptime(committedDate["node"]["committedDate"], "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=pytz.utc).astimezone(timezone(tz)) + hour = date.hour + weekday = date.strftime('%A') + if 6 <= hour < 12: + morning += 1 + if 12 <= hour < 18: + daytime += 1 + if 18 <= hour < 24: + evening += 1 + if 0 <= hour < 6: + night += 1 + + if weekday == "Monday": + Monday += 1 + if weekday == "Tuesday": + Tuesday += 1 + if weekday == "Wednesday": + Wednesday += 1 + if weekday == "Thursday": + Thursday += 1 + if weekday == "Friday": + Friday += 1 + if weekday == "Saturday": + Saturday += 1 + if weekday == "Sunday": + Sunday += 1 + + sumAll = morning + daytime + evening + night + sum_week = Sunday + Monday + Tuesday + Friday + Saturday + Wednesday + Thursday + title = translate['I am an Early'] if morning + daytime >= evening + night else translate['I am a Night'] + one_day = [ + {"name": "🌞 " + translate['Morning'], "text": str(morning) + " commits", + "percent": round((morning / sumAll) * 100, 2)}, + {"name": "🌆 " + translate['Daytime'], "text": str(daytime) + " commits", + "percent": round((daytime / sumAll) * 100, 2)}, + {"name": "🌃 " + translate['Evening'], "text": str(evening) + " commits", + "percent": round((evening / sumAll) * 100, 2)}, + {"name": "🌙 " + translate['Night'], "text": str(night) + " commits", + "percent": round((night / sumAll) * 100, 2)}, + ] + dayOfWeek = [ + {"name": translate['Monday'], "text": str(Monday) + " commits", "percent": round((Monday / sum_week) * 100, 2)}, + {"name": translate['Tuesday'], "text": str(Tuesday) + " commits", + "percent": round((Tuesday / sum_week) * 100, 2)}, + {"name": translate['Wednesday'], "text": str(Wednesday) + " commits", + "percent": round((Wednesday / sum_week) * 100, 2)}, + {"name": translate['Thursday'], "text": str(Thursday) + " commits", + "percent": round((Thursday / sum_week) * 100, 2)}, + {"name": translate['Friday'], "text": str(Friday) + " commits", "percent": round((Friday / sum_week) * 100, 2)}, + {"name": translate['Saturday'], "text": str(Saturday) + " commits", + "percent": round((Saturday / sum_week) * 100, 2)}, + {"name": translate['Sunday'], "text": str(Sunday) + " commits", "percent": round((Sunday / sum_week) * 100, 2)}, + ] + + string = string + '**' + title + '** \n\n' + '```text\n' + make_commit_list(one_day) + '\n\n```\n' + + if show_days_of_week.lower() in truthy: + max_element = { + 'percent': 0 + } + + for day in dayOfWeek: + if day['percent'] > max_element['percent']: + max_element = day + days_title = translate['I am Most Productive on'] % max_element['name'] + string = string + '📅 **' + days_title + '** \n\n' + '```text\n' + make_commit_list(dayOfWeek) + '\n\n```\n' + + return string + + +async def get_waka_time_stats(): + stats = '' + no_activity = translate["No Activity Tracked This Week"] + + data = await DownloadManager.get_remote_json("waka_latest") + if showCommit.lower() in truthy: + stats = stats + await generate_commit_list(data['data']['timezone']) + '\n\n' + + if showTimeZone.lower() in truthy or showLanguage.lower() in truthy or showEditors.lower() in truthy or showProjects.lower() in truthy or showOs.lower() in truthy: + stats += '📊 **' + translate['This Week I Spend My Time On'] + '** \n\n' + stats += '```text\n' + + if showTimeZone.lower() in truthy: + tzone = data['data']['timezone'] + stats = stats + '⌚︎ ' + translate['Timezone'] + ': ' + tzone + '\n\n' + + if showLanguage.lower() in truthy: + if len(data['data']['languages']) == 0: + lang_list = no_activity + else: + lang_list = make_list(data['data']['languages']) + stats = stats + '💬 ' + translate['Languages'] + ': \n' + lang_list + '\n\n' + + if showEditors.lower() in truthy: + if len(data['data']['editors']) == 0: + edit_list = no_activity + else: + edit_list = make_list(data['data']['editors']) + stats = stats + '🔥 ' + translate['Editors'] + ': \n' + edit_list + '\n\n' + + if showProjects.lower() in truthy: + if len(data['data']['projects']) == 0: + project_list = no_activity + else: + # Re-order the project list by percentage + data['data']['projects'] = sorted(data['data']['projects'], key=lambda x: x["percent"], + reverse=True) + project_list = make_list(data['data']['projects']) + stats = stats + '🐱‍💻 ' + translate['Projects'] + ': \n' + project_list + '\n\n' + + if showOs.lower() in truthy: + if len(data['data']['operating_systems']) == 0: + os_list = no_activity + else: + os_list = make_list(data['data']['operating_systems']) + stats = stats + '💻 ' + translate['operating system'] + ': \n' + os_list + '\n\n' + + stats += '```\n\n' + + return stats + + +def generate_language_per_repo(result): + language_count = {} + total = 0 + for repo in result['data']['user']['repositories']['edges']: + if repo['node']['primaryLanguage'] is None: + continue + language = repo['node']['primaryLanguage']['name'] + total += 1 + if language not in language_count.keys(): + language_count[language] = {} + language_count[language]['count'] = 1 + else: + language_count[language]['count'] = language_count[language]['count'] + 1 + data = [] + sorted_labels = list(language_count.keys()) + sorted_labels.sort(key=lambda x: language_count[x]['count'], reverse=True) + most_language_repo = sorted_labels[0] + for label in sorted_labels: + percent = round(language_count[label]['count'] / total * 100, 2) + extension = " repos" + if language_count[label]['count'] == 1: + extension = " repo" + data.append({ + "name": label, + "text": str(language_count[label]['count']) + extension, + "percent": percent + }) + + title = translate['I Mostly Code in'] % most_language_repo + return '**' + title + '** \n\n' + '```text\n' + make_list(data) + '\n\n```\n' + + +async def get_yearly_data(): + repository_list = await DownloadManager.get_remote_graphql("user_repository_list", username=user.login, id=user.node_id) + loc = LinesOfCode(user, ghtoken, repository_list, ignored_repos_name) + yearly_data = await loc.calculateLoc() + if showLocChart.lower() in truthy: + await loc.plotLoc(yearly_data) + return yearly_data + + +async def get_line_of_code() -> str: + repositoryList = await DownloadManager.get_remote_graphql("user_repository_list", username=user.login, id=user.node_id) + loc = LinesOfCode(user, ghtoken, repositoryList, ignored_repos_name) + yearly_data = await loc.calculateLoc() + total_loc = sum( + [yearly_data[year][quarter][lang] for year in yearly_data for quarter in yearly_data[year] for lang in + yearly_data[year][quarter]]) + return millify(int(total_loc)) + + +async def get_short_info(): + string = '**🐱 ' + translate['My GitHub Data'] + '** \n\n' + if user.disk_usage is None: + disk_usage = humanize.naturalsize(0) + print("Please add new github personal access token with user permission") + else: + disk_usage = humanize.naturalsize(user.disk_usage) + data = await DownloadManager.get_remote_json("github_stats") + if len(data['years']) > 0: + this_year_data = data['years'][0] + total = this_year_data['total'] + year = this_year_data['year'] + string += '> 🏆 ' + translate['Contributions in the year'] % (humanize.intcomma(total), year) + '\n > \n' + + string += '> 📦 ' + translate["Used in GitHub's Storage"] % disk_usage + ' \n > \n' + is_hireable = user.hireable + public_repo = user.public_repos + private_repo = user.owned_private_repos + if private_repo is None: + private_repo = 0 + if is_hireable: + string += "> 💼 " + translate["Opted to Hire"] + "\n > \n" + else: + string += "> 🚫 " + translate["Not Opted to Hire"] + "\n > \n" + + string += '> 📜 ' + string += translate['public repositories'] % public_repo + " " + '\n > \n' if public_repo != 1 else translate[ + 'public repository'] % public_repo + " " + '\n > \n' + string += '> 🔑 ' + string += translate['private repositories'] % private_repo + " " + ' \n > \n' if private_repo != 1 else translate[ + 'private repository'] % private_repo + " " + '\n > \n' + + return string + + +async def get_stats(github) -> str: + '''Gets API data and returns markdown progress''' + + stats = '' + repositoryList = await DownloadManager.get_remote_graphql("user_repository_list", username=user.login, id=user.node_id) + + if show_loc.lower() in truthy or showLocChart.lower() in truthy: + # This condition is written to calculate the lines of code because it is heavy process soo needs to be calculate once this will reduce the execution time + await get_yearly_data() + + if show_total_code_time.lower() in truthy: + data = await DownloadManager.get_remote_json("waka_all") + stats += '![Code Time](http://img.shields.io/badge/' + quote( + str("Code Time")) + '-' + quote(str( + data['data']['text'])) + '-blue)\n\n' + + if show_profile_view.lower() in truthy: + data = github.get_repo(f"{user.login}/{user.login}").get_views_traffic(per="week") + stats += '![Profile Views](http://img.shields.io/badge/' + quote(str(translate['Profile Views'])) + '-' + str( + data['count']) + '-blue)\n\n' + + if show_loc.lower() in truthy: + stats += '![Lines of code](https://img.shields.io/badge/' + quote( + str(translate['From Hello World I have written'])) + '-' + quote( + str(await get_line_of_code())) + '%20' + quote(str(translate['Lines of code'])) + '-blue)\n\n' + + if show_short_info.lower() in truthy: + stats += await get_short_info() + + if show_waka_stats.lower() in truthy: + stats += await get_waka_time_stats() + + if showLanguagePerRepo.lower() in truthy: + stats = stats + generate_language_per_repo(repositoryList) + '\n\n' + + if showLocChart.lower() in truthy: + stats += '**' + translate['Timeline'] + '**\n\n' + branch_name = github.get_repo(f'{user.login}/{user.login}').default_branch + stats = stats + '![Chart not found](https://raw.githubusercontent.com/' + user.login + '/' + user.login + '/' + branch_name + '/charts/bar_graph.png) \n\n' + + if show_updated_date.lower() in truthy: + now = datetime.datetime.utcnow() + d1 = now.strftime(updated_date_format) + stats = stats + "\n Last Updated on " + d1 + " UTC" + + return stats + + +def decode_readme(data: str): + '''Decode the contents of old readme''' + decoded_bytes = base64.b64decode(data) + return str(decoded_bytes, 'utf-8') + + +def generate_new_readme(stats: str, readme: str): + '''Generate a new Readme.md''' + stats_in_readme = f"{START_COMMENT}\n{stats}\n{END_COMMENT}" + return re.sub(listReg, stats_in_readme, readme) + + +async def main(): + global translate, user + + if ghtoken is None: + raise Exception('Token not available') + user = Github(ghtoken).get_user() + print(f"Current user: {user.login}") + await init_download_manager(waka_key, ghtoken, user) + + try: + with open(os.path.join(os.path.dirname(__file__), 'translation.json'), encoding='utf-8') as config_file: + data = json.load(config_file) + translate = data[locale] + except Exception as e: + print("Cannot find the Locale choosing default to english") + translate = data['en'] + + g = Github(ghtoken) + waka_stats = await get_stats(g) + + repo = g.get_repo(f"{user.login}/{user.login}") + contents = repo.get_readme() + rdmd = decode_readme(contents.content) + new_readme = generate_new_readme(stats=waka_stats, readme=rdmd) + + if commit_by_me.lower() in truthy: + committer = InputGitAuthor(user.login or commit_username, user.email or commit_email) + else: + committer = InputGitAuthor( + commit_username or 'readme-bot', + commit_email or '41898282+github-actions[bot]@users.noreply.github.com' + ) + if new_readme != rdmd: + try: + repo.update_file(path=contents.path, message=commit_message, + content=new_readme, sha=contents.sha, branch=branchName, + committer=committer) + except: + repo.update_file(path=contents.path, message=commit_message, + content=new_readme, sha=contents.sha, branch='main', + committer=committer) + print("Readme updated") + + +if __name__ == '__main__': + start_time = datetime.datetime.now().timestamp() * 1000 + run(main()) + end_time = datetime.datetime.now().timestamp() * 1000 + print(f"Program processed in {round(end_time - start_time, 0)} miliseconds.") diff --git a/make_bar_graph.py b/sources/make_bar_graph.py similarity index 95% rename from make_bar_graph.py rename to sources/make_bar_graph.py index fd48727..b4ea8c9 100644 --- a/make_bar_graph.py +++ b/sources/make_bar_graph.py @@ -1,11 +1,5 @@ -import os -from asyncio import run - import pandas as pd -import numpy as np import altair as alt -import json -import os from download_manager import DownloadManager diff --git a/translation.json b/sources/translation.json similarity index 100% rename from translation.json rename to sources/translation.json