Exemple #1
0
def _potential_relations(obj):
    """Given an object return tuples of name, index, relation value.

    Returns both IRelationValue attributes as well as ITemporaryRelationValue
    attributes.

    If this is a IRelationList attribute, index will contain the index
    in the list. If it's a IRelation attribute, index will be None.
    """
    for iface in providedBy(obj).flattened():
        for name, field in getFields(iface).items():
            if IRelation.providedBy(field):
                try:
                    relation = getattr(obj, name)
                except AttributeError:
                    # can't find this relation on the object
                    continue
                yield name, None, relation
            if IRelationList.providedBy(field):
                try:
                    l = getattr(obj, name)
                except AttributeError:
                    # can't find the relation list on this object
                    continue
                if l is not None:
                    for i, relation in enumerate(l):
                        yield name, i, relation
Exemple #2
0
    def toFieldValue(self, value):
        """Converts from widget value to field.

        :param value: List of UID's separated by separator defined
        :type value: string

        :returns: List of content objects
        :rtype: list | tuple | set
        """
        if not value:
            return self.field.missing_value

        collectionType = self.field._type
        if isinstance(collectionType, tuple):
            collectionType = collectionType[-1]

        separator = getattr(self.widget, 'separator', ';')
        value = value.split(separator)

        if IRelationList.providedBy(self.field):
            try:
                catalog = getToolByName(self.widget.context, 'portal_catalog')
            except AttributeError:
                catalog = getToolByName(getSite(), 'portal_catalog')

            objects = {item.UID: item.getObject()
                       for item in catalog(UID=value) if item}

            return collectionType(objects[uid]
                                  for uid in value
                                  if uid in objects.keys())
        else:
            return collectionType(v for v in value)
 def set(self, data, only_keys=None):
     if not only_keys:
         only_keys = data.keys()
     # relations are done later to avoid circular dependencies errors
     db = i.IDatabaseGetter(self.context).database()
     intids = getUtility(IIntIds)
     for it in [k for k in data if k in only_keys]:
         value = data[it]
         field = i.ILiberticEvent.get(it)
         if IRelationList.providedBy(field) and bool(value):
             newval = []
             for v in value:
                 if not IRelationValue.providedBy(v):
                     v = RelationValue(intids.getId(v))
                 newval.append(v)
             value = newval
         ctx = self.context
         if it in ['expires', 'effective']:
             ctx = IPublication(self.context)
         if (it in ['contained', 'related'] and value):
             nval = []
             for itm in value:
                 if not isinstance(itm, basestring):
                     itm = IUUID(itm)
                 nval.append(itm)
             value = tuple(nval)
         setattr(ctx, it, value)
     IExcludeFromNavigation(self.context).exclude_from_nav = False
     db.reindexObject()
    def copy_fields(self, translation):
        doomed = False

        target_language = queryAdapter(translation, ILanguage).get_language()
        relation_copier = lambda r, l=target_language, f=self.copy_relation: f(r, l)

        for schema in iterSchemata(self.context):
            for field_name in schema:
                if ILanguageIndependentField.providedBy(schema[field_name]):
                    value = getattr(schema(self.context), field_name, _marker)

                    if value == _marker:
                        continue
                    elif IRelationValue.providedBy(value):
                        value = self.copy_relation(value, target_language)
                    elif IRelationList.providedBy(schema[field_name]):
                        value = map(relation_copier, value or [])

                    doomed = True
                    setattr(schema(translation), field_name, value)

        # If at least one field has been copied over to the translation
        # we need to inform subscriber to trigger an ObjectModifiedEvent
        # on that translation.
        return doomed
    def copy_fields(self, translation):
        doomed = False

        target_language = queryAdapter(translation, ILanguage).get_language()

        def relation_copier(rel, lang=target_language, fun=self.copy_relation):
            return fun(rel, lang)

        for schema in iterSchemata(self.context):
            for field_name in schema:
                if ILanguageIndependentField.providedBy(schema[field_name]):
                    value = getattr(schema(self.context), field_name, _marker)

                    if value == _marker:
                        continue
                    elif IRelationValue.providedBy(value):
                        value = self.copy_relation(value, target_language)
                    elif IRelationList.providedBy(schema[field_name]):
                        value = map(relation_copier, value or [])

                    doomed = True
                    setattr(schema(translation), field_name, value)

        # If at least one field has been copied over to the translation
        # we need to inform subscriber to trigger an ObjectModifiedEvent
        # on that translation.
        return doomed
def _potential_relations(obj):
    """Given an object return tuples of name, index, relation value.

    Returns both IRelationValue attributes as well as ITemporaryRelationValue
    attributes.

    If this is a IRelationList attribute, index will contain the index
    in the list. If it's a IRelation attribute, index will be None.
    """
    for iface in providedBy(obj).flattened():
        for name, field in getFields(iface).items():
            frel = name + '_rel'
            _rel = iface.queryTaggedValue(frel)
            if _rel is not None:
                field = _rel
                name = frel

            if IRelation.providedBy(field):
                try:
                    relation = getattr(obj, name)
                except AttributeError:
                    # can't find this relation on the object
                    continue
                yield name, None, relation
            if IRelationList.providedBy(field):
                try:
                    l = getattr(obj, name)
                except AttributeError:
                    # can't find the relation list on this object
                    continue
                if l is not None:
                    for i, relation in enumerate(l):
                        yield name, i, relation
Exemple #7
0
    def toFieldValue(self, value):
        """Converts from widget value to field.

        :param value: List of UID's separated by separator defined
        :type value: string

        :returns: List of content objects
        :rtype: list | tuple | set
        """
        if not value:
            return self.field.missing_value

        collectionType = self.field._type
        if isinstance(collectionType, tuple):
            collectionType = collectionType[-1]

        separator = getattr(self.widget, 'separator', ';')
        value = value.split(separator)

        if IRelationList.providedBy(self.field):
            try:
                catalog = getToolByName(self.widget.context, 'portal_catalog')
            except AttributeError:
                catalog = getToolByName(getSite(), 'portal_catalog')

            objects = {
                item.UID: item.getObject()
                for item in catalog(UID=value) if item
            }

            return collectionType(objects[uid] for uid in value
                                  if uid in objects.keys())
        else:
            return collectionType(v for v in value)
def has_relation_fields(fti):
    for schema in iterSchemataForType(fti):
        for fieldname in schema:
            field = schema[fieldname]
            if (IRelationChoice.providedBy(field) or
                IRelationList.providedBy(field)):
                return True
    return False
Exemple #9
0
def has_relation_fields(fti):
    for schema in iterSchemataForType(fti):
        for fieldname in schema:
            field = schema[fieldname]
            if (IRelationChoice.providedBy(field)
                    or IRelationList.providedBy(field)):
                return True
    return False
 def afterRetrieveModifier(self, obj, repo_clone, preserve=()):
     """Restore relations from the working copy."""
     if IDexterityContent.providedBy(obj):
         for schemata in iterSchemata(obj):
             for name, field in getFields(schemata).items():
                 if IRelationChoice.providedBy(field) or IRelationList.providedBy(field):
                     field.set(field.interface(repo_clone), field.query(field.interface(obj)))
     return [], [], {}
 def afterRetrieveModifier(self, obj, repo_clone, preserve=()):
     """Restore relations from the working copy."""
     if IDexterityContent.providedBy(obj):
         for schemata in iterSchemata(obj):
             for name, field in getFields(schemata).items():
                 if (IRelationChoice.providedBy(field) or
                         IRelationList.providedBy(field)):
                     field.set(field.interface(repo_clone),
                               field.query(field.interface(obj)))
     return [], [], {}
