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 [], [], {}
示例#3
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)
 def toFieldValue(self, value):
     if not value:
         return value
     intids = component.queryUtility(IIntIds)
     for row in value:
         for key in row:
             if row[key] and IRelationChoice.providedBy(self.field.value_type.schema[key]):
                 to_id = intids.queryId(row[key])
                 if to_id:
                     relation = RelationValue(to_id)
                     _setRelation(row[key], key, relation)
                     row[key] = relation
     return value
 def toWidgetValue(self, value):
     if not value:
         return value
     new_value = []
     for row in value:
         new_row = {}
         for key in row:
             new_row[key] = row[key]
             if row[key] and IRelationChoice.providedBy(self.field.value_type.schema[key]):
                 if hasattr(row[key], 'to_object'):
                     new_row[key] = row[key].to_object
         new_value.append(new_row)
     return new_value
    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, [], []
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 __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 __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 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 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)
示例#12
0
    def __getattribute__(self, name):
        if name.startswith('_') or name.startswith(
                'portal_') or name.startswith(
                    '@@') or name == 'sql_id' or name in SpecificAttrs:
            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:
                                value = ''
                            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)
示例#13
0
    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)
示例#14
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)
示例#15
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
示例#16
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