Last active
November 27, 2018 17:11
-
-
Save Kutkovsky/3a2dcbe6b0ea197b1eee219e0beac9b2 to your computer and use it in GitHub Desktop.
Another version of Toggl-parser.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/python3 | |
import sys | |
import csv | |
import xlwt | |
import requests | |
import json | |
import pandas | |
from datetime import datetime | |
def parse_file(filename): | |
csv_file = sys.argv[1] | |
# if argument given raises an exception - we should try use a default name or file in the same dir w/ .csv? | |
wb = open(csv_file) | |
reader = csv.reader(wb) | |
data = [] | |
# We need Cols: 3, empty, 5, 7, 9 for `Project`, `Effort`, `Task | |
# description`, `Start date`, `End date` | |
first_row = True | |
for row in reader: | |
if first_row: # skip first row | |
first_row = False | |
continue | |
project = str(row[3]) | |
time = row[11] # We using `Duration` value for the effort calculation | |
effort = int(time[0:2]) + int(int(time[3:5])) / 60 + \ | |
int(int(time[6:7])) / 3600 # Hourly effort formula | |
task = str(row[5]) | |
started = str(row[7]) | |
completed = str(row[9]) | |
data.append((project, effort, task, started, completed)) | |
return data | |
def get_workspace(token): | |
print('Proceeding with your token, getting your workspace id now...') | |
r = requests.get('https://www.toggl.com/api/v8/workspaces', auth=(token, 'api_token')) | |
req = r.json() | |
r.status_code | |
r.raise_for_status() | |
workspace = req[0]['id'] # we know user's workspace id now | |
return workspace | |
def parse_online(token, workspace_id): | |
# TODO: add two more arguments for parsing requested period of time | |
print('Proceeding with your token, collecting your data now...') | |
since = '2018-10-01' # Begin of retrieved records | |
until = '2018-10-31' # End of retrieved period | |
r = requests.get("https://toggl.com/reports/api/v2/details?", auth=(token, 'api_token'), params={ | |
'workspace_id': workspace_id, | |
'page': '1', # we did 50 records. So this a minimum. Less will lead to fail? TODO: the rest | |
'since': since, | |
'until': until, | |
'user_agent': 'api_test' | |
}) | |
data = r.json() | |
''' | |
Or... The first request for amount of records retrieving (dry run). | |
Then we'll do a work request??? | |
''' | |
pages_amount = int(data['total_count'] / 50) | |
pages_remainder = int(data['total_count']) % 50 | |
print(pages_amount, pages_remainder) # this give us amount of loops (w/ 50 recs each) and a remainder | |
parsed = [] | |
for rec in range(00, 50): | |
project = data['data'] [rec] ['project'] | |
effort = ((lambda dur: dur / 1000 / 3600) (data['data'] [rec] ['dur'])) # Millisec -> Sec -> Hours in decimal (effort) | |
task = data['data'] [rec] ['description'] | |
started = data['data'] [rec] ['start'] | |
completed = data['data'] [rec] ['end'] | |
parsed.append((project, effort, task, started, completed)) | |
print(parsed) | |
return parsed | |
def export_xls(data): | |
xls_file = 'timereport.xls' # TODO: add date period to the filename automatically | |
book = xlwt.Workbook(encoding="utf-8") | |
date_format = xlwt.XFStyle() | |
date_format.num_format_str = 'yyyy/mm/dd' | |
sheet1 = book.add_sheet("Efforts") | |
# create DataFrame to remove duplicates | |
df = pandas.DataFrame( | |
data, columns=['project', 'effort', 'task', 'started', 'completed']) | |
# sum duplicates | |
df = df.groupby(['project', 'task', 'started', 'completed'] | |
).sum().reset_index() | |
# add header row to xls file | |
sheet1.write(0, 0, 'Project-Task') | |
sheet1.write(0, 1, 'Effort') | |
sheet1.write(0, 2, 'Description') | |
sheet1.write(0, 3, 'Started Date') | |
sheet1.write(0, 4, 'Completion Date') | |
for i, row in df.iterrows(): | |
sheet1.write(i+1, 0, row['project']) | |
sheet1.write(i+1, 1, row['effort']) | |
sheet1.write(i+1, 2, row['task']) | |
sheet1.write(i+1, 3, datetime.strptime( | |
row['started'], '%Y-%m-%d'), date_format) | |
sheet1.write(i+1, 4, datetime.strptime( | |
row['completed'], '%Y-%m-%d'), date_format) | |
i += 1 | |
book.save(xls_file) | |
print('The Toggl data has been successfully exported:',xls_file) | |
def print_usage(): | |
print('''Usage: python3 toggl.py <CSV filename> | <toggl API token> | |
python3 toggl.py <CSV file> - parse the given file and generate timereport.xls at the same directory | |
python3 toggl.py <toggle API token> - request detailed report from Toggl and generate timereport.xls | |
Supposed, that you have Toggl account already for start using this utility. | |
As for our company - the best practice will be the following: | |
- Create Client names i.e. `Microsoft` | |
- Create a bunch of Project names | |
formatted as `ProjectName.TypeOfActivity` i.e. `AppCenter.Development` | |
- Start track your every activity by using a dropdown menu | |
and by selecting the right `ProjectName.TypeOfActivity` value | |
- You all set! | |
Finally, you can either download a CSV-file from the Report page | |
(go https://toggl.com/app/reports/detailed/<your workspace id will be here>/period/thisMonth) | |
or use API-token (go https://toggl.com/app/profile for get your one) for the further parsing.''') | |
sys.exit() | |
if len(sys.argv) < 2: | |
print_usage() | |
argument = str(sys.argv[1]) | |
if argument[-4:] == '.csv': # the given argument ends with ".csv" | |
print('Parsing the file given:', argument) | |
export_xls(parse_file(argument)) | |
else: | |
print('Proceed with token given. Request data online and parsing ') | |
export_xls(parse_online(argument, get_workspace(argument))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment