Created
March 8, 2023 00:56
-
-
Save d4hines/15f459026754a0e9da07bb01da046192 to your computer and use it in GitHub Desktop.
Recurring and Deferred Tasks in Roam Research
This file contains hidden or 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
let tags = [ | |
'weekly', | |
'biweekly', | |
'monthly', | |
'bimonthly', | |
'biannually', | |
'spring', | |
'fall', | |
'summer', | |
'winter', | |
'yearly' | |
]; | |
let roamFormat = "MMMM Do, YYYY"; | |
const getNextDate = (tag) => { | |
const today = new Date(); | |
let date; | |
switch(tag) { | |
case "weekly": | |
date = moment().add(1, "week"); | |
break; | |
case "biweekly": | |
date = moment().add(2, "week"); | |
break; | |
case "monthly": | |
date = moment().add(1, "month"); | |
break; | |
case "bimonthly": | |
date = moment().add(2, "month"); | |
break; | |
case "biannually": | |
date = moment().add(2, "year"); | |
break; | |
case "spring": | |
case "fall": | |
case "summer": | |
case "winter": | |
case "yearly": | |
date = moment().add(1, "year"); | |
break; | |
throw new Error("bad tag"); | |
}; | |
return date.format(roamFormat); | |
} | |
const makeTodos = async () => { | |
for (const tag of tags) { | |
let references = window.roamAlphaAPI.q(`[ | |
:find ?uid ?text ?page ?child_uid ?next_due_date | |
:in $ ?title | |
:where | |
[?page :node/title ?title] | |
[?e :block/refs ?page] | |
[?e :block/string ?text] | |
[?e :block/uid ?uid] | |
[?e :block/children ?child] | |
[?next_due_date_id :node/title "next_due_date"] | |
[?child :block/refs ?next_due_date_id] | |
[?child :block/uid ?child_uid] | |
[?child :block/string ?next_due_date] | |
]`, tag); | |
for(const [uid, text, page, child_uid, next_due_date] of references) { | |
console.log(`Found todo: '${text}'`) | |
const due_date = moment(next_due_date.slice(17, -2), roamFormat); | |
if(moment().isSameOrAfter(due_date)) { | |
const todo_text = `{{[[TODO]]}} ((${uid}))`; | |
console.log("It's time to create new todo"); | |
await window.roamAlphaAPI.createBlock( | |
{ location: {"parent-uid": moment().format("MM-DD-YYYY"), | |
"order": 100000}, // use very large number to add at the bottom | |
block: {string: todo_text }}) | |
console.log("Todo created"); | |
await window.roamAlphaAPI.deleteBlock({block: {uid: child_uid}}); | |
console.log("Old due date deleted"); | |
let new_due_date = getNextDate(tag); | |
console.log("new due date is ", new_due_date) | |
await window.roamAlphaAPI.createBlock({ | |
location: {"parent-uid": uid, order: -1}, | |
block: {string: `#next_due_date [[${new_due_date}]]`} | |
}); | |
console.log("New due date created"); | |
} | |
} | |
} | |
}; | |
async function promoteDeferredTodos() { | |
let results = window.roamAlphaAPI.q(`[ | |
:find ?uid ?text ?other_page_title | |
:in $ | |
:where | |
[?page :node/title "Deferred TODO"] | |
[?e :block/refs ?page] | |
[?e :block/refs ?other_page] | |
[?e :block/string ?text] | |
[?e :block/uid ?uid] | |
[?other_page :node/title ?other_page_title] | |
[(!= ?page ?other_page)] | |
]`); | |
console.log(results); | |
for (const [uid, text, dateStr] of results) { | |
let date = moment(dateStr, roamFormat); | |
const diff = moment().diff(date, 'hours'); | |
if(diff > 0) { | |
const updatedText = text.replace("[[Deferred TODO]]", "{{[[TODO]]}}"); | |
console.log(`promoting todo '${updatedText}'`); | |
await window.roamAlphaAPI.updateBlock({ | |
block: { uid, string: updatedText }, | |
}); | |
} | |
} | |
} | |
async function waitUntilReady(n) { | |
const isSynced = document.getElementsByClassName("rm-sync--synced").length; | |
if(typeof window.moment == "function" && isSynced) { | |
await makeTodos(); | |
await promoteDeferredTodos(); | |
} else if (n > 10) { | |
alert("Recurring Task Management: document never became ready"); | |
} else { | |
setTimeout(() => waitUntilReady(n + 1), 1000) | |
} | |
} | |
waitUntilReady(0); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment