diff options
Diffstat (limited to 'chimere/utils.py')
| -rw-r--r-- | chimere/utils.py | 97 | 
1 files changed, 70 insertions, 27 deletions
| diff --git a/chimere/utils.py b/chimere/utils.py index 1aa639a..20dc99e 100644 --- a/chimere/utils.py +++ b/chimere/utils.py @@ -80,6 +80,7 @@ class ImportManager(object):      def create_or_update_item(self, cls, values, import_key, version=None,                                key='', pk=None, category=None): +        from models import PropertyModel          updated, created, item = False, False, None          import_key = unicode(import_key).replace(':', '^')          if not values.get('name'): @@ -87,6 +88,11 @@ class ImportManager(object):          if not key:              key = self.importer_instance.importer_type          item = None +        pms = [pm["slug"] for pm in PropertyModel.objects.values('slug').all()] +        properties = {} +        for k in values.keys(): +            if k in pms: +                properties[k] = values.pop(k)          if import_key or pk:              dct_import = {                  'import_key__icontains': '%s:%s;' % (key, import_key), @@ -134,6 +140,7 @@ class ImportManager(object):              if not self.importer_instance.associate_marker_to_way\                      and cls.__name__ == 'Route':                  values['has_associated_marker'] = False +              try:                  item = cls.objects.create(**values)                  item.modified_since_import = False @@ -150,6 +157,8 @@ class ImportManager(object):          else:              for cat in self.importer_instance.categories.all():                  item.categories.add(cat) +        for prop in properties: +            item.setProperty(prop, properties[prop])          return item, updated, created      @classmethod @@ -332,6 +341,9 @@ class ShapefileManager(ImportManager):           - number of new item ;           - number of item updated ;           - error detail on error + +        The filtr argument allow to specify match between the shapefile cols +        and the db. JSON format is used.          """          from models import Marker, Route, Polygon          new_item, updated_item, msg = 0, 0, '' @@ -366,19 +378,53 @@ class ShapefileManager(ImportManager):          shapefilename = tmpdir + os.sep + sources[0]          ds = DataSource(shapefilename)          lyr = ds[0] -        # for this first version it is assumed that the first field is a -        # id name and the second field is the name -        id_name = lyr.fields[0] if len(lyr.fields) > 0 else None -        # test if id_name is well guess -        if id_name: -            ids = lyr.get_fields(id_name) -            if len(ids) != len(set(ids)): -                id_name = None -        lbl_name = None -        if len(lyr.fields) > 1: -            lbl_name = lyr.fields[1] -        elif id_name: -            lbl_name = id_name +        default_dct = {} +        filtr = self.importer_instance.filtr +        if filtr: +            try: +                filtr = json.JSONDecoder().decode(self.importer_instance.filtr) +            except ValueError: +                return ( +                    new_item, updated_item, +                    _(u"Bad configuration: filter must be a valid " +                      u"JSON string")) +            for k in ('id',): +                if k not in filtr: +                    return ( +                        new_item, updated_item, +                        _(u"The key \"%s\" is missing in the " +                          u"filter.") % k) +            for k in filtr: +                try: +                    ids = lyr.get_fields(k) +                except: +                    return ( +                        new_item, updated_item, +                        _(u"Config: {} is not an appropriate column name " +                          u"for this Shapefile. Available columns " +                          u" are: {}").format(k, u", ".join( +                              [j for j in lyr.fields]))) +            default_dct = {'origin': self.importer_instance.origin, +                           'license': self.importer_instance.license} +            if 'prefix_name' in filtr: +                default_dct['name'] = filtr.pop('prefix_name') +            if 'prefix_description' in filtr: +                default_dct['description'] = filtr.pop('prefix_description') +        else: +            # if no filtr it is assumed that the first field is a +            # id name and the second field is the name +            id_name = lyr.fields[0] if len(lyr.fields) > 0 else None +            # test if id_name is well guess +            if id_name: +                ids = lyr.get_fields(id_name) +                if len(ids) != len(set(ids)): +                    id_name = None +            filtr['id'] = id_name +            if len(lyr.fields) > 1: +                filtr["name"] = lyr.fields[1] +            elif id_name: +                filtr["name"] = id_name +          if lyr.geom_type not in ('Point', 'LineString', 'Polygon'):              return (0, 0, _(u"Type of geographic item (%s) of this shapefile "                              u"is not managed by Chimère.") % lyr.geom_type) @@ -395,32 +441,29 @@ class ShapefileManager(ImportManager):              geom_cls = Route          # indexes = []          for idx, feat in enumerate(lyr): -            name = unicode(idx) -            if lbl_name: -                name = feat.get(lbl_name) +            dct = default_dct.copy() +            for k in filtr: +                val = feat.get(k)                  try: -                    name = unicode(name) +                    val = unicode(val)                  except UnicodeDecodeError:                      try: -                        name = unicode( -                            name.decode(settings.CHIMERE_SHAPEFILE_ENCODING)) +                        val = unicode( +                            val.decode(settings.CHIMERE_SHAPEFILE_ENCODING))                      except:                          continue +                if filtr[k] not in dct: +                    dct[filtr[k]] = '' +                dct[filtr[k]] += val              try:                  geoms = [feat.geom.wkt]              except:                  return (0, 0, _(u"Bad Shapefile"))              if feat.geom.geom_type == 'MultiLineString':                  geoms = [geom.wkt for geom in feat.geom] -            import_key = feat.get(id_name) if id_name and len(geoms) == 1 \ -                else '' +            import_key = dct.pop('id')              for geom in geoms: -                dct = { -                    geom_key: 'SRID=%s;%s' % (srid, geom), -                    'name': name, -                    'origin': self.importer_instance.origin, -                    'license': self.importer_instance.license -                } +                dct[geom_key] = 'SRID=%s;%s' % (srid, geom)                  item, updated, created = self.create_or_update_item(                      geom_cls, dct, import_key)                  if updated: | 