Exemple #12
0
    def set_field_values(self, obj):
        for name, field in self.iter_fields(obj):

            if name in self.arguments:
                value = self.arguments.get(name)

                if HAS_RELATION and IRelationChoice.providedBy(field):
                    value = self._as_relation_value(value)
                elif HAS_RELATION and IRelationList.providedBy(field):
                    value = [self._as_relation_value(item) for item in value]

                field.set(field.interface(obj), value)
Exemple #13
0
    def toWidgetValue(self, value):
        """Converts from field value to widget.

        :param value: List of catalog brains.
        :type value: list

        :returns: List of of UID separated by separator defined on widget.
        :rtype: string
        """
        if not value:
            return self.field.missing_value
        separator = getattr(self.widget, 'separator', ';')
        if IRelationList.providedBy(self.field):
            return separator.join([IUUID(o) for o in value if o])
        else:
            return separator.join(v for v in value if v)
Exemple #14
0
    def toWidgetValue(self, value):
        """Converts from field value to widget.

        :param value: List of catalog brains.
        :type value: list

        :returns: List of of UID separated by separator defined on widget.
        :rtype: string
        """
        if not value:
            return self.field.missing_value
        separator = getattr(self.widget, 'separator', ';')
        if IRelationList.providedBy(self.field):
            return separator.join([IUUID(o) for o in value if value])
        else:
            return separator.join(v for v in value if v)
    def getOnCloneModifiers(self, obj):
        """Removes relations.
        """
        relations = {}
        if IDexterityContent.providedBy(obj):
            for schemata in iterSchemata(obj):
                for name, field in getFields(schemata).items():
                    if (IRelationChoice.providedBy(field) or
                        IRelationList.providedBy(field)):
                        field_value = field.query(field.interface(obj))
                        if field_value is not None:
                            relations[id(aq_base(field_value))] = True

        def persistent_id(obj):
            return relations.get(id(obj), None)

        def persistent_load(obj):
            return None

        return persistent_id, persistent_load, [], []
Exemple #16
0
def extract_relations(obj):
    assignable = IBehaviorAssignable(obj, None)
    if assignable is None:
        return
    for behavior in assignable.enumerateBehaviors():
        if behavior.marker != behavior.interface:
            for name, field in getFields(behavior.interface).items():
                if IRelation.providedBy(field):
                    try:
                        relation = getattr(behavior.interface(obj), name)
                    except AttributeError:
                        continue
                    yield behavior.interface, name, relation
                if IRelationList.providedBy(field):
                    try:
                        l = getattr(behavior.interface(obj), name)
                    except AttributeError:
                        continue
                    if l is not None:
                        for relation in l:
                            yield behavior.interface, name, relation
    def get_fieldtype_by_schema(self, field):
        type_field = ""
        if IRelationList.providedBy(field):
            type_field = "relation"
        elif "ListField" in str(field):
            type_field = "datagridfield"
            self.datagrids[field.__name__] = False
        elif IChoice.providedBy(field):
            type_field = "choice"
        elif ITextLine.providedBy(field):
            type_field = "text"
        elif IList.providedBy(field):
            type_field = "list"
        elif IText.providedBy(field):
            type_field = "text"
        elif IRichText.providedBy(field):
            type_field = "text"
        else:
            type_field = "unknown"

        return type_field
    def get_default_value_by_schema(self, field):
        type_field = " "
        if IRelationList.providedBy(field):
            type_field = []
        elif "ListField" in str(field):
            type_field = []
            self.datagrids[field.__name__] = False
        elif IChoice.providedBy(field):
            type_field = " "
        elif ITextLine.providedBy(field):
            type_field = " "
        elif IList.providedBy(field):
            type_field = []
        elif IText.providedBy(field):
            type_field = " "
        elif IRichText.providedBy(field):
            type_field = " "
        else:
            type_field = " "

        return type_field
Exemple #19
0
def get_blobs_from_relations(value, field):
    """Extract the blobs from relationfields.
    """
    blobs = []
    if IRelationChoice.providedBy(field):
        rel = value
        if rel and not rel.isBroken():
            rel_obj = rel.to_object
            if rel_obj.portal_type == 'Image':
                blobs = [rel_obj.image]
            elif rel_obj.portal_type == 'File':
                blobs = [rel_obj.file]

    if IRelationList.providedBy(field):
        for rel in value:
            if rel and not rel.isBroken():
                rel_obj = rel.to_object
                if rel_obj.portal_type == 'Image':
                    blobs.append(rel_obj.image)
                elif rel_obj.portal_type == 'File':
                    blobs.append(rel_obj.file)
    return blobs
def get_blobs_from_relations(value, field):
    """Extract the blobs from relationfields.
    """
    blobs = []
    if IRelationChoice.providedBy(field):
        rel = value
        if rel and not rel.isBroken():
            rel_obj = rel.to_object
            if rel_obj.portal_type == 'Image':
                blobs = [rel_obj.image]
            elif rel_obj.portal_type == 'File':
                blobs = [rel_obj.file]

    if IRelationList.providedBy(field):
        for rel in value:
            if rel and not rel.isBroken():
                rel_obj = rel.to_object
                if rel_obj.portal_type == 'Image':
                    blobs.append(rel_obj.image)
                elif rel_obj.portal_type == 'File':
                    blobs.append(rel_obj.file)
    return blobs
Exemple #21
0
def extract_relations(obj):
    assignable = IBehaviorAssignable(obj, None)
    if assignable is None:
        return
    for behavior in assignable.enumerateBehaviors():
        if behavior.marker == behavior.interface:
            continue
        for name, field in getFields(behavior.interface).items():
            if IRelation.providedBy(field):
                try:
                    relation = getattr(behavior.interface(obj), name)
                except AttributeError:
                    continue
                yield behavior.interface, name, relation
            if IRelationList.providedBy(field):
                try:
                    rel_list = getattr(behavior.interface(obj), name)
                except AttributeError:
                    continue
                if rel_list is not None:
                    for relation in rel_list:
                        yield behavior.interface, name, relation
    def validate(self, value):

        if value:

            intids = getUtility(IIntIds)

            checkedout = []
            for iid in value:
                if not IRelationList.providedBy(self.field):
                    iid = int(iid)
                    doc = intids.getObject(int(iid))
                else:
                    doc = iid

                brain = uuidToCatalogBrain(IUUID(doc))
                if brain.checked_out:
                    checkedout.append(doc.title)

            if len(checkedout):
                raise Invalid(_(
                        u'error_checked_out_document',
                        default=u'The documents (${title}) are still checked out. \
                                Please checkin them in bevore deliver',
                        mapping={'title': ', '.join(checkedout)}))
