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.

 
AAPL
$116.47
Apple Inc.
+0.16
MSFT
$47.98
Microsoft Corpora
-0.72
GOOG
$537.50
Google Inc.
+2.67

MacTech Search:
Community Search:

Software Updates via MacUpdate

Cobook 3.0.7 - Intelligent address book....
Cobook Contacts is an intuitive, engaging address book. Solve the problem of contact management with Cobook Contacts and its simple interface and powerful syncing and integration possibilities.... Read more
StatsBar 1.9 - Monitor system processes...
StatsBar gives you a comprehensive and detailed analysis of the following areas of your Mac: CPU usage Memory usage Disk usage Network and bandwidth usage Battery power and health (MacBooks only)... Read more
Cyberduck 4.6 - FTP and SFTP browser. (F...
Cyberduck is a robust FTP/FTP-TLS/SFTP browser for the Mac whose lack of visual clutter and cleverly intuitive features make it easy to use. Support for external editors and system technologies such... Read more
Maya 2015 - Professional 3D modeling and...
Maya is an award-winning software and powerful, integrated 3D modeling, animation, visual effects, and rendering solution. Because Maya is based on an open architecture, all your work can be scripted... Read more
Evernote 6.0.1 - Create searchable notes...
Evernote allows you to easily capture information in any environment using whatever device or platform you find most convenient, and makes this information accessible and searchable at anytime, from... Read more
calibre 2.11 - Complete e-library manage...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital... Read more
Herald 5.0.1 - Notification plugin for M...
Note: Versions 2.1.3 (for OS X 10.7), 3.0.6 (for OS X 10.8), and 4.0.8 (for OS X 10.9) are no longer supported by the developer. Herald is a notification plugin for Mail.app, Apple's Mac OS X email... Read more
Firetask 3.7 - Innovative task managemen...
Firetask uniquely combines the advantages of classical priority-and-due-date-based task management with GTD. Stay focused and on top of your commitments - Firetask's "Today" view shows all relevant... Read more
TechTool Pro 7.0.6 - Hard drive and syst...
TechTool Pro is now 7, and this is the most advanced version of the acclaimed Macintosh troubleshooting utility created in its 20-year history. Micromat has redeveloped TechTool Pro 7 to be fully 64... Read more
PhotoDesk 3.0.1 - Instagram client for p...
PhotoDesk lets you view, like, comment, and download Instagram pictures/videos! (NO Uploads! / Image Posting! Instagram forbids that! AND you *need* an *existing* Instagram account). But you can do... Read more

Latest Forum Discussions

See All

Ubisoft Gives Everyone Two New Ways to E...
Ubisoft Gives Everyone Two New Ways to Earn In-Game Stuff for Far Cry 4 Posted by Jessica Fisher on November 21st, 2014 [ permalink ] | Read more »
Golfinity – Tips, Tricks, Strategies, an...
Dig this: Would you like to know what we thought of being an infinite golfer? Check out our Golfinity review! Golfinity offers unlimited ways to test your skills at golf. Here are a few ways to make sure your score doesn’t get too high and your... | Read more »
Dark Hearts, The Sequel to Haunting Meli...
Dark Hearts, The Sequel to Haunting Melissa, is Available Now Posted by Jessica Fisher on November 21st, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Meowza! Toyze Brings Talking Tom to Life...
Meowza! | Read more »
Square Enix Announces New Tactical RPG f...
Square Enix Announces New Tactical RPG for Mobile, Heavenstrike Rivals. Posted by Jessica Fisher on November 21st, 2014 [ permalink ] With their epic stories and gorgeous graphics, | Read more »
Quest for Revenge (Games)
Quest for Revenge 1.0.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.0 (iTunes) Description: The great Kingdom of the west has fallen. The gods ignore the prayers of the desperate. A dark warlord has extinguished... | Read more »
Threadz is a New Writing Adventure for Y...
Threadz is a New Writing Adventure for You and Your Friends Posted by Jessica Fisher on November 21st, 2014 [ permalink ] In the tradition of round-robin storytelling, | Read more »
SteelSeries Stratus XL Hardware Review
Made by: SteelSeries Price: $59.99 Hardware/iOS Integration Rating: 4 out of 5 stars Usability Rating: 4.5 out of 5 stars Reuse Value Rating: 4.25 out of 5 stars Build Quality Rating: 4.5 out of 5 stars Overall Rating: 4.31 out of 5 stars | Read more »
ACDSee (Photography)
ACDSee 1.0.0 Device: iOS iPhone Category: Photography Price: $1.99, Version: 1.0.0 (iTunes) Description: Capture, perfect, and share your photos with ACDSee. The ACDSee iPhone app combines an innovative camera, a powerful photo... | Read more »
ProTube for YouTube (Entertainment)
ProTube for YouTube 2.0.2 Device: iOS Universal Category: Entertainment Price: $1.99, Version: 2.0.2 (iTunes) Description: ProTube is the ultimate, fully featured YouTube app. With it's highly polished design, ProTube offers ad-free... | Read more »

Price Scanner via MacPrices.net

Save up to $400 with Apple refurbished 2014 1...
The Apple Store has restocked Apple Certified Refurbished 2014 15″ Retina MacBook Pros for up to $400 off the cost of new models. An Apple one-year warranty is included with each model, and shipping... Read more
New 13-inch 1.4GHz MacBook Air on sale for $8...
 Adorama has the 2014 13″ 1.4GHz/128GB MacBook Air on sale for $899.99 including free shipping plus NY & NJ tax only. Their price is $100 off MSRP. B&H Photo has the 13″ 1.4GHz/128GB MacBook... Read more
Apple Expected to Reverse Nine-Month Tablet S...
Apple and Samsung combined accounted for 62 percent of the nearly 36 million branded tablets shipped in 3Q 2014, according to early vendor shipment share estimates from market intelligence firm ABI... Read more
Stratos: 30 Percent of US Smartphone Owners t...
Stratos, Inc., creator of the Bluetooth Connected Card Platform, has announced results from its 2014 Holiday Mobile Payments Survey. The consumer survey found that nearly one out of three (30 percent... Read more
2014 1.4GHz Mac mini on sale for $449, save $...
 B&H Photo has lowered their price on the new 1.4GHz Mac mini to $449.99 including free shipping plus NY tax only. Their price is $50 off MSRP, and it’s the lowest price available for this new... Read more
Check Apple prices on any device with the iTr...
MacPrices is proud to offer readers a free iOS app (iPhones, iPads, & iPod touch) and Android app (Google Play and Amazon App Store) called iTracx, which allows you to glance at today’s lowest... Read more
64GB iPod touch on sale for $249, save $50
Best Buy has the 64GB iPod touch on sale for $249 on their online store for a limited time. Their price is $50 off MSRP. Choose free shipping or free local store pickup (if available). Sale price for... Read more
15″ 2.2GHz Retina MacBook Pro on sale for $17...
 B&H Photo has the 2014 15″ 2.2GHz Retina MacBook Pro on sale for $1799.99 for a limited time. Shipping is free, and B&H charges NY sales tax only. B&H will also include free copies of... Read more
New Logitech AnyAngle Case/Stand Brings Flexi...
Logitec has announced the newest addition to its suite of tablet products — the Logitech AnyAngle. A protective case with an any-angle stand for iPad Air 2 and all iPad mini models, AnyAngle is the... Read more
Notebook PC Shipments Rise Year-Over-Year as...
According to preliminary results from the upcoming DisplaySearch Quarterly Mobile PC Shipment and Forecast Report, the global notebook PC market grew 10 percent year-over-year in Q3’14 to 49.4... Read more

Jobs Board

*Apple* Solutions Consultant (ASC)- Retail S...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Project Manager, *Apple* Financial Services...
**Job Summary** Apple Financial Services (AFS) offers consumers, businesses and educational institutions ways to finance Apple purchases. We work with national and Read more
*Apple* Store Leader Program - College Gradu...
Job Description: Job Summary As an Apple Store Leader Program agent, you can continue your education as you major in the art of leadership at the Apple Store. You'll Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Senior Event Manager, *Apple* Retail Market...
…This senior level position is responsible for leading and imagining the Apple Retail Team's global event strategy. Delivering an overarching brand story; in-store, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.