TweetFollow Us on Twitter

Fun with AppleScript

Volume Number: 19 (2003)
Issue Number: 5
Column Tag: Administrivia

Fun with AppleScript

A fairly useless detour that nonetheless shows you some tricks with iTunes and Entourage v.X

by John C. Welch

Welcome

Okay, so my last couple of articles have been technical, (no surprise, this is Mac*TECH*, after all), but nonetheless, they were pretty dry to not only read, but write as well. (The USB2 spec is a great cure for insomnia) So this time, I thought I'd take a bit of a turn, and share a fun bit of AppleScript that I had done with iTunes and Microsoft Entourage for Mac OS X.

Get Sig From iTunes

Someone had shown me a neat application that was designed to get the name of the current track from iTunes, and insert the track information into your Entourage email message. It was well put together, but there were some things that I didn't like about it. First, it was a background application polling two other applications. That seemed a bit kludgy to me, as this script didn't really need to run that way. To my way of thinking, it is more of an Entourage script, so it should run inside of Entourage. Since Entourage is extremely scriptable, and has support for schedules that let you schedule, among other things, AppleScripts, it seemed to me that there was a way to have this run in Entourage's application space. A few hours of work, and 'voila', it was done.

If you want to just download the script, it's available from:

<http://web.mit.edu/jwelch/www/files/Mac OS X Scripts/EntourageX/SigFromiTunes.hqx>

The most recent versions are there, and it is fairly well commented, so if you don't want to type this all in manually, you can just download it from there.

Main functions of the script

As I saw it, the script had to do a few things, which made writing it pretty easy. It had to be able to get the current track information from iTunes, which I defined as the Track Name, the Track Artist, and the Track Album. If iTunes wasn't playing, then it had to substitute a signature from the user's list of random signatures. If there weren't any random signatures to use, then it had to insert a default signature. I ended up finding some interesting challenges in this, including one bug that could only happen in such a specific configuration, that it got its own name, "The La Grua Bug".

The script then had to take this iTunes information, and create a signature out of it, and insert this text into a predefined signature in Entourage. I ended up attaching the script to a schedule that runs every minute, so the track info is current. As of this article, it's been running constantly whenever I run Entourage, (which is pretty much 24x7), and no real problems.

Like most things with AppleScript, you end up getting help from the people in the community, both with the coding and with the testing. For the coding, I want to thank the folks on the Entourage mailing list,<mailto:Entourage-Talk-on@lists.letterrip.com> specifically Paul Berkowitz, and Dan Crevier, (who also works for the MacBU and is a major reason for the AppleScript quality in things like Outlook Express and Entourage.). For testing, besides the aforementioned (Jeff) La Grua, I'd like to thank the members of the Your Mac Life mailing list, <http://lists.mymacgroups.com/mailman/listinfo/yml>, who were quite helpful during the testing of this script.

Some caveats:

    1) This has been tested by me and most others in Entourage v.X and iTunes 2/3 in Mac OS X only. I have had reports of it working correctly in Mac OS 9 with the native versions of the programs there. If it does, cool, but I'm not going to worry if it doesn't. If you wish to change things to fix that, excellent.

    2) It only works with Entourage. I thought about Eudora, but the AppleScript dictionary for that Application makes my head hurt. If you want to get it to work with Eudora, please let me know when you do, I personally know a few people who will love you for it. It can't work with Mail at the moment, and Netscape's dictionary isn't even close to allowing it. I don't use PowerMail, or MailSmith, so I don't know if you could modify it for that. But anyone who wishes to may certainly use my code as a starting point.

    3) I'm not an AppleScript genius. I'm a pickup truck programmer. Most of my solutions are simple enough that I can read them in six months and remember why I did it that way. If you care to optimize my code, please do, and then comment it so I can maybe pick up a pointer or two.

So enough of this, let's dig into the code!

The AppleScript Code

The first section of this sets up some basic variables, and checks to see if iTunes is running at all. If it is, then we set a flag to show this. Otherwise, we avoid trying to get the track information, and dump into the 'iTunes isn't playing' sections.

set isiTunesRunning to 0
set theNewSig to ""
set iTunesIsPlaying to 0

The first three lines are pretty simple. Two flags, 'isiTunesRunning' and 'iTunesIsPlaying' are set to 0, which is the safer value. 'theNewSig', the variable used to hold the signature that will be built is initialized here as well.

try 
--the try allows for problems getting the process list from the finder without needing to 
--pop dialogs in e'rage if this times out
   tell application "Finder"
      if (get name of every process) contains "iTunes" then
         
--if iTunes isn't running, then assume the user wants things this way, and leave things 
--alone like a good boy
         set isiTunesRunning to 1
      end if
   end tell
on error
   quit
end try

This section asks the Finder if iTunes is running. If it isn't, then isiTunesRunning stays at 0, if it is, then it gets set to 1. The try block was needed because if Entourage was particularly busy, or the Finder was, or both were busy, then you'd get an error alert complaining that the script couldn't get the name of every process. If any errors occur, the script quits, and you just wait until the next run to update things.

if isiTunesRunning = 1 then
   
   tell application "iTunes" 
   --start talking to iTunes
      
      
      if player state is playing then 
      --now we want to see if iTunes is even playing         
         set iTunesIsPlaying to 1
         set theName to the name of the current track 
         --get the track name
         set theArtist to the artist of the current track 
         --get the artist name
         set theAlbum to the album of the current track 
         --get the album name         
         if theAlbum is "" then set theAlbum to "Beats the hell out of me" 
         --default if no album name
         if theArtist is "" then set theArtist to "Who the hell knows" 
         --default if no artist name
         if theName is "" then set theName to "Too Zen for me" 
         --default if no track name         
         set theNewSig to "--
I'm listening to " & theName & " by " & theArtist & " off of " & theAlbum 
         --now we set the sig to the  iTunes values. This has to 
         --happen here, otherwise we override other defaults, that would be bad
      end if
      
   end tell 
   --our iTunes work is done
   
   if iTunesIsPlaying = 1 then 
   --iTunes is running AND playing      
      buildSig(theNewSig) 
      --build the signature from the iTunes data, and update the e'rage sig since we call 
      --the same code twice, let's make it a handler, and save space
   else 
   --iTunes is running, but not playing      
      set theNewSig to buildSigWithoutiTunes(theNewSig) 
      --call the handler that builds a sig without iTunes running
      buildSig(theNewSig) 
      --update the sent sig to some random sig  created by the previous line
   end if
   
else 
--iTunes isn't running or playing
   
   set theNewSig to buildSigWithoutiTunes(theNewSig) 
   --call the handler that builds a sig without iTunes running
   
   buildSig(theNewSig) 
   --update the sent sig to some random sig  created by the previous line
   
end if

The first line of this section tests to see if iTunes is running. If the flag, 'isiTunesRunning' is set to 1, then iTunes is running, and we start talking to iTunes. Otherwise, this section is skipped. The 'tell block' routes all the commands inside the 'tell block' to iTunes, and the first thing we need to know is the player state. ITunes could be on, but not playing. So the 'if player stated is playing' line asks iTunes for this information. There are five possible values for 'player state': stopped, playing, paused, rewinding, fast forwarding. Since we only care about playing, we use that as our test. If the 'player state' is playing, then 'iTunesIsPlaying' is set to 1.

Since iTunes is playing, we now get the names of the track, the artist, and the album the track comes from and put them into theName, theArtist, and theAlbum, respectively. We then test to see if any of these variables are blank, indicating that iTunes doesn't have this information, and if they are, we insert default values into them. Once this is done, we create the new signature text, and put it into 'theNewSig'. The reason why it looks a little odd is that I inserted returns so that we sould get a good structure in the email message. The code for these is '\r', but when you compile the script, AppleScript converts these to actual returns, so you get the breaks instead of the characters. The pre-compiled code for the signature text is:

