Apple events overridden.


Ilya Shebalin
 

Hi, 
I faced an issue of iTunes (or QuickTime Player) being unable to respond to events sent by my script long ago, even posted here, but now I seem to figure out the true reason behind such an odd behavior. The script is designed to wake me up at the time I tell it by interacting through dialogs by playing an iTunes tune or a one opened and played by QTP and is saved as a plugin activated upon invoking from the scripts menu icon. The strangest part is that  if I launch iTunes or QTP after I'm done with firing up the script (which, of course, always happens before the wake-up time) then the script wouldn't work but would otherwise. This is confirmed by thorough experimenting. Do this:
  1. Save the script to your user scripts folder and make sure the scripts menu icon is checked to display on the menu bar. 
  2. Run the script from there, set the time, date and song. For the purposes of testing set the closest time to the one of the actual testing.
  3. After you're done launch iTunes and quit it.
  4. When the time you set in steps ##1 & 2 arrives nothing happens. If you won't do step #3 it will.


 My question would be: is there a way to work around this obvious misbehavior/bug?  


The script is (please consider going through the information put in my comments):

property start_date : ""
property end_date : ""
property AlarmDate : ""
on MakeUnixDate(AlarmDate) --assembles the date suitable for shell commands. NB. The presence of this particular handler  was determined by my localization. US users probably won't need it and, thus, can safely disregard. For those only do shell script part is essential and has to remain for which placing it inside the handler is not necessary.  All credits for pointing me out to a better implementation of OS X-to-Unix dates conversion found inside this handler go to Yvan Koenig.
set locale_Date to date AlarmDate
set timeString to time string of locale_Date
set Unix_day to text -2 thru -1 of ((100 + (day of locale_Date)) as string)
set Unix_month to text -2 thru -1 of ((100 + (month of locale_Date)) as string)
set Unix_year to text -2 thru -1 of (year of locale_Date as string)
set ShortUnix_date to Unix_day & Unix_month & Unix_year 
set FullUnixDate to Unix_date & timeString


do shell script "sudo pmset schedule wake " & quote & FullUnixDate & quote password "" with administrator privileges  --IMPORTANT! Type in your user password instead of the empty quotes before running the script


end MakeUnixDate

repeat


display dialog "Enter event start date" default answer start_date buttons {"Cancel", "OK"} default button "OK"
set EnteredStartTime to text returned of result


try
set start_time to date EnteredStartTime


exit repeat
on error
display dialog "Invalid date. Try again."
try
on error number -128
return
end try
end try
end repeat


repeat
set EndTimePrompt to display dialog "Enter event end date" default answer end_date buttons {"Cancel", "OK"} default button "OK"
set EnteredEndTime to text returned of EndTimePrompt


try
set end_time to date EnteredEndTime
if end_time ≥ start_time then
exit repeat
else


display dialog "Invalid data: end date can't go before start date." & return & return & "Error: end date " & quote & date string of end_time & ", " & time string of end_time & quote & space & "entered is before start date " & quote & date string of start_time & ", " & time string of start_time & quote
end if
on error
display dialog "Invalid date. Try again."
try
on error number -128
return
end try
end try
end repeat

display dialog "Start date: " & start_time & return & "End date: " & end_time

set EventSummaryPrompt to display dialog "Enter brief description" default answer ""
set EventSummaryResponse to text returned of EventSummaryPrompt

set EventLocationPrompt to display dialog "Enter location" default answer ""
set EventLocationResponse to text returned of EventLocationPrompt

set EventNotesPrompt to display dialog "Enter miscellaneous information" default answer ""
set EventNotesResponse to text returned of EventNotesPrompt

set EventAlarmPrompt to display dialog "Enter reminder time, min before the start date " & (time string of start_time) default answer ""
set EventAlarmResponse to (text returned of EventAlarmPrompt) as real
set AlarmTriggerTime to start_time - EventAlarmResponse * minutes


tell application "iCal"
run
set AllCalendars to get name of every calendar
set AppleScript's text item delimiters to return
set CalendarColumn to AllCalendars as text
delay 3
set CalendarListPrompt to display dialog "Your calendars:" & return & return & CalendarColumn default answer ""
set CalendarListResponse to text returned of CalendarListPrompt
set NewCalendarEvent to make new event with properties {start date:start_time, end date:end_time, summary:EventSummaryResponse, location:EventLocationResponse, description:EventNotesResponse, status:confirmed} at end of calendar CalendarListResponse


set AlarmNotificationPrompt to display dialog "Set a reminder?" buttons {"No reminder", "Set"} default button "Set"
if button returned of AlarmNotificationPrompt is "Set" then
display dialog "Enter name of the reminder" default answer ""
set ToDoSummary to text returned of result
set NewTodo to make new todo with properties {priority:high priority, summary:ToDoSummary} at the end of calendar named CalendarListResponse
set SoundAlarmPrompt to display dialog "Set a sound alarm for the reminder?" buttons {"No sound alarm", "Set"} default button "Set"


if button returned of SoundAlarmPrompt is "Set" then
display dialog "Enter a date for the reminder" default answer ""
set AlarmDate to text returned of result
display dialog "Choose sound for the sound alarm" & return & return & "Basso, Frog, Hero, Pop, Submarine, Blow, Funk, Morse, Purr, Tink, Bottle, Glass, Ping, Sosumi" default answer ""
set SoundAlarmName to text returned of result
set SoundAlarm to make new sound alarm with properties {trigger date:date AlarmDate, sound name:SoundAlarmName} at the end of NewTodo
my MakeUnixDate(AlarmDate)
else


display dialog "Enter date for the silent reminder" & return & return default answer ""
set AlarmDate to text returned of result
set DisplayAlarm to make new display alarm with properties {trigger date:date AlarmDate} at the end of NewTodo


my MakeUnixDate(AlarmDate)
end if


end if
display dialog "Done. iCal quits" buttons {"OK"} default button "OK" giving up after 2
quit


end tell

MakeUnixDate(AlarmTriggerTime as text)

===============================SKIP UNTIL HERE IF YOU'RE ON MOUNTAIN LION OR HIGHER=============================================


repeat

display dialog "Enter wake-up date" default answer start_date buttons {"Cancel", "OK"} default button "OK"
set EnteredStartTime to text returned of result

try
set AlarmTriggerTime to date EnteredStartTime

exit repeat
on error
display dialog "Invalid date. Try again."
try
on error number -128
return
end try
end try
end repeat

set locale_Date to AlarmTriggerTime
set timeString to time string of locale_Date
set Unix_day to text -2 thru -1 of ((100 + (day of locale_Date)) as string)
set Unix_month to text -2 thru -1 of ((100 + (month of locale_Date)) as string)
set Unix_year to text -2 thru -1 of (year of locale_Date as string)
set ShortUnix_date to Unix_day & Unix_month & Unix_year 
set FullUnixDate to Unix_date & timeString

do shell script "sudo pmset schedule wake " & quote & FullUnixDate & quote password "" with administrator privileges  --IMPORTANT! Type in your user password in place of the empty quotes before running the script


tell application "iTunes"
launch
ignoring case, white space, diacriticals and punctuation
set playlistList to name of every playlist of source "Library" --IMPORTANT! The name of this source may be different in your localization


set the_body to items 2 thru -1 of playlistList --formatting the list excluding the source's name
set AppleScript's text item delimiters to return
set formatted_body to the_body as text
set theHeader to item 1 of playlistList & return & return --formatting the list including the source's name which will now be its header


display dialog theHeader & formatted_body buttons {"Cancel", "Continue"} default button "Continue" default answer "" --all playlists of the uppermost level are displayed


set playlistName to text returned of result --enter the playlist of your choice


set targetPlaylistName to name of playlist named playlistName --the entered value is the name of the playlist you chose and it becomes a value of the variable.


set targetTrackList to name of every track of playlist named targetPlaylistName --all tracks of the chosed playlist
set the_body to items of targetTrackList --formatting the list containing the tracks
set AppleScript's text item delimiters to return
set formatted_body to the_body as text
end ignoring
set theHeader to "Playlist " & targetPlaylistName & return & return
display dialog theHeader & formatted_body buttons {"Cancel", "Continue"} default button "Continue" default answer "" --list of all tracks pf the chosen playlist, formatted


set TrackName to text returned of result --enter the track of your choice
set targetTrackName to name of track named TrackName --the entered value is the name of the track you chose and it becomes a value of the variable.
set TrackToPlay to track named targetTrackName --этот трек будет воспроизведён и становится переменной, передаваемой программе "iTunes"




set VolumePrompt to display dialog "Set volume for the iTunes track" & return & return & "Any integer between 0 (min) and 100 (max)" default answer ""
set EnteredVolume to text returned of VolumePrompt --set volume for the track


display dialog "Done. iTunes quits" buttons {"OK"} default button "OK" giving up after 2
quit
end tell





repeat until (current date) = AlarmTriggerTime
delay 1
end repeat


tell application "iTunes"
launch
set visible of browser window 1 to false
set sound volume to EnteredVolume
if TrackToPlay exists then
set track_time to duration of TrackToPlay
play TrackToPlay
delay (track_time)
end if
set sound volume to 100
quit it
end tell

P.S. Already having composed this message I realized that for many of you the iCal part might be irrelevant since it's been replaced by Contacts and Reminders in Mountain Lion and onwards. However, since the most significant part of the script may not necessarily involve creating a Calendar event and the countdown to iTunes launch is of greater importance, those of you, who're on newer than Lion version of OS are suggested to skip the part up to the indicated part (separated from the iCal part with the hatch) and copy paste the rest of the script.


Sincerely Yours,
Ilya Shebalin
           ilja.shebalin@... 



Join applescript@apple-dev.groups.io to automatically receive all group messages.