Scripting Palm Desktop in Leopard

I know that Palm Desktop is getting old, and now with Intel Macs running Leopard, I have discovered a few of my Applescripts no longer function. I whipped up a nifty script last year to select certain categories on my Palm to generate Christmas Card lists for my wife, and it no longer functions due to this single (currently dysfunctional) handler:

set addr_counts to {}
	tell application "Palm Desktop"
		set a to every category
		repeat with an_cat in a
			set the_cat_id to category id (an_cat's id) --For searching, need to set the category id to a variable
			set cat_addr_count to (count (every address whose primary category is the_cat_id))--<<<<<Here is where the script fails
			if cat_addr_count ≠ 0 then
				set end of addr_counts to {(an_cat's id), (an_cat's name), cat_addr_count}
			end if
		end repeat
	end tell
	return addr_counts

Every address in Palm Desktop has a Primary Category assignation property, that looks like this:

tell application "Palm Desktop"
	address 666's primary category
end tell
-->category id 36 of application "Palm Desktop"

The problem has always been to go from a list of category properties, get their names and ids so you could choose the correct ones, and then go back to the property for searching the database. For instance, a list of categories looks like this:

tell application "Palm Desktop"
	every category
end tell
-->{category id 52 of application "Palm Desktop", category id 58 of application "Palm Desktop", category id 54 of application "Palm Desktop", category id 37 of application "Palm Desktop", category id 59 of application "Palm Desktop", category id 57 of application "Palm Desktop", category id 46 of application "Palm Desktop", category id 48 of application "Palm Desktop", category id 55 of application "Palm Desktop", category id 39 of application "Palm Desktop", category id 51 of application "Palm Desktop", category id 60 of application "Palm Desktop", category id 41 of application "Palm Desktop", category id 47 of application "Palm Desktop", category id 36 of application "Palm Desktop", category id 53 of application "Palm Desktop", category id 45 of application "Palm Desktop", category id 49 of application "Palm Desktop", category id 42 of application "Palm Desktop", category id 40 of application "Palm Desktop", category id 56 of application "Palm Desktop", category id 43 of application "Palm Desktop", category id 50 of application "Palm Desktop"}

Each category has a few properties:

tell application "Palm Desktop"
	properties of category id 36 of application "Palm Desktop"
end tell

-->{name:"Personal", color index:1, class:category, id:36}

But, as outlined above, the address records do not simply use the category id number, but rather that irritating category id 36 of application “Palm Desktop”, so one cannot simply script any of these (Error is -1723 - Can’t get . Access not allowed.):

tell application "Palm Desktop"
	every address whose primary category's name = "Boy Scouts"
end tell
-->Palm Desktop got an error: Can't get every address whose name of primary category = "Boy Scouts". Access not allowed.
tell application "Palm Desktop"
	every address whose primary category's id = 52
end tell
-->Palm Desktop got an error: Can't get every address whose id of primary category = 52. Access not allowed.

What used to work was to allow the user to choose a category name, then go back and assign a variable to the category property of the selected name, then get the addresses of that category, using the property value. The handler above simply created a 3 item list of category id, category name, and then number of addresses in each category, which then went to a table for selection. Now, not even this works (The error generated is -1728 - Can’t get .):

tell application "Palm Desktop"
	every address whose primary category is category id 36 of application "Palm Desktop"
end tell

-->Palm Desktop got an error: Can't get every address whose primary category = category id 36 of application "Palm Desktop".

So, anyway, I know that Palm Desktop is old, is a Carbon application, and has practically no future. But I really like it, and for me, there is nothing comparable out there. (iPhone’s Address Book is nowhere near as robust as the standard desktop Address Book, not to mention the Palm.) I know that very few of you have ever scripted Palm Desktop, but if you have some time to look into this, I would appreciate it. The latest version I use is for the Tungsten E2 (4.2.1) and is available for download here. So far, these are the only scripts I have found that simply do not function within Leopard. I had a few other scripts (not Palm Desktop) that were slightly different, but the issues were easily resolved.

As always, any advice or recommendations are appreciated.

I an not running Leopard, but some of my results were similar to yours, so maybe you will find the last bit of code useful. I have neither written nor run AppleScript for Palm Desktop before, but since I have it installed I played with it a bit. I have Palm Desktop 4.2.2 and I am running it under Mac OS X 10.4.11 on a PPC system.

Category access seems relatively sane here:

tell application "Palm Desktop"
	get every category --> (* a list of category objects: {category id 40 of application "Palm Desktop", .} *)
	set persCatName to "Personal"
	get every category whose name is persCatName --> (* a  list of just one category object: {category id 4 of application "Palm Desktop"} *)
	set persCat to first item of result --> category id 4 of application "Palm Desktop"
	persCatName is name of persCat --> true
	set persCatId to id of persCat --> 4
	persCat is category id persCatId --> true
	persCat is category persCatName --> true
	category id persCatId is category persCatName --> true
	
	-- Access by index is not the same as access by id
	category persCatId is category id persCatId --> false
	category persCatId --> category id 20 of application "Palm Desktop"
end tell

My results for fetching addresses with a filter reference form are similar, but not identical to yours:

tell application "Palm Desktop"
	try
		every address whose primary category's name = persCatName
	on error m
		log "ERROR 1: " & m
		(*ERROR 1: Palm Desktop got an error: Can't get every address whose name of primary category = "Personal".*)
	end try
	try
		every address whose primary category's id = persCatId
	on error m
		log "ERROR 2: " & m
		(*ERROR 2: Palm Desktop got an error: Can't get every address whose id of primary category = 4.*)
	end try
	try
		every address whose primary category is category id persCatId
	on error m
		log "ERROR 3: " & m
		(*ERROR 3: Palm Desktop got an error: Invalid key form.*)
	end try
	try
		every address whose primary category = category persCatName
	on error m
		log "ERROR 4: " & m
		(*ERROR 4: Class has no elements of this type*)
	end try
	try
		every address whose primary category = persCat
	on error m
		log "ERROR 5: " & m
		(*ERROR 5: Palm Desktop got an error: Can't get every address whose primary category = category id 4 of application "Palm Desktop".*)
	end try
end tell

None of them work, but some of them fail in the same way. On a whim, I tried first instead of every:

tell application "Palm Desktop"
	try
		first address whose primary category's name = persCatName
		--> address id 40 of application "Palm Desktop"
	on error m
		log "ERROR 6: " & m
	end try
	try
		first address whose primary category's id = persCatId
		--> address id 40 of application "Palm Desktop"
	on error m
		log "ERROR 7: " & m
	end try
	try
		first address whose primary category is category id persCatId
	on error m
		log "ERROR 8: " & m
		(*ERROR 8: Palm Desktop got an error: Invalid key form.*)
	end try
	try
		first address whose primary category = category persCatName
	on error m
		log "ERROR 9: " & m
		(*ERROR 9: Class has no elements of this type*)
	end try
	try
		first address whose primary category = persCat
		--> address id 40 of application "Palm Desktop"
	on error m
		log "ERROR 10: " & m
	end try
end tell

It seems that 6, 7, and 10 worked OK to fetch the first address from my “Personal” category. I do not know why first works even though every fails, but it is not the first time I have seen odd results from filter reference forms.

Here is another head scratcher:

tell application "Palm Desktop"
	set x to category "Personal"
	try
		first address whose primary category = result
	on error m
		log "ERROR 11: " & m
		(*ERROR 11: Can't get primary category whose it = category id 4 of application "Palm Desktop". Access not allowed.*)
	end try
	first address whose primary category = x --> address id 40 of application "Palm Desktop"
end tell

Anyway, since indexed filter references work, we can make up our own count routine and plow through them by hand. It will be slow, but maybe it will work for you:

to indirectCount(a, c)
	-- For some reason, we can not use count with filter references, but we can use indexed filter references.
	-- We will do a binary search to find the last valid index.
	set bottom to 1
	set probe to 4
	set top to missing value -- (count addresses) could be a maximum, but it probably isn't too useful as one
	
	set growth to 20
	set growing to true
	
	repeat
		if a's checkIndexInCategory(probe, c) then
			if probe + 1 = top then return probe
			set bottom to probe
			if growing then
				set probe to probe + growth
			else
				set probe to (bottom + top) div 2
			end if
		else
			if probe = 1 then return 0
			set growing to false
			set top to probe
			set probe to (bottom + top) div 2
		end if
	end repeat
end indirectCount

to countAddrs(c)
	script
		to checkIndexInCategory(i, c)
			tell application "Palm Desktop" to exists (address i whose primary category is c)
		end checkIndexInCategory
	end script
	indirectCount(result, c)
end countAddrs

set addr_counts to {}
tell application "Palm Desktop"
	set a to every category
	repeat with an_cat in a
		set the_cat to contents of an_cat
		set cat_addr_count to my countAddrs(the_cat)
		if cat_addr_count ≠ 0 then
			set end of addr_counts to {the_cat's id, the_cat's name, cat_addr_count}
		end if
	end repeat
end tell
return addr_counts

Model: iBook G4 933
AppleScript: 1.10.7
Browser: Safari 3.0.4 (523.12)
Operating System: Mac OS X (10.4)

chrys:

Great stuff!! Thank you for taking the time to look into that and for your suggestions/observations. I have a G4 iBook at home that also has Leopard installed, so I played a bit with it last night when I got home, and the most amazing thing was that most of my old code actually functioned correctly! I did not have time to test everything, but so far, at least with my version (I need to see if I can get 4.2.2) there seems to be some sort of underlying chipset issue, which makes no sense to me.

I will report back here in a few days (or weeks) with my findings.