Commit 79119142 authored by Vincent Pelletier's avatar Vincent Pelletier

CatalogTool: Split getCategoryParameterDict in 2

One part working on {base_category_id: [document_value_set]}, and the other
producing that structure out of a flat list of (base_category_id-prefixed)
category relative urls.
The former used to be included in the latter, but in some case caller
already has the documents handy instead of only urls, in which case we can
avoid a layer of document lookups.
parent 06af6169
...@@ -1056,14 +1056,17 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject): ...@@ -1056,14 +1056,17 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
) )
return related_key_list return related_key_list
security.declarePublic('getCategoryParameterDict') security.declarePublic('getCategoryValueDictParameterDict')
def getCategoryParameterDict(self, category_list, category_table='category', strict_membership=True, forward=True, onMissing=lambda category: True): def getCategoryValueDictParameterDict(self, base_category_dict, category_table='category', strict_membership=True, forward=True):
""" """
From a list of categories, produce a catalog keyword argument dictionary From a mapping from base category ids to lists of documents, produce a
testing (strict or not, forward or reverse relation) membership to these catalog keyword argument dictionary testing (strict or not, forward or
categories. reverse relation) membership to these documents with their respective
base categories.
category_list (list of category relative urls with their base categories)
base_category_dict (dict with base category ids as keys and document lists
as values)
Note: mutated by this method.
category_table ('category' or 'predicate_category') category_table ('category' or 'predicate_category')
Controls the table to use for membership lookup. Controls the table to use for membership lookup.
strict_membership (bool) strict_membership (bool)
...@@ -1072,12 +1075,6 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject): ...@@ -1072,12 +1075,6 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
forward (bool) forward (bool)
Whether document being looked up bears the relation (true) or is its Whether document being looked up bears the relation (true) or is its
target (false). target (false).
onMissing (callable)
Called for each category which does not exist.
Receives faulty relative url as "category" argument.
False return value skips the entry.
True return value causes a None placeholder to be inserted.
Raised exceptions will propagate.
Return a dictionnary whose keys are catalog parameter names and values Return a dictionnary whose keys are catalog parameter names and values
are sets of uids. are sets of uids.
...@@ -1091,26 +1088,49 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject): ...@@ -1091,26 +1088,49 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
flag_list.append('strict') flag_list.append('strict')
prefix = ('_'.join(flag_list) + '__') if flag_list else '' prefix = ('_'.join(flag_list) + '__') if flag_list else ''
suffix = ('' if forward else '__related') + '__uid' suffix = ('' if forward else '__related') + '__uid'
base_category_dict = {}
portal_categories = self.getPortalObject().portal_categories
getBaseCategoryId = portal_categories.getBaseCategoryId
getCategoryUid = portal_categories.getCategoryUid
for relative_url in category_list:
category_uid = getCategoryUid(relative_url)
if category_uid is not None or onMissing(category=relative_url):
base_category_dict.setdefault(
getBaseCategoryId(relative_url),
set(),
).add(category_uid)
parent_uid_set = base_category_dict.pop('parent', None) parent_uid_set = base_category_dict.pop('parent', None)
base_category_uid_dict = {
base_category_id: {document.getUid() for document in document_set}
for base_category_id, document_set in base_category_dict.iteritems()
}
result = { result = {
prefix + x + suffix: y prefix + x + suffix: y
for x, y in base_category_dict.iteritems() for x, y in base_category_uid_dict.iteritems()
} }
if parent_uid_set is not None: if parent_uid_set is not None:
result['parent_uid'] = parent_uid_set result['parent_uid'] = parent_uid_set
return result return result
security.declarePublic('getCategoryParameterDict')
def getCategoryParameterDict(self, category_list, onMissing=lambda category: True, **kw):
"""
From a list of categories, produce a catalog keyword argument dictionary
testing (strict or not, forward or reverse relation) membership to these
categories.
category_list (list of category relative urls with their base categories)
onMissing (callable)
Called for each category which does not exist.
Receives faulty relative url as "category" argument.
False return value skips the entry.
True return value causes a None placeholder to be inserted.
Raised exceptions will propagate.
Other arguments & return value: see getCategoryValueDictParameterDict.
"""
base_category_dict = defaultdict(set)
portal_categories = self.getPortalObject().portal_categories
getBaseCategoryId = portal_categories.getBaseCategoryId
getCategoryValue = portal_categories.getCategoryValue
for relative_url in category_list:
category_uid = getCategoryValue(relative_url)
if category_uid is not None or onMissing(category=relative_url):
base_category_dict[getBaseCategoryId(relative_url)].add(category_uid)
return self.getCategoryValueDictParameterDict(
base_category_dict,
**kw
)
def _aq_dynamic(self, name): def _aq_dynamic(self, name):
""" """
Automatic related key generation. Automatic related key generation.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment