Skip to content

Instantly share code, notes, and snippets.

@leoruhland
Created January 30, 2020 12:52
Show Gist options
  • Save leoruhland/9a4e52b22dfae4e396eee00d9c86d7e7 to your computer and use it in GitHub Desktop.
Save leoruhland/9a4e52b22dfae4e396eee00d9c86d7e7 to your computer and use it in GitHub Desktop.
Transform raw data from Toggl to a summarizing information grouping duration hours by task.
const csv = require('csv-parser');
const fs = require('fs');
const createCsvWriter = require('csv-writer').createObjectCsvWriter;
const csvWriter = createCsvWriter({
path: 'out.csv',
header: [
{ id: 'date', title: 'Date' },
{ id: 'project', title: 'Project' },
{ id: 'description', title: 'Description' },
{ id: 'duration', title: 'Hours' },
]
});
const data = [];
const addTimes = (startTime, endTime) => {
var times = [0, 0, 0]
var max = times.length
var a = (startTime || '').split(':')
var b = (endTime || '').split(':')
// normalize time values
for (var i = 0; i < max; i++) {
a[i] = isNaN(parseInt(a[i])) ? 0 : parseInt(a[i])
b[i] = isNaN(parseInt(b[i])) ? 0 : parseInt(b[i])
}
// store time values
for (var i = 0; i < max; i++) {
times[i] = a[i] + b[i]
}
var hours = times[0]
var minutes = times[1]
var seconds = times[2]
if (seconds >= 60) {
var m = (seconds / 60) << 0
minutes += m
seconds -= 60 * m
}
if (minutes >= 60) {
var h = (minutes / 60) << 0
hours += h
minutes -= 60 * h
}
return ('0' + hours).slice(-2) + ':' + ('0' + minutes).slice(-2) + ':' + ('0' + seconds).slice(-2)
}
const csvRowExtract = (row) => {
data.push({
project: row['Project'],
description: row['Description'],
date: row['Start date'],
duration: row['Duration']
});
};
const csvReduce = (acc, each) => {
if (acc[each.project] === undefined) {
acc[each.project] = [];
}
if (acc[each.project][each.description] === undefined) {
acc[each.project][each.description] = [];
}
acc[each.project][each.description].push(each);
return acc;
}
const eachProject = (acc, each) => {
if (acc[each.project] === undefined) {
acc[each.project] = [];
}
if (acc[each.project][each.description] === undefined) {
acc[each.project][each.description] = [];
}
acc[each.project][each.description].push(each);
return acc;
}
fs.createReadStream('data.csv')
.pipe(csv())
.on('data', csvRowExtract)
.on('end', () => {
console.log('CSV processed');
const csvData = data.reduce(csvReduce, {});
const projects = Object.keys(csvData);
const resultArray = projects.map(project => {
const projectData = csvData[project];
const tasks = Object.keys(projectData);
return tasks.map(task => {
const taskData = projectData[task];
const project = taskData[0].project;
const description = taskData[0].description;
const date = (taskData.length === 1) ? taskData[0].date : taskData[0].date + ' - ' + taskData[taskData.length - 1].date;
const duration = taskData.reduce((acc, each) => {
return addTimes(acc, each.duration);
}, '00:00:00');
return {
date,
project,
description,
duration
}
});
});
const result = resultArray.reduce((acc, each) => {
each.map(e => {
acc.push(e);
})
return acc;
}, [])
csvWriter
.writeRecords(result)
.then(() => console.log('CSV written'));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment