[Pythonmac-SIG] Two appscript problems, plus a stupid question

has hengist.podd at virgin.net
Sat Mar 25 17:49:07 CET 2006


Andrew Barnert wrote:

>If this list is the wrong place, I apologize; just let
>me know and I'll ask in the right place. Otherwise:

Here's fine.

>First, whenever I try to get a date through appscript,
>at least from iTunes, I get a "CommandError: long int
>too large to convert to int".
>Second, whenever I ask for a missing value, the result
>is something like aem.AEType('gnsm').

Oops, more endian problems. Ta for the heads-up. Fixed and uploaded.


>Finally, the stupid question: Is there any easy way to
>convert a list of references into a single reference
>to the list? (To allow a single IPC call instead of
>one per reference.)

Nope. There are one or two apps that will accept lists of references (e.g. Finder) as the direct parameter to a command, but that's about it. With stuff like this you're always limited in what you can do by the individual application.

Incidentally, the interprocess messaging itself is relative cheap on OS X; the main performance hit tends to be the time taken by applications to evaluate references and perform commands. Lots of opportunities for inefficient algorithms to burn cycles; amalgamating many operations into one simply minimises the amount of waste.


>In my iTunes scripts, I do this by generating a big
>filter:
>
>  # fast version
>  dids = [168, 142, 57, 39, 277, ...]
>  idfilters = [(its.database_ID == did) for did in
>dids]
>  idfilter = idfilters[0]
>  for f in idfilters[1:]:
>    idfilter = idfilter.OR(f)
>  trackrefs = library.file_tracks.filter(idfilter)
>  names = trackrefs.name()
>
>Is there an easier way to get all the names in a
>single IPC call?

Not that I can think of. The obvious thing would be to say:

	trackrefs = library.file_tracks.filter(its.database_ID.isin(dids))

but iTunes isn't smart enough to understand the isin() in that filter test, so I think you're stuck with your multiple equality tests.

Another technique is to grab all the IDs with one command and all names/whatever with another, then filter one against the other in Python; what's quicker will depend on the amount of data involved.


>(Also, is there a way I can filter on
>the ID instead of having the fetch and keep around the
>database_ID for everything?)

While iTunes likes to use by-ID specifiers, it makes it damnably hard to get the ID numbers used. Its dictionary doesn't show an 'id' property on any of its classes, although an undocumented one does appear to exist. Feel free to file a bug report on this - it causes problems for AppleScript as well as appscript.

To deal with missing terminology in Python, you either use appscript.dump to output the keyword-code translation tables to an external module and patch that by hand, or else drop into aem to build at least part of the reference using raw codes:

itunes = app('iTunes')
tracksRef = itunes.playlists[1].tracks
trackIDsRef = tracksRef.AS_objspec.property('ID  ')
ids = itunes.get(trackIDsRef)
print ids


>Here's what I'm doing this for: My other Mac has the
>whole library on shuffle, and I hear something and
>think, "Wow, what was that song?" So I do this:
>
>  $ ssh emac
>  $ iwhat `ilast 3`
>[...]

Nice.

HTH

has
-- 
http://freespace.virgin.net/hamish.sanderson/


More information about the Pythonmac-SIG mailing list