Exemple #23
0
    def get_export_data(
        self,
        portal_type,
        blob_format,
        richtext_format,
        blacklist,
        whitelist,
        query,
    ):
        """Return a list of dicts with a dict for each object.

        The key is the name of the field/value and the value the value.
        """
        all_fields = get_schema_info(portal_type, blacklist, whitelist)

        results = []
        catalog = api.portal.get_tool('portal_catalog')
        if not query:
            query = dict()
        query['portal_type'] = portal_type
        if 'Language' not in query and HAS_MULTILINGUAL and \
                'Language' in catalog.indexes():
            query['Language'] = 'all'

        if 'path' not in query:
            query['path'] = {}
            query['path']['query'] = '/'.join(self.context.getPhysicalPath())

        brains = catalog(query)
        for brain in brains:
            obj = brain.getObject()
            item_dict = dict()

            for fieldname, field in all_fields:
                if fieldname in self.ADDITIONAL_MAPPING:
                    # The way to access the value from this fields is
                    # overridden in ADDITIONAL_MAPPING
                    continue

                value = field.get(field.interface(obj))
                if not value:
                    # set a value anyway to keep the dimensions of all
                    value = ''
                    # make sure we do no more transforms
                    field = None

                if IRichTextValue.providedBy(value):
                    value = transform_richtext(value, mimetype=richtext_format)

                if IRelationList.providedBy(field):
                    rel_val = []
                    for relation in value:
                        rel_val.append(get_url_for_relation(relation))
                    value = pretty_join(rel_val)

                if IRelationChoice.providedBy(field):
                    value = get_url_for_relation(value)

                if INamed.providedBy(value):
                    value = get_blob_url(value, brain, blob_format, fieldname)

                if IDatetime.providedBy(field) or IDate.providedBy(field):
                    value = api.portal.get_localized_time(value,
                                                          long_format=True)

                if safe_callable(value):
                    value = value()

                if isinstance(value, list) or isinstance(value, tuple):
                    value = pretty_join(value)

                if HAS_GEOLOCATION and isinstance(value, Geolocation):
                    value = value.__dict__
                item_dict[fieldname] = value

            # Update the data with additional info or overridden getters
            item_dict.update(self.additional_data(obj, blacklist))

            results.append(item_dict)
        return results
Exemple #24
0
    def __getattribute__(self, name):
        if name.startswith('_') or name.startswith(
                'portal_') or name.startswith('@@') or name == 'sql_id':
            return super(SQLDexterityItem, self).__getattribute__(name)
        connection = queryUtility(ISQLConnectionsUtility,
                                  name=self.portal_type,
                                  default=None)
        if connection == None and self.portal_type:
            fti = queryUtility(IDexterityFTI,
                               name=self.portal_type,
                               default=None)
            if not fti:
                return None
            updateConnectionsForFti(fti)
            connection = queryUtility(ISQLConnectionsUtility,
                                      name=self.portal_type,
                                      default=None)
        if name == 'view':
            #be sure session and sqlitem are up to date
            self._v_sql_item = None
            connection.session.close()
        if not connection:
            return super(SQLDexterityItem, self).__getattribute__(name)
        if name == 'UID' and self.sql_virtual:
            return self.portal_type + '-' + connection.sql_table + '-' + str(
                self.sql_id)
        if name == 'id' and 'id' not in connection.fieldnames.keys():
            if not self.sql_virtual:
                return super(SQLDexterityItem, self).__getattribute__(name)
            fti = ISQLTypeSettings(
                getUtility(IDexterityFTI, name=self.portal_type))
            nameFromTitle = INameFromTitle(self, None)
            if nameFromTitle is not None and nameFromTitle.title:
                sql_folder_id = getattr(fti, 'sql_folder_id',
                                        'data-' + self.portal_type)
                title = nameFromTitle.title
                folder = None
                if IRelationValue.providedBy(sql_folder_id):
                    folder = sql_folder_id.to_object
                elif sql_folder_id and sql_folder_id.startswith('/'):
                    portal = getToolByName(getSite(),
                                           'portal_url').getPortalObject()
                    folder = portal.restrictedTraverse(sql_folder_id)
                if folder:
                    name = INameChooser(folder).chooseName(title, self)
                    return name
#                return INameChooser(getSite()).chooseName(title, self)
#                return getUtility(IURLNormalizer).normalize(title)
                return self.sql_id
        if name in connection.fieldnames.keys():
            sql_column = connection.fieldnames[name]
            sql_item = self.getSQLItem()
            try:
                sql_id = getattr(sql_item, connection.sql_id_column, None)
            except orm_exc.DetachedInstanceError:
                self._v_sql_item = None
                sql_item = self.getSQLItem()
                sql_id = getattr(sql_item, connection.sql_id_column, None)
            fieldname = 'name'
            if sql_item and sql_column:
                while '.' in sql_column:
                    sql_key = sql_column.split('.')[0]
                    sql_item = getattr(sql_item, sql_key, None)
                    if isinstance(sql_item, list):
                        value = sql_item
                        fieldname = sql_column.split('.')[-1]
                        break
                    sql_column = '.'.join(sql_column.split('.')[1:])
                else:
                    if not isinstance(sql_item, list):
                        value = getattr(sql_item, sql_column, None)
                if not value and (isinstance(value, list)
                                  or hasattr(value, '_sa_instance_state')):
                    value = ''
                elif (isinstance(value, list)
                      or hasattr(value, '_sa_instance_state')):
                    sqlftis = [
                        a for a in getAllUtilitiesRegisteredFor(IDexterityFTI)
                        if
                        'collective.behavior.sql.behavior.behaviors.ISQLContent'
                        in a.behaviors and getattr(a, 'sql_table', None)
                    ]
                    if name == 'subject':
                        return tuple(
                            [getattr(a, fieldname, '') for a in value])
                    tableftis = []
                    for iface in iterSchemataForType(self.portal_type):
                        if name in iface.names():
                            field = iface[name]
                            if IRelationChoice.providedBy(
                                    field) or IRelationList.providedBy(field):
                                if IRelationChoice.providedBy(field):
                                    allowed_types = field.source.query.get(
                                        'portal_type', [])
                                else:
                                    allowed_types = field.value_type.source.query.get(
                                        'portal_type', [])
                                tableftis = []
                                for sqlfti in sqlftis:
                                    adapted = ISQLTypeSettings(sqlfti, None)
                                    if isinstance(value, list):
                                        classname = value[0].__class__.__name__
                                    else:
                                        classname = value.__class__.__name__
                                    if adapted and getattr(
                                            adapted, 'sql_table',
                                            None) == classname:
                                        if not allowed_types or sqlfti.id in allowed_types:
                                            tableftis.append(adapted)
                                catalog = getToolByName(
                                    getSite(), 'portal_catalog')
                                relations = []
                                for tablefti in tableftis:
                                    sql_id_column = getattr(
                                        tablefti, 'sql_id_column', 'id')
                                    valueids = []
                                    if isinstance(value, list):
                                        valueids = [
                                            getattr(a, sql_id_column, None)
                                            for a in value
                                            if getattr(a, sql_id_column, None)
                                        ]
                                    else:
                                        valueids = getattr(
                                            value, sql_id_column, None)
                                    valueids = [str(a) for a in valueids]
                                    brains = catalog.unrestrictedSearchResults(
                                        portal_type=tablefti.id,
                                        sql_id=valueids)
                                    for brain in brains:
                                        relations.append(
                                            SQLRelationValue(
                                                brain.portal_type, brain.UID,
                                                self))
                                if IRelationChoice.providedBy(
                                        field) and relations:
                                    return relations[0]
                                elif IRelationList.providedBy(
                                        field) and relations:
                                    return relations
                            elif ITuple.providedBy(field):
                                return tuple(
                                    [getattr(a, fieldname, '') for a in value])
                            elif IList.providedBy(field):
                                return [
                                    getattr(a, fieldname, '') for a in value
                                ]
                            elif value and isinstance(value, list):
                                value = getattr(value[0], fieldname, '')
                for iface in iterSchemataForType(self.portal_type):
                    if name == 'subject':
                        try:
                            return tuple([
                                a.decode('utf-8') for a in literal_eval(value)
                            ])
                        except:
                            return tuple([a.strip() for a in value.split(',')])
                    if name in iface.names():
                        field = iface[name]
                        if IRichText.providedBy(field):
                            if not value:
                                return ''
                            if not '<p' in value or not '<br' in value:
                                value = '<p>' + '</p><p>'.join([
                                    a for a in value.split('\n') if a.strip()
                                ]) + '</p>'


#                            try:
#                                value = str(value)
#                            except:
#                                try:
#                                    value = value.decode('utf-8')
#                                except:
#                                    try:
#                                        value = value.encode('utf-8')
#                                    except:
#                                        pass
                            return RichTextValue(unidecode(value))
                        elif INamedBlobImage.providedBy(field):
                            return NamedBlobImage(
                                base64.b64decode(value),
                                filename=unicode(self.portal_type + self.id +
                                                 ".jpg"))
                        elif ITuple.providedBy(field):
                            if not value:
                                return tuple([])
                            try:
                                return tuple([
                                    a.decode('utf-8')
                                    for a in literal_eval(value)
                                ])
                            except:
                                return tuple(
                                    [a.strip() for a in value.split(',')])
                        elif IList.providedBy(field):
                            if not value:
                                return []
                            try:
                                return [
                                    a.decode('utf-8')
                                    for a in literal_eval(value)
                                ]
                            except:
                                return [a.strip() for a in value.split(',')]
                        elif IDatetime.providedBy(field) and hasattr(
                                value, 'day') and not hasattr(value, 'hour'):
                            value = datetime.datetime.combine(
                                value, datetime.datetime.min.time())
                if name in [
                        'expiration_date', 'effective_date', 'effective',
                        'expires'
                ] and hasattr(value, 'day') and not hasattr(value, 'hour'):
                    value = datetime.datetime.combine(
                        value, datetime.datetime.min.time())
                if isinstance(value, unicode) or name == 'id':
                    try:
                        value = str(value)
                    except:
                        pass
                return value
        return super(SQLDexterityItem, self).__getattribute__(name)
 def __getattribute__(self, name):
     if name.startswith('_') or name.startswith('portal_') or name.startswith('@@'):
         return super(SQLDexterityItem, self).__getattribute__(name)
     if name == 'id' and not self.sql_virtual:
         return super(SQLDexterityItem, self).__getattribute__(name)
     connection = queryUtility(ISQLConnectionsUtility, name=self.portal_type, default=None)
     if connection == None and self.portal_type:
         fti = queryUtility(IDexterityFTI, name=self.portal_type, default=None)
         if not fti:
             return None
         updateConnectionsForFti(fti)
         connection = queryUtility(ISQLConnectionsUtility, name=self.portal_type, default=None)
     if not connection:
         return super(SQLDexterityItem, self).__getattribute__(name)
     if name == 'UID':
         return self.portal_type+'-'+connection.sql_table+'-'+str(self.sql_id)
     if name == 'id' and 'id' not in connection.fieldnames.keys():
         fti = ISQLTypeSettings(getUtility(IDexterityFTI, name=self.portal_type))
         nameFromTitle = INameFromTitle(self, None)
         if nameFromTitle is not None and nameFromTitle.title:
             sql_folder_id = getattr(fti, 'sql_folder_id', 'data-'+self.portal_type)
             title = nameFromTitle.title
             if IRelationValue.providedBy(name):
                 folder = sql_folder_id.to_object
                 if folder:
                     return INameChooser(folder).chooseName(title, self)
             return INameChooser(getSite()).chooseName(title, self)
     if name in connection.fieldnames.keys():
         sql_column = connection.fieldnames[name]
         sql_item = self.getSQLItem()
         fieldname = 'name'
         if sql_item and sql_column:
             while '.' in sql_column:
                 sql_item = getattr(sql_item, sql_column.split('.')[0], None)
                 if sql_item and ((isinstance(sql_item, list) and len(sql_item)>1) or hasattr(sql_item, '_sa_instance_state')):
                     value = sql_item
                     fieldname = sql_column.split('.')[-1]
                     break
                 sql_column = '.'.join(sql_column.split('.')[1:])
             else:
                 value = getattr(sql_item, sql_column, None)
             #this is a relation
             if value and (isinstance(value, list) or hasattr(value, '_sa_instance_state')):
                 sqlftis = [a for a in getAllUtilitiesRegisteredFor(IDexterityFTI) if 'collective.behavior.sql.behavior.behaviors.ISQLContent' in a.behaviors and getattr(a, 'sql_table', None)]
                 if name == 'subject':
                     return tuple([getattr(a, fieldname, '') for a in value])
                 tableftis = []
                 for iface in iterSchemataForType(self.portal_type):
                     if name in iface.names():
                         field = iface[name]
                         if IList.providedBy(field):
                             return [getattr(a, fieldname, '') for a in value] # hope it has name!
                         elif ITuple.providedBy(field):
                             return tuple([getattr(a, fieldname, '') for a in value])
                         if IRelationChoice.providedBy(field) or IRelationList.providedBy(field):
                             if IRelationChoice.providedBy(field):
                                 allowed_types = field.source.query.get('portal_type', [])
                             else:
                                 allowed_types = field.value_type.source.query.get('portal_type', [])
                             tableftis = []
                             for sqlfti in sqlftis:
                                 adapted = ISQLTypeSettings(sqlfti, None)
                                 if isinstance(value, list):
                                     classname = value[0].__class__.__name__
                                 else:
                                     classname = value.__class__.__name__
                                 if adapted and getattr(adapted, 'sql_table', None) == classname:
                                     if not allowed_types or sqlfti.id in allowed_types:
                                         tableftis.append(adapted)
                     
                             catalog = getToolByName(getSite(), 'portal_catalog')
                             relations = []
                             for tablefti in tableftis:
                                 sql_id_column = getattr(tablefti, 'sql_id_column', 'id')
                                 valueids = []
                                 if isinstance(value, list):
                                     valueids = [getattr(a, sql_id_column, None) for a in value if getattr(a, sql_id_column, None)]
                                 else:
                                     valueids = getattr(value, sql_id_column, None)
                                 brains = catalog.searchResults(portal_type=tablefti.id, sql_id=valueids)
                                 for brain in brains:
                                     relations.append(SQLRelationValue(brain.portal_type, brain.sql_id))
                             if IRelationChoice.providedBy(field) and relations:
                                 return relations[0]
                             elif IRelationList.providedBy(field) and relations:
                                 return relations
             for iface in iterSchemataForType(self.portal_type):
                 if name == 'subject':
                     try:
                         return tuple([a.decode('utf-8') for a in literal_eval(value)])
                     except:
                         return tuple([a.strip() for a in value.split(',')])
                 if name in iface.names():
                     field = iface[name]
                     if IRichText.providedBy(field):
                         return RichTextValue(value)
                     if INamedBlobImage.providedBy(field):
                         return NamedBlobImage(base64.b64decode(value), filename=unicode(self.portal_type+self.id+".jpg"))
                     if IList.providedBy(field):
                         try:
                             return [a.decode('utf-8') for a in literal_eval(value)]
                         except:
                             return [a.strip() for a in value.split(',')]
                     if ITuple.providedBy(field):
                         try:
                             return tuple([a.decode('utf-8') for a in literal_eval(value)])
                         except:
                             return tuple([a.strip() for a in value.split(',')])
                         
             if isinstance(value, unicode) or name == 'id':
                 try:
                     return str(value)
                 except:
                     pass
             return value
     return super(SQLDexterityItem, self).__getattribute__(name)
    def get_export_data(
        self,
        portal_type,
        blob_format,
        richtext_format,
        blacklist,
        whitelist,
        query,
    ):
        """Return a list of dicts with a dict for each object.

        The key is the name of the field/value and the value the value.
        """
        all_fields = get_schema_info(portal_type, blacklist, whitelist)

        results = []
        catalog = api.portal.get_tool('portal_catalog')
        if not query:
            query = dict()
        query['portal_type'] = portal_type
        if 'Language' not in query and HAS_MULTILINGUAL and \
                'Language' in catalog.indexes():
            query['Language'] = 'all'

        brains = catalog(query)
        for brain in brains:
            obj = brain.getObject()
            item_dict = dict()

            for fieldname, field in all_fields:
                if fieldname in self.ADDITIONAL_MAPPING:
                    # The way to access the value from this fields is
                    # overridden in ADDITIONAL_MAPPING
                    continue

                value = field.get(field.interface(obj))
                if not value:
                    # set a value anyway to keep the dimensions of all
                    value = ''
                    # make sure we do no more transforms
                    field = None

                if IRichTextValue.providedBy(value):
                    value = transform_richtext(value, mimetype=richtext_format)

                if IRelationList.providedBy(field):
                    rel_val = []
                    for relation in value:
                        rel_val.append(get_url_for_relation(relation))
                    value = pretty_join(rel_val)

                if IRelationChoice.providedBy(field):
                    value = get_url_for_relation(value)

                if INamed.providedBy(value):
                    value = get_blob_url(value, brain, blob_format, fieldname)

                if IDatetime.providedBy(field) or IDate.providedBy(field):
                    value = api.portal.get_localized_time(
                        value, long_format=True)

                if safe_callable(value):
                    value = value()

                if isinstance(value, list) or isinstance(value, tuple):
                    value = pretty_join(value)

                item_dict[fieldname] = value

            # Update the data with additional info or overridden getters
            item_dict.update(self.additional_data(obj, blacklist))

            results.append(item_dict)
        return results
    def __getattribute__(self, name):
        if name.startswith('_') or name.startswith('portal_') or name.startswith('@@') or name == 'sql_id':
            return super(SQLDexterityItem, self).__getattribute__(name)
        connection = queryUtility(ISQLConnectionsUtility, name=self.portal_type, default=None)
        if connection == None and self.portal_type:
            fti = queryUtility(IDexterityFTI, name=self.portal_type, default=None)
            if not fti:
                return None
            updateConnectionsForFti(fti)
            connection = queryUtility(ISQLConnectionsUtility, name=self.portal_type, default=None)
        if name == 'view':
            #be sure session and sqlitem are up to date
            self._v_sql_item = None
            connection.session.close()
        if not connection:
            return super(SQLDexterityItem, self).__getattribute__(name)
        if name == 'UID' and self.sql_virtual:
            return self.portal_type+'-'+connection.sql_table+'-'+str(self.sql_id)
        if name == 'id' and 'id' not in connection.fieldnames.keys():
            if not self.sql_virtual:
                return super(SQLDexterityItem, self).__getattribute__(name)
            fti = ISQLTypeSettings(getUtility(IDexterityFTI, name=self.portal_type))
            nameFromTitle = INameFromTitle(self, None)
            if nameFromTitle is not None and nameFromTitle.title:
                sql_folder_id = getattr(fti, 'sql_folder_id', 'data-'+self.portal_type)
                title = nameFromTitle.title
                folder = None
                if IRelationValue.providedBy(sql_folder_id):
                    folder = sql_folder_id.to_object
                elif sql_folder_id and sql_folder_id.startswith('/'):
                    portal = getToolByName(getSite(), 'portal_url').getPortalObject()
                    folder = portal.restrictedTraverse(sql_folder_id)
                if folder:
                    name = INameChooser(folder).chooseName(title, self)
                    return name
