Skip to content

Commit 15d40a0

Browse files
committed
readme updated
1 parent 0a25ff4 commit 15d40a0

1 file changed

Lines changed: 66 additions & 5 deletions

File tree

README.md

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1-
**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.**
2-
31
# Profile-Readme-WakaTime
42
![LICENSE](https://img.shields.io/github/license/avinal/Profile-Readme-WakaTime?style=flat-square)
3+
![Release](https://img.shields.io/github/v/release/avinal/Profile-Readme-WakaTime?style=flat-square)
4+
5+
If you use WakaTime to track your coding activity. You can add that to your README as a picture.
6+
Just add this action to any of your repository and there you have it. See mine below.
57

6-
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.
8+
## My WakaTime Coding Activity
9+
<img src="https://github.com/avinal/avinal/blob/master/images/stat.svg" alt="Avinal WakaTime Activity"/>
710

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

@@ -29,7 +33,8 @@ jobs:
2933
name: Update the WakaTime Stat
3034
runs-on: ubuntu-latest
3135
steps:
32-
# If you have forked this repo then you can use <username>/Profile-Readme-WakaTime@master
36+
# Use avinal/Profile-Readme-WakaTime@<latest-release-tag> for latest stable release
37+
# Do not change the line below except the word master with tag number maybe
3338
- uses: avinal/Profile-Readme-WakaTime@master
3439
with:
3540
WAKATIME_API_KEY: ${{ secrets.WAKATIME_API_KEY }}
@@ -43,4 +48,60 @@ on:
4348
schedule:
4449
- cron: '1 0 * * *'
4550
```
46-
Thanks!
51+
52+
## Implementation Details
53+
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.
54+
55+
1. *[main.py](https://github.com/avinal/Profile-Readme-WakaTime/blob/master/main.py)* python script. This script contains many procedures.
56+
* [Getting JSON data file via WakaTime API](https://github.com/avinal/Profile-Readme-WakaTime/blob/master/main.py#L52)
57+
```python
58+
def get_stats() -> list:
59+
...
60+
return data_list
61+
```
62+
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.
63+
* [Setting the Timeline](https://github.com/avinal/Profile-Readme-WakaTime/blob/master/main.py#L13)
64+
```python
65+
def this_week(dates: list) -> str:
66+
...
67+
return f"Coding Activity During: {week_start.strftime('%d %B, %Y')} to {week_end.strftime('%d %B, %Y')}"
68+
```
69+
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
70+
```json
71+
date: "YYYY-MM-DDTHH:MM:SSZ"
72+
```
73+
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.
74+
* [Creating a bar graph](https://github.com/avinal/Profile-Readme-WakaTime/blob/master/main.py#L21)
75+
```python
76+
def make_graph(data: list):
77+
...
78+
savefig(...)
79+
```
80+
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.
81+
82+
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.
83+
```bash
84+
remote_repo="https://${GITHUB_ACTOR}:${INPUT_GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
85+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
86+
git config user.name "GitHub Actions"
87+
```
88+
*41898282* is the id assigned to the github-actions bot. Don't ask where I found them 🙂.
89+
90+
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.
91+
```bash
92+
# '/' is the seperator
93+
IFS='/' read -ra reponame <<< "${GITHUB_REPOSITORY}"
94+
# returned {username, repository}
95+
repository="${reponame[1]}"
96+
```
97+
After that all other commands are pretty straight. Commit the added files and push them.
98+
99+
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.
100+
101+
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.
102+
```dockerfile
103+
CMD python3 /main.py && /entrypoint.sh
104+
```
105+
This part is the smallest yet took the most time and tries while developing this action.
106+
107+
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 commit comments

Comments
 (0)