def __new__(cls, context, request, view, manager):
     chain = _get_context_chain(context)
     chain.pop() # bungeni_app
     top_section = chain.pop()
     
     if not chain:
         return
     
     # we require the tree to begin with a container object
     if not IReadContainer.providedBy(chain[-1]):
         return
     
     # remove any views from navigation tree
     if not(IAlchemistContent.providedBy(chain[0]) or 
             IAlchemistContainer.providedBy(chain[0]) or
             ISection.providedBy(chain[0])
         ):
         chain.pop(0)
     
     subcontext = chain[-1]
     if (len(chain) > 1 or
             IReadContainer.providedBy(subcontext) and 
             not IAlchemistContainer.providedBy(subcontext) and 
             len(subcontext)
         ):
         inst = object.__new__(cls, context, request, view, manager)
         inst.chain = chain
         inst.top_section_url = url.absoluteURL(top_section, request)
         inst.id_prefix = "nav"
         return inst
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
Example #3
0
    def __new__(cls, context, request, view, manager):
        chain = _get_context_chain(context)
        chain.pop()  # bungeni_app
        top_section = chain.pop()

        if not chain:
            return

        # we require the tree to begin with a container object
        if not IReadContainer.providedBy(chain[-1]):
            return

        # remove any views from navigation tree
        if not (IAlchemistContent.providedBy(chain[0])
                or IAlchemistContainer.providedBy(chain[0])
                or ISection.providedBy(chain[0])):
            chain.pop(0)

        subcontext = chain[-1]
        if (len(chain) > 1 or IReadContainer.providedBy(subcontext)
                and not IAlchemistContainer.providedBy(subcontext)
                and len(subcontext)):
            inst = object.__new__(cls, context, request, view, manager)
            inst.chain = chain
            inst.top_section_url = url.absoluteURL(top_section, request)
            inst.id_prefix = "nav"
            return inst
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, "short_name", 
                    context.__class__.__name__)
    elif IAlchemistContainer.providedBy(context):
        domain_model = context._class 
        try:
            descriptor = queryModelDescriptor(domain_model)
        except:
            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
    elif ILocation.providedBy(context) and \
         IDCDescriptiveProperties.providedBy(context):
        title = context.title
    return title
Example #5
0
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, "short_name",
                                context.__class__.__name__)
    elif IAlchemistContainer.providedBy(context):
        domain_model = context._class
        try:
            descriptor = queryModelDescriptor(domain_model)
        except:
            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
    elif ILocation.providedBy(context) and \
         IDCDescriptiveProperties.providedBy(context):
        title = context.title
    return title
Example #6
0
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)
Example #7
0
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)
Example #8
0
 def domain_model(self):
     unproxied = removeSecurityProxy(self.context)
     if IAlchemistContainer.providedBy(unproxied):
         return unproxied.domain_model
     elif IAlchemistContent.providedBy(unproxied):
         return unproxied.__class__
     else:
         raise AttributeError("Could not find domain model for context: %s", unproxied)
Example #9
0
 def domain_model(self):
     unproxied = removeSecurityProxy(self.context)
     if IAlchemistContainer.providedBy(unproxied):
         return unproxied.domain_model
     elif IAlchemistContent.providedBy(unproxied):
         return unproxied.__class__
     else:
         raise AttributeError("Could not find domain model for context: %s",
                              unproxied)
Example #10
0
 def form_name(self):
     # play nice w/ containers or content views, or content
     domain_model = getattr(self.context, "domain_model", None)
     if domain_model is None:
         domain_model = getattr(self, "domain_model", None)
         if (domain_model is None
                 and IAlchemistContent.providedBy(self.context)):
             domain_model = self.context.__class__
     if domain_model is None:
         return self.mode.title()
     return "%s %s" % (self.mode.title(), domain_model.__name__)
Example #11
0
def cascade_modifications(obj):
    """Cascade modify events on an object to the direct parent.
    !+NAMING(mr, nov-2012) why cascade (implies down?!) instead of bubble (up, usually)?
    Plus, we are not cascading *modifications* anyway, we are just notifying of such... !
    !+EVENT_CONSUMER_ISSUE(mr, nov-2012) why fire new events off the ancestor if 
    the descendent has presumably already fired off its own modified event? 
    If anything it should be a new specialized type of event, with a pointer to 
    the original trigger object (descendent that was modified), so that the 
    consumer can know it is a "derived" event and maybe act accordingly... as
    it is, all modified event handlers registerd will execute, e.g. auditing of 
    the change if the ancestor is auditable, but the change had already been 
    audited on the originator modified descendent object.
    """
    if not ILocation.providedBy(obj):
        return
    if IAlchemistContainer.providedBy(obj.__parent__):
        if IAlchemistContent.providedBy(obj.__parent__.__parent__):
            notify(ObjectModifiedEvent(obj.__parent__.__parent__))
    elif IAlchemistContent.providedBy(obj.__parent__):
        notify(ObjectModifiedEvent(obj.__parent__))
Example #12
0
def cascade_modifications(obj):
    """Cascade modify events on an object to the direct parent.
    !+NAMING(mr, nov-2012) why cascade (implies down?!) instead of bubble (up, usually)?
    Plus, we are not cascading *modifications* anyway, we are just notifying of such... !
    !+EVENT_CONSUMER_ISSUE(mr, nov-2012) why fire new events off the ancestor if 
    the descendent has presumably already fired off its own modified event? 
    If anything it should be a new specialized type of event, with a pointer to 
    the original trigger object (descendent that was modified), so that the 
    consumer can know it is a "derived" event and maybe act accordingly... as
    it is, all modified event handlers registerd will execute, e.g. auditing of 
    the change if the ancestor is auditable, but the change had already been 
    audited on the originator modified descendent object.
    """
    if not ILocation.providedBy(obj):
        return
    if IAlchemistContainer.providedBy(obj.__parent__):
        if IAlchemistContent.providedBy(obj.__parent__.__parent__):
            notify(ObjectModifiedEvent(obj.__parent__.__parent__))
    elif IAlchemistContent.providedBy(obj.__parent__):
        notify(ObjectModifiedEvent(obj.__parent__))
Example #13
0
 def form_name(self):
     # play nice w/ containers or content views, or content
     domain_model = getattr(self.context, "domain_model", None)
     if domain_model is None:
         domain_model = getattr(self, "domain_model", None)
         if (domain_model is None
                 and IAlchemistContent.providedBy(self.context)):
             domain_model = self.context.__class__
     if domain_model is None:
         return self.mode.title()
     return "%s %s" % (self.mode.title(), domain_model.__name__)
Example #14
0
 def __call__(self, context):
     if IAlchemistContent.providedBy(context):
         ctx = context
     elif  IAlchemistContainer.providedBy(context):
         domain_model = removeSecurityProxy(context.domain_model)
         ctx = domain_model()
     workflow = interfaces.IWorkflow(ctx)
     items = []
     for status in workflow.states.keys():
         items.append(SimpleTerm(status, status, 
             _(workflow.get_state(status).title)))
     return SimpleVocabulary(items)
Example #15
0
    def form_name(self):
        parent = self.context.__parent__
        if IAlchemistContainer.providedBy(parent):
            descriptor = queryModelDescriptor(parent.domain_model)
        elif IAlchemistContent.providedBy(self.context):
            descriptor = queryModelDescriptor(self.context.__class__)
        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
Example #16
0
    def form_name(self):
        parent = self.context.__parent__
        if IAlchemistContainer.providedBy(parent):
            descriptor = queryModelDescriptor(parent.domain_model)
        elif IAlchemistContent.providedBy(self.context):
            descriptor = queryModelDescriptor(self.context.__class__)
        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
Example #17
0
    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
Example #18
0
    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 = queryModelDescriptor(self.context.__class__)
        elif IAlchemistContainer.providedBy(parent):
            descriptor = queryModelDescriptor(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
Example #19
0
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
Example #20
0
def filterFields(context, form_fields):
    omit_names = []
    if IAlchemistContent.providedBy(context):
        md = queryModelDescriptor(context.__class__)
        for field in form_fields:
            try:
                can_write = security.canWrite(context, field.__name__)
                can_read = security.canAccess(context, field.__name__)
            except AttributeError:
                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)
Example #21
0
def filterFields(context, form_fields):
    omit_names = []
    if IAlchemistContent.providedBy(context):
        md = queryModelDescriptor(context.__class__)
        for field in form_fields:
            try:
                can_write = security.canWrite(context, field.__name__)
                can_read = security.canAccess(context, field.__name__)
            except AttributeError:
                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)
Example #22
0
        try:
            if prop_type == domain.vp.Binary:
                fname=PersistFiles.store_file(obj, parent, prop_name, root_key)
                if fname:
                    result[prop_name] = dict(saved_file=fname)
            else:
                result[prop_name] = getattr(obj, prop_name)
            extended_props.append(prop_name)
        except zope.security.interfaces.NoInteraction:
            log.error("Extended property %s requires an interaction.",
                prop_name)

    
    # any additional attributes - this allows us to capture any derived attributes
    seen_keys.extend(include + exclude + extended_props)
    if IAlchemistContent.providedBy(obj):
        try:
            domain_schema = utils.get_derived_table_schema(type(obj))
            known_names = [ k for k, d in 
                domain_schema.namesAndDescriptions(all=True) ]
            extra_properties = set(known_names).difference(set(seen_keys))
            seen_keys.extend(extra_properties)
            for prop_name in extra_properties:
                try:
                    result[prop_name] = getattr(obj, prop_name)
                except zope.security.interfaces.NoInteraction:
                    log.error("Attribute %s requires an interaction.", prop_name)
        except KeyError:
            log.warn("Could not find table schema for %s", obj)
    
    # any other properties defined on class
Example #23
0
                                        value=value,
                                        displayAs=display_name
                                    )
                                    continue
            result[property.key] = value
    
    for prop_name, prop_type in obj.__class__.extended_properties:
        try:
            result[prop_name] = getattr(obj, prop_name)
        except zope.security.interfaces.NoInteraction:
            log.error("Extended property %s requires an interaction.",
                prop_name)

    
    # any additional attributes - this allows us to capture any derived attributes
    if IAlchemistContent.providedBy(obj):
        seen_keys = ( [ prop.key for prop in mapper.iterate_properties ] + 
            include + exclude)
        try:
            domain_schema = utils.get_derived_table_schema(type(obj))
            known_names = [ k for k, d in 
                domain_schema.namesAndDescriptions(all=True) ]
            extra_properties = set(known_names).difference(set(seen_keys))
            for prop_name in extra_properties:
                try:
                    result[prop_name] = getattr(obj, prop_name)
                except zope.security.interfaces.NoInteraction:
                    log.error("Attribute %s requires an interaction.",
                        prop_name)

        except KeyError:
Example #24
0
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
Example #25
0
 def expand(self, chain, include_siblings=True):
     if len(chain) == 0:
         return ()
     context = chain.pop()
     items = []
     if IApplication.providedBy(context):
         items.extend(self.expand(chain))
     elif IAlchemistContent.providedBy(context):
         _url = url.absoluteURL(context, self.request)
         selected = len(chain) == 0
         
         if chain:
             nodes = self.expand(chain)
         else:
             containers = utils.get_managed_containers(context)
             nodes = []
             self.expand_containers(nodes, containers, _url, chain, None)
         
         items.append({
                 "id": self.get_nav_entry_id(_url),
                 "label": IDCDescriptiveProperties(context).title,
                 "url": _url,
                 "current": True,
                 "selected": selected,
                 "kind": "content",
                 "nodes": nodes,
             })
     elif IAlchemistContainer.providedBy(context):
         # loop through all managed containers of the parent
         # object, and include the present container as the
         # "current" node.
         parent = context.__parent__
         assert parent is not None
         _url = url.absoluteURL(parent, self.request)
         
         # append managed containers as child nodes            
         if include_siblings is True:
             if IApplication.providedBy(parent):
                 containers = [ (name, parent[name])
                     for name in 
                         location.model_to_container_name_mapping.values()
                     if name in parent ]
             elif IReadContainer.providedBy(parent):
                 containers = list(parent.items())
             else:
                 containers = utils.get_managed_containers(parent)
         else:
             containers = [(context.__name__, context)]
         self.expand_containers(items, containers, _url, chain, context)
     elif ILocation.providedBy(context):
         # e.g. bungeni.core.content.Section, DisplayForm
         _url = url.absoluteURL(context, self.request)
         selected = len(chain) == 0
         if selected and IReadContainer.providedBy(context):
             nodes = []
             try:
                 self.expand_containers(
                     nodes, context.items(), _url, chain, context)
             except:
                 pass
         else:
             nodes = self.expand(chain)
         _title = getattr(context, "title", None) or \
             getattr(context, "page_title", "!+BungeniBrowserView.title")
         items.append({
                 "id": self.get_nav_entry_id(_url),
                 # !+BungeniBrowserView.title
                 "label": _title, #IDCDescriptiveProperties(context).title,
                 "url": _url,
                 "current": True,
                 "selected": selected,
                 "kind": "location",
                 "nodes": nodes,
             })
     elif IReadContainer.providedBy(context):
         #!+NavigationTreeViewlet-EXPAND-IReadContainer(mr, oct-2012) does this ever execute?!
         raise Exception("!+NavigationTreeViewlet-EXPAND-IReadContainer [%s]" % context)
         items.extend(self.expand(chain))
     return items
