Scripts for a Tickler File

I wrote a few scripts to create and manage a GTD-like tickler file. The basic idea is that you can send notes (reminders, files, etc.) to yourself in the future. For instance, if you want to be reminded of buying a book as a gift, you can put a webarchive of its Amazon page in the tickler file for a particular date.

In it’s original form, a tickler file would have 12 monthly folders and 31 folders for the next 31 days. Each day, you’d empty the day’s folder into the inbox and move the folder to the next month.

It’s easy to create a set of folders and manually do that filing and emptying, but here are some scripts to automate it. The point of this is that you never have to look inside the tickler: it’s emptied automatically and you can file items to specified dates automatically.

As usual, these scripts and this post come without any claims for safety or functionality and any implementation and application of them is entirely at your own risk.

Comments and suggestions welcome. These scripts have been partially ripped from various sources and are my first scripts, and hence not the nicest programming style.

  1. Script to generate the folders

This script actually generates not 43 folders, but 378 folders: one for each month and one for each day in each month (incl, Feb 29). The main folder is called “** Tickler” so that it sorts nicely to the top.


property FOLDERS_MONTHS : {"01 January", "02 February", "03 March", "04 April", "05 May", "06 June", "07 July", "08 August", "09 September", "10 October", "11 November", "12 December"}
property FOLDERS_DAYS : {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}
property MONTH_DAYS : {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

tell application "DEVONthink Pro"
	
	set ticklerFolder to "/** Tickler"
	set ticklerGroup to create location ticklerFolder
	
	set theMonth to 1
	repeat until theMonth = 13
		
		set monthFolder to ticklerFolder & "/" & (item theMonth in FOLDERS_MONTHS)
		set monthGroup to create location monthFolder
		
		set countDays to (item theMonth in MONTH_DAYS)
		set theDay to 1
		repeat until theDay = (countDays + 1)
			set dayFolder to monthFolder & "/" & (item theDay in FOLDERS_DAYS)
			set dayGroup to create location dayFolder
			set theDay to theDay + 1
		end repeat
		
		set theMonth to theMonth + 1
	end repeat
	
end tell


  1. Script to empty the day’s folder into the inbox

This script should be run automatically at night, e.g., as an iCal alarm. It empties the current day’s folder into a folder called “* Inbox”.


property FOLDERS_MONTHS : {"01 January", "02 February", "03 March", "04 April", "05 May", "06 June", "07 July", "08 August", "09 September", "10 October", "11 November", "12 December"}
property FOLDERS_DAYS : {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}

tell application "DEVONthink Pro"
	activate
	
	set inboxFolder to create location "/* Inbox"
	set ticklerFolder to "/** Tickler"
	set currentMonth to item (month of (current date)) of FOLDERS_MONTHS
	set currentDay to item (day of (current date)) of FOLDERS_DAYS
	set currentFolder to create location (ticklerFolder & "/" & currentMonth & "/" & currentDay)
	set theChildren to the children of currentFolder
	repeat with theRecord in theChildren
		move record theRecord to inboxFolder
	end repeat
	
end tell

  1. This script asks for a date and files (=moves) the selected items to the folder for that date. If it doesn’t understand the date format, nothing happens - no error message and no files are moved.

-- Acceptable date formats
-- "tomorrow" = the day after today
-- "Monday" (or any day in listDays) = the first day with that name following today
-- "This Monday" (or "t" & any day in listDays) = that day in the same week (Mon to Sun) as today - could be in the past
-- "Next Monday" (or "n" & any day in listDays) = that day in the week (Mon to Sun) following today
-- whatever formats AppleScript usually understands, such as "Feb 5"

property FOLDERS_MONTHS : {"01 January", "02 February", "03 March", "04 April", "05 May", "06 June", "07 July", "08 August", "09 September", "10 October", "11 November", "12 December"}
property FOLDERS_DAYS : {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}
property listDays : {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "M", "T", "W", "R", "F", "S", "U"}

set dateSet to false
set theDateString to ""

tell application "DEVONthink Pro"
	
	set theSelection to the selection
	if (count of theSelection) < 1 then error "Please select one or more items."
	
	repeat
		display dialog "Enter the date to use:" default answer "" buttons {"Cancel", "OK"} default button 2
		set theDateString to the text returned of the result
		if theDateString is not "" then exit repeat
	end repeat
	
end tell

ignoring case
	set toDay to weekday of (current date) as integer
	if theDateString is "tomorrow" then
		set theDate to (current date) + 1 * days
		set dateSet to true
	end if
	repeat with whichDay from 1 to count of listDays
		if first word of theDateString is item whichDay of listDays then
			if (whichDay mod 7) > toDay then
				set theDate to (current date) + ((whichDay mod 7) - toDay + 1) * days
			else
				set theDate to (current date) + ((whichDay mod 7) - toDay + 8) * days
			end if
			set dateSet to true
		end if
		if first word of theDateString is in {"this", "t"} then
			if second word of theDateString is item whichDay of listDays then
				if (whichDay mod 7) = 0 then
					set theAdj to 8 -- if week begins with Sunday, not Monday, set this to 1
				else
					set theAdj to 1
				end if
				set theDate to (current date) + ((whichDay mod 7) - toDay + theAdj) * days
				set dateSet to true
			end if
		end if
		if first word of theDateString is in {"next", "n"} then
			if second word of theDateString is item whichDay of listDays then
				if (whichDay mod 7) = 0 then
					set theAdj to 15 -- if week begins with Sunday, not Monday, set this to 8
				else
					set theAdj to 8
				end if
				set theDate to (current date) + ((whichDay mod 7) - toDay + theAdj) * days
				set dateSet to true
			end if
		end if
	end repeat
	if not dateSet then
		set dateSet to true
		try
			set theDate to date theDateString
		on error
			--display alert "DEVONthink Pro" message "Invalid Date"
			set dateSet to false
		end try
	end if
end ignoring

if dateSet then
	tell application "DEVONthink Pro"
		
		set ticklerFolder to "/** Tickler"
		set theMonth to item (month of theDate) of FOLDERS_MONTHS
		set theDay to item (day of theDate) of FOLDERS_DAYS
		set theFolder to create location (ticklerFolder & "/" & theMonth & "/" & theDay)
		
		repeat with theItem in theSelection
			move record theItem to theFolder
		end repeat
		
	end tell
end if

  1. Various scripts to file the selected items to prespecified dates.

Monday of next week


property FOLDERS_MONTHS : {"01 January", "02 February", "03 March", "04 April", "05 May", "06 June", "07 July", "08 August", "09 September", "10 October", "11 November", "12 December"}
property FOLDERS_DAYS : {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}

tell application "DEVONthink Pro"
	
	set theSelection to the selection
	if (count of theSelection) < 1 then error "Please select one or more items."
	
	set ticklerFolder to "/** Tickler"
	set theWeekday to weekday of (current date) as integer
	set theMonth to item (month of ((current date) + (9 - theWeekday) * days)) of FOLDERS_MONTHS
	set theDay to item (day of ((current date) + (9 - theWeekday) * days)) of FOLDERS_DAYS
	set theFolder to create location (ticklerFolder & "/" & theMonth & "/" & theDay)
	
	repeat with theItem in theSelection
		move record theItem to theFolder
	end repeat
	
end tell

First day of next month


property FOLDERS_MONTHS : {"01 January", "02 February", "03 March", "04 April", "05 May", "06 June", "07 July", "08 August", "09 September", "10 October", "11 November", "12 December"}
property FOLDERS_DAYS : {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}


tell application "DEVONthink Pro"
	
	set theSelection to the selection
	if (count of theSelection) < 1 then error "Please select one or more items."
	
	set ticklerFolder to "/** Tickler"
	set theDate to current date
	set theDate's day to 32 -- this rolls the month over to the next month
	set theDate's day to 1 -- this might not be necessary at all
	set theMonth to item (month of theDate) of FOLDERS_MONTHS
	set theDay to "01"
	set theFolder to create location (ticklerFolder & "/" & theMonth & "/" & theDay)
	
	repeat with theItem in theSelection
		move record theItem to theFolder
	end repeat
	
end tell

Later by 1 week (= 7 days, modify easily for x number of weeks)


property FOLDERS_MONTHS : {"01 January", "02 February", "03 March", "04 April", "05 May", "06 June", "07 July", "08 August", "09 September", "10 October", "11 November", "12 December"}
property FOLDERS_DAYS : {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}

tell application "DEVONthink Pro"
	
	set theSelection to the selection
	if (count of theSelection) < 1 then error "Please select one or more items."
	
	set ticklerFolder to "/** Tickler"
	set theMonth to item (month of ((current date) + 7 * days)) of FOLDERS_MONTHS
	set theDay to item (day of ((current date) + 7 * days)) of FOLDERS_DAYS
	set theFolder to create location (ticklerFolder & "/" & theMonth & "/" & theDay)
	
	repeat with theItem in theSelection
		move record theItem to theFolder
	end repeat
	
end tell

Wow!

Thanks a lot, these scripts are great!

Hi, saw this in today’s blog post. Excellent script! I’m new to the forums, but not to DT and DA. I’ve just started playing around with scripts a little bit, so I look forward to trying a few for these apps myself.

Thanks again for a really useful one (and thanks Eric for tweeting it so I’d know about it…although I would have seen it in the blog later when I caught up on NNW :smiley:

Cheers!

First off, Sampsa, thanks for sharing your scripts. They helped me get my life together! No joke. Second, I hope you are still checking this message board as I have a question on one of the scripts (2. Script to empty the day’s folder into the inbox). I typically have two DevonThink databases open during the day (one called GTD and the other called Research).

I have found that if Research is the database that I have active when I go to bed, then the script attempts to run on that database. I end up getting a Tickler folder with the month/day nested folders and an Inbox folder in that database, rather than the appropriate contents of my actual Tickler in the GTD database moved to the Inbox.

Can you suggest how I can amend the script to ensure that it makes my GTD database the active database, before attempting to move files? I have tried to play around with it without any success.

This may be years too late for you, adad, but in case others are interested here is how I modified the scripts so that they always point to the correct database:

property FOLDERS_MONTHS : {"01 January", "02 February", "03 March", "04 April", "05 May", "06 June", "07 July", "08 August", "09 September", "10 October", "11 November", "12 December"}
property FOLDERS_DAYS : {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}

tell application "DEVONthink Pro"
	activate
	set theDatabase to database named "43 Folders"
	tell theDatabase
		set theInbox to parent named "* Inbox" in theDatabase
		set currentMonth to item (month of (current date)) of FOLDERS_MONTHS
		set currentDay to item (day of (current date)) of FOLDERS_DAYS
		set theTickler to parent named "** Tickler" of theDatabase
		set monthFolder to (get id of child named currentMonth of theTickler)
		set dayFolder to (get id of child named currentDay of parent id monthFolder)
		set theSource to parent id dayFolder
		set theChildren to the children of theSource
	end tell
	repeat with theRecord in theChildren
		move record theRecord to theInbox from theSource
	end repeat
end tell

The other scripts can be similarly modified so you can move a file from any database or group to the tickler file.

Thanks for the timely update. :open_mouth:

tell application "DEVONthink Pro"
   activate
   set theDatabase to database named "43 Folders"

you know, of course, that this hardcodes the database name – one that maybe not everyone uses? You could do


set theDatabase to the current database

Also


tell application "DEVONthink Pro"

is deprecated, and this method that uses the OS X 4 letter ID is preferred:


tell application ID "DNtp"

Was interested in making bullet journal functionality using the tickler scripts as a basis with some modification unfortunately new to applescript and having trouble .

Here is the plot:
Using a tickler file as presented in this blog.

The current tickler file moves the records from the date in question ( say Dec 25 ) to the inbox leaving no records in Dec 25 .The records that were in Dec 25 are now in the inbox using applescript ‘move’.

Now I wish to move only action records to the inbox as specified by some leading character (say ! ) and leave non action records as journal records in Dec 25. ( records for information but not action)

So one line of applescript to identify record starting with “!” or appropriate identifier should do the trick any applescript experts out there care to help

Here’s a simple stab at it…

set theChildren to (children of theSource whose name begins with "!")
if theChildren ≠ {} then
 repeat with theRecord in theChildren
      move record theRecord to theInbox from theSource
   end repeat
end if

Works like a dream - thank you.

Can now closely simulate and improve on the functionality of a bullet journal ie You can journal and store information items for future reference and at the same time spit out identified action items to the inbox for immediate processing


property FOLDERS_MONTHS : {"01 January", "02 February", "03 March", "04 April", "05 May", "06 June", "07 July", "08 August", "09 September", "10 October", "11 November", "12 December"}
property FOLDERS_DAYS : {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}

tell application id "DNtp"
	activate
	set theDatabase to database named "2018"
	set inboxFolder to create location "/* Inbox"
	set ticklerFolder to "/** Tickler"
	set currentMonth to item (month of (current date)) of FOLDERS_MONTHS
	set currentDay to item (day of (current date)) of FOLDERS_DAYS
	set currentFolder to create location (ticklerFolder & "/" & currentMonth & "/" & currentDay)
	
	
	set theChildren to (children of currentFolder whose name begins with "!")
	if theChildren ≠ {} then
		repeat with theRecord in theChildren
			move record theRecord to inboxFolder from currentFolder
		end repeat
	end if
	
end tell


You’re welcome.