-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
160 lines (122 loc) · 5.13 KB
/
index.js
File metadata and controls
160 lines (122 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
const moment = require('moment')
const momentDurationFormatSetup = require("moment-duration-format");
const dotenv = require('dotenv')
const {base64, getEnvVar, getMonthArg, getEntriesByDay} = require('./utils')
// attach momentDuration plugin to moment
momentDurationFormatSetup(moment);
const BASE_URL = 'https://api.track.toggl.com/api/v9'
dotenv.config({path: '.env.local'})
const isCommand = (tokens) => {
const args = process.argv.slice(2) // Remove the first two arguments
const command = args[0]
// Check if the argument exists and is in the format 'yyyy-mm'
return !command || tokens.includes(command);
}
const authorization = `Basic ${base64(`${getEnvVar('TOGGL_API_TOKEN', true)}:api_token`)}`;
const getTaskBlocks = day =>
day.records.reduce((acc, record) => {
const duration = getDuration(record)
const currentDurationSum = moment.duration(acc[record.description] || '00:00', 'hh:mm')
const newDurationSum = moment.duration(currentDurationSum.asMilliseconds() + duration.asMilliseconds())
acc[record.description] = formatDuration(newDurationSum)
return acc
}, {})
const getDuration = timeBlock => moment.duration(
moment(timeBlock.endTime, 'HH:mm').diff(moment(timeBlock.startTime, 'HH:mm'))
)
const formatDuration = duration => moment.utc(duration.asMilliseconds()).format('HH:mm')
const getFormattedDuration = timeBlock => {
const duration = getDuration(timeBlock)
return formatDuration(duration)
}
const printEntries = byDay => {
byDay.forEach(day => {
console.log('**************************************')
console.log(`${day.day} (${moment(day.day).format('dddd')})`)
console.log('**************************************\n')
day.records.forEach(record => {
console.log(`${record.startTime} - ${record.endTime}: ${record.description}`)
})
console.log('---')
day.timeBlocks.forEach(timeBlock => {
const duration = getFormattedDuration(timeBlock)
console.log(`${timeBlock.startTime} - ${timeBlock.endTime} (${duration})`)
})
console.log('---')
const taskBlocks = getTaskBlocks(day)
Object.keys(taskBlocks).forEach(description => {
console.log(`${taskBlocks[description]}: ${description}`)
})
console.log('---')
console.log(day.hoursTotal)
console.log('\n')
})
}
const printMonthSummary = (byDay, monthArg) => {
if (byDay.length > 0) {
console.log('**************************************')
console.log(`Summary for month ${moment(byDay[0].day).format('MMMM')} ${moment(byDay[0].day).format('YYYY')}`)
console.log('**************************************\n')
const totalWorkDuration = byDay.map(day => day.hoursTotal).reduce((sum, dayTotal) => sum + moment.duration(dayTotal).asMinutes(), 0)
console.log(`Total work duration: ${moment.duration(totalWorkDuration, "minutes").format("HH:mm")}`)
const averageWorkHoursPerWorkingDay = totalWorkDuration / getWorkingDayCount(monthArg)
console.log(`Average work hours per working day: ${moment.duration(averageWorkHoursPerWorkingDay, "minutes").format("HH:mm")}`)
}
}
const getWorkingDayCount = (monthArg) => {
const daysInMonth = moment(monthArg, 'YYYY-MM').daysInMonth();
const today = moment()
let workingDayCount = 0;
for (let day = 1; day <= daysInMonth; day++) {
const date = moment(`${monthArg}-${day}`, 'YYYY-MM-DD');
if (date.isAfter(today)) {
return workingDayCount
}
if (date.isoWeekday() >= 1 && date.isoWeekday() <= 5) { // Monday to Friday
workingDayCount++
}
}
return workingDayCount;
}
async function showEntries() {
const monthArg = getMonthArg()
const byDay = await getEntriesByDay(monthArg, authorization)
printEntries(byDay)
printMonthSummary(byDay, monthArg)
}
const showHelp = () => {
console.log('**************************************')
console.log('year-month\tShow all entries and a summary for the month and project (TOGGL_PROJECT_ID)')
console.log('Example: node index.js 2023-06\n')
console.log('p, projects\tShow a list of your projects')
console.log('Example: node index.js p\n')
console.log('h, help\tshow this help')
console.log('Example: node index.js h')
console.log('**************************************')
}
async function showProjects() {
const response = await fetch(`${BASE_URL}/me/projects`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': authorization
}
})
const entries = await response.json()
console.log('**************************************')
console.log('Your currently active projects:')
entries.forEach(entry => {
console.log("'" + entry.name + "' --> " + entry.id)
})
console.log('**************************************')
}
async function run() {
if (getMonthArg() !== null) {
await showEntries();
} else if (isCommand("p", "projects")) {
await showProjects();
} else {
showHelp()
}
}
run()