Modify All Alerts In All All-Day Events

I would like to set all Alerts, in all All-Day events, in all calendars, in Calendar, to None. Is AppleScript capable of performing this? My four calendars contain approximately 40,000 (forty-thousand) All-Day events. I want this script to ignore the calendars that I subscribe to. (Holidays, et al.)

Thank you.

Kurt

Hi,

try this, I guess it’ll take some time for that amount of events


tell application "Calendar"
	set writableCalendars to calendars whose writable is true -- ignore subscripted calendars
	repeat with aCalendar in writableCalendars
		set allDayEvents to (every event of aCalendar whose allday event is true)
		repeat with anEvent in allDayEvents
			tell anEvent
				delete every display alarm
				delete every mail alarm
				delete every open file alarm
				delete every sound alarm
			end tell
		end repeat
	end repeat
end tell

Hello, Stefan.

Thank you for your prompt response.

Your code looks sound. Did you test it? I don’t want to lose the alerts in my scheduled events, both past and future. I am prepared to try your script, and, if it exhibits problems, restore my calendars from backup. However, I want to inquire, first.

Thank you.

Kurt

I tested the script with a new created calendar and a couple of events, it’s pretty straight forward.
But please consider that all kind of alarms will be deleted.

Run this script to see which calendars are affected, it doesn’t change anything


tell application "Calendar"
	set writableCalendars to title of calendars whose writable is true -- ignore subscripted calendars
end tell
choose from list writableCalendars

Hello, Stefan.

I ran the small test script. As you intented, it presented a list of my calendars, that I have created, and, it did not list the calendars, that I subscribe to. Thank you.

I interpret your reply,

“But please consider that all kind of alarms will be deleted.”

as meaning that my scheduled events alarms (for example, 2PM to 6PM, as opposed to All Day) will be deleted, too. Is my interpretation correct?

It appears that this code,


set allDayEvents to (every event of aCalendar whose allday event is true)
       repeat with anEvent in allDayEvents

fulfills my request, and, it preserves my alerts in my scheduled events, as I wanted it to.

Kurt

of course I meant all kind of alarms of every all-day event

Hello, Stefan.

Thank you for clarifying my confusion. I’ll give your script a try.

Thank you.

Kurt

Hello, Stefan.

The script stopped, after four minutes, and, it produced the following error message, both inside the script editor, and, on the screen, which I clicked and dismissed:


error "Calendar got an error: AppleEvent timed out." number -1712

I performed a perfunctory and random review of all day events. All of them still display alerts. I even checked the very first one, and, the very last one.

Kurt

Ok, the line to filter the events exceeds the default timeout of 2 minutes.
This version increases the timeout to 24 hours.
As i mentioned before the script will take a long time, but certainly not a whole day :wink:


tell application "Calendar"
	set writableCalendars to calendars whose writable is true -- ignore subscripted calendars
	repeat with aCalendar in writableCalendars
		with timeout of 86400 seconds -- 24 hours
			set allDayEvents to (every event of aCalendar whose allday event is true)
		end timeout
		repeat with anEvent in allDayEvents
			tell anEvent
				delete every display alarm
				delete every mail alarm
				delete every open file alarm
				delete every sound alarm
			end tell
		end repeat
	end repeat
end tell

Hi guys.

Is this any faster? The script, not Calendar, filters the allday events.


tell application "Calendar"
	set writableCalendars to calendars whose writable is true -- ignore subscripted calendars
	repeat with aCalendar in writableCalendars
		set {theseIds, theseAlldayEvents} to {uid, allday event} of every event of aCalendar
		repeat with i from 1 to (count theseAlldayEvents)
			if (item i of theseAlldayEvents) then
				tell event id (item i of theseIds) of aCalendar
					delete every display alarm
					delete every mail alarm
					delete every open file alarm
					delete every sound alarm
				end tell
			end if
		end repeat
	end repeat
end tell

I guess, but with an amount of 40k events the fetching line might time out, too

Hello, Stefan.

Here is my experience with the script.

I started the script on Monday 2015-03-30 1347. I used the script that included the timeout of 86400 seconds.

I checked the script’s progress on Monday 2015-03-30 2220. It was still running. Calendar was running, but, was neither visible nor responsive. I did not interact with Calendar or the running script, further. No other applications were running.

