Hi Everyone,
I’ve been looking for different ways of getting a list of my daily schedule and/or availability. Does anyone have a script that can do this? I use multiple calendars, so it would be great if it could use two. Ideally, I’d like to use text expander to trigger the apple script to paste in my daily schedule in my journal and availability for emails (I know Apple Shortcuts can do this).
Maybe there’s an option in Fantastical I’ve missed?
I found this AppleScript, but it is very very slow:
**on** getDateRange()
**set** today **to** ( **current date** )
**set** d1 **to** today's short date string
**set** d2 **to** short date string **of** (today + 6 * days)
**set** dateRange **to** text returned **of** ( **display dialog** "Enter the required date range:" default answer d1 & " - " & d2)
**set** dateRangeStart **to** *date* ( *text* **from** *word* 1 **to** *word* 3 **of** dateRange)
**set** dateRangeEnd **to** *date* ( *text* **from** *word* -3 **to** *word* -1 **of** dateRange)
**set** dateRangeEnd's time **to** days - 1 -- Sets the last date's time to 23:59:59, the last second of the range.
**return** {dateRangeStart, dateRangeEnd}
**end** getDateRange
-- Return the start dates, summaries, and calendar names of events in the given date range.
-- {{start date, summary, calendar name}, {start date, summary, calendar name}, … }
**on** filterToDateRange(theStartDates, theSummaries, theCalendarNames, dateRangeStart, dateRangeEnd)
**script** o
**property** sDates : theStartDates
**property** summaries : theSummaries
**property** cNames : theCalendarNames
**property** filteredData : {}
**end** **script**
**repeat** **with** i **from** 1 **to** ( **count** theCalendarNames)
**set** o's sDates **to** *item* i **of** theStartDates
**set** o's summaries **to** *item* i **of** theSummaries
**set** thisCalendarName **to** *item* i **of** theCalendarNames
**repeat** **with** j **from** 1 **to** ( **count** o's sDates)
**set** thisStartDate **to** *item* j **of** o's sDates
**if** ( **not** ((thisStartDate **comes before** dateRangeStart) **or** (thisStartDate **comes after** dateRangeEnd))) **then**
**set** thisSummary **to** *item* j **of** o's summaries
**set** **end** **of** o's filteredData **to** {thisStartDate, thisSummary, thisCalendarName}
**end** **if**
**end** **repeat**
**end** **repeat**
**return** o's filteredData
**end** filterToDateRange
-- Sort the filtered data by start date.
**on** sortByDate(filteredData)
-- A sort-customisation object which compares the first items of two sublists taken from the list being sorted.
**script** custom
**on** isGreater(a, b)
**return** ( **beginning** **of** a > **beginning** **of** b)
**end** isGreater
**end** **script**
CustomShellSort(filteredData, 1, -1, {comparer:custom})
**end** sortByDate
-- Shell sort. Algorithm: Donald Shell, 1959. AppleScript implementation: Nigel Garvey, 2010.
**on** CustomShellSort(theList, l, r, customiser)
**script** o
**property** comparer : **me**
**property** slave : **me**
**property** lst : theList
**on** shsrt(l, r)
**set** step **to** (r - l + 1) **div** 2
**repeat** **while** (step > 0)
slave's setStep(step)
**repeat** **with** j **from** (l + step) **to** r
**set** v **to** *item* j **of** o's lst
**repeat** **with** i **from** (j - step) **to** l **by** -step
**tell** *item* i **of** o's lst
**if** (comparer's isGreater( **it** , v)) **then**
**set** *item* (i + step) **of** o's lst **to** **it**
**else**
**set** i **to** i + step
**exit** **repeat**
**end** **if**
**end** **tell**
**end** **repeat**
**set** *item* i **of** o's lst **to** v
slave's rotate(i, j)
**end** **repeat**
**set** step **to** (step / 2.2) **as** *integer*
**end** **repeat**
**end** shsrt
-- Default comparison and slave handlers for an ordinary sort.
**on** isGreater(a, b)
(a > b)
**end** isGreater
**on** rotate(a, b)
**end** rotate
**on** setStep(a)
**end** setStep
**end** **script**
-- Process the input parameters.
**set** listLen **to** ( **count** theList)
**if** (listLen > 1) **then**
-- Negative and/or transposed range indices.
**if** (l < 0) **then** **set** l **to** listLen + l + 1
**if** (r < 0) **then** **set** r **to** listLen + r + 1
**if** (l > r) **then** **set** {l, r} **to** {r, l}
-- Supplied or default customisation scripts.
**if** (customiser's *class* **is** *record* ) **then** **set** {comparer:o's comparer, slave:o's slave} **to** (customiser & {comparer:o, slave:o})
-- Do the sort.
o's shsrt(l, r)
**end** **if**
**return** -- nothing.
**end** CustomShellSort
-- Create a new TextEdit document with text derived from the gathered data.
**on** composeText(filteredData)
**tell** *application* "TextEdit"
-- Make a new document, with a minimal text so that we can discover the name of its font.
**set** newDoc **to** ( **make** new *document* with properties { *text* :" "})
**set** baseFont **to** font **of** newDoc's *text*
-- This ASSUMES that an equivalent bold font exists and that its name is the same as the plain font with " bold" appended.
**set** boldFont **to** baseFont & " bold"
-- Dummy text no longer needed.
**set** newDoc's *text* **to** ""
**activate**
**end** **tell**
**if** (filteredData **is** {}) **then**
-- If no events have been discovered in the date range, print that fact.
**tell** *application* "TextEdit" **to** **make** new *paragraph* at **end** **of** newDoc's *text* with data "No events found in this period." with properties {font:boldFont}
**else**
-- Otherwise print the event details.
**set** currentCalendarDate **to** "" -- The calendar date currently being processed. (None yet.)
**repeat** **with** i **from** 1 **to** ( **count** filteredData)
-- Get the data for an event from the list of filtered data.
**set** {{date string:thisCalendarDate, hours:thisStartTimeH, minutes:thisStartTimeM}, thisSummary, thisCalendar} **to** *item* i **of** filteredData
-- If the calendar date is different from the one we've been processing up till now, output an empty line and the new date string to TextEdit.
**if** (thisCalendarDate **is** **not** currentCalendarDate) **then**
**tell** *application* "TextEdit"
**make** new *paragraph* at **end** **of** newDoc's *text* with data linefeed with properties {font:baseFont}
**make** new *paragraph* at **end** **of** newDoc's *text* with data (thisCalendarDate & linefeed) with properties {font:boldFont}
**end** **tell**
-- Make the new date the one currently being processed.
**set** currentCalendarDate **to** thisCalendarDate
**end** **if**
-- Create a 24-hour time string from the hours and minutes of the start date.
**tell** (10000 + thisStartTimeH * 100 + thisStartTimeM) **as** *text* **to** **set** thisStartTime **to** *text* 2 **thru** 3 & ":" & *text* 4 **thru** 5
-- Output the entry for this event to TextEdit.
**tell** *application* "TextEdit" **to** **make** new *paragraph* at **end** **of** newDoc's *text* with data ("\"" & thisCalendar & "\" calendar: " & thisStartTime & " " & thisSummary & linefeed) with properties {font:baseFont}
**end** **repeat**
**end** **if**
**end** composeText
**on** main()
**say** "Getting data from Calendar. It may take a while…"
**tell** *application* "Calendar" **to** **set** {{theStartDates, theSummaries}, theCalendarNames} **to** {{start date, summary} **of** *events* , name} **of** *calendars*
**set** {dateRangeStart, dateRangeEnd} **to** getDateRange()
**set** filteredData **to** filterToDateRange(theStartDates, theSummaries, theCalendarNames, dateRangeStart, dateRangeEnd)
sortByDate(filteredData)
composeText(filteredData)
**end** main
main()