#                return INameChooser(getSite()).chooseName(title, self)
#                return getUtility(IURLNormalizer).normalize(title)
                return self.sql_id
        if name in connection.fieldnames.keys():
            sql_column = connection.fieldnames[name]
            sql_item = self.getSQLItem()
            try:
                sql_id = getattr(sql_item, connection.sql_id_column, None)
            except orm_exc.DetachedInstanceError:
                self._v_sql_item = None
                sql_item = self.getSQLItem()
                sql_id = getattr(sql_item, connection.sql_id_column, None)
            fieldname = 'name'
            if sql_item and sql_column:
                while '.' in sql_column:
                    sql_key = sql_column.split('.')[0]
                    sql_item = getattr(sql_item, sql_key, None)
                    if isinstance(sql_item, list):
                        value = sql_item
                        fieldname = sql_column.split('.')[-1]
                        break
                    sql_column = '.'.join(sql_column.split('.')[1:])
                else:
                    if not isinstance(sql_item, list):
                        value = getattr(sql_item, sql_column, None)
                if not value and (isinstance(value, list) or hasattr(value, '_sa_instance_state')):
                    value = ''
                elif (isinstance(value, list) or hasattr(value, '_sa_instance_state')):
                    sqlftis = [a for a in getAllUtilitiesRegisteredFor(IDexterityFTI) if 'collective.behavior.sql.behavior.behaviors.ISQLContent' in a.behaviors and getattr(a, 'sql_table', None)]
                    if name == 'subject':
                        return tuple([getattr(a, fieldname, '') for a in value])
                    tableftis = []
                    for iface in iterSchemataForType(self.portal_type):
                        if name in iface.names():
                            field = iface[name]
                            if IRelationChoice.providedBy(field) or IRelationList.providedBy(field):
                                if IRelationChoice.providedBy(field):
                                    allowed_types = field.source.query.get('portal_type', [])
                                else:
                                    allowed_types = field.value_type.source.query.get('portal_type', [])
                                tableftis = []
                                for sqlfti in sqlftis:
                                    adapted = ISQLTypeSettings(sqlfti, None)
                                    if isinstance(value, list):
                                        classname = value[0].__class__.__name__
                                    else:
                                        classname = value.__class__.__name__
                                    if adapted and getattr(adapted, 'sql_table', None) == classname:
                                        if not allowed_types or sqlfti.id in allowed_types:
                                            tableftis.append(adapted)
                                catalog = getToolByName(getSite(), 'portal_catalog')
                                relations = []
                                for tablefti in tableftis:
                                    sql_id_column = getattr(tablefti, 'sql_id_column', 'id')
                                    valueids = []
                                    if isinstance(value, list):
                                        valueids = [getattr(a, sql_id_column, None) for a in value if getattr(a, sql_id_column, None)]
                                    else:
                                        valueids = getattr(value, sql_id_column, None)
                                    valueids = [str(a) for a in valueids]
                                    brains = catalog.unrestrictedSearchResults(portal_type=tablefti.id, sql_id=valueids)
                                    for brain in brains:
                                        relations.append(SQLRelationValue(brain.portal_type, brain.UID, self))
                                if IRelationChoice.providedBy(field) and relations:
                                    return relations[0]
                                elif IRelationList.providedBy(field) and relations:
                                    return relations
                            elif ITuple.providedBy(field):
                                return tuple([getattr(a, fieldname, '') for a in value])
                            elif IList.providedBy(field):
                                return [getattr(a, fieldname, '') for a in value]
                            elif value and isinstance(value, list):
                                value = getattr(value[0], fieldname, '')
                for iface in iterSchemataForType(self.portal_type):
                    if name == 'subject':
                        try:
                            return tuple([a.decode('utf-8') for a in literal_eval(value)])
                        except:
                            return tuple([a.strip() for a in value.split(',')])
                    if name in iface.names():
                        field = iface[name]
                        if IRichText.providedBy(field):
                            if not value:
                                return ''
                            if not '<p' in value or not '<br' in value:
                                value = '<p>'+'</p><p>'.join([a for a in value.split('\n') if a.strip()])+'</p>'
