Spotlight Searching in Python - Mac OSX

C

cjstevens

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!
 
D

Diez B. Roggisch

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!


I can only imagine that you need an event-loop to make notifications
work. That's usually needed under OS X.

Diez
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top