Friday, March 9, 2012

Notification Silencer (was AppleScript ain't so bad)

Sick of getting inappropriate popups during screen-sharing sessions? This took about 30 minutes to hack up after I figured out where to look. It could still be a lot better of course, but it does the job.

UPDATE: resurrected in 2021:

-- Run via crontab: 0,1,29,30,31,59 8-18 * * 1,2,3,4,5 osascript ~/Library/Mobile\ Documents/com~apple~ScriptEditor2/Documents/meeting-test.scpt > /Users/jcoates/Library/Logs/meeting-test.log

set Cals2Check to "Calendar"

set curdate to current date

set tomorrow to (current date) + 86400

set delims to AppleScript's text item delimiters

if Cals2Check contains ", " then

set AppleScript's text item delimiters to {", "}

else

set AppleScript's text item delimiters to {","}

end if

set caltitles to every text item of Cals2Check

set AppleScript's text item delimiters to delims

-- if Outlook isn't running, let's just move along

tell application "System Events"

set outlook_running to (name of processes) contains "Microsoft Outlook"

end tell

if not (outlook_running) then

quit

end if

tell application "System Events"

set Slack_running to (name of processes) contains "Slack"

end tell

tell application "Microsoft Outlook"

--We need to get the ID of each calendar, as the names are not always unique (this may be an issue with mounted shared calendars)

set calIDs to {}

repeat with i from 1 to number of items in caltitles

set caltitle to item i of caltitles

set calIDs to calIDs & (id of every calendar whose name is caltitle)

end repeat

--Now we get a list of events from each of the calendar that match our time criteria

set calEvents to {}

repeat with i from 1 to number of items in calIDs

set CalID to item i of calIDs

tell (calendar id CalID)

-- find events that are currently active and truly busy. filter out the really long ones.

set calEvents to calEvents & (every calendar event whose (start time < (curdate)) and (end time > (curdate) and (end time < (tomorrow)) and (free busy status = busy) and (all day flag = false)))

end tell

end repeat

if number of items in calEvents > 0 then

-- I'm in a meeting, so quiet down

tell application "Microsoft Outlook"

-- set working offline to true

set display alerts to false

end tell

if (Slack_running) then

-- uses https://github.com/samknight/slack_applescript

tell script "Slack"

set do not disturb

end tell

end if

-- I'd like to toggle the OS Do Not Disturb function here; for now, just leaving it on all the time

return (curdate & "shhhhhhhh" & subject of item 1 of calEvents)

else

-- I'm not in a meeting, so tell me things

tell application "Microsoft Outlook"

-- set working offline to false

set display alerts to true

end tell

if (Slack_running) then

-- uses https://github.com/samknight/slack_applescript

tell script "Slack"

set as active

end tell

end if

-- I'd like to toggle the OS Do Not Disturb function here; for now, just leaving it on all the time

return (curdate & "let's play!")

end if

end tell

end

   

UPDATE: I've made a few changes to filter out corner cases. This script is a daily life saver.


UPDATE AGAIN: Now supports Mountain Lion Messages as well.


-- Run via crontab: 0,1,29,30,31,59 8-18 * * 1,2,3,4,5 osascript /Users/jcoates/bin/meeting-test.scpt > /Users/jcoates/Library/Logs/meeting-test.log
set Cals2Check to "Calendar,Solutions"
set curdate to current date
set tomorrow to (current date) + 86400
set delims to AppleScript's text item delimiters
if Cals2Check contains ", " then
set AppleScript's text item delimiters to {", "}
else
set AppleScript's text item delimiters to {","}
end if
set caltitles to every text item of Cals2Check
set AppleScript's text item delimiters to delims
-- if Outlook isn't running, let's just move along
tell application "System Events"
set outlook_running to (name of processes) contains "Microsoft Outlook"
end tell
if not (outlook_running) then
quit
end if
tell application "System Events"
set adium_running to (name of processes) contains "Adium"
end tell
tell application "System Events"
set messages_running to (name of processes) contains "Messages"
end tell
tell application "System Events"
set skype_running to (name of processes) contains "Skype"
end tell
tell application "Microsoft Outlook"
--We need to get the ID of each calendar, as the names are not always unique (this may be an issue with mounted shared calendars)
set calIDs to {}
repeat with i from 1 to number of items in caltitles
set caltitle to item i of caltitles
set calIDs to calIDs & (id of every calendar whose name is caltitle)
end repeat
--Now we get a list of events from each of the calendar that match our time criteria
set calEvents to {}
repeat with i from 1 to number of items in calIDs
set CalID to item i of calIDs
tell (calendar id CalID)
-- find events that are currently active and truly busy. filter out the really long ones.
set calEvents to calEvents & (every calendar event whose (start time < (curdate)) and (end time > (curdate) and (end time < (tomorrow)) and (free busy status = busy) and (all day flag = false)))
end tell
end repeat
if number of items in calEvents > 0 then
-- I'm in a meeting, so quiet down
tell application "Microsoft Outlook"
-- set working offline to true
set display alerts to false
end tell
if (adium_running) then
tell application "Adium"
go invisible
-- quit
end tell
end if
if (messages_running) then
tell application "Messages"
log out
-- quit
end tell
end if
if (skype_running) then
tell application "Skype"
send command "SET USERSTATUS INVISIBLE" script name "AppleScript status setter"
-- quit
end tell
end if
return (curdate & "shhhhhhhh" & subject of item 1 of calEvents)
else
-- I'm not in a meeting, so tell me things
tell application "Microsoft Outlook"
-- set working offline to false
set display alerts to true
end tell
if (adium_running) then
tell application "Adium"
-- run
go available
end tell
end if
if (messages_running) then
tell application "Messages"
log in
-- quit
end tell
end if
if (skype_running) then
tell application "Skype"
-- run
send command "SET USERSTATUS ONLINE" script name "AppleScript status setter"
end tell
end if
return (curdate & "let's play!")
end if
end tell