-
-
Save EvanHahn/cd5c705063b0300ffe6e8346f4e104a0 to your computer and use it in GitHub Desktop.
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
function stringify({ keys, objects }) { | |
let result = ""; | |
result += row(keys); | |
for (const obj of objects) { | |
result += "\r\n"; | |
result += row(values(obj, keys)); | |
} | |
return result; | |
} | |
function row(values) { | |
return values.map(serialize).join(","); | |
} | |
function serialize(value) { | |
switch (typeof value) { | |
case "string": | |
return serializeString(value); | |
case "number": | |
return Number.isNaN(value) ? "" : String(value); | |
case "bigint": | |
case "boolean": | |
return String(value); | |
case "undefined": | |
return ""; | |
case "object": | |
if (value === null) return ""; | |
return serializeDate(value); | |
default: | |
throw new MissingCaseError(value); | |
} | |
} | |
function serializeString(str) { | |
return shouldFieldBeQuoted(str) ? `"${str.replace(/"/gm, '""')}"` : str; | |
} | |
function shouldFieldBeQuoted(str) { | |
return str.includes(",") || str.includes('"') || str.includes("\r\n"); | |
} | |
function serializeDate(date) { | |
return isNaN(date.valueOf()) ? "" : date.toISOString(); | |
} | |
function values(obj, keys) { | |
return keys.map((key) => obj[key]); | |
} | |
class MissingCaseError extends Error { | |
constructor(_value) { | |
super("This should be impossible"); | |
} | |
} | |
function formatTask(task) { | |
return { | |
"Completed Date": task.getCompletedDate(), | |
Completed: task.isCompleted(), | |
"Created Date": task.getCreatedDate(), | |
"Due Date": formatDateThatMightHaveTime( | |
task.getDueDate(), | |
task.hasDueTime() | |
), | |
"Estimate (minutes)": task.getEstimate()?.getMinutes() || null, | |
ID: task.getId(), | |
List: task.getList().getName(), | |
"Modified Date": task.getModifiedDate(), | |
Name: task.getName(), | |
"Parent Task ID": task.getParent()?.getId() || null, | |
Permalink: task.getPermalink(), | |
Priority: formatPriority(task.getPriority()), | |
Recurring: task.isRecurring(), | |
"Start Date": formatDateThatMightHaveTime( | |
task.getStartDate(), | |
task.hasStartTime() | |
), | |
URL: task.getUrl()?.toString() || null, | |
}; | |
} | |
function formatDateThatMightHaveTime(date, hasTime) { | |
if (!date || isNaN(date.valueOf())) return null; | |
return hasTime ? date : date.toISOString().slice(0, 10); | |
} | |
function formatPriority(priority) { | |
if (!priority) return null; | |
const result = priority.toString(); | |
return result === "NoPriority" ? null : result; | |
} | |
function main() { | |
const tasks = rtm.getSelectedTasks(); | |
if (!tasks.length) { | |
return rtm.newMessage( | |
"No tasks selected", | |
"Select 1 or more tasks to export as CSV." | |
); | |
} | |
const csvData = stringify({ | |
keys: ["Name", "Completed", "Estimate (minutes)", "Due Date", "Priority"], | |
objects: tasks.map(formatTask), | |
}); | |
return rtm.newFile(csvData, rtm.MediaType.CSV, "remember_the_milk.csv"); | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks thanks thanks!