示例#1
0
    def do_import(self, meta_type, data, REQUEST=None):
        """ """
        if REQUEST and not self.getParentNode().checkPermissionPublishObjects():
            raise Unauthorized

        errors = []

        schema = self.getSite().getSchemaTool().getSchemaForMetatype(meta_type)
        if schema is None:
            raise ValueError('Schema for meta-type not found: "%s"' % meta_type)

        content_type = self.getSite().get_pluggable_item(meta_type)
        add_object = content_type['add_method']

        location_obj = self.getParentNode()

        # build a list of property names based on the object schema
        # TODO: extract this loop into a separate function
        prop_map = {}
        for widget in schema.listWidgets():
            prop_name = widget.prop_name()

            if widget.multiple_form_values:
                for subname in widget.multiple_form_values:
                    prop_subname = prop_name + '.' + subname
                    prop_map[widget.title + ' - ' + subname] = {
                        'column': prop_subname,
                        'convert': widget.convert_from_user_string,
                    }
                if isinstance(widget, GeoWidget):
                    for subname in widget.multiple_form_values:
                        self.geo_fields[subname] = prop_name + '.' + subname
            else:
                prop_map[widget.title] = {
                    'column': prop_name,
                    'convert': widget.convert_from_user_string,
                }

        # and now for dynamic properties
        dynprop_tool = self.getSite().getDynamicPropertiesTool()
        for dyn_prop in dynprop_tool.getDynamicProperties(meta_type):
            prop_map[dyn_prop.name] = {
                'column': dyn_prop.id,
                'convert': lambda x: x,
            }

        try:
            reader = UnicodeReader(data)
            try:
                header = reader.next()
            except StopIteration:
                msg = 'Invalid CSV file'
                if REQUEST is None:
                    raise ValueError(msg)
                else:
                    errors.append(msg)
                    reader = []

            record_number = 0
            obj_ids = []

            for row in reader:
                try:
                    record_number += 1
                    # TODO: extract this block into a separate function
                    properties = {}
                    extra_properties = {}
                    for column, value in zip(header, row):
                        if value == '':
                            continue
                        if column not in prop_map:
                            extra_properties[column] = value
                            continue
                        key = prop_map[column]['column']
                        convert = prop_map[column]['convert']
                        properties[key] = convert(value)
                    properties = self.do_geocoding(properties)
                    ob_id = add_object(location_obj, _send_notifications=False, **properties)
                    ob = location_obj._getOb(ob_id)
                    if extra_properties:
                        adapter = ICSVImportExtraColumns(ob, None)
                        if adapter is not None:
                            adapter.handle_columns(extra_properties)
                    obj_ids.append(ob.getId())
                    ob.submitThis()
                    ob.approveThis()
                except UnicodeDecodeError, e:
                    raise
                except Exception, e:
                    self.log_current_error()
                    msg = ('Error while importing from CSV, row ${record_number}: ${error}',
                           {'record_number': record_number, 'error': str(e)})
                    if REQUEST is None:
                        raise ValueError(msg)
                    else:
                        errors.append(msg)
示例#2
0
             })
         warnings.append(msg)
         address = properties.pop(self.geo_fields['address'])
     ob_id = add_object(location_obj,
                        _send_notifications=False,
                        **properties)
     ob = location_obj._getOb(ob_id)
     if address:
         setattr(ob, self.geo_fields['address'].split('.')[0],
                 Geo(address=address))
         #user = self.REQUEST.AUTHENTICATED_USER.getUserName()
         #notify(NyContentObjectEditEvent(ob, user))
     if extra_properties:
         adapter = ICSVImportExtraColumns(ob, None)
         if adapter is not None:
             extra_props_messages = adapter.handle_columns(
                 extra_properties)
             if extra_props_messages:
                 errors.append(extra_props_messages)
     obj_ids.append(ob.getId())
     ob.submitThis()
     ob.approveThis(_send_notifications=False)
 except UnicodeDecodeError, e:
     raise
 except Exception, e:
     self.log_current_error()
     msg = (
         'Error while importing from file, row ${record_number}: ${error}',
         {
             'record_number':
             record_number + 1,  # account for header
             'error': str(e)