I'm trying to mod a python script that reads the OS X Dock plist. I've never seen python code before this and I can't seem to figure out if I'm encountering a formatting error or a syntax error or both...

Here is the original code snippet, which returns a formatted list of items in the Dock;

# since we are only reading the plist, make a copy before converting it to be read
            os.system('cp '+plist_path+' /tmp/com.patternbuffer.dockutil.tmp.plist')
            pl = plistFromPath('/tmp/com.patternbuffer.dockutil.tmp.plist')
            # print a tab separated line for each item in the plist
            # for each section
            for section in ['persistent-apps', 'persistent-others']:
                # for item in section
                for item in pl[section]:
                    try:
            	# join and print relevant data into a string separated by tabs
                        print '\t'.join((item['tile-data']['file-label'], item['tile-data']['file-data']['_CFURLString'], section, plist_path))
                    except:
                        pass
            # clean up temp file
            try:
                os.remove('/tmp/com.patternbuffer.dockutil.tmp.plist')
            except:
                pass

This works but does not include an entry for Dashboard, Yes, I know Dashboard does not have a standard entry in the plist, but does have the placeholder label 'dashboard-tile'. pl is an array of strings and print outputs a formatted string of values.

Can anybody show me how to test for the string 'dashboard-tile' and then print 'Dashboard' so it will be included in the list of items returned using the above code? It will always be be in 'persistent-apps' and should be in one of the strings in pl. It may not always be the first item (after the Finder).

Recommended Answers

All 7 Replies

Litle help...

for item in pl[section]:
    if item.has_key('dashboard-tile'):
        try:
            print '\t'.join((item['tile-data']['file-label'], item['tile-data']['file-data']['_CFURLString'], item['tile-data']['dashboard-tile'], section, plist_path))

Cheers and Happy coding

Thanks for the reply Beat_Slayer...

While I'm completely unfamiliar with Python, I can read code, and I don't think your example will work. Maybe I was unclear or maybe your not familiar with OS X...

Here is what item contains for Dashboard in the plist;

Dict(**{'tile-data': Dict(**{'file-label': ''}), 'tile-type': 'dashboard-tile'})

The Dashboard item does not contain the normal key/value pairs that the rest of the plist contains. It only is a placeholder in the plist as Dashboard is actually placed in the Dock by hard coding.

I need something like this;

for item in pl[section]:
            	        try:
            	    	if item.find('dashboard-tile',0) !0:
            	        	print "Dashboard" # dont need other values because there are none
            	        else:
            	            	print '\t'.join((item['tile-data']['file-label'], item['tile-data']['file-data']['_CFURLString'], item['tile-data']['dashboard-tile'], section, plist_path))

Variations of this have produced syntax errors, indent errors, or returns no data at all.

Yeah, I've no OS X experience.

Why don't you paste here the full plist? It would get easier.

For the correction, maybe:

for item in pl[section]:
    try:
      	if item.find('dashboard-tile') != -1:
       	    print "Dashboard" # dont need other values because there are none
        else:
            print '\t'.join((item['tile-data']['file-label'], item['tile-data']['file-data']['_CFURLString'], section, plist_path))

EDIT: Look what I've just found. plistlib — Generate and parse Mac OS X .plist files


Cheers and Happy coding

Thanks again Beat_Slayer

Posting the plist wouldn't help because the specific block for Dashboard does not contain the same key/value dictionary as the other entries and is completely nonstandard. Apple does some goofy things some time and this is the case with my problem.

Yeah, I saw that mistake right after I posted... It should be -1, I was writing by hand and not pasting in code.

I also looked at plistlib. This handles standard plist dict value pairs. But as I stated Apple is doing something very nonstandard here. So plistlib will fail just like the script I have does.

I did find that I can put print "Dashboard" in the exception block and I get the list I'm looking for. But I don't know what else might cause an exception error also so I can not rely on that as a proper workaround.

So other than checking for a wrong value from find do you see any other issues with my snippet above. I'm still getting syntax errors. You should know I'm editing by hand in a simple text editor and not using anything appropriate that would probably format the code properly.

And like this?

for item in pl[section]:
    if item.find('dashboard-tile') != -1:
        print "Dashboard" # dont need other values because there are none
        print '\t'.join((item['tile-data']['file-label'], item['tile-data']['file-data']['_CFURLString'], item['tile-data']['dashboard-tile'], section, plist_path))
    else:
        print '\t'.join((item['tile-data']['file-label'], item['tile-data']['file-data']['_CFURLString'], section, plist_path))

If you post your present code, I can do some clean up.

Cheers and Happy coding

Thank you for sticking with me on this...

After four hours of trial an error I was able to run without encountering an error in the code. The output I expected was a list of items from the Dock. Instead I got nothing... So I uncommented my print "Dashboard" line in the exception block and I got a list of all Dashboards. By the way, I don't need your line #4, but the rest is what I have now. The try seems to be failing and I'm guessing it tests for a valid dictionary entry? Since the condition is either -1 or not -1, I don't understand why this should throw an exception for all conditions. But Python is still a mystery to me.

I guess my solution is to put the if condition in the exception block. I've proven that the Dashboard entry throws the exception, so checking for dashboard-tile will satisfy my needs, i guess. So, how does Python end a conditional block? I don't see an endif.

Well, I've certainly learned quite a bit about Python in the last two days...

items in pl are dictionaries and not strings as I thought. Item.find produced an error because it was not a string. Using get seems to work and I may be able to place the condition back in the try block.

Here's my solution. Please post any corrections you may find in my code.

for item in pl[section]:
                    try:
            	# join and print relevant data into a string separated by tabs
                       	    print '\t'.join((item['tile-data']['file-label'], item['tile-data']['file-data']['_CFURLString'], section, plist_path))
                    except:
            		if item.get('tile-type') == 'dashboard-tile':
                            print "Dashboard"
                        pass
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.