"--\rI'm listening to " & theName & " by " & theArtist & " off of " & theAlbum

The '&' characters allow me to concatenate the data in the three track variables into the text string of the signature. Once that is done, we close the if statement with an 'end if', and the tell block with an 'end tell', and that's all we need to talk to iTunes for.

The next if statement checks the value of 'iTunesIsPlaying'. If it is 1, then we call the handler 'buildSig()' and pass it the variable theNewSig that we just created. This handler is pretty short, as seen below:

on buildSig(theSignature) 
--handler/subroutine to set the sig in E'Rage
   
   tell application "Microsoft Entourage"
   --this actually ends up setting the signature *after* you send the mail,
   --but until I get a proper signature property, it's the only non-kludgy way to do this
      if exists signature "iTunesSig" then 
      --if iTunes Sig is there
         set the content of signature "iTunesSig" to theSignature 
         --change the contents         
      else 
      --if it isn't there         
         make new signature with properties {name:"iTunesSig", content:theSignature, include in 
         random:false} 
         --create iTunes Sig, with the correct contents         
      end if
   end tell
   
end buildSig

This handler tells Entourage to set a specific signature to the contents of 'theSignature', which is carrying the data from theNewSig. One quirk here is that you are actually changing the signature after the message is sent, as you can't directly manipulate the signature in an email message yet. The first 'if' inside the tell block asks Entourage if a signature named "iTunes Sig" exists. If it does, then the content of that signature is changed to the content of 'theSignature', and we're done with the handler. If "iTunes Sig" doesn't exist, then we use the 'make new signature' statement to create the signature, name it "iTunes Sig", set the content to 'theSignature', and make it a non-random signature. (that last bit is important. If "iTunes Sig" is random, you can start setting up for the La Grua bug.) Once that's done, we're done with the handler, and we jump back into the main program.

Now, at the beginning of the signature building block of code, we checked to see if iTunes was playing. If it wasn't , (if we got to here, then iTunes is running, but is not playing), then we have to create a different signature, so we set 'theNewSig' to the results of a different handler, 'buildSigWithoutiTunes()', and pass it 'theNewSig'. This handler's code is shown below:

on buildSigWithoutiTunes(theSignature)
   
   tell application "Microsoft Entourage" 
   --here's where we use a random signature, thank Paul Berkowitz for the help here      
      set randomSigs to every signature whose include in random is true
      if the length of randomSigs is equal to 1 then
      (* this is to catch the La Grua bug, wherein you only have one sig set to random, 
      namely the iTunesSig. This creates a problem where instead of the not playing 
      message    you get the name of the last tune to play until you run iTunes again. *)
         set theSignature to the name of the first item of randomSigs
         if theSignature is "iTunesSig" then
            set theSignature to "-- 
 itunes isn't playing right now"
         end if
      end if
      if the length of randomSigs is greater than 1 then 
      --more than one signature in the random list
         set theSignature to some item of randomSigs 
         --'this gives you the numerical ID of the selected sig
         set theSignature to the content of theSignature 
         --this gives you the text content of the selected sig
      else 
      --uh - oh, no random sigs         
         set theSignature to "-- 
 itunes isn't playing right now"
      end if
   end tell
   return theSignature
end buildSigWithoutiTunes

So now, we have to deal with creating a signature that has nothing to do with iTunes, since it isn't playing anything. We tell Entourage to create a list of signatures that have the random flag set to true. Next we avoid the La Grua bug, by checking to see if the number of items in this list is 1. If it is, we set 'theSignature' to the name of that single item. If that name is "iTunesSig" then we don't want to use potentially very old track information, so we change the contends of 'theSignature' to "--\r iTunes isn't playing right now", we return theSignature, and we're done with the handler.

