def _get_due(self, value=None): if value is None: value = getattr(self.context, 'due', None) if not value: taskplanner = self._get_taskplanner(self.context) if taskplanner: value = getattr(taskplanner, 'due', None) if not value: return _type = value.get('type') _value = value.get('value') if _type == 'date': return parse_datetime(_value) elif _type == 'computed': field4 = getattr(self.context, _value['field4']) if not field4: return field3 = self._get_value(_value['field3'], TIME_RELATIONS)[2] if safe_callable(field4): field4 = field4() if isinstance(field4, DateTime): field4 = pydt(field4) if field3 is None: return field4 else: field2 = self._get_value(_value['field2'], TIME_UNITS)[2] field1 = int(_value['field1']) return field4 + field2(field3 * field1) elif _type == 'computed_dow': field4 = getattr(self.context, _value['field4']) if not field4: return field3 = self._get_value(_value['field3'], TIME_RELATIONS)[2] if safe_callable(field4): field4 = field4() if isinstance(field4, DateTime): field4 = pydt(field4) if field3 is None: return field4 else: field2 = self._get_value(_value['field2'], DAYS_OF_WEEK)[2] field1 = int(_value['field1']) return field4 + field2(field3 * field1)
def updateTranslatedPaths(obj, path=None): if (base_hasattr(obj, 'indexObject') and safe_callable(obj.indexObject) and base_hasattr(obj, 'getPhysicalPath') and safe_callable(obj.getPhysicalPath)): try: path = '/'.join(obj.getPhysicalPath()) catalog._catalog.updateTanslatedPaths(obj, path) results.append('Updated %s' % path) transaction.commit() except: pass
def sortable_title(instance): """Uses the default Plone sortable_text index lower-case """ title = plone_sortable_title(instance) if safe_callable(title): title = title() return title.lower()
def toFieldValue(self, value): """Converts from widget value to field. :param value: Value inserted by datetime widget. :type value: string :returns: `datetime.datetime` object. :rtype: datetime """ if not value: return self.field.missing_value tmp = value.split(' ') if not tmp[0]: return self.field.missing_value value = tmp[0].split('-') if len(tmp) == 2 and ':' in tmp[1]: value += tmp[1].split(':') else: value += ['00', '00'] # TODO: respect the selected zone from the widget and just fall back # to default_zone default_zone = self.widget.default_timezone zone = default_zone(self.widget.context)\ if safe_callable(default_zone) else default_zone ret = datetime(*map(int, value)) if zone: tzinfo = pytz.timezone(zone) ret = tzinfo.localize(ret) return ret
def _getNavQuery(self): context = self.context navtree_properties = self.navtree_properties customQuery = getattr(context, 'getCustomNavQuery', False) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} rootPath = getNavigationRoot(context) query['path'] = {'query': rootPath, 'depth': 1} blacklist = navtree_properties.getProperty('metaTypesNotToList', ()) all_types = self.portal_catalog.uniqueValuesFor('portal_type') query['portal_type'] = [t for t in all_types if t not in blacklist] sortAttribute = navtree_properties.getProperty('sortAttribute', None) if sortAttribute is not None: query['sort_on'] = sortAttribute sortOrder = navtree_properties.getProperty('sortOrder', None) if sortOrder is not None: query['sort_order'] = sortOrder if navtree_properties.getProperty('enable_wf_state_filtering', False): query['review_state'] = navtree_properties.getProperty( 'wf_states_to_show', []) query['is_default_page'] = False if self.site_properties.getProperty('disable_nonfolderish_sections', False): query['is_folderish'] = True return query
def get_pattern_options(self): portal = getToolByName(getSite(), 'portal_url').getPortalObject() ajax_url = portal.absolute_url() + '/@@json_recurrence' request = portal.REQUEST first_day = self.first_day first_day = first_day() if safe_callable(first_day) else first_day params = dict( ajaxContentType='application/x-www-form-urlencoded; charset=UTF-8', ajaxURL=ajax_url, firstDay=first_day, hasRepeatForeverButton=self.show_repeat_forever, lang=request.LANGUAGE, ributtonExtraClass='allowMultiSubmit', startField=self.startField, startFieldDay=self.startFieldDay, startFieldMonth=self.startFieldMonth, startFieldYear=self.startFieldYear, ) return json.dumps({ "locationization": translations(request), "language": request.LANGUAGE, "configuration": params })
def process_value(self, value): """Process publication value """ # UID -> ReportModel if self.is_uid(value): return self.to_report_model(value) # Content -> ReportModel elif api.is_object(value): return self.to_report_model(value) # String -> Unicode elif isinstance(value, basestring): return safe_unicode(value) # DateTime -> DateTime elif isinstance(value, DateTime): return value # Process list values elif isinstance(value, (LazyMap, list, tuple)): return map(self.process_value, value) # Process dict values elif isinstance(value, (dict)): return {k: self.process_value(v) for k, v in value.iteritems()} # Process function elif safe_callable(value): return self.process_value(value()) # Always return the unprocessed value last return value
def _getNavQuery(self): # check whether we only want actions registry = getUtility(IRegistry) navigation_settings = registry.forInterface(INavigationSchema, prefix="plone", check=False) customQuery = getattr(self.context, 'getCustomNavQuery', False) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} query['path'] = {'query': getNavigationRoot(self.context), 'depth': 1} query['portal_type'] = [t for t in navigation_settings.displayed_types] query['sort_on'] = navigation_settings.sort_tabs_on if navigation_settings.sort_tabs_reversed: query['sort_order'] = 'reverse' else: query['sort_order'] = 'ascending' if navigation_settings.filter_on_workflow: query['review_state'] = navigation_settings.workflow_states_to_show query['is_default_page'] = False if not navigation_settings.nonfolderish_tabs: query['is_folderish'] = True return query
def _get_compare_attr(obj, attr): val = getattr(obj, attr, None) if safe_callable(val): val = val() if isinstance(val, DateTime): val = pydt(val) return val
def isExpired(content): """ Find out if the object is expired (copied from skin script) """ expiry = None # NOTE: We also accept catalog brains as 'content' so that the # catalog-based folder_contents will work. It's a little # magic, but it works. # ExpirationDate should have an ISO date string, which we need to # convert to a DateTime # Try DC accessor first if base_hasattr(content, 'ExpirationDate'): expiry = content.ExpirationDate # Try the direct way if not expiry and base_hasattr(content, 'expires'): expiry = content.expires # See if we have a callable if safe_callable(expiry): expiry = expiry() # Convert to DateTime if necessary, ExpirationDate may return 'None' if expiry and expiry != 'None' and isinstance(expiry, basestring): expiry = DateTime(expiry) if isinstance(expiry, DateTime) and expiry.isPast(): return 1 return 0
def indexObject(obj, path): if (base_hasattr(obj, 'indexObject') and safe_callable(obj.indexObject)): try: obj.indexObject() annotions = IAnnotations(obj) catalog = getToolByName(obj, 'portal_catalog', None) if ANNOTATION_KEY in annotions: conversation = annotions[ANNOTATION_KEY] conversation = conversation.__of__(obj) for comment in conversation.getComments(): try: comment = comment.__of__(conversation) if catalog: catalog.indexObject(comment) except StopIteration: # pragma: no cover pass except TypeError: # Catalogs have 'indexObject' as well, but they # take different args, and will fail pass
def sortable_title(obj): """Custom sortable_title indexer for RepositoryFolders. This implementation doesn't count space needed for zero padded numbers towards the maximum length. We need this for repofolders because otherwise for deeply nested folders the reference numbers alone eat up all the available space (40 characters). """ title = getattr(obj, 'Title', None) if title is not None: if safe_callable(title): title = title() if isinstance(title, basestring): # Ignore case, normalize accents, strip spaces sortabletitle = mapUnicode(safe_unicode(title)).lower().strip() # Replace numbers with zero filled numbers sortabletitle = num_sort_regex.sub(zero_fill, sortabletitle) # Determine the length of the sortable title padded_numbers = re.findall(num_sort_regex, sortabletitle) max_length = MAX_SORTABLE_TITLE + sum([ len(match) - len(match.lstrip('0')) for match in padded_numbers ]) # Truncate to prevent bloat, take bits from start and end if len(sortabletitle) > max_length: start = sortabletitle[:(max_length - 13)] end = sortabletitle[-10:] sortabletitle = start + '...' + end return sortabletitle.encode('utf-8') return ''
def process_value(self, value): """Process publication value """ # UID -> SuperModel if api.is_uid(value): # Do not process "0" as the portal object # -> Side effect in specifications when the value is "0" if value == "0": return "0" return self.to_super_model(value) # Content -> SuperModel elif api.is_object(value): return self.to_super_model(value) # String -> Unicode elif isinstance(value, basestring): return safe_unicode(value).encode("utf-8") # DateTime -> DateTime elif isinstance(value, DateTime): return value # Process list values elif isinstance(value, (LazyMap, list, tuple)): return map(self.process_value, value) # Process dict values elif isinstance(value, (dict)): return {k: self.process_value(v) for k, v in value.iteritems()} # Process function elif safe_callable(value): return self.process_value(value()) # Always return the unprocessed value last return value
def stringify(self, value): """Convert value to string This method is used to generate a simple JSON representation of the object (without dereferencing objects etc.) """ # SuperModel -> UID if ISuperModel.providedBy(value): return str(value) # DateTime -> ISO8601 format elif isinstance(value, (DateTime)): return value.ISO8601() # Image/Files -> filename elif safe_hasattr(value, "filename"): return value.filename # Dict -> convert_value_to_string elif isinstance(value, dict): return {k: self.stringify(v) for k, v in value.iteritems()} # List -> convert_value_to_string if isinstance(value, (list, tuple, LazyMap)): return map(self.stringify, value) # Callables elif safe_callable(value): return self.stringify(value()) elif isinstance(value, unicode): value = value.encode("utf8") try: return str(value) except (AttributeError, TypeError, ValueError): logger.warn("Could not convert {} to string".format(repr(value))) return None
def _getNavQuery(self): # check whether we only want actions registry = getUtility(IRegistry) navigation_settings = registry.forInterface( INavigationSchema, prefix="plone", check=False ) customQuery = getattr(self.context, 'getCustomNavQuery', False) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} query['path'] = { 'query': getNavigationRoot(self.context), 'depth': 1 } query['portal_type'] = [t for t in navigation_settings.displayed_types] query['sort_on'] = navigation_settings.sort_tabs_on if navigation_settings.sort_tabs_reversed: query['sort_order'] = 'reverse' else: query['sort_order'] = 'ascending' if navigation_settings.filter_on_workflow: query['review_state'] = navigation_settings.workflow_states_to_show query['is_default_page'] = False if not navigation_settings.nonfolderish_tabs: query['is_folderish'] = True return query
def sortable_title(obj): """Custom sortable_title indexer for all content types. This is a copy from Products.CMFPlone.CatalogTool.sortable_title except that we overwrite MAX_SORTABLE_TITLE with SORTABLE_TITLE_LENGTH. We set set it to a high enough value to basically avoid ever cropping the title, even with number padding. This is to avoid sorting issues in content listings. """ title = getattr(obj, 'Title', None) if title is not None: if safe_callable(title): title = title() if isinstance(title, basestring): # Ignore case, normalize accents, strip spaces sortabletitle = mapUnicode(safe_unicode(title)).lower().strip() # Replace numbers with zero filled numbers sortabletitle = num_sort_regex.sub(zero_fill, sortabletitle) # Truncate to prevent bloat, take bits from start and end if len(sortabletitle) > SORTABLE_TITLE_LENGTH: start = sortabletitle[:(SORTABLE_TITLE_LENGTH - 13)] end = sortabletitle[-10:] sortabletitle = start + u'...' + end return sortabletitle.encode('utf-8') return ''
def tabular_fielddata(self, item, fieldname): """tabular_fielddata. :param item: :param fieldname: """ value = getattr(item, fieldname, '') if safe_callable(value): value = value() if fieldname in [ 'CreationDate', 'ModificationDate', 'Date', 'EffectiveDate', 'ExpirationDate', 'effective', 'expires', 'start', 'end', 'created', 'modified', 'last_comment_date']: value = self.context.toLocalizedTime(value, long_format=1) return { # 'title': _(fieldname, default=fieldname), 'value': value }
def _getNavQuery(self, rootPath=None): customQuery = getattr(self.context, 'getCustomNavQuery', False) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} if rootPath == None: rootPath = getMultiAdapter((self.context, self.request), name="plone_portal_state").navigation_root_path() query['path'] = {'query' : rootPath, 'depth' : 1} if self.sections_displayed_types: query['portal_type'] = self.sections_displayed_types else: query['portal_type'] = ['Folder', 'Collection', 'Topic', 'Collage', 'FormFolder'] if self.sortAttribute is not None: query['sort_on'] = self.sortAttribute if self.sortOrder is not None: query['sort_order'] = self.sortOrder rootItem = self.context.restrictedTraverse(rootPath) if self.enable_wf_state_filtering and rootItem.portal_type not in ['MemberFolder']: query['review_state'] = self.sections_wf_states_to_show query['is_default_page'] = False if self.disable_nonfolderish_sections: query['is_folderish'] = True return query
def __init__(self, context, data): self.context = context self.data = data portal_properties = getToolByName(context, "portal_properties") navtree_properties = getattr(portal_properties, "navtree_properties") # Acquire a custom nav query if available customQuery = getattr(context, "getCustomNavQuery", None) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} # Construct the path query root = get_root(context, data.root_path) if root is not None: rootPath = "/".join(root.getPhysicalPath()) else: rootPath = getNavigationRoot(context) currentPath = "/".join(context.getPhysicalPath()) # If we are above the navigation root, a navtree query would return # nothing (since we explicitly start from the root always). Hence, # use a regular depth-1 query in this case. if currentPath != rootPath and not currentPath.startswith(rootPath + "/"): query["path"] = {"query": rootPath, "depth": 1} else: query["path"] = {"query": currentPath, "navtree": 1} topLevel = data.topLevel if topLevel and topLevel > 0: query["path"]["navtree_start"] = topLevel + 1 # XXX: It'd make sense to use 'depth' for bottomLevel, but it doesn't # seem to work with EPI. # Only list the applicable types query["portal_type"] = utils.typesToList(context) # Apply the desired sort sortAttribute = navtree_properties.getProperty("sortAttribute", None) if sortAttribute is not None: query["sort_on"] = sortAttribute sortOrder = navtree_properties.getProperty("sortOrder", None) if sortOrder is not None: query["sort_order"] = sortOrder # Filter on workflow states, if enabled registry = getUtility(IRegistry) navigation_settings = registry.forInterface(INavigationSchema, prefix="plone") if navigation_settings.filter_on_workflow: query["review_state"] = navigation_settings.workflow_states_to_show self.query = query
def __init__(self, context, portlet): self.context = context self.portlet = portlet portal_properties = getToolByName(context, 'portal_properties') navtree_properties = getattr(portal_properties, 'navtree_properties') # Acquire a custom nav query if available customQuery = getattr(context, 'getCustomNavQuery', None) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} # Construct the path query root = uuidToObject(portlet.root_uid) if root is not None: rootPath = '/'.join(root.getPhysicalPath()) else: rootPath = getNavigationRoot(context) currentPath = '/'.join(context.getPhysicalPath()) # If we are above the navigation root, a navtree query would return # nothing (since we explicitly start from the root always). Hence, # use a regular depth-1 query in this case. if currentPath != rootPath and not currentPath.startswith(rootPath + '/'): query['path'] = {'query': rootPath, 'depth': 1} else: query['path'] = {'query': currentPath, 'navtree': 1} topLevel = portlet.topLevel if topLevel and topLevel > 0: query['path']['navtree_start'] = topLevel + 1 # XXX: It'd make sense to use 'depth' for bottomLevel, but it doesn't # seem to work with EPI. # Only list the applicable types query['portal_type'] = utils.typesToList(context) # Apply the desired sort sortAttribute = navtree_properties.getProperty('sortAttribute', None) if sortAttribute is not None: query['sort_on'] = sortAttribute sortOrder = navtree_properties.getProperty('sortOrder', None) if sortOrder is not None: query['sort_order'] = sortOrder # Filter on workflow states, if enabled registry = getUtility(IRegistry) navigation_settings = registry.forInterface( INavigationSchema, prefix="plone" ) if navigation_settings.filter_on_workflow: query['review_state'] = navigation_settings.workflow_states_to_show self.query = query
def is_indexable(self, obj): """Checks if the object can be indexed """ if not (base_hasattr(obj, "reindexObject")): return False if not (safe_callable(obj.reindexObject)): return False return True
def get_id(item): if not item: return None getId = getattr(item, 'getId') if not utils.safe_callable(getId): # Looks like a brain return getId return getId()
def get_id(item): if not item: return '' getId = getattr(item, 'getId') if not utils.safe_callable(getId): # Looks like a brain return getId return getId()
def _indexObject(obj): if (base_hasattr(obj, 'getObject') and safe_callable(obj.getObject)): # Wake up any brains obj = obj.getObject() if (base_hasattr(obj, 'indexObject') and safe_callable(obj.indexObject)): try: obj.indexObject() except TypeError: # Catalogs have 'indexObject' as well, but they # take different args, and will fail pass except: # Log indexing exceptions but continue log_exc('Could not reindex %s'%( '/'.join(obj.getPhysicalPath())))
def __init__(self, context, portlet): self.context = context self.portlet = portlet portal_properties = getToolByName(context, 'portal_properties') navtree_properties = getattr(portal_properties, 'navtree_properties') portal_url = getToolByName(context, 'portal_url') # Acquire a custom nav query if available customQuery = getattr(context, 'getCustomNavQuery', None) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} # Construct the path query rootPath = getNavigationRoot(context, relativeRoot=portlet.root) currentPath = '/'.join(context.getPhysicalPath()) # If we are above the navigation root, a navtree query would return # nothing (since we explicitly start from the root always). Hence, # use a regular depth-1 query in this case. if not currentPath.startswith(rootPath): query['path'] = {'query' : rootPath, 'depth' : 1} else: query['path'] = {'query' : currentPath, 'navtree' : 1} topLevel = portlet.topLevel or navtree_properties.getProperty('topLevel', 0) if topLevel and topLevel > 0: query['path']['navtree_start'] = topLevel + 1 # XXX: It'd make sense to use 'depth' for bottomLevel, but it doesn't # seem to work with EPI. # Only list the applicable types query['portal_type'] = utils.typesToList(context) # Apply the desired sort sortAttribute = navtree_properties.getProperty('sortAttribute', None) if sortAttribute is not None: query['sort_on'] = sortAttribute sortOrder = navtree_properties.getProperty('sortOrder', None) if sortOrder is not None: query['sort_order'] = sortOrder # Filter on workflow states, if enabled if navtree_properties.getProperty('enable_wf_state_filtering', False): query['review_state'] = navtree_properties.getProperty('wf_states_to_show', ()) ############# Added by expanding navigation query['path']['navtree']='' query['path']['query']='' ############# End added self.query = query
def __init__(self, context, portlet): self.context = context self.portlet = portlet portal_properties = getToolByName(context, 'portal_properties') navtree_properties = getattr(portal_properties, 'navtree_properties') # Acquire a custom nav query if available customQuery = getattr(context, 'getCustomNavQuery', None) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} # Construct the path query root = uuidToObject(portlet.root_uid) if root is not None: rootPath = '/'.join(root.getPhysicalPath()) else: rootPath = getNavigationRoot(context) currentPath = '/'.join(context.getPhysicalPath()) # If we are above the navigation root, a navtree query would return # nothing (since we explicitly start from the root always). Hence, # use a regular depth-1 query in this case. if currentPath != rootPath and not currentPath.startswith(rootPath + '/'): query['path'] = {'query': rootPath, 'depth': 1} else: query['path'] = {'query': currentPath, 'navtree': 1} topLevel = portlet.topLevel if topLevel and topLevel > 0: query['path']['navtree_start'] = topLevel + 1 # XXX: It'd make sense to use 'depth' for bottomLevel, but it doesn't # seem to work with EPI. # Only list the applicable types query['portal_type'] = utils.typesToList(context) # Apply the desired sort sortAttribute = navtree_properties.getProperty('sortAttribute', None) if sortAttribute is not None: query['sort_on'] = sortAttribute sortOrder = navtree_properties.getProperty('sortOrder', None) if sortOrder is not None: query['sort_order'] = sortOrder # Filter on workflow states, if enabled registry = getUtility(IRegistry) navigation_settings = registry.forInterface(INavigationSchema, prefix="plone") if navigation_settings.filter_on_workflow: query['review_state'] = navigation_settings.workflow_states_to_show self.query = query
def getMethodAliases(self, typeInfo): """Given an FTI, return the dict of method aliases defined on that FTI. If there are no method aliases (i.e. this FTI doesn't support it), return None""" getMethodAliases = getattr(typeInfo, "getMethodAliases", None) if getMethodAliases is not None and utils.safe_callable(getMethodAliases): return getMethodAliases() else: return None
def indexObject(obj, path): if (base_hasattr(obj, 'indexObject') and safe_callable(obj.indexObject)): try: obj.indexObject() except TypeError: # Catalogs have 'indexObject' as well, but they # take different args, and will fail pass
def __init__(self, context, portlet): self.context = context self.portlet = portlet portal_properties = getToolByName(context, 'portal_properties') navtree_properties = getattr(portal_properties, 'navtree_properties') portal_url = getToolByName(context, 'portal_url') portal_languages = getToolByName(context, 'portal_languages') # Acquire a custom nav query if available customQuery = getattr(context, 'getCustomNavQuery', None) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} #import pdb;pdb.set_trace() # Construct the path query preferred_path = "/%s" % portal_languages.getPreferredLanguage() rootPathX = getNavigationRoot(context, relativeRoot=portlet.root) rootPathY = getNavigationRoot(context, relativeRoot=preferred_path) rootPath = portal_url.getPortalPath()+preferred_path print "X: portlet.root based. rootPath: %s, portlet.root: %s" %(rootPathX, portlet.root) print "Y: preferred_path based. rootPath: %s, preferred_path: %s" %(rootPathY, preferred_path) print "Current: rootPath+preferred_path: %s %s" %(rootPath, preferred_path) currentPath = '/'.join(context.getPhysicalPath()) # If we are above the navigation root, a navtree query would return # nothing (since we explicitly start from the root always). Hence, # use a regular depth-1 query in this case. query['path'] = {'query' : rootPath, 'navtree' : 1, 'navtree_start': 1} topLevel = portlet.topLevel or navtree_properties.getProperty('topLevel', 0) topLevel = 0 # Only list the applicable types query['portal_type'] = utils.typesToList(context) # Apply the desired sort sortAttribute = navtree_properties.getProperty('sortAttribute', None) if sortAttribute is not None: query['sort_on'] = sortAttribute sortOrder = navtree_properties.getProperty('sortOrder', None) if sortOrder is not None: query['sort_order'] = sortOrder # Filter on workflow states, if enabled if navtree_properties.getProperty('enable_wf_state_filtering', False): query['review_state'] = navtree_properties.getProperty('wf_states_to_show', ()) self.query = query
def __init__(self, context, portlet): self.context = context self.portlet = portlet portal_url = getToolByName(context, 'portal_url') portal = portal_url.getPortalObject() portal_properties = getToolByName(context, 'portal_properties') navtree_properties = getattr(portal_properties, 'navtree_properties') pm = getToolByName(portal,'portal_membership') user = pm.getAuthenticatedMember() # Acquire a custom nav query if available customQuery = getattr(context, 'getCustomNavQuery', None) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} # Construct the path query if hasattr(portlet, 'root'): root = portlet.root else: root = uuidToObject(portlet.root_uid) rootPath = getNavigationRoot(context, relativeRoot=root) currentPath = '/'.join(context.getPhysicalPath()) # If we are above the navigation root, a navtree query would return # nothing (since we explicitly start from the root always). Hence, # use a regular depth-1 query in this case. query['path'] = {'query' : rootPath, 'depth' : 2} topLevel = portlet.topLevel or navtree_properties.getProperty('topLevel', 0) if topLevel and topLevel > 0: query['path']['navtree_start'] = topLevel + 1 # XXX: It'd make sense to use 'depth' for bottomLevel, but it doesn't # seem to work with EPI. # Only list the applicable types query['portal_type'] = utils.typesToList(context) # Apply the desired sort sortAttribute = navtree_properties.getProperty('sortAttribute', None) if sortAttribute is not None: query['sort_on'] = sortAttribute sortOrder = navtree_properties.getProperty('sortOrder', None) if sortOrder is not None: query['sort_order'] = sortOrder # Filter on workflow states, if enabled if not user or not user.has_permission('List folder contents', self.context): if navtree_properties.getProperty('enable_wf_state_filtering', False): query['review_state'] = navtree_properties.getProperty('wf_states_to_show', ()) self.query = query
def _get_compare_attr(obj, attr): """Return an compare attribute, supporting AT, DX and IEventAccessor objects. """ val = getattr(obj, attr, None) if safe_callable(val): val = val() if isinstance(val, DateTime): val = pydt(val) return val
def getMethodAliases(self, typeInfo): # Given an FTI, return the dict of method aliases defined on that # FTI. If there are no method aliases (i.e. this FTI doesn't support # it), return None. getMethodAliases = getattr(typeInfo, 'getMethodAliases', None) if getMethodAliases is not None \ and utils.safe_callable(getMethodAliases): return getMethodAliases() else: return None
def getEntry(self, object): attrs = re.findall('%\([^\)]+\)', self.contents) map = {} for attr in attrs: attr = attr[2:-1] if map.has_key(attr): continue value = getattr(object, attr, '') modifier = getattr(self, attr, None) if modifier and safe_callable(modifier): value = modifier(object, value) elif safe_callable(value): value = value() if value and not attr in self.noescape: value = vformat(value) map[attr] = safe_unicode(value) for required in self.required: if not map[required]: return '' return self.template % {'contents': self.contents % map}
def get_data(content, security=False, domain=None): """Return data to index in ES. """ uid = get_uid(content) if not uid: return None, None title = content.Title() try: # wrap content, so the SearchableText will be # delegated to IIndexer adapters as appropriate. # This will e.g. take care of PDF file indexing. cat = getToolByName(content, 'portal_catalog') wrapper = IndexableObjectWrapper(content, cat) text = getattr(wrapper, 'SearchableText', None) if safe_callable(text): text = text() except: text = title url = content.absolute_url() if domain: parts = urlparse.urlparse(url) url = urlparse.urlunparse((parts[0], domain) + parts[2:]) data = {'title': title, 'metaType': content.portal_type, 'sortableTitle': sortable_string(title), 'description': content.Description(), 'subject': content.Subject(), 'contributors': content.Contributors(), 'url': url, 'author': content.Creator(), 'content': text} if security: data['authorizedUsers'] = get_security(content) if hasattr(aq_base(content), 'pub_date_year'): data['publishedYear'] = getattr(content, 'pub_date_year') created = content.created() if created is not (None, 'None'): data['created'] = created.strftime('%Y-%m-%dT%H:%M:%S') modified = content.modified() if modified is not (None, 'None'): data['modified'] = modified.strftime('%Y-%m-%dT%H:%M:%S') if (not security or 'Anonymous' in data['authorizedUsers']) and \ IContentish.providedBy(content): data['suggest'] = ISuggester(content).terms() return uid, data
def sortable_sortkey_title(instance): """Returns a sortable title as a mxin of sortkey + lowercase sortable_title """ title = sortable_title(instance) if safe_callable(title): title = title() sort_key = instance.getSortKey() if sort_key is None: sort_key = 999999 return "{:010.3f}{}".format(sort_key, title)
def sortable_title(obj): title = getattr(obj, 'Title', None) if title is not None: if safe_callable(title): title = title() if isinstance(title, basestring): sortabletitle = safe_unicode(title).lower().strip() sortabletitle = num_sort_regex.sub(zero_fill, sortabletitle) sortabletitle = sortabletitle[:70].encode('utf-8') return locale.strxfrm(sortabletitle) return ''
def _pretty_title_or_id(context, obj, empty_value=_marker): """Return the best possible title or id of an item, regardless of whether obj is a catalog brain or an object, but returning an empty title marker if the id is not set (i.e. it's auto-generated). """ # if safe_hasattr(obj, 'aq_explicit'): # obj = obj.aq_explicit #title = getattr(obj, 'Title', None) title = None if base_hasattr(obj, 'Title'): title = getattr(obj, 'Title', None) if safe_callable(title): title = title() if title: return title item_id = getattr(obj, 'getId', None) if safe_callable(item_id): item_id = item_id() if item_id and not isIDAutoGenerated(context, item_id): return item_id if empty_value is _marker: empty_value = getEmptyTitle(context) return empty_value
def indexObject(obj, path): if (base_hasattr(obj, 'indexObject') and safe_callable(obj.indexObject)): try: obj.indexObject() pdtool = obj.portal_discussion if pdtool.isDiscussionAllowedFor(obj): tb = pdtool.getDiscussionFor(obj) for ob in tb.getReplies(): ob.indexObject() except TypeError: # Catalogs have 'indexObject' as well, but they # take different args, and will fail pass
def getQuery(self, context): user = self.portal_state.member() portal_properties = getToolByName(context, 'portal_properties') navtree_properties = getattr(portal_properties, 'navtree_properties') # Acquire a custom nav query if available customQuery = getattr(context, 'getCustomNavQuery', None) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} # Construct the path query rootPath = self.navigationTreeRootPath() currentPath = '/'.join(context.getPhysicalPath()) query['is_default_page'] = False # If we are above the navigation root, a navtree query would return # nothing (since we explicitly start from the root always). Hence, # use a regular depth-1 query in this case. if currentPath!=rootPath and not currentPath.startswith(rootPath+'/'): query['path'] = {'query' : rootPath, 'depth' : 1} else: query['path'] = {'query' : currentPath, 'navtree' : 1} # XXX: It'd make sense to use 'depth' for bottomLevel, but it doesn't # seem to work with EPI. # Only list the applicable types ploneUtils = getToolByName(self.context, 'plone_utils') friendlyTypes = ploneUtils.getUserFriendlyTypes() if 'MemberDataContainer' in friendlyTypes: friendlyTypes.remove('MemberDataContainer') query['portal_type'] = friendlyTypes # Apply the desired sort sortAttribute = navtree_properties.getProperty('sortAttribute', None) if sortAttribute is not None: query['sort_on'] = sortAttribute sortOrder = navtree_properties.getProperty('sortOrder', None) if sortOrder is not None: query['sort_order'] = sortOrder # Filter on workflow states, if enabled if not user or not user.has_permission('List folder contents', self.context): if navtree_properties.getProperty('enable_wf_state_filtering', False): query['review_state'] = navtree_properties.getProperty('wf_states_to_show', ()) return query
def __init__(self, context): portal_properties = getToolByName(context, 'portal_properties') navtree_properties = getattr(portal_properties, 'navtree_properties') # Acquire a custom nav query if available customQuery = getattr(context, 'getCustomNavQuery', None) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} # Construct the path query rootPath = getNavigationRoot(context) currentPath = '/'.join(context.getPhysicalPath()) # If we are above the navigation root, a navtree query would return # nothing (since we explicitly start from the root always). Hence, # use a regular depth-1 query in this case. if not currentPath.startswith(rootPath): query['path'] = {'query': rootPath, 'depth': 1} else: query['path'] = {'query': currentPath, 'navtree': 1} topLevel = navtree_properties.getProperty('topLevel', 0) if topLevel and topLevel > 0: query['path']['navtree_start'] = topLevel + 1 # XXX: It'd make sense to use 'depth' for bottomLevel, but it doesn't # seem to work with EPI. # Only list the applicable types query['portal_type'] = utils.typesToList(context) # Apply the desired sort sortAttribute = navtree_properties.getProperty('sortAttribute', None) if sortAttribute is not None: query['sort_on'] = sortAttribute sortOrder = navtree_properties.getProperty('sortOrder', None) if sortOrder is not None: query['sort_order'] = sortOrder # Filter on workflow states, if enabled if navtree_properties.getProperty('enable_wf_state_filtering', False): query['review_state'] = \ navtree_properties.getProperty('wf_states_to_show', ()) self.query = query
def __init__(self, context): registry = getUtility(IRegistry) navigation_settings = registry.forInterface(INavigationSchema, prefix="plone") # Acquire a custom nav query if available customQuery = getattr(context, 'getCustomNavQuery', None) if customQuery is not None and utils.safe_callable(customQuery): query = customQuery() else: query = {} # Construct the path query rootPath = getNavigationRoot(context) currentPath = '/'.join(context.getPhysicalPath()) # If we are above the navigation root, a navtree query would return # nothing (since we explicitly start from the root always). Hence, # use a regular depth-1 query in this case. if not currentPath.startswith(rootPath): query['path'] = {'query': rootPath, 'depth': 1} else: query['path'] = {'query': currentPath, 'navtree': 1} query['path']['navtree_start'] = 0 # XXX: It'd make sense to use 'depth' for bottomLevel, but it doesn't # seem to work with EPI. # Only list the applicable types query['portal_type'] = utils.typesToList(context) # Apply the desired sort sortAttribute = navigation_settings.sort_tabs_on if sortAttribute is not None: query['sort_on'] = sortAttribute if navigation_settings.sort_tabs_reversed: query['sort_order'] = 'desc' else: query['sort_order'] = 'asc' # Filter on workflow states, if enabled if navigation_settings.filter_on_workflow: query['review_state'] = navigation_settings.workflow_states_to_show self.query = query
def notifications(self): dates = [] rules = None # if assignee is asking for notifications look first if there are # customezed ones current = api.user.get_current().getId() annotations = self._setup_annotations() assignee = getattr(self.context, 'assignee', None) if assignee and current in assignee and \ current in annotations[TASK_NOTIFICATIONS_KEY]: rules = annotations[TASK_NOTIFICATIONS_KEY][current] # in all other cases just return notifications else: rules = getattr(self.context, 'notifications', None) if not rules: taskplanner = self._get_taskplanner(self.context) if taskplanner: rules = getattr(taskplanner, 'notifications', None) if rules: for rule in rules: if rule['field4'] == 'due': field4 = self._get_due( getattr(self.context, rule['field4'])) else: field4 = getattr(self.context, rule['field4']) if not field4: continue field3 = self._get_value(rule['field3'], TIME_RELATIONS)[2] if safe_callable(field4): field4 = field4() if isinstance(field4, DateTime): field4 = pydt(field4) if field3 is None: dates.append(field4) else: field2 = self._get_value(rule['field2'], TIME_UNITS)[2] field1 = int(rule['field1']) dates.append(field4 + field2(field3 * field1)) return dates
def sortable_id(obj): """put any zeros before the id so its possible to sort the id correctly """ _id = getattr(obj, 'getId', None) if _id is not None: if safe_callable(_id): _id = _id() if isinstance(_id, basestring): value = _id.lower().strip() # Replace numbers with zero filled numbers value = num_sort_regex.sub(zero_fill, value) # Truncate to prevent bloat value = safe_unicode(value)[:40].encode('utf-8') return value return ''
def __call__(self, **kwargs): title = getattr(self.obj, 'Title', None) if title is not None: if safe_callable(title): if kwargs.has_key('lang'): try: title = title(lang=kwargs['lang']) except: title = title() else: title = title() if isinstance(title, basestring): sortabletitle = title.lower().strip() # Replace numbers with zero filled numbers sortabletitle = num_sort_regex.sub(zero_fill, sortabletitle) # Truncate to prevent bloat sortabletitle = safe_unicode(sortabletitle)[:30].encode('utf-8') return sortabletitle return ''
def render(self, content, field_id): """Dexterity type rendering of field values""" # https://github.com/plone/plone.app.contenttypes/blob/master/plone/app/contenttypes/browser/folder.py renderer = self.render_methods_dx.get(field_id, None) if renderer is not None: return renderer(content, field_id) value = getattr(content, field_id, '') # catch relation fields target = getattr(value, 'to_object', None) if target is not None: title = target.Title() url = target.absolute_url() return "<a href='%s'>%s</a>" % (url, title) if safe_callable(value): value = value() return value
def indexObject(obj, path): if (base_hasattr(obj, 'reindexObject') and safe_callable(obj.reindexObject)): try: self.reindexObject(obj, idxs=idxs) # index conversions from plone.app.discussion annotions = IAnnotations(obj) if DISCUSSION_ANNOTATION_KEY in annotions: conversation = annotions[DISCUSSION_ANNOTATION_KEY] conversation = conversation.__of__(obj) for comment in conversation.getComments(): try: self.indexObject(comment, idxs=idxs) except StopIteration: # pragma: no cover pass except TypeError: # Catalogs have 'indexObject' as well, but they # take different args, and will fail pass