Last active
November 5, 2016 18:57
-
-
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)
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
--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