Example #26
0
    def expand(self, chain, include_siblings=True):
        if len(chain) == 0:
            return ()

        context = chain.pop()
        items = []

        if IApplication.providedBy(context):
            items.extend(self.expand(chain))

        elif IAlchemistContent.providedBy(context):
            _url = url.absoluteURL(context, self.request)
            if IDCDescriptiveProperties.providedBy(context):
                title = context.title
            else:
                props = IDCDescriptiveProperties(context, None)
                if props is not None:
                    title = props.title
                else:
                    title = context.short_name

            selected = len(chain) == 0

            if chain:
                nodes = self.expand(chain)
            else:
                kls = context.__class__
                containers = [(key, getattr(context, key))
                              for key, value in kls.__dict__.items()
                              if isinstance(value, ManagedContainerDescriptor)]
                nodes = []
                self.expand_containers(nodes, containers, _url, chain, None)

            items.append({
                'title': title,
                'url': _url,
                'current': True,
                'selected': selected,
                'kind': 'content',
                'nodes': nodes,
            })

        elif IAlchemistContainer.providedBy(context):
            # loop through all managed containers of the parent
            # object, and include the present container as the
            # 'current' node.
            parent = context.__parent__
            assert parent is not None
            _url = url.absoluteURL(parent, self.request)

            # append managed containers as child nodes
            kls = type(proxy.removeSecurityProxy(parent))

            if include_siblings is True:
                if IApplication.providedBy(parent):
                    containers = [
                        (name, parent[name]) for name in
                        location.model_to_container_name_mapping.values()
                        if name in parent
                    ]
                elif IReadContainer.providedBy(parent):
                    containers = list(parent.items())
                else:
                    containers = [
                        (key, getattr(parent, key))
                        for key, value in kls.__dict__.items()
                        if isinstance(value, ManagedContainerDescriptor)
                    ]
            else:
                containers = [(context.__name__, context)]

            self.expand_containers(items, containers, _url, chain, context)

        elif ILocation.providedBy(context):
            _url = url.absoluteURL(context, self.request)
            #props = IDCDescriptiveProperties.providedBy(context) and \
            #    context or IDCDescriptiveProperties(context)
            if IDCDescriptiveProperties.providedBy(context):
                props = IDCDescriptiveProperties(context)
            else:
                props = context
            props = proxy.removeSecurityProxy(props)

            selected = len(chain) == 0
            if selected and IReadContainer.providedBy(context):
                nodes = []
                try:
                    self.expand_containers(nodes, context.items(), _url, chain,
                                           context)
                except:
                    pass
            else:
                nodes = self.expand(chain)
            i_id = getattr(props, 'id', 'N/A')
            items.append({
                'title': getattr(props, 'title', i_id),
                'url': _url,
                'current': True,
                'selected': selected,
                'kind': 'location',
                'nodes': nodes,
            })

        elif IReadContainer.providedBy(context):
            items.extend(self.expand(chain))

        return items