If the number of items in randomSigs is greater than one, then we set 'theSignature' to 'some item' of 'randomSigs, (AppleScriptese for 'gimme a random selection from that list'). This gives us the index number for a random selection from that list. We then reset 'theSignature' to the contents of the signature that the index points to. Once that is finished, we return 'theSignature' and we're done. The 'else' statement is only there if the number of random signatures is not 1 and not greater than 1, so all that's left is 0 random signatures. In that case, we set 'theSignature' to "--\r iTunes isn't playing right now", we return 'theSignature' and we're done with the handler.

However, while we now have a signature ready to go, even though iTunes isn't playing, we still haven't told Entourage to actually change the signature. Well, we could just put that code into the buildSigWithoutiTunes(), but why duplicate code? As we saw earlier, we already have that code built and running, why not use it? After all, code reuse is 'a good thing'. So that's what we do. If we review two of the last lines in the main body of the program:

set theNewSig to buildSigWithoutiTunes(theNewSig) --call the handler that builds a 
sig without iTunes running
   
   buildSig(theNewSig) --update the sent sig to some rangom sig  created by the previous line

We see that the first line is what calls the buildSigWithoutiTunes(), and sets 'theNewSig' to the returned value. The next line calls our previously discussed buildSig() handler, and passes it 'theNewSig'. That handler is what creates the new sig in iTunes. So we don't have to re-enter the same code. It's a nice way to keep your code listings shorter. The next line closes up the if statement that checked to see if iTunes was even running, and that's the end of the main program, and we're done. You'll want to save this as a compiled script, not as an application. You can save it anywhere, but I prefer to save it in ~/Documents/Microsoft User Data/Entourage Script Menu Items/, so I can run it manually from the Entourage Script menu if need be.

Setting Up Entourage

So now we have a script, how do we get Entourage to use this bit of script we have created? Well, first you'll want to create a schedule so it can run regularly. I've been running it every minute for about five months now without a problem. The schedule setup is pretty simple, as we can see below:


Setup for iTunes Script Schedule

You give it a name, set it to be a repeating schedule, and set the action to be 'Run AppleScript' and point it at the 'sigFromiTunes' script. Make sure the 'Enabled' checkbox is checked, click 'OK' and your schedule is set. The next step is to attach the signature that this schedule is going to be creating to an account. I chose my mac.com account, as I mostly use that for personal email. The setup for that is pretty easy as well. This account happens to be an IMAP account, but the setup for POP accounts is the same. Go to the 'Tools' menu, and select 'Accounts'. In the list of accounts, double-click the account you want this signature to attach to, and select the Options tab. Then in the signature pull down, pick the appropriate entry for the iTunes Signature, normally 'iTunesSig'. My setup is seen below:


Account setup for iTunesSig

Once that's done, click 'OK', and you're all set to wow your friends with your vast collection of legal MP3s.

Conclusion

Well, it's not a terribly serious or network-related use for AppleScript, but then again, you are supposed to have some fun with your Mac every once in a while. Otherwise, you may as well use Windows. Also, I have done some testing, and this should work on iTunes 3 as well as 2.X, but if it doesn't, by all means, feel free to fix it. Finally, here are some URLs that can help you with this, or any other AppleScripting projects you may have:


