summaryrefslogtreecommitdiff
path: root/ishtar_common/models.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@proxience.com>2015-05-03 16:02:46 +0200
committerÉtienne Loks <etienne.loks@proxience.com>2015-05-03 16:02:46 +0200
commit5429ff2d3639bc96dc6bbd9d45a60a490a555775 (patch)
tree1f80cbb46ef1df0be2a42c34320e2ea8e507e805 /ishtar_common/models.py
parent466e0c8d4d27db904ea4bb8a856f83e468705f4a (diff)
downloadIshtar-5429ff2d3639bc96dc6bbd9d45a60a490a555775.tar.bz2
Ishtar-5429ff2d3639bc96dc6bbd9d45a60a490a555775.zip
Import: add management of link between user data and db data
Diffstat (limited to 'ishtar_common/models.py')
-rw-r--r--ishtar_common/models.py106
1 files changed, 85 insertions, 21 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index f2193eae2..1f059f2f5 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -28,6 +28,7 @@ from importlib import import_module
import os
import re
import tempfile
+import unicodecsv
from django.conf import settings
from django.core.cache import cache
@@ -955,13 +956,6 @@ class OrganizationType(GeneralType):
verbose_name_plural = _(u"Organization types")
ordering = ('label',)
-IMPORT_STATE = (("C", _(u"Created")),
- ("AP", _(u"Analyse in progress")),
- ("A", _(u"Analysed")),
- ("P", _(u"Import pending")),
- ("IP", _(u"Import in progress")),
- ("F", _(u"Finished")))
-
MODELS = [
('archaeological_operations.models.Operation', _(u"Operation")),
('archaeological_operations.models.Parcel', _(u"Parcels")),
@@ -985,6 +979,9 @@ def get_model_fields(model):
return fields
class ImporterType(models.Model):
+ """
+ Description of a table to be mapped with ishtar database
+ """
name = models.CharField(_(u"Name"), blank=True, null=True,
max_length=100)
description = models.CharField(_(u"Description"), blank=True, null=True,
@@ -1022,7 +1019,7 @@ class ImporterType(models.Model):
LINE_FORMAT.append(None)
continue
for target in column.targets.all():
- ft = target.formater_type.get_formater_type()
+ ft = target.formater_type.get_formater_type(target)
if not ft:
continue
formater_types.append(ft)
@@ -1032,8 +1029,9 @@ class ImporterType(models.Model):
formater_kwargs['regexp'] = re.compile(
column.regexp_pre_filter.regexp)
formater_kwargs['duplicate_fields'] = [field.field_name
- for field in column.duplicate_fields.all()]
- formater = ImportFormater(targets, formater_types, **formater_kwargs)
+ for field in column.duplicate_fields.all()]
+ formater = ImportFormater(targets, formater_types,
+ **formater_kwargs)
LINE_FORMAT.append(formater)
args = {'OBJECT_CLS':OBJECT_CLS, 'DESC':self.description,
'DEFAULTS':DEFAULTS, 'LINE_FORMAT':LINE_FORMAT}
@@ -1041,6 +1039,9 @@ class ImporterType(models.Model):
return newclass
class ImporterDefault(models.Model):
+ """
+ Targets of default values in an import
+ """
importer_type = models.ForeignKey(ImporterType, related_name='defaults')
target = models.CharField(u"Target", max_length=500)
class Meta:
@@ -1071,6 +1072,9 @@ class ImporterDefault(models.Model):
return values
class ImporterDefaultValues(models.Model):
+ """
+ Default values in an import
+ """
default_target = models.ForeignKey(ImporterDefault,
related_name='default_values')
target = models.CharField(u"Target", max_length=500)
@@ -1096,6 +1100,9 @@ class ImporterDefaultValues(models.Model):
return ""
class ImporterColumn(models.Model):
+ """
+ Import file column description
+ """
importer_type = models.ForeignKey(ImporterType, related_name='columns')
col_number = models.IntegerField(_(u"Column number"), default=1)
regexp_pre_filter = models.ForeignKey("Regexp", blank=True, null=True)
@@ -1105,6 +1112,9 @@ class ImporterColumn(models.Model):
verbose_name_plural = _(u"Importer - Columns")
class ImporterDuplicateField(models.Model):
+ """
+ Direct copy of result in other fields
+ """
column = models.ForeignKey(ImporterColumn, related_name='duplicate_fields')
field_name = models.CharField(_(u"Field name"), blank=True, null=True,
max_length=200)
@@ -1124,6 +1134,9 @@ class Regexp(models.Model):
IMPORTER_TYPES = []
class ImportTarget(models.Model):
+ """
+ Ishtar database target for a column
+ """
column = models.ForeignKey(ImporterColumn, related_name='targets')
target = models.CharField(u"Target", max_length=500)
regexp_filter = models.ForeignKey("Regexp", blank=True, null=True)
@@ -1132,6 +1145,26 @@ class ImportTarget(models.Model):
verbose_name = _(u"Importer - Target")
verbose_name_plural = _(u"Importer - Targets")
+ def __unicode__(self):
+ return u" - ".join([unicode(self.column), self.target[:50]])
+
+class TargetKey(models.Model):
+ """
+ User's link between import source and ishtar database.
+ Also temporary used for GeneralType to point missing link before adding
+ them in ItemKey table
+ """
+ target = models.ForeignKey(ImporterColumn, related_name='keys')
+ key = models.TextField(_(u"Key"), blank=True, null=True)
+ value = models.TextField(_(u"Value"))
+ is_set = models.BooleanField(_(u"Is set"), default=False)
+
+ class Meta:
+ unique_together = ('target', 'value')
+
+ def __unicode__(self):
+ return u" - ".join([unicode(self.target), self.key[:50]])
+
TARGET_MODELS = [
('OrganizationType', _(u"Organization type")),
('SourceType', _(u"Source type")),
@@ -1190,10 +1223,10 @@ class FormaterType(models.Model):
if self.format_type in IMPORTER_TYPES_CHOICES:
return IMPORTER_TYPES_CHOICES[self.format_type]
- def get_formater_type(self):
+ def get_formater_type(self, target):
if self.formater_type not in IMPORTER_TYPES_DCT.keys():
return
- kwargs = {}
+ kwargs = {'target':target}
if self.many_split:
kwargs['many_split'] = self.many_split
if self.formater_type == 'TypeFormater':
@@ -1206,35 +1239,44 @@ class FormaterType(models.Model):
model = import_module(self.options)
return TypeFormater(model, **kwargs)
elif self.formater_type == 'IntegerFormater':
- return IntegerFormater()
+ return IntegerFormater(**kwargs)
elif self.formater_type == 'FloatFormater':
- return FloatFormater()
+ return FloatFormater(**kwargs)
elif self.format_type == 'UnicodeFormater':
try:
- return UnicodeFormater(int(self.options.strip()))
+ return UnicodeFormater(int(self.options.strip()), **kwargs)
except ValueError:
return
elif self.format_type == 'DateFormater':
- return DateFormater(self.options)
+ return DateFormater(self.options, **kwargs)
+
+IMPORT_STATE = (("C", _(u"Created")),
+ ("AP", _(u"Analyse in progress")),
+ ("A", _(u"Analysed")),
+ ("P", _(u"Import pending")),
+ ("IP", _(u"Import in progress")),
+ ("F", _(u"Finished")))
class Import(models.Model):
user = models.ForeignKey('IshtarUser')
importer_type = models.ForeignKey(ImporterType)
imported_file = models.FileField(_(u"Imported file"),
upload_to="upload/imports/")
+ skip_lines = models.IntegerField(default=1)
error_file = models.FileField(_(u"Error file"),
upload_to="upload/imports/",
blank=True, null=True)
result_file = models.FileField(_(u"Result file"),
upload_to="upload/imports/",
blank=True, null=True)
- state = models.CharField(_(u"State"), max_length=2, choices=IMPORT_STATE)
- creation_date = models.DateTimeField(_(u"Creation date"), blank=True,
- null=True)
+ state = models.CharField(_(u"State"), max_length=2, choices=IMPORT_STATE,
+ default='C')
+ creation_date = models.DateTimeField(_(u"Creation date"), auto_now_add=True,
+ blank=True, null=True)
end_date = models.DateTimeField(_(u"End date"), blank=True,
- null=True)
+ null=True, editable=False)
seconds_remaining = models.IntegerField(_(u"Seconds remaining"), blank=True,
- null=True)
+ null=True, editable=False)
class Meta:
verbose_name = _(u"Import")
verbose_name_plural = _(u"Imports")
@@ -1243,6 +1285,28 @@ class Import(models.Model):
return u"%s - %s" % (unicode(self.importer_type),
unicode(self.user))
+ @property
+ def importer_instance(self):
+ return self.importer_type.importer_class(skip_lines=self.skip_lines,
+ import_instance=self)
+
+ @property
+ def data_table(self):
+ encodings = [settings.ENCODING, settings.ALT_ENCODING, 'utf-8']
+ with open(self.imported_file.filename) as csv_file:
+ for encoding in encodings:
+ try:
+ return [line for line in unicodecsv.reader(csv_file,
+ encoding=encoding)]
+ except UnicodeDecodeError:
+ if encoding != encodings[-1]:
+ csv_file.seek(0)
+ continue
+ return []
+
+ def initialize(self):
+ self.importer_instance.initialize(self.data_table, output='db')
+
class Organization(Address, Merge, OwnPerms, ValueGetter):
TABLE_COLS = ('name', 'organization_type',)
name = models.CharField(_(u"Name"), max_length=300)