Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Scripting Bridge equivalent to AppleScript "every"

Hi

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

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

Thanks

Praful

MacBook Pro, Mac OS X (10.5.2)

Posted on Mar 23, 2008 6:03 AM

Reply
9 replies

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


HTH

Mar 23, 2008 11:35 AM in response to hhas

Thanks for the reply.

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.

I found that rb-appscript did not work when I tried to get all contacts from a particular address book. I thought (when I asked the question) it was related to the fact that the address book that did not work was remote and cached locally as a favourite. I've tried with another local (large) address book and that does not work either. There seems to be something about the size of the address book that's upsetting rb-appscript.

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

address book.contacts.get.findall do |c|
p "#{c.first_name.get} #{c.last_name.get}"
end

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: -1708
MESSAGE: Application could not handle this command.
COMMAND: app("/Applications/Microsoft Office
2004/Microsoft Entourage").address_books.ID(620).contacts.get()
from /Library/Ruby/Gems/1.8/gems/rb-appscript-0.5.1/lib/appscript.rb:642:in
`method_missing'
--------------------------


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?

The equivalent AppleScript is fine.

Any help appreciated.

Thanks

Praful

Mar 23, 2008 12:05 PM in response to hhas

As an aside, I had already used the ASDictionary tool (nice) but the ASTranslate did not work for me for Ruby. The Python translation is fine and, of course, you can deduce the Ruby one from that. When I entered what you did, I get the message "Ruby translation not available." I am using ASTranslate v0.3.1.

For those considering options, the whole documentation for rb-appscript is much better than Scripting Bridge and it certainly looks the more professional package, which is probably a reflection of its maturity.

Praful

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:

address book.contacts.get.findall do |c|
p "#{c.first_name.get} #{c.last_name.get}"
end

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 Reference.new(self, @referencecodecs.fully_unpack_objectspecifier(desc))
end
end
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)

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.

{quote}

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.

Mar 24, 2008 8:30 AM in response to hhas

I have only one version of Ruby unless ASTranslate is picking up Netbean's jRuby.

To perform a search I'm using

address book.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?

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.

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?

Thanks

Praful

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

address book.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:

http://appscript.sourceforge.net/rb-appscript/doc/appscript-manual/09_referencef 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:

http://appscript.sourceforge.net/rb-appscript/doc/appscript-manual/11_applicatio 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:

http://www.ruby-doc.org

Scripting Bridge equivalent to AppleScript "every"

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.