#                            try:
#                                value = str(value)
#                            except:
#                                try:
#                                    value = value.decode('utf-8')
#                                except:
#                                    try:
#                                        value = value.encode('utf-8')
#                                    except:
#                                        pass
                            return RichTextValue(unidecode(value))
                        elif INamedBlobImage.providedBy(field):
                            return NamedBlobImage(base64.b64decode(value), filename=unicode(self.portal_type+self.id+".jpg"))
                        elif ITuple.providedBy(field):
                            if not value:
                                return tuple([])
                            try:
                                return tuple([a.decode('utf-8') for a in literal_eval(value)])
                            except:
                                return tuple([a.strip() for a in value.split(',')])
                        elif IList.providedBy(field):
                            if not value:
                                return []
                            try:
                                return [a.decode('utf-8') for a in literal_eval(value)]
                            except:
                                return [a.strip() for a in value.split(',')]
                        elif IDatetime.providedBy(field) and hasattr(value, 'day') and not hasattr(value, 'hour'):
                            value = datetime.datetime.combine(value, datetime.datetime.min.time())
                if name in ['expiration_date','effective_date', 'effective', 'expires'] and hasattr(value, 'day') and not hasattr(value, 'hour'):
                    value = datetime.datetime.combine(value, datetime.datetime.min.time())
                if isinstance(value, unicode) or name == 'id':
                    try:
                        value = str(value)
                    except:
                        pass
                return value
        return super(SQLDexterityItem, self).__getattribute__(name)
    def __getattribute__(self, name):
        if name.startswith('_') or name.startswith(
                'portal_') or name.startswith('@@'):
            return super(SQLDexterityItem, self).__getattribute__(name)
        if name == 'id' and not self.sql_virtual:
            return super(SQLDexterityItem, self).__getattribute__(name)
        connection = queryUtility(ISQLConnectionsUtility,
                                  name=self.portal_type,
                                  default=None)
        if connection == None and self.portal_type:
            fti = queryUtility(IDexterityFTI,
                               name=self.portal_type,
                               default=None)
            if not fti:
                return None
            updateConnectionsForFti(fti)
            connection = queryUtility(ISQLConnectionsUtility,
                                      name=self.portal_type,
                                      default=None)
        if not connection:
            return super(SQLDexterityItem, self).__getattribute__(name)
        if name == 'UID':
            return self.portal_type + '-' + connection.sql_table + '-' + str(
                self.sql_id)
        if name == 'id' and 'id' not in connection.fieldnames.keys():
            fti = ISQLTypeSettings(
                getUtility(IDexterityFTI, name=self.portal_type))
            nameFromTitle = INameFromTitle(self, None)
            if nameFromTitle is not None and nameFromTitle.title:
                sql_folder_id = getattr(fti, 'sql_folder_id',
                                        'data-' + self.portal_type)
                title = nameFromTitle.title
                if IRelationValue.providedBy(name):
                    folder = sql_folder_id.to_object
                    if folder:
                        return INameChooser(folder).chooseName(title, self)
                return INameChooser(getSite()).chooseName(title, self)
        if name in connection.fieldnames.keys():
            sql_column = connection.fieldnames[name]
            sql_item = self.getSQLItem()
            fieldname = 'name'
            if sql_item and sql_column:
                while '.' in sql_column:
                    sql_item = getattr(sql_item,
                                       sql_column.split('.')[0], None)
                    if sql_item and (
                        (isinstance(sql_item, list) and len(sql_item) > 1)
                            or hasattr(sql_item, '_sa_instance_state')):
                        value = sql_item
                        fieldname = sql_column.split('.')[-1]
                        break
                    sql_column = '.'.join(sql_column.split('.')[1:])
                else:
                    value = getattr(sql_item, sql_column, None)
                #this is a relation
                if value and (isinstance(value, list)
                              or hasattr(value, '_sa_instance_state')):
                    sqlftis = [
                        a for a in getAllUtilitiesRegisteredFor(IDexterityFTI)
                        if
                        'collective.behavior.sql.behavior.behaviors.ISQLContent'
                        in a.behaviors and getattr(a, 'sql_table', None)
                    ]
                    if name == 'subject':
                        return tuple(
                            [getattr(a, fieldname, '') for a in value])
                    tableftis = []
                    for iface in iterSchemataForType(self.portal_type):
                        if name in iface.names():
                            field = iface[name]
                            if IList.providedBy(field):
                                return [
                                    getattr(a, fieldname, '') for a in value
                                ]  # hope it has name!
                            elif ITuple.providedBy(field):
                                return tuple(
                                    [getattr(a, fieldname, '') for a in value])
                            if IRelationChoice.providedBy(
                                    field) or IRelationList.providedBy(field):
                                if IRelationChoice.providedBy(field):
                                    allowed_types = field.source.query.get(
                                        'portal_type', [])
                                else:
                                    allowed_types = field.value_type.source.query.get(
                                        'portal_type', [])
                                tableftis = []
                                for sqlfti in sqlftis:
                                    adapted = ISQLTypeSettings(sqlfti, None)
                                    if isinstance(value, list):
                                        classname = value[0].__class__.__name__
                                    else:
                                        classname = value.__class__.__name__
                                    if adapted and getattr(
                                            adapted, 'sql_table',
                                            None) == classname:
                                        if not allowed_types or sqlfti.id in allowed_types:
                                            tableftis.append(adapted)

                                catalog = getToolByName(
                                    getSite(), 'portal_catalog')
                                relations = []
                                for tablefti in tableftis:
                                    sql_id_column = getattr(
                                        tablefti, 'sql_id_column', 'id')
                                    valueids = []
                                    if isinstance(value, list):
                                        valueids = [
                                            getattr(a, sql_id_column, None)
                                            for a in value
                                            if getattr(a, sql_id_column, None)
                                        ]
                                    else:
                                        valueids = getattr(
                                            value, sql_id_column, None)
                                    brains = catalog.searchResults(
                                        portal_type=tablefti.id,
                                        sql_id=valueids)
                                    for brain in brains:
                                        relations.append(
                                            SQLRelationValue(
                                                brain.portal_type,
                                                brain.sql_id))
                                if IRelationChoice.providedBy(
                                        field) and relations:
                                    return relations[0]
                                elif IRelationList.providedBy(
                                        field) and relations:
                                    return relations
                for iface in iterSchemataForType(self.portal_type):
                    if name == 'subject':
                        try:
                            return tuple([
                                a.decode('utf-8') for a in literal_eval(value)
                            ])
                        except:
                            return tuple([a.strip() for a in value.split(',')])
                    if name in iface.names():
                        field = iface[name]
                        if IRichText.providedBy(field):
                            return RichTextValue(value)
                        if INamedBlobImage.providedBy(field):
                            return NamedBlobImage(
                                base64.b64decode(value),
                                filename=unicode(self.portal_type + self.id +
                                                 ".jpg"))
                        if IList.providedBy(field):
                            try:
                                return [
                                    a.decode('utf-8')
                                    for a in literal_eval(value)
                                ]
                            except:
                                return [a.strip() for a in value.split(',')]
                        if ITuple.providedBy(field):
                            try:
                                return tuple([
                                    a.decode('utf-8')
                                    for a in literal_eval(value)
                                ])
                            except:
                                return tuple(
                                    [a.strip() for a in value.split(',')])

                if isinstance(value, unicode) or name == 'id':
                    try:
                        return str(value)
                    except:
                        pass
                return value
        return super(SQLDexterityItem, self).__getattribute__(name)
    def export_blobs(self, portal_type, blob_type, blacklist, whitelist):
        """Return a zip-file with file and/or images  for the required export.
        """
        all_fields = get_schema_info(portal_type, blacklist, whitelist)
        if blob_type == 'images':
            fields = [
                i for i in all_fields if
                INamedImageField.providedBy(i[1]) or
                INamedBlobImageField.providedBy(i[1])]
        elif blob_type == 'files':
            fields = [
                i for i in all_fields if
                INamedFileField.providedBy(i[1]) or
                INamedBlobFileField.providedBy(i[1])]
        elif blob_type == 'related':
            fields = [
                i for i in all_fields if
                IRelationChoice.providedBy(i[1]) or
                IRelationList.providedBy(i[1])]

        tmp_file = NamedTemporaryFile()
        zip_file = zipfile.ZipFile(tmp_file, 'w')

        catalog = api.portal.get_tool('portal_catalog')
        query = {'portal_type': portal_type}
        blobs_found = False
        if HAS_MULTILINGUAL and 'Language' in catalog.indexes():
            query['Language'] = 'all'
        for brain in catalog(query):
            obj = brain.getObject()
            for fieldname, field in fields:
                # manually filter for fields
                # if fieldname not in ['primary_picture']:
                #     continue
                blobs = []
                value = field.get(field.interface(obj))
                if not value:
                    continue

                if blob_type != 'related':
                    blobs = [value]
                elif IRelationChoice.providedBy(field) or \
                        IRelationList.providedBy(field):
                    blobs = get_blobs_from_relations(value, field)

                for blob in blobs:
                    if not blob:
                        continue
                    filename = str((blob.filename).encode('utf8'))
                    zip_file.writestr(
                        '{0}_{1}/{2}'.format(
                            brain.UID,  # or: brain.id.upper(),
                            fieldname,
                            filename),
                        str(blob.data)
                    )
                    blobs_found = True

        zip_file.close()
        if not blobs_found:
            return 'No {0} found'.format(blob_type)
        data = file(tmp_file.name).read()
        response = self.request.response
        response.setHeader('content-type', 'application/zip')
        response.setHeader('content-length', len(data))
        response.setHeader(
            'content-disposition',
            'attachment; filename="{0}.zip"'.format(blob_type))
        return response.write(data)
