Now Playing

I've been having fun over the last couple of days playing with a nice combination of SOAP, Applescript, Amazon, Drupal and iTunes.

The result of this unholy alliance is my Now Playing script, which is yet another of those publish-what-iTunes-is-doing-as-if-anyone-cared tools.

At the moment I've got an applescript with an idle loop that gets the current track info from iTunes, looks it up on amazon to get a picture, then writes the information out to a small html file.

I've then got a bit of PHP code in a custom Drupal block which reads in the html.

At some point it would be nice to merge these into one script, but I think that there might be issues with a perl script on the server talking to an application running logged in as another user (time for a bit more experimentation).

I'm really impressed at the ease with which one can make SOAP requests from Applescript. This stuff has apparently been around since 2001, but I've been so wrapped up with Championship Manager that I had no idea.

Thanks to Tim Jarrett, for some scripts which helped set me off in the right direction.

As it happens, his Amazon Handler script seems to be a bit out of date now, so after a lot of head scratching, I figured out how to do things using the latest Amazon SOAP api.

By way of a thank you, here's some example code. I haven't generalised things as much as Tim did, so this function is for a very specific job (look up a track and return urls for the amazon page and an image), but it should give you some idea:


on amazonLookup(trackName, bandName)
    try
        set soapParameters to ¬
             { ¬
                |SubscriptionId|:"1HT82XR9S43B5V8YDQ02", ¬
                |SearchIndex|:"Music", ¬
                |Title|:trackName, ¬
                |Artist|:bandName, ¬
                |ResponseGroup|:"Small,Images" ¬
            }

        using terms from application "http://www.apple.com/placebo"
            tell application "http://webservices.amazon.com/onca/soap?Service=AWSECommerceService"
                set soapResult to call soap ¬
                    { ¬
                        method name: "ItemSearch", ¬
                        method namespace uri: "http://webservices.amazon.com/AWSECommerceServices/2005-02-23", ¬
                        parameters: soapParameters, ¬
                        SOAPAction: "http://soap.amazon.com" ¬
                    }   
            end tell
        end using terms from
        
        set soapOutput to |items| of soapResult
        set itemList to |item| of soapOutput
        repeat with i in itemList
            try
                set a to the itemattributes of i
                if the productgroup of a is "Music" then
                    if the artist of a is bandName then
                        set imageURL to the |url| of the smallimage of i
                        set trackURL to the detailpageurl of i
                        return {ok:true, track:trackURL, image:imageURL}
                    end if
                end if
            end try
        end repeat
    end try
    
    return {ok:false}
end amazonLookup

It took me a long time to figure out exactly what parameters I was supposed to be supplying in the SOAP call (the Apple documentation is a bit sketchy), but once I did, it worked like a dream, and it opens up all sorts of interesting possibilities.

What you get back from the call soap call is a compound record which follows the same structure as the XML SOAP reply. From there it is easy enough to extract the information that you're after.

As I mentioned, this code just gives a very specific example of one call to Amazon to do one thing. There's a lot more you can do, and the Amazon documentation seems quite extensive.

Have fun...

Sam Deane's picture

Comments

Good job

Sam--good work on this. Absolutely right the Amazon code is out of date. I generated it one day when Amazon released their API. About a year later I started playing with it again and wrote a testbed that would actually use it. Then 10.3 came out and broke the scripts--something about too many levels of indirection in the way I structured the event handlers. Plus Amazon had been revving their APIs and eventually turned the v.1 API off.

Your approach seems much more straightforward. Glad my stuff was marginally helpful.

Now Playing

I fiddled around with AppleScript/SOAP to do basically this - and couldn't get anywhere. I hope you don't mind, I pinched most of the code directly from you!

Anyway, my program is an iTunes Controller/Rater/Artwork Finder (this last bit is new!), that allows for more than just 0-5 star rating.

All I really need to do is make it so that my program responds quicker, rather than just 'freezing' for the time it takes to download the artwork.

Oh, and if you create an AppleScriptStudio program, you can set up a script that only updates when iTunes' song changes. You can get the source code for the previous version of iTunesRater from my website, this shows how I did it.

The newest version (incorporating your code) will be there as soon as I have finished the 'adding of artwork to iTunes" routines. Which won't happen until after tomorrow - I'm off to the races!

Sam Deane's picture

No problem

I'm glad that the code was useful :)