Skip to content

Commit

Permalink
Merge pull request #2 from dhutchison/fix/pagination-support
Browse files Browse the repository at this point in the history
fix: corrected number of days & added pagination support
  • Loading branch information
dhutchison committed Sep 22, 2020
2 parents e39c615 + 3e3e3f8 commit b0aa81d
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 19 deletions.
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@devwithimagination/toggl-summary-cli",
"version": "0.1.0",
"version": "0.1.1",
"description": "",
"scripts": {
"build": "tsc",
Expand Down
51 changes: 39 additions & 12 deletions src/cli.ts
@@ -1,28 +1,55 @@
#!/usr/bin/env node
import axios, { AxiosRequestConfig } from 'axios'
import axios from 'axios'
import chalk from 'chalk'
import * as ora from 'ora'
import { Duration } from '@js-joda/core'


import { Configuration, processConfiguration } from './configuration-processor';
import { DetailedReportResponse } from './structures';
import { DetailedReportItem, DetailedReportResponse } from './structures';
import { calculateTimeTotals, formatMillis } from './time-reporter'

const apiUrl = 'https://toggl.com/reports/api/v2/details';

/* Define a function for loading our report data from the API. This handles pagination */
const getDetailedReportData = async (page: number): Promise<DetailedReportItem[]> => {
config.apiConfig.params.page = page;

const response = await axios.get<DetailedReportResponse>(apiUrl, config.apiConfig)
const data = response.data.data;

/* Print out the total time as reported from the API */
console.log(
chalk.green('Report page loaded',
config.apiConfig.params.page,
'total booked time:',
formatMillis(response.data.total_grand)));

if (config.debug) {
// console.log('API Response Payload: %o', response.data);

console.log('Pagination details: total_count: %s, per_page: %s',
response.data.total_count, response.data.per_page)
}

/**
* If there are more pages, call the API again, otherwise return the data
*/
if (response.data.data.length > 0 && response.data.data.length === response.data.per_page) {
return data.concat(await getDetailedReportData(page+1))
} else {
return data
}
}

/* Configure API request from command line options */
const config: Configuration = processConfiguration();

/* Call the API */
axios.get<DetailedReportResponse>('https://toggl.com/reports/api/v2/details', config.apiConfig)
.then(response => {

/* Print out the total time as reported from the API */
console.log(
chalk.green('Report loaded, total booked time:',
formatMillis(response.data.total_grand)));
getDetailedReportData(1)
// axios.get<DetailedReportResponse>('https://toggl.com/reports/api/v2/details', config.apiConfig)
.then(detailedItems => {

/* Iterate through the items to work out the time summary */
const timeSummary = calculateTimeTotals(response.data.data, config.debug);
const timeSummary = calculateTimeTotals(detailedItems, config.debug);

/* Print out the output */
console.log(chalk.magenta('==== Totals for', config.apiConfig.params.since, 'to', config.apiConfig.params.until, '===='));
Expand Down
3 changes: 2 additions & 1 deletion src/configuration-processor.ts
Expand Up @@ -57,7 +57,7 @@ export function processConfiguration(): Configuration {
}

const since = LocalDate.parse(program.day);
const until = (program.week ? since.plusDays(7) : since);
const until = (program.week ? since.plusDays(6) : since);

const apiConfig: AxiosRequestConfig = {
auth: {
Expand All @@ -69,6 +69,7 @@ export function processConfiguration(): Configuration {
'Accept-Language': 'en-gb',
},
params: {
page: 1,
user_agent: program.email,
workspace_id: program.workspaceId,
since: since.toString(),
Expand Down
19 changes: 14 additions & 5 deletions src/time-reporter.ts
Expand Up @@ -166,8 +166,15 @@ export function calculateTimeTotals(reportData: SimplifiedDetailedReportItem[],
.forEach((entry, index, array) => {

if (debug) {
console.log('Time entry for %s: %s',
entry.description, Duration.ofMillis(entry.dur));
console.log(chalk.gray('======================'))
console.log('Counts so far: total %s, breaks %s, booked %s, unbooked: %s',
formatMillis(timeSummary.timeCount),
formatMillis(timeSummary.breakTime),
formatMillis(timeSummary.bookedTime),
formatMillis(timeSummary.unbookedTime));
console.log('Time entry for %s: %s (%s - %s)',
entry.description, formatMillis(entry.dur),
entry.start, entry.end);
}

/* An entry is a "break start" marker if all the following are true:
Expand All @@ -191,15 +198,17 @@ export function calculateTimeTotals(reportData: SimplifiedDetailedReportItem[],
/* The previous entry was a 'break start' marker.
* Gap time is break time */
timeSummary.breakTime += timeBetweenEntries.toMillis();
console.log(chalk.greenBright(
'Break time!', formatMillis(timeBetweenEntries.toMillis())));
if (debug) {
console.log(chalk.greenBright(
'Break time!', formatMillis(timeBetweenEntries.toMillis())));
}
} else if (index === 0 || areEntriesForTheSameDay(array[index - 1], array[index])) {
/* Gap time is unbooked time if the end of the last item is the same
* day as the current item */
timeSummary.unbookedTime += timeBetweenEntries.toMillis();

/* Only log it to the console if it is more than 5 minutes */
if (timeBetweenEntries.toMinutes() > 5) {
if (debug && timeBetweenEntries.toMinutes() > 5) {
console.log(chalk.yellow(
'Unbooked time since last entry:',
formatMillis(timeBetweenEntries.toMillis())));
Expand Down

0 comments on commit b0aa81d

Please sign in to comment.