Skip navigation
This discussion is archived

Scripting Bridge equivalent to AppleScript "every"

2062 Views 9 Replies Latest reply: Mar 27, 2008 2:46 PM by Praful RSS
Praful Calculating status...
Currently Being Moderated
Mar 23, 2008 6:03 AM

What is the Scripting Bridge equivalent in Ruby to the following AppleScript:

tell application "Microsoft Entourage" to set allContacts to every contact in anAddressBook


MacBook Pro, Mac OS X (10.5.2)
  • hhas Calculating status...
    Currently Being Moderated
    Mar 23, 2008 9:28 AM (in response to Praful)
    Unless you've a particular reason to be using Scripting Bridge, I'd suggest taking a look at rb-appscript first. As well as providing a native API and better application compatibility than SB, you also get a couple of nifty developers tools:

    - ASDictionary exports application dictionaries in a nice, clear HTML format (objc-appscript example) that's much easier to read than the raw ObjC headers that sdp generates for SB.

    - ASTranslate allows you to type in an AppleScript command and run it to get the appscript equivalent. For example:

    tell application "Microsoft Entourage" to get every contact in address book 1

    translates to:

    app("/Applications/Microsoft Office X/Microsoft Entourage").address_books[1].contacts.get

    which you can then tidy up by hand as needed:

    require 'appscript'
    include Appscript

    Entourage = app("Microsoft Entourage")

    all_contacts = Entourage.address_books[1].contacts.get

  • hhas Level 2 Level 2 (190 points)
    Currently Being Moderated
    Mar 23, 2008 7:07 PM (in response to Praful)
    Praful wrote:
    Having browsed various group, I concluded that rb-appscript was my best bet. However, I've had an issue with it, which I've posted to the rb-appscript mailing list.

    Hmm, doesn't seem to have appeared there yet. (I posted a message to it on Sat. and it hasn't appeared either - could be an issue with the RubyForge mailing lists, or an overzealous spam filter somewhere inbetween.)

    This works in rb-appscript with a small address book but not with a large one:

    addressbook.contacts.get.findall do |c|
    p "#{c.first_name.get} #{c.last_name.get}"

    The error message is:
    OSERROR: -1708

    MS applications' scripting support can be rather cranky, and prone to compatibility problems with Apple event bridges other than AppleScript's. My first guess is that Entourage may not like one of appscript's extra performance optimisations, as I've already heard of it causing some problems with Excel. Fortunately, appscript's very open and flexible by design, so can generally be tweaked to work with awkward applications. Try adding the following patch to your script and let me know if that fixes it:

    require 'appscript'
    include Appscript

    class AppData # disable caching feature
    def unpackobjectspecifier(desc)
    return, @referencecodecs.fully_unpack_objectspecifier(desc))

    Entourage = app('Microsoft Entourage')

    (I'd test it here, but I've only got Office X and the version of En'rage that comes with that seems to be buggy as it's not returning any contacts at all.)

    Running address_book.contacts.get as you suggested returns successfully for a small address book but not a large one (>5000 contacts). The error message is:

    /Library/Ruby/Gems/1.8/gems/rb-appscript-0.5.1/lib/appscript.rb:540:in `sendcommand': CommandError (Appscript::CommandError)
    OSERROR: -609
    MESSAGE: Connection is invalid.
    COMMAND: app("/Applications/Microsoft Office 2004/Microsoft Entourage").address_books.ID(403).contacts.get()
    from /Library/Ruby/Gems/1.8/gems/rb-appscript-0.5.1/lib/appscript.rb:642:in `method_missing'

    Perhaps it's timing out?

    Could be; either that or Entourage is crashing. (Error -609 normally means it's crashed, but there's a glitch in Apple's APIs that cause timeouts to sometimes raise error -609 instead of the usual -1712.) It's odd that the equivalent AppleScript seems to work - appscript is designed to mimic AppleScript as closely as possible for compatibility's sake - but you could try increasing the timeout delay to see if that helps, e.g.:

    app("/Applications/Microsoft Office 2004/Microsoft Entourage").address_books.ID(403).contacts.get(:timeout => 10000)
  • hhas Level 2 Level 2 (190 points)
    Currently Being Moderated
    Mar 23, 2008 7:15 PM (in response to Praful)
    Praful wrote:
    As an aside, I had already used the ASDictionary tool (nice) but the ASTranslate did not work for me for Ruby.


    ASTranslate currently relies on your existing Ruby installation to provide Ruby translations. If you've more than one Ruby installation on your system, the simplest thing is just to install rb-appscript on all of them; that way, ASTranslate can't miss it. (If it's still not behaving after that, drop us an email and I'll look into it further.)

    Eliminating this dependency is one of the things on my TODO list, but I've quite a lot on my plate at the moment so can't yet say when it'll happen.
  • hhas Level 2 Level 2 (190 points)
    Currently Being Moderated
    Mar 24, 2008 5:09 PM (in response to Praful)
    Praful wrote:
    I have only one version of Ruby unless ASTranslate is picking up Netbean's jRuby.

    It should pick up whatever ruby interpreter is found first on $PATH. Not sure why it isn't working for you. Have you tried it with a different application at all?

    To perform a search I'm using

    addressbook.contacts[its.firstname.eq("Fred")].get(:timeout => 50000).each do |c|....

    1. How do I find out what other operators are valid as well as eq in the search? One example has ne (not equal). Are the others gt, lt, gte, lte?! And what about the boolean operators?

    Supported operators are listed under the 'by Filter' reference form section in ch.9 of the appscript manual: orms.html

    2. You provided the timeout argument. Is there a way of finding out the arguments? I've seen the help in the doc about introspection (properties, commands, parameters, etc) but can't work out how I would have found out the parameters to the get command.

    Default parameters (:wait_reply, :timeout, :result_type, :ignore) are described in ch.11 of the appscript manual, and are available on all commands: ncommands.html

    To find out what other parameters (if any) a particular application command has, see its dictionary definition. ASDictionary can export application dictionaries in HTML format, or you can look up individual command definitions via appscript's built-in help, e.g. to view the definition for Finder's 'make' command:

    app('Finder').help '-t make'

    (Note that using appscript's built-in help requires ASDictionary to be installed and its preferences configured.)

    3. Related to 2 above: I originally used get.find_all because I saw an example. I thought I'd tried get.each. However, get.each works. How do I find out which commands and properties are available on the get command?

    The value returned by the 'get' command will depend on what you called it on. In your case, you called it on a reference to every contact of an address book, so the result will be a list (Array object) containing zero or more references.

    To find out what methods are provided by Ruby's Array class, look it up in the Ruby documentation, e.g. see:


More Like This

  • Retrieving data ...

Bookmarked By (0)


  • This solved my question - 10 points
  • This helped me - 5 points
This site contains user submitted content, comments and opinions and is for informational purposes only. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. All postings and use of the content on this site are subject to the Apple Support Communities Terms of Use.