Back to index

plone3  3.1.7
queryCatalog.py
Go to the documentation of this file.
00001 ## Script (Python) "queryCatalog"
00002 ##bind container=container
00003 ##bind context=context
00004 ##bind namespace=
00005 ##bind script=script
00006 ##bind subpath=traverse_subpath
00007 ##parameters=REQUEST=None,show_all=0,quote_logic=0,quote_logic_indexes=['SearchableText','Description','Title'],use_types_blacklist=False,show_inactive=False,use_navigation_root=False
00008 ##title=wraps the portal_catalog with a rules qualified query
00009 ##
00010 from ZODB.POSException import ConflictError
00011 from Products.ZCTextIndex.ParseTree import ParseError
00012 from Products.CMFCore.utils import getToolByName
00013 from Products.CMFPlone.browser.navtree import getNavigationRoot
00014 
00015 results=[]
00016 catalog=context.portal_catalog
00017 indexes=catalog.indexes()
00018 query={}
00019 show_query=show_all
00020 second_pass = {}
00021 
00022 if REQUEST is None:
00023     REQUEST = context.REQUEST
00024 
00025 def quotestring(s):
00026     return '"%s"' % s
00027 
00028 def quotequery(s):
00029     if not s:
00030         return s
00031     try:
00032         terms = s.split()
00033     except ConflictError:
00034         raise
00035     except:
00036         return s
00037     tokens = ('OR', 'AND', 'NOT')
00038     s_tokens = ('OR', 'AND')
00039     check = (0, -1)
00040     for idx in check:
00041         if terms[idx].upper() in tokens:
00042             terms[idx] = quotestring(terms[idx])
00043     for idx in range(1, len(terms)):
00044         if (terms[idx].upper() in s_tokens and
00045             terms[idx-1].upper() in tokens):
00046             terms[idx] = quotestring(terms[idx])
00047     return ' '.join(terms)
00048 
00049 # We need to quote parentheses when searching text indices (we use
00050 # quote_logic_indexes as the list of text indices)
00051 def quote_bad_chars(s):
00052     bad_chars = ["(", ")"]
00053     for char in bad_chars:
00054         s = s.replace(char, quotestring(char))
00055     return s
00056 
00057 def ensureFriendlyTypes(query):
00058     ploneUtils = getToolByName(context, 'plone_utils')
00059     portal_type = query.get('portal_type', [])
00060     if not same_type(portal_type, []):
00061         portal_type = [portal_type]
00062     Type = query.get('Type', [])
00063     if not same_type(Type, []):
00064         Type = [Type]
00065     typesList = portal_type + Type
00066     if not typesList:
00067         friendlyTypes = ploneUtils.getUserFriendlyTypes(typesList)
00068         query['portal_type'] = friendlyTypes
00069 
00070 def rootAtNavigationRoot(query):
00071     if 'path' not in query:
00072         query['path'] = getNavigationRoot(context)
00073 
00074 # Avoid creating a session implicitly.
00075 for k in REQUEST.keys():
00076     if k in ('SESSION',):
00077         continue
00078     v = REQUEST.get(k)
00079     if v and k in indexes:
00080         if k in quote_logic_indexes:
00081             v = quote_bad_chars(v)
00082             if quote_logic:
00083                 v = quotequery(v)
00084         query[k] = v
00085         show_query = 1
00086     elif k.endswith('_usage'):
00087         key = k[:-6]
00088         param, value = v.split(':')
00089         second_pass[key] = {param:value}
00090     elif k in ('sort_on', 'sort_order', 'sort_limit'):
00091         if k == 'sort_limit' and not same_type(v, 0):
00092             query[k] = int(v)
00093         else:
00094             query[k] = v
00095 
00096 for k, v in second_pass.items():
00097     qs = query.get(k)
00098     if qs is None:
00099         continue
00100     query[k] = q = {'query':qs}
00101     q.update(v)
00102 
00103 # doesn't normal call catalog unless some field has been queried
00104 # against. if you want to call the catalog _regardless_ of whether
00105 # any items were found, then you can pass show_all=1.
00106 if show_query:
00107     try:
00108         if use_types_blacklist:
00109             ensureFriendlyTypes(query)
00110         if use_navigation_root:
00111             rootAtNavigationRoot(query)
00112         query['show_inactive'] = show_inactive
00113         results = catalog(**query)
00114     except ParseError:
00115         pass
00116 
00117 return results