Spotlight Searching in Python - Mac OSX

cjstevens at gmail.com cjstevens at gmail.com
Mon Sep 8 01:19:57 EDT 2008


Hi all, I'm having some issues getting a spotlight search to work
similar to the program demonstrated here:
http://pyobjc.sourceforge.net/examples/pyobjc-framework-Cocoa/AppKit/PredicateEditorSample/


Here is my class, complete with the code I am trying to use it with at
the end.


import objc, sys, os, osax, time
from Foundation import *
from ScriptingBridge import *
from appscript import *


class SystemBridge(NSObject):
	"""Class to use the scripting bridge to interact with the system"""
	_hideapp = objc.ivar(u"hideapp")
	_volume = objc.ivar(u"volume")
	_filename = objc.ivar(u"filename")
	_filetype = objc.ivar(u"filetype")
	_auth = objc.ivar(u"auth")
	_logout = objc.ivar(u"logout")
	query = objc.ivar(u"query")
	StdAdditions = osax.ScriptingAddition()

	def init(self):
		super(SystemBridge, self).init()
	        # create and initalize our query
        	self.query = NSMetadataQuery.alloc().init()

        	# setup our Spotlight notifications
        	nf = NSNotificationCenter.defaultCenter()
        	nf.addObserver_selector_name_object_(self,
'queryNotification:', None, self.query)



        	# XXX: this framework isn't wrapped yet!
 
self.query.setSortDescriptors_([NSSortDescriptor.alloc().initWithKey_ascending_('kMDItemDisplayName',
True)])
        	self.query.setDelegate_(self)



		return self

	def hideApplication_(self, _hideapp):
		app(u'System Events').processes[_hideapp].visible.set(False)

    	def loadResultsFromQuery_(self, notif):
       		results = notif.object().results()

        	NSLog("search count = %d", len(results))

        	# iterate through the array of results, and match to the
existing stores
        	for item in results:
            		nameStr = item.valueForAttribute_('kMDItemDisplayName')
			print nameStr


    	def queryNotification_(self, note):
        # the NSMetadataQuery will send back a note when updates are
happening.
        # By looking at the [note name], we can tell what is happening
        	if note.name() ==
NSMetadataQueryDidStartGatheringNotification:
            # the query has just started
            		NSLog("search: started gathering")


        	elif note.name() ==
NSMetadataQueryDidFinishGatheringNotification:
            # at this point, the query will be done. You may recieve
an update
            # later on.
           		NSLog("search: finished gathering");
            		self.loadResultsFromQuery_(note)

        	elif note.name() ==
NSMetadataQueryGatheringProgressNotification:
            # the query is still gathering results...
            		NSLog("search: progressing...")

        	elif note.name() == NSMetadataQueryDidUpdateNotification:
            # an update will happen when Spotlight notices that a file
as
            # added, removed, or modified that affected the search
results.
            		NSLog("search: an update happened.")


    	def spotlightFriendlyPredicate_(self, predicate):
        	if predicate == NSPredicate.predicateWithValue_(True) or
predicate == NSPredicate.predicateWithValue_(False):
            		return False

        	elif isinstance(predicate, NSCompoundPredicate):

            		type = predicate.compoundPredicateType()
            		cleanSubpredicates = []
            		for dirtySubpredicate in predicate.subpredicates():
                		cleanSubpredicate =
self.spotlightFriendlyPredicate_(
                    			dirtySubpredicate)
                		if cleanSubpredicate:
                    			cleanSubpredicates.append(cleanSubpredicate)

            		if len(cleanSubpredicates) == 0:
                		return None

            		else:
                		if len(cleanSubpredicates) == 1 and type !=
NSNotPredicateType:
                    			return cleanSubpredicates[0]

                		else:
                    			return
NSCompoundPredicate.alloc().initWithType_subpredicates_(type,
cleanSubpredicates)

        	else:
            		return predicate

	def createNewSearchForPredicate_(self, predicate):

            	# Format search file type
            	thePredicate = NSPredicate.predicateWithFormat_(
                	"(kMDItemContentType =
'com.apple.iwork.keynote.key')")
            	tempPredicate = NSPredicate.predicateWithFormat_(
                	"(kMDItemDisplayName IN[c] 'preso')")
		predicate = NSCompoundPredicate.andPredicateWithSubpredicates_(
                	[thePredicate, tempPredicate])


            	self.query.setPredicate_(predicate)
            	self.query.startQuery()


	def changeVolume_(self, setvolume):
		self.StdAdditions.set_volume(output_volume=setvolume)

	def getVolume_(self):
		return StdAdditions.get_volume_settings()[k.output_volume]


_x = SystemBridge.alloc().init()

#predicate = u"kMDItemDisplayName IN[c] 'preso'"
#predicate = _x.spotlightFriendlyPredicate_(predicate)
if predicate is not None:
	_x.createNewSearchForPredicate_(predicate)




As you can see, I am trying to use a notifier just like the example
linked above. The class does not work as expected, and just displays
"search: started gathering", none of the other notifier events happen
at all!

Have I missed something out translating this to PyObjC? The weird
thing is, most of that code is straight from the example which works
fine, so I can't figure out why mine won't work! Any help would be
hugely appreciated, I need to get this finished soon!



More information about the Python-list mailing list