Back to index

plone3  3.1.7
seeker.py
Go to the documentation of this file.
00001 from Products.AdvancedQuery import Eq, Generic
00002 from Products.CMFCore.utils import getToolByName
00003 from wicked.interfaces import IWickedQuery, IAmWicked
00004 from wicked.utils import memoizedproperty, memoize, match, packBrain, cleanUID
00005 from zope.interface import implements
00006 from zope.component import adapts
00007 
00008 
00009 _marker = object()
00010 class AdvQueryMatchingSeeker(object):
00011     """
00012     An advanced query specific 
00013     CMFish catalog query handler
00014     """
00015     implements(IWickedQuery)
00016     adapts(IAmWicked)
00017 
00018     chunk = _marker
00019     normalled = _marker
00020     scope = _marker
00021     
00022     def __init__(self, context):
00023         self.context = context
00024         self.catalog = getToolByName(context, 'portal_catalog')
00025         self.path = '/'.join(context.aq_inner.aq_parent.getPhysicalPath())    
00026         self.evalQ = self.catalog.evalAdvancedQuery
00027 
00028     def configure(self, chunk, normalled, scope):
00029         self.chunk = chunk
00030         self.normalled = normalled
00031         self.scope = scope
00032 
00033     def _query(self, query, sort=('created',)):
00034         if sort:
00035             return self.evalQ(query, sort)
00036         else:
00037             return self.evalQ(query)
00038 
00039     def queryUIDs(self, uids):
00040         return self._query(Generic('UID', uids), sort=None)
00041 
00042     @property
00043     def scopedQuery(self):
00044         chunk, title = self.chunk, self.title
00045         query = (Eq('getId', chunk) | Eq('Title', title))
00046         if not self.scope is _marker:
00047             # XXX let's move this out of attr storage
00048             # on the content to at least an annotation
00049             scope = getattr(self.context, self.scope, self.scope)
00050             if callable(scope):
00051                 scope = scope()
00052             if scope:
00053                 query = Generic('path', scope) & query
00054         return query
00055 
00056     @property
00057     def basicQuery(self):
00058         chunk, normalled = self.chunk, self.normalled
00059         getId = chunk
00060         self.title = title = '"%s"' % chunk
00061         query = Generic('path', {'query': self.path, 'depth': -1}) \
00062                 & (Eq('getId', chunk) | Eq('Title', title) | Eq('getId', normalled))
00063         return query
00064 
00065     @property
00066     @match
00067     def scopedSearch(self):
00068         return self._query(self.scopedQuery)
00069 
00070     @property
00071     @match
00072     def search(self):
00073         return self._query(self.basicQuery)
00074 
00075     def _aggquery(self, name, query):
00076         curr = getattr(self, name, _marker)
00077         if curr is _marker:
00078             curr = query
00079         else:
00080             curr |= query
00081         setattr(self, name, curr)
00082         return curr
00083 
00084     @property
00085     def bquery(self):
00086         return self._aggquery('_bquery', self.basicQuery)
00087 
00088     @property
00089     def squery(self):
00090         return self._aggquery('_squery', self.scopedQuery)
00091 
00092     # memo prevents dups
00093     @memoize 
00094     def aggregate(self, link, normalled, scope):
00095         """
00096         builds aggregated queries for scoped and basic
00097         """
00098         self.configure(link, normalled, scope)
00099         self.bquery 
00100         self.squery 
00101 
00102     @memoizedproperty
00103     def agg_brains(self):
00104         """
00105         aggregregate search returns
00106         """
00107         return list(self._query(self._bquery))
00108 
00109     @memoizedproperty
00110     def agg_scoped_brains(self):
00111         """
00112         aggregregate search returns
00113         """
00114         return list(self._query(self._squery))
00115 
00116     __call__ = _query