Skip to content

Instantly share code, notes, and snippets.

@alifeee
Last active June 29, 2024 20:43
Show Gist options
  • Save alifeee/5ccfdff391f1bfc894f6e21beb78996d to your computer and use it in GitHub Desktop.
Save alifeee/5ccfdff391f1bfc894f6e21beb78996d to your computer and use it in GitHub Desktop.
Toggl Track API JSON to CSV conversion
"""create a histogram of "hours per week" from timesheets"""
import csv
import sys
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
import numpy
FNAME = "combined.csv"
with open(FNAME, "r", encoding="utf-8") as file:
reader = csv.DictReader(file)
data = [row for row in reader]
# sort
data = sorted(data, key= lambda r: datetime.strptime(r["start"][0:10], "%Y-%m-%d"))
first_date = datetime.strptime(data[0]["start"][0:10], "%Y-%m-%d")
isoy, isow, isod = first_date.isocalendar()
first_date_week = datetime.fromisocalendar(isoy, isow, 1)
dates_bins = [first_date_week]
seconds = [0]
for row in data:
last_dt = dates_bins[-1]
lisoy, lisow, lisod = last_dt.isocalendar()
this_dt = datetime.strptime(row["start"][0:10], "%Y-%m-%d")
sisoy, sisow, sisod = this_dt.isocalendar()
duration_s = row["duration"]
while sisoy > lisoy or sisow > lisow:
next_dt = last_dt + timedelta(days=7)
dates_bins.append(next_dt)
seconds.append(0)
last_dt = dates_bins[-1]
lisoy, lisow, lisod = last_dt.isocalendar()
seconds[-1] += int(duration_s)
last_date = datetime.strptime(data[-1]["start"][0:10], "%Y-%m-%d")
lisoy, lisow, lisod = last_date.isocalendar()
last_date_week = datetime.fromisocalendar(lisoy, lisow + 1, 1)
dates_bins.append(last_date_week)
print("dates_bins", dates_bins)
print("seconds", seconds)
hours = [s / 3600 for s in seconds]
plt.stairs(hours, dates_bins, fill=True)
plt.xlabel("Week")
plt.ylabel("Hours")
plt.grid(axis="y")
plt.show()
#!/bin/bash
# turns Toggl JSON API data into CSV format
# currently ignores any array fields
# you can override the TOGGL_KEYS env variable to set which keys you want in the CSV
# usage
# get toggl data
# https://developers.track.toggl.com/docs/api/time_entries/index.html
# curl https://api.track.toggl.com/api/v9/me/time_entries -H "Content-Type: application/json" -u <email>:<password> > toggl.json
# curl https://api.track.toggl.com/api/v9/me/time_entries -H "Content-Type: application/json" -u <api token>:api_token > toggl.json
# get January entries, e.g.,
# curl "https://api.track.toggl.com/api/v9/me/time_entries?start_date=2024-01-01&end_date=2024-02-01" -H "Content-Type: application/json" -u <api token>:api_token > 2024-01_toggl.json
# script:
# as argument:
# ./parse_toggl.sh toggl.json
# as pipe
# cat toggl.json | /parse_toggl.sh
# or just directly pipe curl output to the script (use "-s" with curl to suppress loading output to stderr)
# from https://gist.github.com/alifeee/5ccfdff391f1bfc894f6e21beb78996d
KEYS="${TOGGL_KEYS:-.id, .workspace_id, .project_id, .task_id, .billable, .start, .stop, .duration, .description, .duronly, .at, .server_deleted_at, .user_id, .uid, .wid, .pid}"
# print CSV headers
echo $KEYS | awk -F', ' '{for (i=1; i<NF; i++) {printf "%s,", substr($i, 2)}} END {printf "\n"}'
# print CSV content (parse JSON with jq)
cat $1 | jq -r '.[] | ['"${KEYS}"'] | @csv'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment