Looking for an AppleScript about using Ebbinghaus forgetting curve with OmniFocus

As a student, Ebbinghaus forgetting curve principle is very useful. Very appreciate for your help.

Can you be more specific? What should the program you are seeking actually “do”? Should it randomly put up a dialog that says “Remember Ebbhinghaus”? Should it re-order your Projects by their date last reviewed? Should it calculate statistics about your use of OmniFocus?

Why do you want to do any of this in OmniFocus anyway?


JJW

Well I hope that it can remind me to check memorial tasks after 24h, 2day, 4day, 7day, 15day since set those tasks. I use omnifocus to organise my daily routine and those tasks are important parts of my life. So if this function can be realised by omnifocus it will be very helpful or I will have to use other app to do this job which is not very convinence

Check? You mean review, right? So what you want is something that advances the review date by those increments automatically.

The manual fix is to adjust the next review time each time you review the project.

My approach with AppleScript would be to take the current project being viewed, get its review increment, and adjust it according to your table.

Here is an exceptionally crude starting point. This takes the current project selection, copies its review interval to a variable theReview, and then adjusts the review interval to 1 day from today.

on run
tell application "OmniFocus"
	tell the content of front document window of default document to set itsID to the id of every selected tree
	tell default document
		set itsReview to the review interval of the first flattened project whose id = itsID
		set the review interval of the first flattened project whose id = itsID to {unit:day, steps:1, fixed:false}
	end tell
end tell
end run

This offers something that you or someone else might build.


JJW

Thank you! I found an old AppleScript just now that meet my need, but it doesn’t suit OF2. it shows that: “can’t find target file id “DefaultDueTime” of document 1”. and 1 is the action name I use to test the Applescript. could you help me to check it?

– Ebbinghaus review scheduler
– schedules tasks for reviewing learned material in spirit of Ebbinghaus forgetting curves
– Bill Palmer, February 2013

property pReviewProject : “Review” – name of project which will receive tasks
property pReviewIntervals : {4, 6, 14, 29} – number of days before each repeat, augment as desired
property pReviewDaysUntilDue : 2 – allow two days after start date for completion
property pAutoSave : false – set this to false for faster performance but slightly more risk

on GetDefaultDueTime()
tell application id “OFOC” to tell front document to set timeStr to value of target file id “DefaultDueTime”
set {otid, text item delimiters} to {text item delimiters, “:”}
set {dueHour, dueMin, dueSec, text item delimiters} to every text item in timeStr & otid
return (((dueHour * 60) + dueMin) * 60 + dueSec)
end GetDefaultDueTime

on ProcessAction(selAction, dstProject, dateToday, dueTimeOffset)
local startDate, dueDate, i
tell application id “OFOC”
repeat with i from 1 to (length of pReviewIntervals)
set newAction to duplicate selAction to end of tasks of dstProject
set startDate to dateToday + (item i of pReviewIntervals) * days
set dueDate to startDate + pReviewDaysUntilDue * days + dueTimeOffset
tell newAction to set {defer date, due date, completed} to {startDate, dueDate, false} – if user already completed original, we need to make duplicate active
end repeat
end tell
end ProcessAction

on run {}
set dateToday to (current date) - (time of (current date))
set dueTime to my GetDefaultDueTime()
tell application id “OFOC”
tell front document
tell content of first document window
set lstSelected to value of (selected trees where class of its value is task)
if ((count of lstSelected) = 0) then
display alert “No suitable tasks in selection”
return
end if
end tell
try
set dstProject to first flattened project whose name is pReviewProject
on error
display alert “Could not find destination project “” & ¬
pReviewProject & “””
return
end try
set oldWillAutosave to will autosave
set will autosave to pAutoSave
try – catch any errors and restore autosave setting
repeat with thisOne in lstSelected
my ProcessAction(thisOne, dstProject, dateToday, dueTime)
end repeat
end try
set will autosave to oldWillAutosave
end tell
end tell
end run

For some reason,

value of setting id "DefaultDueTime"

doesn’t contain seconds, so I modified the script to reflect that. It should work, now.

-- Ebbinghaus review scheduler
-- schedules tasks for reviewing learned material in spirit of Ebbinghaus forgetting curves
-- Bill Palmer, February 2013

property pReviewProject : "Review" -- name of project which will receive tasks
property pReviewIntervals : {3, 3 * 7, 3 * 30, 365, 2 * 365} -- number of days before each repeat, augment as desired
property pReviewDaysUntilDue : 2 -- allow two days after start date for completion
property pAutoSave : false -- set this to false for faster performance but slightly more risk

on GetDefaultDueTime()
	tell application id "OFOC" to tell front document to set timeStr to value of setting id "DefaultDueTime"
	set {otid, text item delimiters} to {text item delimiters, ":"}
	set {dueHour, dueMin, text item delimiters} to every text item in timeStr & otid
	return (((dueHour * 60) + dueMin) * 60)
end GetDefaultDueTime

on ProcessAction(selAction, dstProject, dateToday, dueTimeOffset)
	local startDate, dueDate, i
	tell application id "OFOC"
		repeat with i from 1 to (length of pReviewIntervals)
			set newAction to duplicate selAction to end of tasks of dstProject
			set startDate to dateToday + (item i of pReviewIntervals) * days
			set dueDate to startDate + pReviewDaysUntilDue * days + dueTimeOffset
			tell newAction to set {defer date, due date, completed} to {startDate, dueDate, false} -- if user already completed original, we need to make duplicate active
		end repeat
	end tell
end ProcessAction

on run {}
	set dateToday to (current date) - (time of (current date))
	set dueTime to my GetDefaultDueTime()
	tell application id "OFOC"
		tell front document
			tell content of first document window
				set lstSelected to value of (selected trees where class of its value is task)
				if ((count of lstSelected) = 0) then
					display alert "No suitable tasks in selection"
					return
				end if
			end tell
			try
				set dstProject to first flattened project whose name is pReviewProject
			on error
				display alert "Could not find destination project \"" & ¬
					pReviewProject & "\""
				return
			end try
			set oldWillAutosave to will autosave
			set will autosave to pAutoSave
			try -- catch any errors and restore autosave setting
				repeat with thisOne in lstSelected
					my ProcessAction(thisOne, dstProject, dateToday, dueTime)
				end repeat
			end try
			set will autosave to oldWillAutosave
		end tell
	end tell
end run
1 Like

The script above doesn’t work on my mac. So I write my own AppleScript.
You can see my blog post(in Chinese).

(* 
    Schedule tasks for reviewing material in spirit of Ebbinghaus forgetting curves
    by Kaihao, August 2018
    https://kaihao.io/2018/omnifocus-review-with-ebbinghaus/
    
    Revised from Curt Clifton's "Complete and Await Reply" script (http://curtclifton.net/complete)
*)

# Number of defer days
property deferIntervals : {1, 2, 4, 8, 16, 32}

# Number of days from defer date that the newly created "review" action will be due. Set to a negative number to put no due date on the new action.
property daysUntilDue : -1

set itemTitle to missing value
tell application "OmniFocus"
    tell front document
        tell content of document window 1 -- (first document window whose index is 1)
            set theSelectedItems to value of every selected tree
            if ((count of theSelectedItems) < 1) then
                display alert "You must first select an item to complete." as warning
                return
            end if
            set reversedDeferIntervals to reverse of deferIntervals
            repeat with anItem in theSelectedItems
                set itemTitle to name of anItem
                repeat with i from 1 to (length of deferIntervals)
                    set theDupe to duplicate anItem to after anItem
                    
                    -- Set defer date
                    set deferForDays to item i of reversedDeferIntervals
                    set deferUntilDate to current date
                    set time of deferUntilDate to 0
                    set deferUntilDate to (deferUntilDate) + deferForDays * days
                    set defer date of theDupe to deferUntilDate
                    
                    -- Set due date
                    if (daysUntilDue < 0) then
                        set due date of theDupe to missing value
                    else
                        set due date of theDupe to (defer date of theDupe) + daysUntilDue * days
                    end if
                end repeat
            end repeat
        end tell
    end tell
end tell