Exemple #30
0
    def __iter__(self):  #  noqa
        # need to be refactored
        for item in self.previous:
            pathkey = self.pathkey(*list(item.keys()))[0]
            # not enough info
            if not pathkey:
                yield item
                continue

            path = item[pathkey]
            # Skip the Plone site object itself
            if not path:
                yield item
                continue

            obj = self.context.unrestrictedTraverse(path.lstrip("/"), None)

            # path doesn't exist
            if obj is None:
                yield item
                continue

            if IDexterityContent.providedBy(obj):
                uuid = item.get("plone.uuid")
                if uuid is not None:
                    try:
                        IMutableUUID(obj).set(str(uuid))
                    except Exception:
                        self.errored.append(item["_original_path"])

                files = item.setdefault(self.fileskey, {})

                # For all fields in the schema, update in roughly the same way
                # z3c.form.widget.py would
                for schemata in iterSchemata(obj):
                    for name, field in getFieldsInOrder(schemata):
                        if name == "id":
                            continue
                        if field.readonly:
                            continue
                        # setting value from the blueprint cue
                        value = item.get(name, _marker)
                        if value is not _marker:
                            if IRelationList.providedBy(
                                    field) or IRelationChoice.providedBy(
                                        field):  # noqa
                                self.transmogrifier.fixrelations.append((
                                    "/".join(obj.getPhysicalPath()),
                                    name,
                                    value,
                                ))  # noqa
                            # Value was given in pipeline, so set it
                            deserializer = queryMultiAdapter((field, obj),
                                                             IDeserializer)
                            try:
                                value = deserializer(
                                    value,
                                    files,
                                    item,
                                    self.disable_constraints,
                                    logger=self.log,
                                )
                                field.set(field.interface(obj), value)
                                continue
                            except Exception:
                                continue

                        # Get the widget's current value, if it has one then
                        # leave it alone
                        value = getMultiAdapter(
                            (obj, field), interfaces.IDataManager).query()
                        if not (value is field.missing_value
                                or value is interfaces.NO_VALUE):
                            continue

                        # Finally, set a default value if nothing is set so far
                        default = queryMultiAdapter(
                            (
                                obj,
                                obj.REQUEST,  # request
                                None,  # form
                                field,
                                None,  # Widget
                            ),
                            interfaces.IValue,
                            name="default",
                        )

                        if schemata.__name__ == "IAllowDiscussion":
                            default = item.get("allow_discusion", None)
                            field.set(field.interface(obj), default)
                            continue

                        if default is not None:
                            default = default.get()
                        if default is None:
                            default = getattr(field, "default", None)
                        if default is None:
                            try:
                                default = field.missing_value
                            except AttributeError:
                                pass
                        field.set(field.interface(obj), default)
                notify(ObjectModifiedEvent(obj))
            yield item
