Skip to content

Commit

Permalink
readme updated
Browse files Browse the repository at this point in the history
  • Loading branch information
avinal committed Nov 8, 2020
1 parent 0a25ff4 commit 15d40a0
Showing 1 changed file with 66 additions and 5 deletions.
71 changes: 66 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
**This repository has been archived and won't be updated in future. Please fork a copy if you liked this project and want to modify or keep using.**

# Profile-Readme-WakaTime
![LICENSE](https://img.shields.io/github/license/avinal/Profile-Readme-WakaTime?style=flat-square)
![Release](https://img.shields.io/github/v/release/avinal/Profile-Readme-WakaTime?style=flat-square)

If you use WakaTime to track your coding activity. You can add that to your README as a picture.
Just add this action to any of your repository and there you have it. See mine below.

If you use WakaTime to track your coding activity. You can add that to your README as a picture or embed in your website. Just add this action to any of your repository and there you have it.
## My WakaTime Coding Activity
<img src="https://github.com/avinal/avinal/blob/master/images/stat.svg" alt="Avinal WakaTime Activity"/>

## How to add one to your README.md
1. First get your WakaTime API Key. You can get it from your [WakaTime](https://wakatime.com) account settings.
2. Save WakaTime API Key to Repository Secret. Find that by clicking the Settings tab. Keep the name of secret as **WAKATIME_API_KEY**.
3. Add following line in your README.md of your repo.
```html
<img src="https://github.com/<username>/<repository-name>/blob/master/images/stat.svg" alt="Alternative Text"/>
Example: <img src="https://github.com/avinal/avinal/blob/master/images/stat.svg" alt="Avinal WakaTime Activity"/>
```
You can use this method to embed in web pages too.

Expand All @@ -29,7 +33,8 @@ jobs:
name: Update the WakaTime Stat
runs-on: ubuntu-latest
steps:
# If you have forked this repo then you can use <username>/Profile-Readme-WakaTime@master
# Use avinal/Profile-Readme-WakaTime@<latest-release-tag> for latest stable release
# Do not change the line below except the word master with tag number maybe
- uses: avinal/Profile-Readme-WakaTime@master
with:
WAKATIME_API_KEY: ${{ secrets.WAKATIME_API_KEY }}
Expand All @@ -43,4 +48,60 @@ on:
schedule:
- cron: '1 0 * * *'
```
Thanks!
## Implementation Details
This GitHub Action is divided into three parts. I didn't want to use Docker but it seems it doesn't works well without it. Let dive a little on technical details. Three parts are as below.
1. *[main.py](https://github.com/avinal/Profile-Readme-WakaTime/blob/master/main.py)* python script. This script contains many procedures.
* [Getting JSON data file via WakaTime API](https://github.com/avinal/Profile-Readme-WakaTime/blob/master/main.py#L52)
```python
def get_stats() -> list:
...
return data_list
```
This function parses the json file received and scraps out the useful data as a list of lists. Data scraped are language list, time spent on each language, percentage of time, start date and end date. For this action I have limited the number of languages to 5 however it should be very easy to increase that number.
* [Setting the Timeline](https://github.com/avinal/Profile-Readme-WakaTime/blob/master/main.py#L13)
```python
def this_week(dates: list) -> str:
...
return f"Coding Activity During: {week_start.strftime('%d %B, %Y')} to {week_end.strftime('%d %B, %Y')}"
```
The start date and end date scraped in the last function is used here to set the timeline. Because date in json is provided in UTC as below
```json
date: "YYYY-MM-DDTHH:MM:SSZ"
```
We striped it to simple dates only. We can set the manually by taking the current time from the system. But that method is flawed. But this methos ensures that JSON was received latest and the request was successful. Any anmoly will point to a failure in request.
* [Creating a bar graph](https://github.com/avinal/Profile-Readme-WakaTime/blob/master/main.py#L21)
```python
def make_graph(data: list):
...
savefig(...)
```
Lastly its time to generate the graph and save them as image. This functions uses the data scraped in the first step. Creating a bar graph using `matploylib` is easy. Decorating was a bit deficult. I wanted this graph to merge with GitHub's look so I chose to color the bar as GitHub colors the languages. That data is stored as `colors.json`. Many of the languages have slighly different spelling in GitHub as compared to WakaTime. So some languages are shown in default color. That can be improved if we notice that language and change their color manually. Lastly the graph is saved both as SVG and PNG. SVGs are better to put in a zoomable page.

2. *[entrypoint.py](https://github.com/avinal/Profile-Readme-WakaTime/blob/master/entrypoint.sh)* shell script. This shell script clones the repo, copies the image and push changes to the master. There were several problems. First of all authantication. This was solved by using a remote repository address using GitHub Token. And it seems that GitHub doesn't allows to commit without a username and email. So I used **github-actions** bot email.
```bash
remote_repo="https://${GITHUB_ACTOR}:${INPUT_GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config user.name "GitHub Actions"
```
*41898282* is the id assigned to the github-actions bot. Don't ask where I found them 🙂.

Another problem was to seperate repository name from combined *username/repository-name* provided by `${GITHUB_REPOSITORY}`. GitHub doesn't provied a direct way to get just the repo name. We used *Internal Field Seperator*. It returns an array and works similiar to `split()` command in Python and Java.
```bash
# '/' is the seperator
IFS='/' read -ra reponame <<< "${GITHUB_REPOSITORY}"
# returned {username, repository}
repository="${reponame[1]}"
```
After that all other commands are pretty straight. Commit the added files and push them.

3. *[Dockerfile](https://github.com/avinal/Profile-Readme-WakaTime/blob/master/Dockerfile)* **IMPORTANT** took a lot of time to reach this state 🥱. This is where all the magic happens. We are running `ubuntu:latest` inside the container. We first update the distribution. Then install required python packages. Lastly we envoke the pyhton script and shell script.

There was a almost impossible problem, I searched hundreds of post that *how can I access the generated files inside Docker container*, but no luck. But at last I found a workaround(oviously otherwise you wouldn't be reading this by now 🤣) Actually each command is run in a seperate virtual sub-container. As the command ends its output is also lost but not when you club multiple commands together. At least not until every command is finished. The generated files are available to the next clubbed process. I did that by combining the python script run and shell script run.
```dockerfile
CMD python3 /main.py && /entrypoint.sh
```
This part is the smallest yet took the most time and tries while developing this action.

Finally the project is complete and I wanted to write all the challanges so that somebody could develop a better version or take help from my experience. Hope you enjoyed it.

0 comments on commit 15d40a0

Please sign in to comment.