John Welch <jwelch@mit.edu> is a Consultant with MIT IS, and the Chief Know-It-All for TackyShirt. He has over fifteen years of experience at making computers work. John specializes in figuring out ways in which to make the Mac do what nobody thinks it can, showing that the Mac is the superior administrative platform, and teaching others how to use it in interesting, if sometimes frightening ways. He also does things that don't involve computertry on occasion, or at least that's the rumor.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Monolingual 1.6.4 - Remove unwanted OS X...
Monolingual is a program for removing unnecesary language resources from OS X, in order to reclaim several hundred megabytes of disk space. If you use your computer in only one (human) language, you... Read more
CleanApp 5.0 - Application deinstaller a...
CleanApp is an application deinstaller and archiver.... Your hard drive gets fuller day by day, but do you know why? CleanApp 5 provides you with insights how to reclaim disk space. There are... Read more
Fantastical 2.0 - Create calendar events...
Fantastical is the Mac calendar you'll actually enjoy using. Creating an event with Fantastical is quick, easy, and fun: Open Fantastical with a single click or keystroke Type in your event details... Read more
Cocktail 8.2 - General maintenance and o...
Cocktail is a general purpose utility for OS X that lets you clean, repair and optimize your Mac. It is a powerful digital toolset that helps hundreds of thousands of Mac users around the world get... Read more
Direct Mail 4.0.4 - Create and send grea...
Direct Mail is an easy-to-use, fully-featured email marketing app purpose-built for OS X. It lets you create and send great looking email campaigns. Start your newsletter by selecting from a gallery... Read more
jAlbum Pro 12.6 - Organize your digital...
jAlbum Pro has all the features you love in jAlbum, but comes with a commercial license. With jAlbum, you can create gorgeous custom photo galleries for the Web without writing a line of code!... Read more
jAlbum 12.6 - Create custom photo galler...
With jAlbum, you can create gorgeous custom photo galleries for the Web without writing a line of code! Beginner-friendly, with pro results Simply drag and drop photos into groups, choose a design... Read more
Lyn 1.5.9 - Lightweight image browser an...
Lyn is a lightweight and fast image browser and viewer designed for photographers, graphic artists and Web designers. Featuring an extremely versatile and aesthetically pleasing interface, it... Read more
Sublime Text 3080 - Sophisticated text e...
Sublime Text is a sophisticated text editor for code, markup, and prose. You'll love the slick user interface, extraordinary features, and amazing performance. Goto Anything. Use Goto Anything to... Read more
WALTR 1.0.11 - Drag-and-drop any media f...
WALTR is designed to make it easy to upload and convert any music or video file to an iPad or iPhone format for native playback. It supports a huge variety of media file types, including MP3, MP4,... Read more

Bio Inc's New Expansion is Infectin...
Bio Inc., by DryGin Studios, is the real time strategy game where you infect a human body with the worst virus your evil brain can design. Recently, the game was updated to add a whole lot of new features. Now you can play the new “Lethal”... | Read more »
The Monocular Minion is Here! Despicable...
Despicable Me: Minion Rush, by Gameloft, is introducing a new runner to the mix in their latest update. Now you can play as Carl, the prankster minion. Carl has a few new abilities to play with, including running at a higher speed from the start.... | Read more »
Dungeon of Madness (Games)
Dungeon of Madness 1.0.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0.0 (iTunes) Description: Dungeon of Madness is an action game where you rotate tiles to create our own route. Help the hero by connecting the... | Read more »
Filters for iPhone (Photography)
Filters for iPhone 1.0 Device: iOS iPhone Category: Photography Price: $.99, Version: 1.0 (iTunes) Description: | Read more »
Jump'N'Shoot Attack (Games)
Jump'N'Shoot Attack 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: A mobile game for gamers! Join Louise Lightfoot, the legendary "Master of Jumping and Shooting", on her mission to save... | Read more »
Space Bounties Inc. (Games)
Space Bounties Inc. 1.4 Device: iOS Universal Category: Games Price: $1.99, Version: 1.4 (iTunes) Description: SuperGameDroid: 4/5 "Satisfying futuristic RPG combat, high replay value, and a heavy dose of nostalgia make Space... | Read more »
Gamebook: Pocket RPG (Games)
Gamebook: Pocket RPG 1.0.11 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0.11 (iTunes) Description: Walk into the Land of Lanthir Lamath ruled by wicked skeletons and fight for your life in a thrilling adventure.... | Read more »
Kids Can Mix, Match, and Catch with Tata...
Tatadada MixMatch, by Tatadada Ltd, is a mobile version of the classic game of mix & match. The game uses brightly colored creatures to train your children's pattern matching skills and hand-eye coordination. It's aimed at children around age 5... | Read more »
The Trace: Murder Mystery Game (Games)
The Trace: Murder Mystery Game 1.2.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.2.0 (iTunes) Description: | Read more »
This Week at 148Apps: March 16-20, 2015
Spring Roars In At 148Apps How do you know what apps are worth your time and money? Just look to the review team at 148Apps. We sort through the chaos and find the apps you're looking for. The ones we love become Editor’s Choice, standing out above... | Read more »