Exemple #31
0
    def update_data_for_migration(self, item, obj):
        """Update serialized data to optimze use for migrations.

        1. Drop unused data
        2. Remove all relationfields (done with the serializer relationvalue_converter)
        3. Change some default-fieldnames (AT to DX)
        4. Fix issue with AT Text fields
        5. Fix collection-criteria
        6. Fix image links and scales
        7. Fix view names on Folder, Collection, Topic CT's

        """
        # 1. Drop unused data
        item.pop("@components", None)
        item.pop("next_item", None)
        item.pop("previous_item", None)
        item.pop("immediatelyAddableTypes", None)
        item.pop("locallyAllowedTypes", None)

        # 2. Remove all relationfields
        if HAS_AT and IBaseObject.providedBy(obj):
            for field in obj.schema.fields():
                if isinstance(field, ReferenceField):
                    item.pop(field.__name__, None)
        elif HAS_DX and HAS_RELATIONS and IDexterityContent.providedBy(obj):
            for schema in iterSchemata(obj):
                for name, field in getFields(schema).items():
                    if IRelationChoice.providedBy(field) or IRelationList.providedBy(
                        field
                    ):
                        item.pop(name, None)

        # 3. Change default-fieldnames (AT to DX)
        item = migrate_field(item, "excludeFromNav", "exclude_from_nav")
        item = migrate_field(item, "allowDiscussion", "allow_discussion")
        item = migrate_field(item, "subject", "subjects")

        # Some Date fields
        item = migrate_field(item, "expirationDate", "expires")
        item = migrate_field(item, "effectiveDate", "effective")
        item = migrate_field(item, "creation_date", "created")
        item = migrate_field(item, "modification_date", "modified")

        # Event fields
        item = migrate_field(item, "startDate", "start")
        item = migrate_field(item, "endDate", "end")
        item = migrate_field(item, "openEnd", "open_end")
        item = migrate_field(item, "eventUrl", "event_url")
        # url cannot be a empty string
        if item.get("event_url", None) == "":
            item["event_url"] = None
        item = migrate_field(item, "wholeDay", "whole_day")
        item = migrate_field(item, "contactEmail", "contact_email")
        item = migrate_field(item, "contactName", "contact_name")
        item = migrate_field(item, "contactPhone", "contact_phone")

        # 4. Fix issue with AT Text fields
        # This is done in the ATTextFieldSerializer

        # 5. Fix collection-criteria
        # TODO

        # 6. Fix image links and scales
        # TODO

        # 7. Fix view names on Folders and Collection
        if self.safe_portal_type in ("collection", "topic", "folder"):
            old_layout = item.get("layout", "does_not_exist")
            if old_layout in LISTING_VIEW_MAPPING:
                item["layout"] = LISTING_VIEW_MAPPING[old_layout]

        return item
Exemple #32
0
    def get_export_data(
        self,
        portal_type,
        blob_format,
        richtext_format,
        blacklist,
        whitelist,
        query,
    ):
        """Return a list of dicts with a dict for each object.

        The key is the name of the field/value and the value the value.
        """
        all_fields = get_schema_info(portal_type, blacklist, whitelist)

        results = []
        catalog = api.portal.get_tool('portal_catalog')
        if not query:
            query = dict()
        query['portal_type'] = portal_type
        if 'Language' not in query and HAS_MULTILINGUAL and \
                'Language' in catalog.indexes():
            query['Language'] = 'all'

        brains = catalog.unrestrictedSearchResults(query)
        for brain in brains:
            obj = brain.getObject()
            item_dict = dict()

            for fieldname, field in all_fields:
                if fieldname in self.ADDITIONAL_MAPPING:
                    # The way to access the value from this fields is
                    # overridden in ADDITIONAL_MAPPING
                    continue

                try:
                    value = field.get(field.interface(obj))
                except:
                    print("Skipping object at {0}".format(obj.absolute_url()))
                    break

                if not value:
                    # set a value anyway to keep the dimensions of all
                    value = ''
                    # make sure we do no more transforms
                    field = None

                if IRichTextValue.providedBy(value):
                    value = transform_richtext(value, mimetype=richtext_format)

                if IRelationList.providedBy(field):
                    rel_val = []
                    for relation in value:
                        rel_val.append(get_url_for_relation(relation))
                    value = pretty_join(rel_val)

                if IRelationChoice.providedBy(field):
                    value = get_url_for_relation(value)

                if INamed.providedBy(value):
                    value = get_blob_url(value, brain, blob_format, fieldname)

                if ICollection.providedBy(field):
                    r = []
                    for v in value:
                        if INamed.providedBy(v):
                            r.append(u'{0}/@@download/{1}'.format(
                                obj.absolute_url(), fieldname))
                            # r.append(base64.b64encode(v.data))
                        else:
                            r.append(v)
                    value = r

                if IDatetime.providedBy(field) or IDate.providedBy(field):
                    if value.year < 1000:
                        if value.year < 16:
                            year = value.year + 2000
                        else:
                            year = value.year + 1900
                        if IDate.providedBy(field):
                            value = datetime.date(month=value.month,
                                                  day=value.day,
                                                  year=year)
                        elif IDatetime.providedBy(field):
                            value = datetime.datetime(month=value.month,
                                                      day=value.day,
                                                      year=year,
                                                      hour=value.hour,
                                                      minute=value.minute,
                                                      second=value.second)
                    value = api.portal.get_localized_time(value,
                                                          long_format=True)

                if safe_callable(value):
                    value = value()

                if isinstance(value, list) or isinstance(value, tuple):
                    value = pretty_join(value)

                item_dict[fieldname] = value
            else:
                # Update the data with additional info or overridden getters
                item_dict.update(self.additional_data(obj, blacklist))

                results.append(item_dict)
                continue  # executed if the loop ended normally (no break)
            break  # executed if 'continue' was skipped (break)
        return results
Exemple #33
0
    def export_blobs(self, portal_type, blob_type, blacklist, whitelist):
        """Return a zip-file with file and/or images  for the required export.
        """
        all_fields = get_schema_info(portal_type, blacklist, whitelist)
        if blob_type == 'images':
            fields = [
                i for i in all_fields if INamedImageField.providedBy(i[1])
                or INamedBlobImageField.providedBy(i[1])
            ]
        elif blob_type == 'files':
            fields = [
                i for i in all_fields if INamedFileField.providedBy(i[1])
                or INamedBlobFileField.providedBy(i[1])
            ]
        elif blob_type == 'related':
            fields = [
                i for i in all_fields if IRelationChoice.providedBy(i[1])
                or IRelationList.providedBy(i[1])
            ]

        tmp_file = NamedTemporaryFile()
        zip_file = zipfile.ZipFile(tmp_file, 'w')

        catalog = api.portal.get_tool('portal_catalog')
        query = {'portal_type': portal_type}
        query['path'] = {}
        query['path']['query'] = '/'.join(self.context.getPhysicalPath())

        blobs_found = False
        if HAS_MULTILINGUAL and 'Language' in catalog.indexes():
            query['Language'] = 'all'
        for brain in catalog(query):
            obj = brain.getObject()
            for fieldname, field in fields:
                # manually filter for fields
                # if fieldname not in ['primary_picture']:
                #     continue
                blobs = []
                value = field.get(field.interface(obj))
                if not value:
                    continue

                if blob_type != 'related':
                    blobs = [value]
                elif IRelationChoice.providedBy(field) or \
                        IRelationList.providedBy(field):
                    blobs = get_blobs_from_relations(value, field)

                for blob in blobs:
                    if not blob:
                        continue
                    filename = str((blob.filename).encode('utf8'))
                    zip_file.writestr(
                        '{0}_{1}/{2}'.format(
                            brain.UID,  # or: brain.id.upper(),
                            fieldname,
                            filename),
                        str(blob.data))
                    blobs_found = True

        zip_file.close()
        if not blobs_found:
            return 'No {0} found'.format(blob_type)
        data = file(tmp_file.name).read()
        response = self.request.response
        response.setHeader('content-type', 'application/zip')
        response.setHeader('content-length', len(data))
        response.setHeader('content-disposition',
                           'attachment; filename="{0}.zip"'.format(blob_type))
        return response.write(data)