Skip to content

Instantly share code, notes, and snippets.

@hepcat72
Last active November 5, 2016 18:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hepcat72/2d9560a733bad3ea6f57e60bc6ad63ed to your computer and use it in GitHub Desktop.
Save hepcat72/2d9560a733bad3ea6f57e60bc6ad63ed to your computer and use it in GitHub Desktop.
Applescript Folder Action to create reminders from files added (for user with IFTTT's Google Calendar and Dropbox channels)
--Download this file and put it in your ~/Library/Scripts/Folder Action Scripts folder, then attach it to a dropbox folder to run when items are added to it. Create those files using IFTTT recipes.
--This script creates a reminder from a file (e.g. when my wife adds a new event to her work calendar (containing the word "work" in the title) IFTTT creates a file inside dropbox which this script parses to create a static reminder(s) for a certain time that day, e.g. feed the cat and change the litter)
--Each line of the input file must be (Comments with # characters allowed):
-- Reminder List name to which to add the reminder
-- Due date (e.g. "August 31, 2016" optionally followed by " at 5:00am")
-- Due time (e.g. 9:00 AM)
-- Title (Name of the reminder)
-- Keyword (if found in the original title, reminder is created)
-- Original title (Title of the google calendar event)
--The file name have multiple events (every 6 lines)
on adding folder items to this_folder after receiving added_items
--display dialog "Running folder action"
repeat with i from 1 to number of items in added_items
--display dialog "Processing event file " & i
set this_item to item i of added_items as alias
tell application "Finder"
--get the path of the file
set pathstr to POSIX path of this_item
set exT_name to name extension of this_item
end tell
--Remove time - I only want the start date here
set cmd to "perl -e 'while(<STDIN>){chomp;next if(/^#/);s/^(\\S+ \\d+, \\d+) +(at *)?\\d+:?\\d* *(a|p)?m? *$/$1/ig;print(qq($_\\n))}' < '" & pathstr & "'"
--display dialog "Running command " & cmd
set eventDescList to my (paragraphs of (do shell script cmd))
--display dialog "Command done"
set numEvents to (((number of items in eventDescList) / 6) as integer)
--display dialog "Processing " & numEvents & " events in the file"
repeat with j from 1 to numEvents
set reminderList to item ((j - 1) * 6 + 1) of eventDescList
set dueDate to item ((j - 1) * 6 + 2) of eventDescList & " " & item ((j - 1) * 6 + 3) of eventDescList
set titleName to item ((j - 1) * 6 + 4) of eventDescList
set searchWord to item ((j - 1) * 6 + 5) of eventDescList
set origTitle to item ((j - 1) * 6 + 6) of eventDescList
if searchWord is in origTitle then
tell application "Reminders"
try
set mylist to list reminderList
--display dialog "Parsing date: " & dueDate
set myDate to (my parseDate(dueDate))
--display dialog "Creating reminder: " & titleName & " on date: " & myDate & " in list: " & reminderList
tell mylist
make new reminder at end with properties {name:titleName, due date:myDate, remind me date:myDate}
end tell
on error errStr
--display dialog errStr
end try
end tell
end if
end repeat
end repeat
end adding folder items to
--The following edited methods were obtained from https://gist.github.com/mlgill/3813222#file-new-reminder-from-launchbar
on parseDate(theDateStr)
-- todo: parsing pseudo-natural language date and time with applescript
-- is a pain and rife with special cases (bugs). should convert this
-- subroutine to python and use a real natural language parser.
set theDate to current date
set time of theDate to 0
-- parse the time --
-- applescript's text parsing seems very promiscuous
-- e.g. if letters end up part of the date, they are simply ignored rather than
-- producing an error. this is a lot of work to check for everything, so
-- it hasn't been implemented yet
-- first check for am/pm
set theDateStrOrig to theDateStr
set theDateStr to getArrayValue(theSplit(theDateStr, "am"), 1) as string
set theDateStr to getArrayValue(theSplit(theDateStr, "AM"), 1) as string
if theDateStrOrig is not in theDateStr then
set usesAM to true
else
set usesAM to false
end if
set theDateStrOrig to theDateStr
set theDateStr to getArrayValue(theSplit(theDateStr, "pm"), 1) as string
set theDateStr to getArrayValue(theSplit(theDateStr, "PM"), 1) as string
if theDateStrOrig is not in theDateStr then
set usesPM to true
else
set usesPM to false
end if
-- todo: should throw an error if usesPM and usesAM end up being true
-- split the string into date and time
set theDateTimeArray to theSplit(theDateStr, " ")
-- get the time, which is the last element of theDateTimeArray
set theTimeStr to getArrayValue(theDateTimeArray, -1) as string
set theTimeArray to theSplit(theTimeStr, ":")
-- get the time variables
set theHours to item 1 of theTimeArray
if theTimeArray's length > 1 then
set theMinutes to item 2 of theTimeArray
else
set theMinutes to 0
end if
-- determine how to adjust the hours for am/pm
if (theHours as integer = 12) and usesAM then
set hoursAdjust to -12
else if (theHours as integer ≠ 12) and usesPM then
set hoursAdjust to 12
else
set hoursAdjust to 0
end if
-- calculate the time
set time of theDate to (time of theDate) + (theHours + hoursAdjust) * 3600
set time of theDate to (time of theDate) + theMinutes * 60
-- now parse the date if present --
if theDateTimeArray's length > 1 then
set theDateArray to items 1 thru -2 of theDateTimeArray
set theDateArrayLen to the count of items in theDateArray
-- first see if this is a relative date involving "next"
if theDateArrayLen = 2 then
set theRelativeDateStr to getArrayValue(theDateArray, 1) as string
set theWeekdayStr to getArrayValue(theDateArray, 2) as string
if "next" is in theRelativeDateStr then
-- setting forward 8 days which prevents one week from today being returned for "next sunday" if today is sunday
set time of theDate to (time of theDate) + (8 * 24 * 3600)
end if
set theDate to getWeekday(theDate, theWeekdayStr)
else
-- look for backslashes to decide if this date is relative or numerical
set theDateArraySplit to theSplit(getArrayValue(theDateArray, 1), "/")
set theDateArraySplitLen to the count of items in theDateArraySplit
if theDateArraySplitLen = 1 then
-- relative date without "next", i.e. today, tomorrow, monday, etc.
set theRelativeDayStr to getArrayValue(theDateArraySplit, 1) as string
if "tod" is in theRelativeDayStr then
set theDate to theDate
else if "tom" is in theRelativeDayStr then
set time of theDate to (time of theDate) + (24 * 3600)
else if ("sun" is in theRelativeDayStr or "mon" is in theRelativeDayStr or "tue" is in theRelativeDayStr or "wed" is in theRelativeDayStr or "thu" is in theRelativeDayStr or "fri" is in theRelativeDayStr or "sat" is in theRelativeDayStr) then
-- this prevents today's date from being returned if current day of week is entered
set time of theDate to (time of theDate) + (24 * 3600)
set theDate to getWeekday(theDate, theRelativeDayStr)
end if
else
-- numerical date
set month of theDate to (item 1 of theDateArraySplit) as integer
set day of theDate to (item 2 of theDateArraySplit) as integer
try
set theNewYear to (item 3 of theDateArraySplit) as integer
if theNewYear < 100 then
set theCurrentYear to (year of theDate) as integer
set theNewYear to theNewYear + ((theCurrentYear / 100) as integer) * 100
end if
set year of theDate to theNewYear
end try
end if
end if
end if
return theDate
end parseDate
on theSplit(theString, theDelim)
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelim
set theArray to every text item of theString
set theTrimmedArray to {}
repeat with currentSplitString in theArray
if currentSplitString as string is not equal to "" then
set currentTrimmedString to trim(currentSplitString)
copy currentTrimmedString to the end of theTrimmedArray
end if
end repeat
set AppleScript's text item delimiters to oldDelimiters
return theTrimmedArray
end theSplit
on getArrayValue(array, location)
return item location in array
end getArrayValue
on getWeekday(theDate, theWeekdayStr)
repeat until theWeekdayStr is in ((weekday of theDate) as string)
set time of theDate to (time of theDate) + (24 * 3600)
end repeat
return theDate
end getWeekday
on trim(someText)
-- trimming subroutine from: http://macscripter.net/viewtopic.php?id=18519
repeat until someText does not start with " "
set someText to text 2 thru -1 of someText
end repeat
repeat until someText does not end with " "
set someText to text 1 thru -2 of someText
end repeat
return someText
end trim
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment