forked from ChristianMay21/todo-print-automation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
179 lines (147 loc) · 5.67 KB
/
index.js
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import { TodoistApi } from "@doist/todoist-api-typescript";
import { writeFile } from "fs";
import { readFile } from "fs/promises";
import { spawn } from "child_process";
import path from "path";
async function fetchAndPrintTodoList() {
// Read and parse the config
const config = JSON.parse(
await readFile(new URL("./config.json", import.meta.url))
);
const api = new TodoistApi(config["todoist-api-token"]);
// Get the current time in UTC
const currentTime = new Date();
// Convert to local time
currentTime.setHours(
currentTime.getHours() + config["hour-difference-from-UTC"]
);
const currentYear = currentTime.getFullYear();
const currentMonth = currentTime.getMonth() + 1;
const currentDay = currentTime.getDate();
// Determine if passed task should be included in the printed task list
// The requirements here are based on my personal preferences - you may want to modify them
function includeTask(task) {
//If the task does not have a due date, do not include it in the task list
if (task.due === null) {
return false;
}
const splitTaskString = task.due.date.split("-");
const taskYear = Number(splitTaskString[0]);
const taskMonth = Number(splitTaskString[1]);
const taskDay = Number(splitTaskString[2]);
//Include any tasks due in a previous year
if (taskYear < currentYear) {
return true;
}
//Include tasks due this year, in a previous month
if (taskYear === currentYear && taskMonth < currentMonth) {
return true;
}
//Include tasks due this year, this month, on a previous day or today
if (
taskYear === currentYear &&
taskMonth === currentMonth &&
taskDay <= currentDay
) {
return true;
}
//Any other tasks, do not include
return false;
}
// When my tasks are printed, I prefer to group them by the time that they are due, with each group listed in chronological order.
// Not all tasks in Todoist have a due time - some only have a due date. All of these tasks I include in a group labelled "Any time today:"
function getTimeTaskIsDue(task) {
if (task.due.datetime === undefined) {
return "Any time today:";
}
let taskDueDateTime = new Date(task.due.datetime);
//The statement below simply formats the datetime string returned by todoist into a more human-readable time, e.g. 9:00,
return (
"" +
taskDueDateTime.getHours() +
":" +
(taskDueDateTime.getMinutes() < 10 ? "0" : "") +
taskDueDateTime.getMinutes()
);
}
//Given two separate tasks, this function determines which of the two should come first
function sortByTime(task1, task2) {
//If neither task has a specific time they're due, they are 'equal'
if (task1.due.datetime === undefined && task2.due.datetime === undefined) {
return 0;
}
//If the first task has no specific time, but the second task does, the second task should appear first
if (task1.due.datetime === undefined && task2.due.datetime !== undefined) {
return 1;
}
if (task1.due.datetime !== undefined && task2.due.datetime === undefined) {
return -1;
}
let task1DueDate = new Date(task1.due.datetime);
let task2DueDate = new Date(task2.due.datetime);
return task1DueDate.getHours() - task2DueDate.getHours();
}
function print() {
// Define the name of the PowerShell script
const scriptName = path.join(process.cwd(), "print.ps1");
// Create a child process to execute the script
const child = spawn("powershell.exe", ["-File", scriptName]);
// Listen for data from the script's stdout
child.stdout.on("data", (data) => {
console.log(`Script output: ${data.toString()}`);
});
// Listen for errors, if any
child.stderr.on("data", (error) => {
console.error(`Script error: ${error.toString()}`);
});
// Listen for the script to exit
child.on("close", (code) => {
if (code === 0) {
console.log(`Script completed successfully.`);
} else {
console.error(`Script exited with code ${code}`);
}
});
}
api
.getTasks()
.then((tasks) => {
// This variable contains all tasks that should be included in the todo list printout
let includedTasks = tasks.filter(includeTask).sort(sortByTime);
// Dates are in standard US format (MM/DD/YYYY)
let stringOutput = `Date: ${currentMonth}/${currentDay}/${currentYear} \n`;
// When printed, each task is numbered 1, 2, 3...
//This variable keeps track of the current task index.
let taskNum = 1;
// When printed, tasks are grouped by time they are due
// This variable keeps track of the current grouping
let currentScheduledTime = "";
for (const task of includedTasks) {
// This block creates the headings for each time grouping
if (getTimeTaskIsDue(task) !== currentScheduledTime) {
stringOutput += `\n${getTimeTaskIsDue(task)} \n`;
currentScheduledTime = getTimeTaskIsDue(task);
}
// Add the entry for each individual task
stringOutput += `${taskNum}. ${task.content}\n`;
taskNum++;
}
// Write all tasks to a .txt file - this .txt file will be used by the Powershell script that actually prints the tasks
writeFile(
"tasks.txt",
stringOutput,
(err) => {
if (err) {
console.error(err);
}
},
() => {
// Invoke the powershell script that handles formatting the tasks and printing them
print();
}
);
})
.catch((error) => console.log(error));
}
// Actually invoke all of the functionality defined above
await fetchAndPrintTodoList();