def expand_containers(self, items, containers, _url, chain=(), context=None): # seen_context = False _url = _url.rstrip("/") current = False for key, container in self._sort_containers(containers): assert IAlchemistContainer.providedBy(container) label = container.domain_model.__name__ descriptor = utils.get_descriptor(container.domain_model) if descriptor: label = getattr(descriptor, "container_name", None) or getattr(descriptor, "display_name", None) if context is not None: current = container.__name__ == context.__name__ selected = not len(chain) and current if current: # seen_context = True nodes = self.expand(chain) else: nodes = () key_url = "%s/%s" % (_url, key) items.append( { "id": self.get_nav_entry_id(key_url), "label": translate( label, target_language=get_request_language(request=self.request), domain="bungeni" ), "url": key_url, "current": current, "selected": selected, "kind": "container", "nodes": nodes, } )
def _get_title_from_context(context): title = None if IAlchemistContent.providedBy(context): if IDCDescriptiveProperties.providedBy(context): title = context.title else: props = IDCDescriptiveProperties(context, None) if props is not None: title = props.title else: """ !+ AttributeError: 'GroupAddress' object has no attribute 'short_name': File "/home/undesa/bungeni/cap_installs/bungeni_install/bungeni/releases/20100305100101/src/bungeni.main/bungeni/ui/viewlets/navigation.py", line 59, in _get_title_from_context #title = context.short_name So, we temporarily default the above to the context.__class__.__name__: """ title = getattr(context, "title", context.__class__.__name__) elif IWorkspaceContainer.providedBy(context): # WorkspaceContainer._class is not set (and not unique) and it breaks the # connection between Container -> ContentClass title = context.__name__ elif IAlchemistContainer.providedBy(context): domain_model = context._class try: descriptor = utils.get_descriptor(domain_model) except KeyError, e: log.warn("TYPE_INFO: no descriptor for model %s " "[container=%s] [error=%s]" % (domain_model, context, e)) descriptor = None name = "" if descriptor: name = getattr(descriptor, "container_name", None) if name is None: name = getattr(descriptor, "display_name", None) if not name: name = getattr(context, "__name__", None) title = name
def _sort_containers(self, key_containers): """Sort each container by its domain_model's descriptor order. """ dsu = [(utils.get_descriptor(kc[1].domain_model).order, kc) for kc in key_containers] dsu.sort() return [kc for (order, kc) in dsu]
def filterFields(context, form_fields): omit_names = [] if IAlchemistContent.providedBy(context): md = utils.get_descriptor(context.__class__) for field in form_fields: # field:zope.formlib.form.FormField try: can_write = security.canWrite(context, field.__name__) can_read = security.canAccess(context, field.__name__) except AttributeError: log.warn('filterFields: item [%s] has no field named "%s"', context, field.__name__) can_write = can_read = False if can_write: continue if can_read: field.for_display = True field.custom_widget = md.get(field.__name__).view_widget else: omit_names.append(field.__name__) elif not IAlchemistContainer.providedBy(context): ctx = getattr(context, "context", None) if ctx: filterFields(ctx, form_fields) else: raise NotImplementedError return form_fields.omit(*omit_names)
def __init__(self, context, request, view, manager): self.context = context self.request = request self.__parent__ = context.__parent__ self.manager = manager self.query = None md = utils.get_descriptor(domain.User) self.form_fields = md.fields #.select("user_id", "start_date", "end_date")
def form_name(self): parent = self.context.__parent__ #DESCRIPTOR(miano, June 2011) This originally first checked the parent's #descriptor then the item's descriptor. Why??? #This was causing an error in the display pages of items in the #workspace since the workspace containers have no descriptor #defined for them. if IAlchemistContent.providedBy(self.context): descriptor = utils.get_descriptor(self.context.__class__) elif IAlchemistContainer.providedBy(parent): descriptor = utils.get_descriptor(parent.domain_model) else: raise RuntimeError("Unsupported object: %s." % repr(self.context)) if descriptor: name = getattr(descriptor, "display_name", None) if name is None: name = self.context.__class__.__name__ return name
def form_name(self): parent = self.context.__parent__ # DESCRIPTOR(miano, June 2011) This originally first checked the parent's # descriptor then the item's descriptor. Why??? # This was causing an error in the display pages of items in the # workspace since the workspace containers have no descriptor # defined for them. if IAlchemistContent.providedBy(self.context): descriptor = utils.get_descriptor(self.context.__class__) elif IAlchemistContainer.providedBy(parent): descriptor = utils.get_descriptor(parent.domain_model) else: raise RuntimeError("Unsupported object: %s." % repr(self.context)) if descriptor: name = getattr(descriptor, "display_name", None) if name is None: name = self.context.__class__.__name__ return name
def expand_containers(self, items, containers, _url, chain=(), context=None): #seen_context = False _url = _url.rstrip("/") current = False for key, container in containers: assert IAlchemistContainer.providedBy(container) label = container.domain_model.__name__ descriptor = utils.get_descriptor(container.domain_model) order = 999 if descriptor: order = descriptor.order label = getattr(descriptor, "container_name", None) or \ getattr(descriptor, "display_name", None) if context is not None: current = container.__name__ == context.__name__ selected = not len(chain) and current if current: #seen_context = True nodes = self.expand(chain) else: nodes = () key_url = "%s/%s" % (_url, key) items.append({ "id": self.get_nav_entry_id(key_url), "order": order, "label": translate( label, target_language=get_request_language(request=self.request), domain="bungeni"), "url": key_url, "current": current, "selected": selected, "kind": "container", "nodes": nodes, }) items.sort(key=lambda item: (item['order'], item['label']))
def getFields(context, interface=None, annotation=None): """Generator of all [zope.schema] fields that will be displayed in a container listing. Redefines alchemist.ui.container.getFields, making use of the @listing_columns property of the ModelDescriptor class. """ if interface is None: domain_model = proxy.removeSecurityProxy(context.domain_model) interface = utils.get_derived_table_schema(domain_model) if annotation is None: annotation = utils.get_descriptor(interface) for field_name in annotation.listing_columns: yield interface[field_name]
def get_search_widgets(self): script_html = "" script_js = "" domain_model = proxy.removeSecurityProxy(self.context).domain_model descriptor = utils.get_descriptor(domain_model) for field in descriptor.listing_columns: search_widget = descriptor.get(field).search_widget if search_widget: s_html, s_js = search_widget(self.prefix, field) else: s_html, s_js = text_input_search_widget(self.prefix, field) script_html += s_html script_js += s_js return script_html, script_js
def __init__(self, context, request, view, manager): super(DisplayViewlet, self).__init__(context, request, view, manager) # set add url before we change context self.add_url = self.get_add_url() target = self.get_target() if target is None: self.status = _(u"No item has been set") else: self.context = target self.has_data = True assert self.factory is not None descriptor = utils.get_descriptor(self.factory) self.form_fields = descriptor.fields
def __init__(self, context, request, view, manager): super(DisplayViewlet, self).__init__( context, request, view, manager) # set add url before we change context self.add_url = self.get_add_url() target = self.get_target() if target is None: self.status = _(u"No item has been set") else: self.context = target self.has_data = True assert self.factory is not None descriptor = utils.get_descriptor(self.factory) self.form_fields = descriptor.fields
def expand_containers(self, items, containers, _url, chain=(), context=None): #seen_context = False _url = _url.rstrip("/") current = False for key, container in containers: assert IAlchemistContainer.providedBy(container) # do not include doc containers for docs who do not specifically # declare the parent group instance as a workspace.group_name if IDoc.implementedBy(container.domain_model): group = get_group_for_context(container) assert IGroup.providedBy(group) doc_type_key = naming.polymorphic_identity(container.domain_model) if not group.is_type_workspaced(doc_type_key): continue label = container.domain_model.__name__ descriptor = utils.get_descriptor(container.domain_model) order = 999 if descriptor: order = descriptor.order label = getattr(descriptor, "container_name", None) or \ getattr(descriptor, "display_name", None) if context is not None: current = container.__name__ == context.__name__ selected = not len(chain) and current if current: #seen_context = True nodes = self.expand(chain) else: nodes = () key_url = "%s/%s" % (_url, key) items.append({ "id": self.get_nav_entry_id(key_url), "order": order, "label": translate(label, target_language=get_default_language(), domain="bungeni"), "url": key_url, "current": current, "selected": selected, "kind": "container", "nodes": nodes, }) items.sort(key=lambda item:(item['order'], item['label']))
def setUpColumns(domain_model): """Use model descriptor on domain model extract columns for table listings """ columns = [] table_schema = utils.get_derived_table_schema(domain_model) if not table_schema: raise SyntaxError("Model must have domain interface %r" % (domain_model)) descriptor_model = utils.get_descriptor(table_schema) field_column_names = \ descriptor_model and descriptor_model.listing_columns \ or schema.getFieldNamesInOrder(table_schema) # quick hack for now, dates are last in listings remainder = [] for field_name in field_column_names: if not field_name in table_schema: # we can specify additional columns for tables that are not present in the # the interface, iff they are fully spec'd as columns in the descriptor/annotation if (descriptor_model and field_name in descriptor_model.fields_by_name and descriptor_model.get(field_name).listing_column): pass else: print "bad field, container", field_name, table_schema.__name__ continue info = descriptor_model and descriptor_model.get(field_name) or None if info is not None and info.listing_column: columns.append(info.listing_column) continue field = table_schema[field_name] if isinstance(field, schema.Datetime): remainder.append( column.GetterColumn(title=field.title or field.__name__, getter=DateGetter(field.query))) continue columns.append( column.GetterColumn(title=(field.title or field.__name__), getter=Getter(field.query))) columns.extend(remainder) return columns
def setUpColumns(domain_model): """Use model descriptor on domain model extract columns for table listings """ columns = [] table_schema = utils.get_derived_table_schema(domain_model) if not table_schema: raise SyntaxError("Model must have domain interface %r" % (domain_model)) descriptor_model = utils.get_descriptor(table_schema) field_column_names = \ descriptor_model and descriptor_model.listing_columns \ or schema.getFieldNamesInOrder(table_schema) # quick hack for now, dates are last in listings remainder = [] for field_name in field_column_names: if not field_name in table_schema: # we can specify additional columns for tables that are not present in the # the interface, iff they are fully spec'd as columns in the descriptor/annotation if (descriptor_model and field_name in descriptor_model.fields_by_name and descriptor_model.get(field_name).listing_column ): pass else: print "bad field, container", field_name, table_schema.__name__ continue info = descriptor_model and descriptor_model.get(field_name) or None if info is not None and info.listing_column: columns.append(info.listing_column) continue field = table_schema[field_name] if isinstance(field, schema.Datetime): remainder.append( column.GetterColumn(title=field.title or field.__name__, getter=DateGetter(field.query))) continue columns.append( column.GetterColumn(title=(field.title or field.__name__), getter=Getter(field.query))) columns.extend(remainder) return columns
def get_item_types(self): workspace_config = component.getUtility(IWorkspaceTabsUtility) roles = get_workspace_roles() + ROLES_DIRECTLY_DEFINED_ON_OBJECTS domains = [] for role in roles: dom = workspace_config.get_role_domains(role, self.context.__name__) if dom: for key in dom: if key not in domains: domains.append(key) result = dict([("", "-")]) for d in domains: value = workspace_config.get_type(d) if value: descriptor_model = utils.get_descriptor(d) name = descriptor_model.display_name if descriptor_model else value result[value] = translate(name, context=self.request) return result
def setUpFields(domain_model, mode): """ setup form fields for add/edit/view/search modes, with custom widgets enabled from model descriptor. this expects the domain model and mode passed in and will return a formlib.form.Fields instance """ domain_model = removeSecurityProxy(domain_model) #import time #t = time.time() table_schema = utils.get_derived_table_schema(domain_model) descriptor_model = utils.get_descriptor(table_schema) search_mode = mode == "search" if not descriptor_model: if search_mode: form_fields = formlib.form.Fields(*setUpSearchFields(table_schema)) else: form_fields = formlib.form.Fields(table_schema) return form_fields fields = [] columns = getattr(descriptor_model, "%s_columns" % mode) for field_info in columns: if not field_info.name in table_schema: #print "bad field", field_info.name, table_schema.__name__ continue custom_widget = getattr(field_info, "%s_widget" % mode) if search_mode: fields.append( formlib.form.Field(setUpSearchField( table_schema[field_info.name]), custom_widget=custom_widget)) else: fields.append( formlib.form.Field(table_schema[field_info.name], custom_widget=custom_widget)) form_fields = formlib.form.Fields(*fields) #print "field setup cost", time.time()-t return form_fields
def setUpFields(domain_model, mode): """ setup form fields for add/edit/view/search modes, with custom widgets enabled from model descriptor. this expects the domain model and mode passed in and will return a formlib.form.Fields instance """ domain_model = removeSecurityProxy(domain_model) #import time #t = time.time() table_schema = utils.get_derived_table_schema(domain_model) descriptor_model = utils.get_descriptor(table_schema) search_mode = mode == "search" if not descriptor_model: if search_mode: form_fields = formlib.form.Fields(*setUpSearchFields(table_schema)) else: form_fields = formlib.form.Fields(table_schema) return form_fields fields = [] columns = getattr(descriptor_model, "%s_columns" % mode) for field_info in columns: if not field_info.name in table_schema: #print "bad field", field_info.name, table_schema.__name__ continue custom_widget = getattr(field_info, "%s_widget" % mode) if search_mode: fields.append(formlib.form.Field( setUpSearchField(table_schema[field_info.name]), custom_widget=custom_widget)) else: fields.append(formlib.form.Field( table_schema[field_info.name], custom_widget=custom_widget)) form_fields = formlib.form.Fields(*fields) #print "field setup cost", time.time()-t return form_fields
def _get_title_from_context(context): title = None if IAlchemistContent.providedBy(context): if IDCDescriptiveProperties.providedBy(context): title = context.title else: props = IDCDescriptiveProperties(context, None) if props is not None: title = props.title else: ''' !+ AttributeError: 'GroupAddress' object has no attribute 'short_name': File "/home/undesa/bungeni/cap_installs/bungeni_install/bungeni/releases/20100305100101/src/bungeni.main/bungeni/ui/viewlets/navigation.py", line 59, in _get_title_from_context #title = context.short_name So, we temporarily default the above to the context.__class__.__name__: ''' title = getattr(context, "title", context.__class__.__name__) elif IWorkspaceContainer.providedBy(context): # WorkspaceContainer._class is not set (and not unique) and it breaks the # connection between Container -> ContentClass title = context.__name__ elif IAlchemistContainer.providedBy(context): domain_model = context._class try: descriptor = utils.get_descriptor(domain_model) except KeyError, e: log.warn("TYPE_INFO: no descriptor for model %s " "[container=%s] [error=%s]" % ( domain_model, context, e)) descriptor = None name = "" if descriptor: name = getattr(descriptor, "container_name", None) if name is None: name = getattr(descriptor, "display_name", None) if not name: name = getattr(context, "__name__", None) title = name
def form_name(self): dm = self.context.domain_model try: return utils.get_descriptor(dm).container_name except KeyError: return dm.__name__
def model_descriptor(self): return utils.get_descriptor(self.domain_model)
def form_name(self): descriptor = utils.get_descriptor(self.factory) return descriptor.display_name
def channel_title(self): return utils.get_descriptor( removeSecurityProxy(self.context).domain_model ).container_name
def type(self): descriptor = utils.get_descriptor(self.context.__class__) item_type = descriptor.display_name if descriptor else self.context.type request = get_request() return translate(item_type, context=request)
def descriptor(self): """Get (cached) descriptor instance for self.model_interface. """ if self._descriptor is None: self._descriptor = utils.get_descriptor(self.model_interface) return self._descriptor
def obj2dict(obj, depth, parent=None, include=[], exclude=[], lang=None, root_key=None): """ Returns dictionary representation of a domain object. """ if lang is None: lang = getattr(obj, "language", capi.default_language) result = {} obj = zope.security.proxy.removeSecurityProxy(obj) descriptor = None if IAlchemistContent.providedBy(obj): try: descriptor = utils.get_descriptor(obj) except KeyError: log.error("Could not get descriptor for IAlchemistContent %r", obj) if parent is not None and IWorkflowed.providedBy(obj): permissions = get_object_state_rpm(obj).permissions result["permissions"] = get_permissions_dict(permissions) result["tags"] = IStateController(obj).get_state().tags # Get additional attributes for name in include: value = getattr(obj, name, None) if value is None: continue if not name.endswith("s"): name += "s" if isinstance(value, collections.Iterable): res = [] # !+ allowance for non-container-api-conformant alchemist containers if IAlchemistContainer.providedBy(value): value = value.values() for item in value: i = obj2dict(item, 0, lang=lang, root_key=root_key) res.append(i) result[name] = res else: result[name] = value # Get mapped attributes mapper = class_mapper(obj.__class__) for property in mapper.iterate_properties: if property.key in exclude: continue value = getattr(obj, property.key) if value == parent: continue if value is None: continue if isinstance(property, RelationshipProperty) and depth > 0: if isinstance(value, collections.Iterable): result[property.key] = [] for item in value: result[property.key].append( obj2dict(item, 1, parent=obj, include=[], exclude=exclude + INNER_EXCLUDES, lang=lang, root_key=root_key)) else: result[property.key] = obj2dict(value, depth - 1, parent=obj, include=[], exclude=exclude + INNER_EXCLUDES, lang=lang, root_key=root_key) else: if isinstance(property, RelationshipProperty): continue elif isinstance(property, ColumnProperty): columns = property.columns if len(columns) == 1: if is_column_binary(columns[0]): if (parent and interfaces.ISerializable.providedBy(obj)): #skip serialization of binary fields #that have already been serialized elsewhere continue #save files result[columns[0].key] = dict( saved_file=PersistFiles.store_file( obj, columns[0], root_key)) continue if descriptor: columns = property.columns is_foreign = False if len(columns) == 1: if len(columns[0].foreign_keys): is_foreign = True if (not is_foreign) and (property.key in descriptor.keys()): field = descriptor.get(property.key) if (field and field.property and (schema.interfaces.IChoice.providedBy(field.property) or IVocabularyTextField.providedBy(field.property))): factory = (field.property.vocabulary or field.property.source) if factory is None: vocab_name = getattr(field.property, "vocabularyName", None) factory = zope.component.getUtility( schema.interfaces.IVocabularyFactory, vocab_name) # !+VOCABULARIES(mb, aug-2012)some vocabularies # expect an interaction to generate values # todo - update these vocabularies to work # with no request e.g. in notification threads display_name = None try: vocabulary = factory(obj) #handle vdex hierarchical terms if ITreeVocabulary.providedBy(factory): values = value.splitlines() term_values = [] for val in values: term_values.append( dict(name=property.key, value=val, displayAs=factory.vdex. getTermCaption( factory.getTermById(val), lang))) result[property.key] = term_values continue term = vocabulary.getTerm(value) if lang: if hasattr(factory, "vdex"): display_name = ( factory.vdex.getTermCaption( factory.getTermById(value), lang)) else: display_name = translate( (term.title or term.value), target_language=lang, domain="bungeni") else: display_name = term.title or term.value except zope.security.interfaces.NoInteraction: log.error( "This vocabulary %s expects an" "interaction to generate terms.", factory) # try to use dc adapter lookup try: _prop = mapper.get_property_by_column( property.columns[0]) _prop_value = getattr(obj, _prop.key) dc = IDCDescriptiveProperties( _prop_value, None) if dc: display_name = (IDCDescriptiveProperties( _prop_value).title) except KeyError: log.warn( "No display text found for %s" " on object %s. Unmapped in orm.", property.key, obj) except Exception, e: log.error( "Could not instantiate" " vocabulary %s. Exception: %s", factory, e) finally: # fallback we cannot look up vocabularies/dc if display_name is None: if not isinstance(value, unicode): display_name = unicode(value) if display_name is not None: result[property.key] = dict(name=property.key, value=value, displayAs=display_name) continue
def channel_title(self): return utils.get_descriptor( removeSecurityProxy(self.context).domain_model).container_name
def title(self): descriptor = utils.get_descriptor(self.context.domain_model) return descriptor.container_name
def obj2dict(obj, depth, parent=None, include=[], exclude=[], lang=None, root_key=None): """ Returns dictionary representation of a domain object. """ if lang is None: lang = getattr(obj, "language", capi.default_language) result = {} obj = zope.security.proxy.removeSecurityProxy(obj) descriptor = None if IAlchemistContent.providedBy(obj): try: descriptor = utils.get_descriptor(obj) except KeyError: log.error("Could not get descriptor for IAlchemistContent %r", obj) if parent is not None and IWorkflowed.providedBy(obj): permissions = get_object_state_rpm(obj).permissions result["permissions"] = get_permissions_dict(permissions) result["tags"] = IStateController(obj).get_state().tags # Get additional attributes for name in include: value = getattr(obj, name, None) if value is None: continue if not name.endswith("s"): name += "s" if isinstance(value, collections.Iterable): res = [] # !+ allowance for non-container-api-conformant alchemist containers if IAlchemistContainer.providedBy(value): value = value.values() for item in value: i = obj2dict(item, 0, lang=lang, root_key=root_key) res.append(i) result[name] = res else: result[name] = value # Get mapped attributes seen_keys = [] mapper = class_mapper(obj.__class__) for mproperty in mapper.iterate_properties: if mproperty.key.startswith("_vp"): #skip vertical props continue if mproperty.key in exclude: continue seen_keys.append(mproperty.key) value = getattr(obj, mproperty.key) if value == parent: continue if value is None: continue if isinstance(mproperty, RelationshipProperty) and depth > 0: if isinstance(value, collections.Iterable): result[mproperty.key] = [] for item in value: # !+DEPTH(ah, 2014-09-19) depth was set to 1 here, this causes # a very deep branching for upper level groups like legislature and chamber # and legislature times out occasionally. Doesnt seem neccessary to go depth=1 # for child objects, because they get serialized independently anyway, changing # depth to depth-1 so all dependent objects are iterated 1 level lower than the # parent. # UPDATE(ah, 2014-11-03) Item Schedule is an exceptional case of an object # whose context is within a parent container but is not visible outside of the sitting # it is not a type defined in types.xml and does not have its own # wokflow so we need to handle that in a unique way # we don't decrement the depth and instead process it as is active_depth = depth if item.__class__.__name__ == "ItemSchedule": active_depth = depth else: active_depth = depth-1 result[mproperty.key].append( obj2dict( item, active_depth, parent=obj, include=["owner", "item_schedule", "item_schedule_discussion"], exclude=exclude + INNER_EXCLUDES, lang=lang, root_key=root_key ) ) else: result[mproperty.key] = obj2dict(value, depth-1, parent=obj, include=["owner"], exclude=exclude + INNER_EXCLUDES, lang=lang, root_key=root_key ) else: if isinstance(mproperty, RelationshipProperty): continue elif isinstance(mproperty, ColumnProperty): columns = mproperty.columns if len(columns) == 1: if is_column_binary(columns[0]): fname = PersistFiles.store_file(obj, parent, columns[0].key, root_key) if fname: result[columns[0].key] = dict(saved_file=fname) continue if descriptor: columns = mproperty.columns is_foreign = False if len(columns) == 1: if len(columns[0].foreign_keys): is_foreign = True if (not is_foreign) and (mproperty.key in descriptor.keys()): field = descriptor.get(mproperty.key) if (field and field.property and (schema.interfaces.IChoice.providedBy(field.property) or IVocabularyTextField.providedBy(field.property)) ): factory = field.property.vocabulary or field.property.source if factory is None: vocab_name = getattr(field.property, "vocabularyName", None) factory = get_vocabulary(vocab_name) # !+VOCABULARIES(mb, aug-2012)some vocabularies # expect an interaction to generate values # todo - update these vocabularies to work # with no request e.g. in notification threads display_name = None try: vocabulary = factory(obj) # handle vdex hierarchical terms if ITreeVocabulary.providedBy(factory): values = value.splitlines() term_values = [] for val in values: term_values.append(dict( name=mproperty.key, value=val, displayAs=factory.getTermCaption( factory.getTermById(val), lang=lang))) result[mproperty.key] = term_values continue term = vocabulary.getTerm(value) if lang: if hasattr(factory, "getTermCaption"): display_name = factory.getTermCaption( factory.getTermById(value), lang=lang) else: display_name = translate( term.title or term.value, target_language=lang, domain="bungeni") else: display_name = term.title or term.value except zope.security.interfaces.NoInteraction: log.error("This vocabulary %s expects an interaction " "to generate terms.", factory) # try to use dc adapter lookup try: _prop = mapper.get_property_by_column( mproperty.columns[0]) _prop_value = getattr(obj, _prop.key) dc = IDCDescriptiveProperties(_prop_value, None) if dc: display_name = IDCDescriptiveProperties( _prop_value).title except KeyError: log.warn("No display text found for %s on " "object %s. Unmapped in orm.", property.key, obj) except Exception, e: log.error("Could not instantiate vocabulary %s. " "Exception: %s", factory, e) finally: # fallback we cannot look up vocabularies/dc if display_name is None: if not isinstance(value, unicode): display_name = unicode(value) if display_name is not None: result[mproperty.key] = dict( name=mproperty.key, value=value, displayAs=display_name) continue
def obj2dict(obj, depth, parent=None, include=[], exclude=[], lang=None, root_key=None): """ Returns dictionary representation of a domain object. """ if lang is None: lang = getattr(obj, "language", capi.default_language) result = {} obj = zope.security.proxy.removeSecurityProxy(obj) descriptor = None if IAlchemistContent.providedBy(obj): try: descriptor = utils.get_descriptor(obj) except KeyError: log.error("Could not get descriptor for IAlchemistContent %r", obj) if parent is not None and IWorkflowed.providedBy(obj): permissions = get_object_state_rpm(obj).permissions result["permissions"] = get_permissions_dict(permissions) result["tags"] = IStateController(obj).get_state().tags # Get additional attributes for name in include: value = getattr(obj, name, None) if value is None: continue if not name.endswith("s"): name += "s" if isinstance(value, collections.Iterable): res = [] # !+ allowance for non-container-api-conformant alchemist containers if IAlchemistContainer.providedBy(value): value = value.values() for item in value: i = obj2dict(item, 0, lang=lang, root_key=root_key) res.append(i) result[name] = res else: result[name] = value # Get mapped attributes mapper = class_mapper(obj.__class__) for property in mapper.iterate_properties: if property.key in exclude: continue value = getattr(obj, property.key) if value == parent: continue if value is None: continue if isinstance(property, RelationshipProperty) and depth > 0: if isinstance(value, collections.Iterable): result[property.key] = [] for item in value: result[property.key].append(obj2dict(item, 1, parent=obj, include=[], exclude=exclude + INNER_EXCLUDES, lang=lang, root_key=root_key )) else: result[property.key] = obj2dict(value, depth-1, parent=obj, include=[], exclude=exclude + INNER_EXCLUDES, lang=lang, root_key=root_key ) else: if isinstance(property, RelationshipProperty): continue elif isinstance(property, ColumnProperty): columns = property.columns if len(columns) == 1: if is_column_binary(columns[0]): if (parent and interfaces.ISerializable.providedBy(obj)): #skip serialization of binary fields #that have already been serialized elsewhere continue #save files result[columns[0].key] = dict( saved_file=PersistFiles.store_file( obj, columns[0], root_key ) ) continue if descriptor: columns = property.columns is_foreign = False if len(columns) == 1: if len(columns[0].foreign_keys): is_foreign = True if (not is_foreign) and (property.key in descriptor.keys()): field = descriptor.get(property.key) if (field and field.property and (schema.interfaces.IChoice.providedBy(field.property) or IVocabularyTextField.providedBy(field.property)) ): factory = (field.property.vocabulary or field.property.source ) if factory is None: vocab_name = getattr(field.property, "vocabularyName", None) factory = zope.component.getUtility( schema.interfaces.IVocabularyFactory, vocab_name ) # !+VOCABULARIES(mb, aug-2012)some vocabularies # expect an interaction to generate values # todo - update these vocabularies to work # with no request e.g. in notification threads display_name = None try: vocabulary = factory(obj) #handle vdex hierarchical terms if ITreeVocabulary.providedBy(factory): values = value.splitlines() term_values = [] for val in values: term_values.append(dict( name=property.key, value=val, displayAs=factory.vdex.getTermCaption( factory.getTermById(val), lang ) )) result[property.key] = term_values continue term = vocabulary.getTerm(value) if lang: if hasattr(factory, "vdex"): display_name = ( factory.vdex.getTermCaption( factory.getTermById(value), lang )) else: display_name = translate( (term.title or term.value), target_language=lang, domain="bungeni" ) else: display_name = term.title or term.value except zope.security.interfaces.NoInteraction: log.error("This vocabulary %s expects an" "interaction to generate terms.", factory ) # try to use dc adapter lookup try: _prop = mapper.get_property_by_column( property.columns[0]) _prop_value = getattr(obj, _prop.key) dc = IDCDescriptiveProperties( _prop_value, None) if dc: display_name = ( IDCDescriptiveProperties( _prop_value).title ) except KeyError: log.warn("No display text found for %s" " on object %s. Unmapped in orm.", property.key, obj ) except Exception, e: log.error("Could not instantiate" " vocabulary %s. Exception: %s", factory, e ) finally: # fallback we cannot look up vocabularies/dc if display_name is None: if not isinstance(value, unicode): display_name = unicode(value) if display_name is not None: result[property.key] = dict( name=property.key, value=value, displayAs=display_name ) continue
def obj2dict(obj, depth, parent=None, include=[], exclude=[], lang=None): """ Returns dictionary representation of a domain object. """ if lang is None: lang = getattr(obj, "language", capi.default_language) result = {} obj = removeSecurityProxy(obj) descriptor = None if IAlchemistContent.providedBy(obj): try: descriptor = utils.get_descriptor(obj) except KeyError: log.error("Could not get descriptor for IAlchemistContent %r", obj) # Get additional attributes for name in include: value = getattr(obj, name, None) if value is None: continue if not name.endswith("s"): name += "s" if isinstance(value, collections.Iterable): res = [] # !+ allowance for non-container-api-conformant alchemist containers if IAlchemistContainer.providedBy(value): value = value.values() for item in value: i = obj2dict(item, 0, lang=lang) if name == "versions": permissions = get_head_object_state_rpm(item).permissions i["permissions"] = get_permissions_dict(permissions) res.append(i) result[name] = res else: result[name] = value # Get mapped attributes mapper = class_mapper(obj.__class__) for property in mapper.iterate_properties: if property.key in exclude: continue value = getattr(obj, property.key) if value == parent: continue if value is None: continue if isinstance(property, RelationshipProperty) and depth > 0: if isinstance(value, collections.Iterable): result[property.key] = [] for item in value: result[property.key].append(obj2dict(item, 1, parent=obj, include=[], exclude=exclude + ["changes"], lang=lang )) else: result[property.key] = obj2dict(value, depth-1, parent=obj, include=[], exclude=exclude + ["changes"], lang=lang ) else: if isinstance(property, RelationshipProperty): continue elif isinstance(property, ColumnProperty): columns = property.columns if len(columns) == 1: if is_column_binary(columns[0]): continue if descriptor: columns = property.columns is_foreign = False if len(columns) == 1: if len(columns[0].foreign_keys): is_foreign = True if (not is_foreign) and (property.key in descriptor.keys()): field = descriptor.get(property.key) if (field and field.property and (field.property.__class__ == zope.schema.Choice)): factory = (field.property.vocabulary or field.property.source ) if factory is None: vocab_name = getattr(field.property, "vocabularyName", None) factory = zope.component.getUtility( zope.schema.interfaces.IVocabularyFactory, vocab_name ) #!+VOCABULARIES(mb, Aug-2012)some vocabularies # expect an interaction to generate values # todo - update these vocabularies to work # with no request e.g. in notification threads display_name = None try: vocabulary = factory(obj) term = vocabulary.getTerm(value) if lang: if hasattr(factory, "vdex"): display_name = ( factory.vdex.getTermCaption( factory.getTermById(value), lang )) else: display_name = translate( (term.title or term.value), target_language=lang, domain="bungeni" ) else: display_name = term.title or term.value except NoInteraction: log.error("This vocabulary %s expects an" "interaction to generate terms.", factory ) #try to use dc adapter lookup try: _prop = mapper.get_property_by_column( property.columns[0]) _prop_value = getattr(obj, _prop.key) dc = IDCDescriptiveProperties( _prop_value, None) if dc: display_name = ( IDCDescriptiveProperties( _prop_value).title ) except KeyError: log.warn("No display text found for %s" " on object %s. Unmapped in orm.", property.key, obj ) except Exception, e: log.error("Could not instantiate" " vocabulary %s. Exception: %s", factory, e ) finally: #fallback we cannot look up vocabularies/dc if display_name is None: log.error(value) display_name = unicode(value, errors="escape") result[property.key] = dict( name=property.key, value=value, displayAs=display_name ) continue
def obj2dict(obj, depth, parent=None, include=[], exclude=[], lang=None): """ Returns dictionary representation of a domain object. """ if lang is None: lang = getattr(obj, "language", capi.default_language) result = {} obj = removeSecurityProxy(obj) descriptor = None if IAlchemistContent.providedBy(obj): try: descriptor = utils.get_descriptor(obj) except KeyError: log.error("Could not get descriptor for IAlchemistContent %r", obj) # Get additional attributes for name in include: value = getattr(obj, name, None) if value is None: continue if not name.endswith("s"): name += "s" if isinstance(value, collections.Iterable): res = [] # !+ allowance for non-container-api-conformant alchemist containers if IAlchemistContainer.providedBy(value): value = value.values() for item in value: i = obj2dict(item, 0, lang=lang) if name == "versions": permissions = get_head_object_state_rpm(item).permissions i["permissions"] = get_permissions_dict(permissions) res.append(i) result[name] = res else: result[name] = value # Get mapped attributes mapper = class_mapper(obj.__class__) for property in mapper.iterate_properties: if property.key in exclude: continue value = getattr(obj, property.key) if value == parent: continue if value is None: continue if isinstance(property, RelationshipProperty) and depth > 0: if isinstance(value, collections.Iterable): result[property.key] = [] for item in value: result[property.key].append( obj2dict(item, 1, parent=obj, include=[], exclude=exclude + ["changes"], lang=lang)) else: result[property.key] = obj2dict(value, depth - 1, parent=obj, include=[], exclude=exclude + ["changes"], lang=lang) else: if isinstance(property, RelationshipProperty): continue elif isinstance(property, ColumnProperty): columns = property.columns if len(columns) == 1: if is_column_binary(columns[0]): continue if descriptor: columns = property.columns is_foreign = False if len(columns) == 1: if len(columns[0].foreign_keys): is_foreign = True if (not is_foreign) and (property.key in descriptor.keys()): field = descriptor.get(property.key) if (field and field.property and (field.property.__class__ == zope.schema.Choice)): factory = (field.property.vocabulary or field.property.source) if factory is None: vocab_name = getattr(field.property, "vocabularyName", None) factory = zope.component.getUtility( zope.schema.interfaces.IVocabularyFactory, vocab_name) #!+VOCABULARIES(mb, Aug-2012)some vocabularies # expect an interaction to generate values # todo - update these vocabularies to work # with no request e.g. in notification threads display_name = None try: vocabulary = factory(obj) term = vocabulary.getTerm(value) if lang: if hasattr(factory, "vdex"): display_name = ( factory.vdex.getTermCaption( factory.getTermById(value), lang)) else: display_name = translate( (term.title or term.value), target_language=lang, domain="bungeni") else: display_name = term.title or term.value except NoInteraction: log.error( "This vocabulary %s expects an" "interaction to generate terms.", factory) #try to use dc adapter lookup try: _prop = mapper.get_property_by_column( property.columns[0]) _prop_value = getattr(obj, _prop.key) dc = IDCDescriptiveProperties( _prop_value, None) if dc: display_name = (IDCDescriptiveProperties( _prop_value).title) except KeyError: log.warn( "No display text found for %s" " on object %s. Unmapped in orm.", property.key, obj) except Exception, e: log.error( "Could not instantiate" " vocabulary %s. Exception: %s", factory, e) finally: #fallback we cannot look up vocabularies/dc if display_name is None: log.error(value) display_name = unicode(value, errors="escape") result[property.key] = dict(name=property.key, value=value, displayAs=display_name) continue