Price Scanner via MacPrices.net

Logitech Says MX Master Is Its Most Advanced...
Logitech’s new MX Master Wireless Mouse incorporates the best of Logitech’s many computer mouse innovations into a striking hand-sculpted design. The company claims that the MX Master creates a new... Read more
Save up to $300 on a new Mac, $30 on an iPad,...
Purchase a new Mac or iPad at The Apple Store for Education and take up to $300 off MSRP. All teachers, students, and staff of any educational institution qualify for the discount. Shipping is free,... Read more
Apple refurbished 2014 MacBook Airs available...
The Apple Store lowered prices on Apple Certified Refurbished 2014 MacBook Airs recently, with models now available starting at $679. An Apple one-year warranty is included with each MacBook, and... Read more
Mac Notebook Evolution; A Desktop Replacement...
More often than not right from the beginning, Apple’s Macs have tended to skew toward small. The original Macs were called “compacts,”, and notwithstanding a few exceptions like the honking Big Mac... Read more
13-inch 1.4GHz/128GB MacBook Air (Apple refur...
The Apple Store has Apple Certified Refurbished 2014 13″ 1.4GHz/128GB MacBook Airs available for $759 including free shipping plus Apple’s standard one-year warranty. Their price is $240 off original... Read more
YEP! Alternative Browser for iOS Now Supports...
Pfaeffikon, Switzerland based Power App AG has announced the release of an update to their Yep! Web Browser (v1.3.0) for iOS8 iPhone and iPad. Yep! hit the App Store shortly after the release of iOS... Read more
15-inch Retina MacBook Pros on sale for up to...
B&H Photo has the new 2014 15″ Retina MacBook Pros on sale for up to $250 off MSRP for a limited time. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.2GHz Retina MacBook Pro: $... Read more
Clearance 13-inch Retina MacBook Pros availab...
B&H Photo has leftover 2014 13″ Retina MacBook Pros on sale for up to $250 off original MSRP. Shipping is free, and B&H charges NY sales tax only: - 13″ 2.6GHz/128GB Retina MacBook Pro: $1098... Read more
Clearance 2014 MacBook Airs on sale for up to...
B&H Photo has MacBook Airs on sale for up to $180 off original MSRP. Shipping is free, and B&H charges NY sales tax only: - 11″ 128GB MacBook Air: $789.99 110 off original MSRP - 11″ 256GB... Read more
Apple refurbished Time Capsules available for...
The Apple Store has certified refurbished Time Capsules available for $100 off MSRP. Apple’s one-year warranty is included with each Time Capsule, and shipping is free: - 2TB Time Capsule: $199, $100... Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - D...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Systems Engineer - Pre Sales, Educat...
…is responsible for proactively providing technical expertise to drive sales of Apple solutions into assigned accounts. The SE architects, validates, and assists in Read more
Sr. Technical Services Consultant, *Apple*...
**Job Summary** Apple Professional Services (APS) has an opening for a senior technical position that contributes to Apple 's efforts for strategic and transactional Read more
*Apple* Solutions Consultant - Retail Sales...
**Job Summary** As an Apple Solutions Consultant (ASC) you are the link between our customers and our products. Your role is to drive the Apple business in a retail Read more
*Apple* Solutions Consultant - Retail Sales...
**Job Summary** As an Apple Solutions Consultant (ASC) you are the link between our customers and our products. Your role is to drive the Apple business in a retail Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.