Example #27
0
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
Example #28
0
    def expand(self, chain, include_siblings=True):
        if len(chain) == 0:
            return ()
        context = chain.pop()
        items = []
        if IApplication.providedBy(context):
            items.extend(self.expand(chain))
        elif IAlchemistContent.providedBy(context):
            _url = url.absoluteURL(context, self.request)
            selected = len(chain) == 0

            if chain:
                nodes = self.expand(chain)
            else:
                containers = utils.get_managed_containers(context)
                nodes = []
                self.expand_containers(nodes, containers, _url, chain, None)

            items.append({
                "id": self.get_nav_entry_id(_url),
                "label": IDCDescriptiveProperties(context).title,
                "url": _url,
                "current": True,
                "selected": selected,
                "kind": "content",
                "nodes": nodes,
            })
        elif IAlchemistContainer.providedBy(context):
            # loop through all managed containers of the parent
            # object, and include the present container as the
            # "current" node.
            parent = context.__parent__
            assert parent is not None
            _url = url.absoluteURL(parent, self.request)

            # append managed containers as child nodes
            if include_siblings is True:
                if IApplication.providedBy(parent):
                    containers = [
                        (name, parent[name]) for name in
                        location.model_to_container_name_mapping.values()
                        if name in parent
                    ]
                elif IReadContainer.providedBy(parent):
                    containers = list(parent.items())
                else:
                    containers = utils.get_managed_containers(parent)
            else:
                containers = [(context.__name__, context)]
            self.expand_containers(items, containers, _url, chain, context)
        elif ILocation.providedBy(context):
            # e.g. bungeni.core.content.Section, DisplayForm
            _url = url.absoluteURL(context, self.request)
            selected = len(chain) == 0
            if selected and IReadContainer.providedBy(context):
                nodes = []
                try:
                    self.expand_containers(nodes, context.items(), _url, chain,
                                           context)
                except:
                    pass
            else:
                nodes = self.expand(chain)
            _title = getattr(context, "title", None) or \
                getattr(context, "page_title", "!+BungeniBrowserView.title")
            items.append({
                "id": self.get_nav_entry_id(_url),
                # !+BungeniBrowserView.title
                "label": _title,  #IDCDescriptiveProperties(context).title,
                "url": _url,
                "current": True,
                "selected": selected,
                "kind": "location",
                "nodes": nodes,
            })
        elif IReadContainer.providedBy(context):
            #!+NavigationTreeViewlet-EXPAND-IReadContainer(mr, oct-2012) does this ever execute?!
            raise Exception(
                "!+NavigationTreeViewlet-EXPAND-IReadContainer [%s]" % context)
            items.extend(self.expand(chain))
        return items
Example #29
0
    def expand(self, chain, include_siblings=True):
        if len(chain) == 0:
            return ()

        context = chain.pop()
        items = []

        if IApplication.providedBy(context):
            items.extend(self.expand(chain))

        elif IAlchemistContent.providedBy(context):
            _url = url.absoluteURL(context, self.request)
            if IDCDescriptiveProperties.providedBy(context):
                title = context.title
            else:
                props = IDCDescriptiveProperties(context, None)
                if props is not None:
                    title = props.title
                else:
                    title = context.short_name

            selected = len(chain) == 0
            
            if chain:
                nodes = self.expand(chain)
            else:
                kls = context.__class__
                containers = [
                    (key, getattr(context, key))
                    for key, value in kls.__dict__.items()
                    if isinstance(value, ManagedContainerDescriptor)]
                nodes = []
                self.expand_containers(nodes, containers, _url, chain, None)

            items.append(
                {'title': title,
                 'url': _url,
                 'current': True,
                 'selected': selected,
                 'kind': 'content',
                 'nodes': nodes,
                 })

        elif IAlchemistContainer.providedBy(context):
            # loop through all managed containers of the parent
            # object, and include the present container as the
            # 'current' node.
            parent = context.__parent__
            assert parent is not None
            _url = url.absoluteURL(parent, self.request)

            # append managed containers as child nodes
            kls = type(proxy.removeSecurityProxy(parent))

            if include_siblings is True:
                if IApplication.providedBy(parent):
                    containers = [
                        (name, parent[name])
                        for name in 
                            location.model_to_container_name_mapping.values()
                        if name in parent
                    ]
                elif IReadContainer.providedBy(parent):
                    containers = list(parent.items())
                else:
                    containers = [
                        (key, getattr(parent, key))
                        for key, value in kls.__dict__.items()
                        if isinstance(value, ManagedContainerDescriptor)]
            else:
                containers = [(context.__name__, context)]
                
            self.expand_containers(items, containers, _url, chain, context)

        elif ILocation.providedBy(context):
            _url = url.absoluteURL(context, self.request)
            #props = IDCDescriptiveProperties.providedBy(context) and \
            #    context or IDCDescriptiveProperties(context)
            if IDCDescriptiveProperties.providedBy(context):
                props = IDCDescriptiveProperties(context)
            else:
                props = context
            props = proxy.removeSecurityProxy(props)

            selected = len(chain) == 0
            if selected and IReadContainer.providedBy(context):
                nodes = []
                try:
                    self.expand_containers(
                        nodes, context.items(), _url, chain, context)
                except:
                    pass
            else:
                nodes = self.expand(chain)
            i_id = getattr(props, 'id','N/A')
            items.append(
                {'title': getattr(props, 'title', i_id),
                 'url': _url,
                 'current': True,
                 'selected': selected,
                 'kind': 'location',
                 'nodes': nodes,
                 })

        elif IReadContainer.providedBy(context):
            items.extend(self.expand(chain))

        return items
Example #30
0
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
Example #31
0
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
Example #32
0
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