I have been re-writing an iTunes-via-Calendar-Event controller script (evolved from a previous project https://macscripter.net/viewtopic.php?id=45383, current script below.)
The script is triggered by a calendar event; it is saved as an application, and code signed with my developer ID.
Basically, the Applet parses the Event Summary and queues a playlist with the name of the event.
The Applet is not currently reliable because of an unpredictably occurring error, always the exact same error. To my experience so far, this error only occurs when the Applet is called via the calendar alert; the Applet always works when run from the Finder.
I am not a programmer and cannot find any information to explain this behavior. “memory allocation" seems to be an actual programming thing, not an AppleScript problem.
I think the most likely explanation is a conflict in “CalendarLib.” I would appreciate any insight; a simple search does not reveal any other people with this problem https://duckduckgo.com/?q=applescript+CalendarLib+malloc, so perhaps my implementation is flawed (maybe “fetch events starting date RightNow ending date RightNow” is bad syntax…?)
(the script uses “CalendarLib EC,” functionally identical but without the requirement to use “Script Debugger.”)
Is there an alternate, reliable method of deriving Calendar’s “EVENT SUMMARY” from the current, occurring event…? I will use that instead. The script does not add, change, move, or modify events in any way, I do not need any of those controls—i just want the script to get the name of the current event, to determine the playlist.
Here is the current script:
use script "CalendarLib EC" version "1.1.3"
-- https://macosxautomation.com/applescript/apps/Script_Libs.html#CalendarLib
use scripting additions
global theTimeRightNow
set theTimeRightNow to current date
set theEvents to {}
set theStore to fetch store
set theCal to fetch calendar "TV" cal type cal local event store theStore
set theEvents to fetch events starting date theTimeRightNow ending date theTimeRightNow searching cals {theCal} event store theStore
if theEvents is not {} then
set theEvent to (event info for event (first item of theEvents))
set theEventName to {event_summary of theEvent} as string
else
set theEventName to "> Dead Air" -- default to music playlist if calendar event unclear
end if
set theEventType to the first character of theEventName
set theEventName to parseTheText(theEventName, theEventType & " ") as string -- strip theEventType from name
if theEventType is "#" then SignOff() -- expects "# {optional identifier}"
if theEventType is "*" then MakeMix(theEventName) -- expects "* Playlist1,Playlist2,MixedName"
if theEventType is ">" then PlayShow(theEventName) -- expects "> Playlist"
--tell me to quit -- not sure a "quit" call is necessary...
to PlayShow(theEventName)
set playlistMergedName to "Up Next" -- leave current "Now Playing" going while we assemble the next playlist
set thePlaylistNameWhenItStartsPlaying to "Now Playing"
set PlaylistFiller to "[LOOPS]"
set PlaylistInterstitialsName to "[STATION ID-D]" -- intersitials for the [D]aytime broadcast
if ((hours of (theTimeRightNow)) > 21) or ((hours of (theTimeRightNow)) < 5) then set PlaylistInterstitialsName to "[STATION ID-N]" -- unless it’s [N]ight
MixPlaylists(theEventName, PlaylistInterstitialsName, playlistMergedName)
tell application "iTunes"
set theTrack to some track of playlist PlaylistFiller -- finish by adding a single "LOOP" track to fill out the hour
set enabled of (duplicate theTrack to playlist playlistMergedName) to true
-- maybe DIM SCREEN or ACTIVATE SCREENSAVER or something to conceal playlist switch
activate
set full screen to true
set shuffle enabled to false
set song repeat to off -- one, all, off
set sound volume to 90
play playlist playlistMergedName -- switch to "Up Next"
if (exists playlist thePlaylistNameWhenItStartsPlaying) then delete playlist thePlaylistNameWhenItStartsPlaying -- get rid of old "Now Playing"
tell playlist playlistMergedName to set name to thePlaylistNameWhenItStartsPlaying -- change "Up Next" to "Now Playing"
pause -- no idea why but sometimes iTunes starts playing "offscreen"...
-- maybe RESTORE SCREEN here
play -- ...this pause/play is purely to get itunes playing fullscreen & onscreen
end tell
end PlayShow
to MakeMix(theEventName) -- preshuffle two playlists, sometimes called at 3:am to prep for later in day
set ThePlaylistsNames to parseTheText(theEventName, ",")
set {sourcePlaylistName1, sourcePlaylistName2, MixedPlaylistName} to {item 1 of ThePlaylistsNames, item 2 of ThePlaylistsNames, item 3 of ThePlaylistsNames}
MixPlaylists(sourcePlaylistName1, sourcePlaylistName2, MixedPlaylistName)
end MakeMix
to SignOff()
tell application "iTunes"
activate
stop
set full screen to false -- is this even necessary?
close window 1
end tell
end SignOff
to MixPlaylists(sourcePlaylistName1, sourcePlaylistName2, MixedPlaylistName)
tell application "iTunes"
if (not (exists playlist MixedPlaylistName)) then
set MixedPlaylist to make new user playlist with properties {name:MixedPlaylistName} -- if playlist does not exist, make it
else
set MixedPlaylist to user playlist MixedPlaylistName -- if playlist exists, select it & clean it out
delete tracks of MixedPlaylist
end if
set theTrackCount to (count of tracks of playlist sourcePlaylistName1) -- length will be based on sourcePlaylistName1
--Shuffle based on “CK's Evenly-shuffled Playlists v0.6” by Charles Kelly http://www.manythings.org/mac/
repeat with i from 1 to theTrackCount
if sourcePlaylistName2 contains "STATION" then
set theTrack to some track of playlist sourcePlaylistName2 -- Interstitials
else
set theTrack to track i of playlist sourcePlaylistName2 -- sequential
end if
set enabled of (duplicate theTrack to MixedPlaylist) to true
set theTrack to track i of playlist sourcePlaylistName1
set enabled of (duplicate theTrack to playlist MixedPlaylistName) to true
set unplayed of theTrack to false
end repeat
end tell
end MixPlaylists
to parseTheText(theText, theDelimiter)
set {originalDelimiters, my text item delimiters} to {my text item delimiters, theDelimiter}
set parsedText to text items of theText
set my text item delimiters to originalDelimiters
return parsedText
end parseTheText
Here is an example of a calendar day: (yes, Saturday is all cartoons… i mean, come on.)