diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2022-03-16 18:04:57 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2022-12-12 12:21:00 +0100 |
commit | aaf752eb46b1964f261979c91e424309717b8868 (patch) | |
tree | fdd4a4db0dc83330d09944049aebc8062441b505 | |
parent | 95b1566b4019b8b61a8e1fa8c2bef8b9fcacf273 (diff) | |
download | Ishtar-aaf752eb46b1964f261979c91e424309717b8868.tar.bz2 Ishtar-aaf752eb46b1964f261979c91e424309717b8868.zip |
Geodata: form to create GIS import
-rw-r--r-- | ishtar_common/forms_common.py | 95 | ||||
-rw-r--r-- | ishtar_common/migrations/0221_importertype_type.py | 18 | ||||
-rw-r--r-- | ishtar_common/models_imports.py | 8 | ||||
-rw-r--r-- | ishtar_common/templates/ishtar/import_list.html | 2 | ||||
-rw-r--r-- | ishtar_common/urls.py | 5 | ||||
-rw-r--r-- | ishtar_common/views.py | 9 |
6 files changed, 127 insertions, 10 deletions
diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index af41e2fcf..ed59b6c85 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -27,7 +27,7 @@ import requests import shutil import tempfile from urllib.parse import urlparse, quote -from zipfile import ZipFile, BadZipFile +import zipfile from django import forms from django.conf import settings @@ -203,18 +203,21 @@ class BaseImportForm(BSForm, forms.ModelForm): ] self.fields["importer_type"].choices = [("", "--")] + [ (imp.pk, imp.name) - for imp in models.ImporterType.objects.filter(available=True) + for imp in models.ImporterType.objects.filter(available=True, + type=self.importer_type) ] + if "imported_images" in self.fields: + self.fields["imported_images"].validators = [file_size_validator] + self.fields["imported_file"].validators = [file_size_validator] - self.fields["imported_images"].validators = [file_size_validator] self._post_init() def clean(self): data = self.cleaned_data if ( - data.get("conservative_import", None) - and data.get("importer_type") - and not data.get("importer_type").unicity_keys + data.get("conservative_import", None) + and data.get("importer_type") + and not data.get("importer_type").unicity_keys ): raise forms.ValidationError( _( @@ -222,6 +225,35 @@ class BaseImportForm(BSForm, forms.ModelForm): "Conservative import is not possible." ) ) + return data + + +class NewImportForm(NewImportFormBase): + imported_images_link = forms.URLField( + label=_("Associated images (web link to a zip file)"), required=False + ) + + class Meta: + model = models.Import + fields = ( + "name", + "importer_type", + "imported_file", + "encoding", + "csv_sep", + "imported_images", + "imported_images_link", + "associated_group", + "conservative_import", + "skip_lines", + ) + + HEADERS = { + "name": FormHeader(_("Import (table)")), + } + + def clean(self): + data = super().clean() if data.get("imported_images_link", None) and data.get("imported_images", None): raise forms.ValidationError( _( @@ -232,9 +264,9 @@ class BaseImportForm(BSForm, forms.ModelForm): if data.get("imported_images"): try: images = data.get("imported_images") - zf = ZipFile(images) + zf = zipfile.ZipFile(images) zf.testzip() - except BadZipFile: + except zipfile.BadZipFile: raise forms.ValidationError( _("\"Associated images\" field must be a valid zip file.") ) @@ -289,6 +321,53 @@ class BaseImportForm(BSForm, forms.ModelForm): return item +class NewImportGISForm(NewImportFormBase): + error_css_class = "error" + required_css_class = "required" + importer_type = "gis" + + class Meta: + model = models.Import + fields = ( + "name", + "importer_type", + "imported_file", + "associated_group", + "skip_lines", + ) + + HEADERS = { + "name": FormHeader(_("Import (GIS)")), + } + + def clean_imported_file(self): + value = self.cleaned_data.get("imported_file", None) + if value: + try: + ext = value.name.lower().split(".")[-1] + assert ext in ("zip", "gpkg") + if ext == "zip": + zip_file = zipfile.ZipFile(value) + assert not zip_file.testzip() + has_correct_file = False + for name in zip_file.namelist(): + in_ext = name.lower().split(".")[-1] + if in_ext in ("shp", "gpkg"): + filename = name + has_correct_file = True + break + assert has_correct_file + except AssertionError: + raise forms.ValidationError( + _("GIS file must be a zip containing a ShapeFile or GeoPackage file.") + ) + return value + + def save(self, user, commit=True): + item = super(NewImportGISForm, self).save(commit) + return item + + class TargetKeyForm(forms.ModelForm): class Meta: model = models.TargetKey diff --git a/ishtar_common/migrations/0221_importertype_type.py b/ishtar_common/migrations/0221_importertype_type.py new file mode 100644 index 000000000..7c15f31b6 --- /dev/null +++ b/ishtar_common/migrations/0221_importertype_type.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.24 on 2022-03-16 17:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ishtar_common', '0220_auto_20220222_1534'), + ] + + operations = [ + migrations.AddField( + model_name='importertype', + name='type', + field=models.CharField(choices=[('tab', 'Table'), ('gis', 'GIS')], default='tab', max_length=3, verbose_name='Type'), + ), + ] diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py index 799b3aab9..85b3473f9 100644 --- a/ishtar_common/models_imports.py +++ b/ishtar_common/models_imports.py @@ -119,6 +119,12 @@ class ImporterTypeManager(models.Manager): return self.get(slug=slug) +IMPORT_TYPES = ( + ("tab", "Table"), + ("gis", _("GIS")), +) + + class ImporterType(models.Model): """ Description of a table to be mapped with ishtar database @@ -129,6 +135,8 @@ class ImporterType(models.Model): description = models.CharField( _("Description"), blank=True, null=True, max_length=500 ) + type = models.CharField(_("Type"), max_length=3, choices=IMPORT_TYPES, + default='tab') users = models.ManyToManyField("IshtarUser", verbose_name=_("Users"), blank=True) associated_models = models.ForeignKey( ImporterModel, diff --git a/ishtar_common/templates/ishtar/import_list.html b/ishtar_common/templates/ishtar/import_list.html index 1b571dff7..2f1872610 100644 --- a/ishtar_common/templates/ishtar/import_list.html +++ b/ishtar_common/templates/ishtar/import_list.html @@ -20,7 +20,7 @@ <a href="{% url 'new_import' %}" class="btn btn-success"> <i class="fa fa-plus"></i> {% trans 'import (table)' %} </a> - <a href="#" class="btn btn-success"> + <a href="{% url 'new_import_gis' %}" class="btn btn-success"> <i class="fa fa-plus"></i> {% trans 'import (GIS)' %} </a> </div> diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py index 8f7255d4e..ffa8daebf 100644 --- a/ishtar_common/urls.py +++ b/ishtar_common/urls.py @@ -217,6 +217,11 @@ urlpatterns = [ name="edit_import", ), url( + r"^import-new-gis/$", + check_rights(["change_import"])(views.NewImportGISView.as_view()), + name="new_import_gis", + ), + url( r"^import-list/$", check_rights(["change_import"])(views.ImportListView.as_view()), name="current_imports", diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 81e6d5e05..cb5addc52 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -1378,7 +1378,7 @@ class NewImportView(IshtarMixin, LoginRequiredMixin, CreateView): template_name = "ishtar/form.html" model = models.Import form_class = forms.BaseImportForm - page_name = _("New import") + page_name = _("Import: create (table)") def get_success_url(self): return reverse("current_imports") @@ -1416,6 +1416,13 @@ class EditImportView(IshtarMixin, LoginRequiredMixin, UpdateView): return HttpResponseRedirect(self.get_success_url()) +class NewImportGISView(NewImportView): + template_name = "ishtar/form.html" + model = models.Import + form_class = forms.NewImportGISForm + page_name = _("Import: create (GIS)") + + class ImportListView(IshtarMixin, LoginRequiredMixin, ListView): template_name = "ishtar/import_list.html" model = models.Import |