This morning, at 0600, sixteen hours later, the script window was not visible, nor, was the script icon visible in the dock. Calendar was running, but, was neither visible nor responsive. I right clicked on the Calendar Dock icon. I don’t recall the message’s exact text, however, it suggested that Calendar was not responding. I selected Force Quit from the Apple menu. The Force Quit window contained the following messages, “Your system has run out of application memory. To avoid problems with your computer, quit any application you are not using.” The application list included Finder, Script Editor, and Calendar (paused). The Calendar letters were red.

I clicked on Script Editor, and then, I clicked on Force Quit. The Script Editor entry remained in the list. I clicked on Calendar, and then, I clicked on Force Quit. The Calendar entry exited the list. I closed this window, then, I performed a restart, without incident.

The restart appeared to be normal. I launched Calendar. I reviewed a few dozen All Day Events, at random, from the past five years. All of them still display alerts. (Sidebar: I own two iMacs and and iPhone 6. All three of these devices synchronize though iCloud. Therefore, I checked the Calendar entries on the other iMac, and, on the iPhone, this morning. Again, I reviewed a few dozen All Day Events, at random, from the past five years, on each of these two devices. All of them still display alerts.)

I wanted to provide my results to you, for evaluation, before I make any more entries in Calendar.

Thank you.

Kurt

sorry for the bad experience.
The whose clause of AppleScript can be very slow by accessing a large number of objects.

I created 1000 all-day events by script with two different alarms “ which took about 1 hour “ and tested the line with the whose clause. After 30 minutes I stopped execution, for an amount > 10k it’s hopeless.

Then I ran Nigel’s script.
The line to get the uid and allday event properties took 70 seconds and to delete the alarms of all 1000 events took about half an hour.

So I recommend to use Nigel’s script but with the time out block

	
with timeout of 68400 seconds
	set {theseIds, theseAlldayEvents} to {uid, allday event} of every event of aCalendar
end timeout

Hi, Stefan.

Is this correct:


tell application "Calendar"
	set writableCalendars to calendars whose writable is true -- ignore subscripted calendars
	repeat with aCalendar in writableCalendars
		with timeout of 86400 seconds
			set {theseIds, theseAlldayEvents} to {uid, allday event} of every event of aCalendar
		end timeout
		repeat with i from 1 to (count theseAlldayEvents)
			if (item i of theseAlldayEvents) then
				tell event id (item i of theseIds) of aCalendar
					delete every display alarm
					delete every mail alarm
					delete every open file alarm
					delete every sound alarm
				end tell
			end if
		end repeat
	end repeat
end tell

Thank you.

Kurt

Yes, it is.

The time out block is per calendar.
It will time out when the number of events in one calendar is approx. greater than 48000

I’m only guessing, but I suspect the speed-up is not because you’re doing the filtering locally, but rather because you’re retrieving a list of strings and a list of booleans, whereas Stefan was retrieving a list of calendar events. Building AS object specifiers is pretty time-consuming, and probably much more so with complex objects like calendar events.

It’s a bit like when you ask the Finder for a bunch of files, and the difference using as alias list makes – avoiding all the building of those … of folder “XYZ” of… references saves a lot of time, even though building aliases is probably an extra step internally.

Hello, Stefan and Nigel.

I tried Nigel’s script. It completed its task in a few hours. I’ve reviewed several dozen All Day Events, at random, from the past five years. All of them still display alerts. However, this is the “1 day before” “(default)” Alert. I have not found the other alerts, such as “1 hour”, “2 hours”, “30 minutes”, et cetera. So, it looks like your script, Stefan and Nigel, worked, for the most part. Also, I have not found any occurrences of scheduled events, who’s alerts have been modified. I’m pleased with the results.

Is there a way to remove the “1 day before (default)” Alert, such that it displays “None”?

As I said, I like the results.

Thank you. gentlemen.

Kurt

Yes, in the Preferences of Calendar > Alerts

Sigh. That was a dumb, “Duh” after clicking Submit, question that I posted!

Sometimes, they do slip through.

Kurt

With Objective-C and EventKit creating 1000 events took 21 seconds and deleting the alarms about half a minute.