diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2023-07-29 13:49:11 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2024-02-05 10:49:37 +0100 |
commit | 6e755a2dd02d4b04a85a9f261fa40308b0a9a5c6 (patch) | |
tree | 84bc212db7ab1085feb6b791706db0a014d5e750 /ishtar_common/models_imports.py | |
parent | fb9ca2c2704768dcd8b1b2d27741a2c043834f56 (diff) | |
download | Ishtar-6e755a2dd02d4b04a85a9f261fa40308b0a9a5c6.tar.bz2 Ishtar-6e755a2dd02d4b04a85a9f261fa40308b0a9a5c6.zip |
✨ Imports groups: models, admin
Diffstat (limited to 'ishtar_common/models_imports.py')
-rw-r--r-- | ishtar_common/models_imports.py | 117 |
1 files changed, 91 insertions, 26 deletions
diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py index e91a94868..457d3ff4e 100644 --- a/ishtar_common/models_imports.py +++ b/ishtar_common/models_imports.py @@ -42,7 +42,7 @@ from django.contrib.gis.geos.error import GEOSException from django.core.exceptions import ValidationError, SuspiciousOperation from django.core.files import File from django.core.files.base import ContentFile -from django.core.validators import validate_comma_separated_integer_list +from django.core.validators import validate_comma_separated_integer_list, MinValueValidator from django.db.models.base import ModelBase from django.db.models.signals import pre_delete from django.template.defaultfilters import slugify @@ -129,11 +129,6 @@ class ImporterModel(models.Model): return (self.klass,) -class ImporterTypeManager(models.Manager): - def get_by_natural_key(self, slug): - return self.get(slug=slug) - - IMPORT_TYPES = ( ("tab", _("Table")), ("gis", _("GIS")), @@ -155,6 +150,10 @@ class ImporterType(models.Model): type = models.CharField( _("Type"), max_length=3, choices=IMPORT_TYPES, default="tab" ) + tab_number = models.PositiveIntegerField( + _("Tab number"), default=1, validators=[MinValueValidator(1)], + help_text=_("When using an Excel or Calc file choose the tab number. Keep it to 1 by default.") + ) layer_name = models.CharField( _("Layer name"), max_length=200, @@ -184,6 +183,7 @@ class ImporterType(models.Model): related_name="importer_type_created", ) is_template = models.BooleanField(_("Can be exported"), default=False) + is_import = models.BooleanField(_("Can be import"), default=False) unicity_keys = models.CharField( _('Unicity keys (separator ";")'), blank=True, null=True, max_length=500, help_text=_("Mandatory for update importer. Set to key that identify items " @@ -191,7 +191,7 @@ class ImporterType(models.Model): "1 key.") ) available = models.BooleanField(_("Available"), default=True) - objects = ImporterTypeManager() + objects = SlugModelManager() SERIALIZATION_EXCLUDE = ["users"] class Meta: @@ -377,13 +377,47 @@ class ImporterType(models.Model): col_names.append(formater.label) return cols, col_names - def save(self, *args, **kwargs): if not self.slug: self.slug = create_slug(ImporterType, self.name) return super(ImporterType, self).save(*args, **kwargs) +class ImporterGroup(models.Model): + name = models.CharField(_("Name"), max_length=200) + slug = models.SlugField(_("Slug"), unique=True, max_length=100) + description = models.TextField( + _("Description"), blank=True, default="" + ) + available = models.BooleanField(_("Available"), default=True) + + class Meta: + verbose_name = _("Importer - Group") + verbose_name_plural = _("Importer - Groups") + ordering = ("name",) + ADMIN_SECTION = _("Imports") + objects = SlugModelManager() + + def natural_key(self): + return self.slug, + + def __str__(self): + return self.name + + @property + def importer_types_label(self) -> str: + return " ; ".join([imp.importer_type.name for imp in self.importer_types.all()]) + + +class ImporterGroupImporter(models.Model): + group = models.ForeignKey(ImporterGroup, on_delete=models.CASCADE, related_name="importer_types") + importer_type = models.ForeignKey(ImporterType, on_delete=models.CASCADE, related_name="groups") + order = models.PositiveIntegerField(_("Order"), default=10, validators=[MinValueValidator(1)]) + + class Meta: + ordering = ("group", "order") + + def get_associated_model(parent_model, keys): model = None if isinstance(parent_model, str): @@ -1133,6 +1167,21 @@ IMPORT_STATE = ( ) IMPORT_STATE_DCT = dict(IMPORT_STATE) + +IMPORT_GROUP_STATE = ( + ("C", _("Created")), + ("AP", _("Analyse in progress")), + ("A", _("Analysed")), + ("IQ", _("Import in queue")), + ("IP", _("Import in progress")), + ("PP", _("Post-processing in progress")), + ("FE", _("Finished with errors")), + ("F", _("Finished")), + ("AC", _("Archived")), +) + +IMPORT_GROUP_STATE_DCT = dict(IMPORT_STATE) + ENCODINGS = [ (settings.ENCODING, settings.ENCODING), (settings.ALT_ENCODING, settings.ALT_ENCODING), @@ -1192,13 +1241,11 @@ IMPORT_GEOMETRY = { } -class Import(models.Model): +class BaseImport(models.Model): user = models.ForeignKey( "IshtarUser", blank=True, null=True, on_delete=models.SET_NULL ) name = models.CharField(_("Name"), max_length=500, null=True) - importer_type = models.ForeignKey(ImporterType, on_delete=models.CASCADE, - verbose_name=_("Importer type")) imported_file = models.FileField( _("Imported file"), upload_to="upload/imports/%Y/%m/", @@ -1215,15 +1262,6 @@ class Import(models.Model): max_length=220, help_text=max_size_help(), ) - associated_group = models.ForeignKey( - TargetKeyGroup, - blank=True, - null=True, - on_delete=models.SET_NULL, - help_text=_( - "If a group is selected, target key saved in this group " "will be used." - ), - ) encoding = models.CharField( _("Encoding"), choices=ENCODINGS, default="utf-8", max_length=15, help_text=_("Only required for CSV file"), @@ -1243,6 +1281,39 @@ class Import(models.Model): default=1, help_text=_("Number of header lines in your file (can be 0 and should be 0 for geopackage or Shapefile)."), ) + creation_date = models.DateTimeField( + _("Creation date"), auto_now_add=True, blank=True, null=True + ) + end_date = models.DateTimeField( + _("End date"), auto_now_add=True, blank=True, null=True, editable=False + ) + + class Meta: + abstract = True + + +class ImportGroup(BaseImport): + importer_type = models.ForeignKey(ImporterGroup, on_delete=models.CASCADE, + verbose_name=_("Importer group type")) + current_import = models.PositiveIntegerField(_("Current import"), blank=True, null=True) + state = models.CharField( + _("State"), max_length=2, choices=IMPORT_GROUP_STATE, default="C" + ) + + +class Import(BaseImport): + importer_type = models.ForeignKey(ImporterType, on_delete=models.CASCADE, + verbose_name=_("Importer type")) + # TODO - associated_group: relevant? + associated_group = models.ForeignKey( + TargetKeyGroup, + blank=True, + null=True, + on_delete=models.SET_NULL, + help_text=_( + "If a group is selected, target key saved in this group will be used." + ), + ) error_file = models.FileField( _("Error file"), upload_to="upload/imports/%Y/%m/", @@ -1283,12 +1354,6 @@ class Import(models.Model): default=False, help_text=_("If set to true, do not overload existing values."), ) - creation_date = models.DateTimeField( - _("Creation date"), auto_now_add=True, blank=True, null=True - ) - end_date = models.DateTimeField( - _("End date"), auto_now_add=True, blank=True, null=True, editable=False - ) seconds_remaining = models.IntegerField( _("Remaining seconds"), blank=True, null=True, editable=False ) |