summaryrefslogtreecommitdiff
path: root/ishtar_common/data_importer.py
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common/data_importer.py')
-rw-r--r--ishtar_common/data_importer.py129
1 files changed, 78 insertions, 51 deletions
diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py
index 972d286ed..065720bbf 100644
--- a/ishtar_common/data_importer.py
+++ b/ishtar_common/data_importer.py
@@ -29,7 +29,7 @@ import zipfile
from django.conf import settings
from django.contrib.auth.models import User
from django.core.files import File
-from django.db import IntegrityError, transaction
+from django.db import IntegrityError, DatabaseError, transaction
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _
@@ -64,14 +64,17 @@ class ImportFormater(object):
self.comment = comment
self.force_new = force_new
- def reinit_db_target(self, db_targets):
+ def reinit_db_target(self, db_target, nb=0):
if not self.formater:
return
- elif type(self.formater) not in (list, tuple):
- self.formater.db_target = db_targets[0]
+ if type(db_target) in (list, tuple):
+ db_target = db_target[nb]
+ if type(self.formater) not in (list, tuple):
+ self.formater.db_target = db_target
+ self.formater.init_db_target()
else:
for idx, formater in enumerate(self.formater):
- formater.db_target = db_targets[idx]
+ formater.db_target = db_target
formater.init_db_target()
def init_db_target(self):
@@ -249,6 +252,7 @@ class StrChoiceFormater(Formater, ChoiceChecker):
self.create = False
self.missings = set()
self.new_keys = {}
+ self.match_table = {}
self.many_split = many_split
for key, value in self.choices:
value = unicode(value)
@@ -265,15 +269,18 @@ class StrChoiceFormater(Formater, ChoiceChecker):
if not self.db_target:
return
for target_key in self.db_target.keys.filter(is_set=True).all():
- value = target_key.value
+ key = target_key.key
if not self.strict:
- value = slugify(value)
- if value in self.equiv_dict:
+ key = slugify(key)
+ if key in self.equiv_dict:
continue
- v = target_key.key
- if self.model and v:
- v = self.model.objects.get(pk=v)
- self.equiv_dict[value] = v
+ v = target_key.value
+ if self.model and v and type(v) in (int, unicode):
+ try:
+ v = self.model.objects.get(txt_idx=v)
+ except:
+ v = self.model.objects.get(pk=v)
+ self.equiv_dict[key] = v
def prepare(self, value):
return unicode(value).strip()
@@ -304,9 +311,7 @@ class StrChoiceFormater(Formater, ChoiceChecker):
for v in self.equiv_dict:
q['key'] = v
value = self.equiv_dict[v]
- if hasattr(value, 'txt_idx'):
- value = value.txt_idx
- elif hasattr(value, 'pk'):
+ if hasattr(value, 'pk'):
value = value.pk
q['value'] = value
with transaction.commit_on_success():
@@ -400,10 +405,12 @@ class StrChoiceFormater(Formater, ChoiceChecker):
return
def format(self, value):
+ origin_value = value
value = self.prepare(value)
if not self.strict:
value = slugify(value)
if value in self.equiv_dict:
+ self.match_table[origin_value] = self.equiv_dict[value]
return self.equiv_dict[value]
@@ -418,6 +425,7 @@ class TypeFormater(StrChoiceFormater):
self.db_target = db_target
self.missings = set()
self.equiv_dict, self.choices = {}, []
+ self.match_table = {}
self.new_keys = {}
for item in model.objects.all():
self.choices.append((item.pk, unicode(item)))
@@ -495,6 +503,7 @@ class StrToBoolean(Formater, ChoiceChecker):
self.db_target = db_target
self.missings = set()
self.init_db_target()
+ self.match_table = {}
self.new_keys = {}
def init_db_target(self):
@@ -564,8 +573,10 @@ class StrToBoolean(Formater, ChoiceChecker):
self.report_new(comment)
def format(self, value):
+ origin_value = value
value = self.prepare(value)
if value in self.dct:
+ self.match_table[origin_value] = _(self.dct[value])
return self.dct[value]
logger = logging.getLogger(__name__)
@@ -700,6 +711,7 @@ class Importer(object):
self.import_instance = import_instance
self.archive = None
self.DB_TARGETS = {}
+ self.match_table = {}
if import_instance and import_instance.imported_images:
self.archive = import_instance.imported_images
self._defaults = self.DEFAULTS.copy()
@@ -818,6 +830,7 @@ class Importer(object):
return data
def _importation(self, table):
+ self.match_table = {}
table = list(table)
if not table or not table[0]:
raise ImporterError(self.ERRORS['no_data'], ImporterError.HEADER)
@@ -844,10 +857,10 @@ class Importer(object):
self.now = datetime.datetime.now()
start = datetime.datetime.now()
total = len(table)
- if self.output:
+ if self.output == 'cli':
sys.stdout.write("\n")
for idx_line, line in enumerate(table):
- if self.output:
+ if self.output == 'cli':
left = None
if idx_line > 10:
ellapsed = datetime.datetime.now() - start
@@ -1006,7 +1019,7 @@ class Importer(object):
unicode(self.ERRORS['regex_not_match']) + val))
c_row.append("")
return
- val_group = [v.replace(NEW_LINE_BREAK, '\n')
+ val_group = [v.replace(NEW_LINE_BREAK, '\n') if v else ''
for v in match.groups()]
else:
val_group = [val]
@@ -1025,12 +1038,17 @@ class Importer(object):
values = re.split(func.many_split, values[0])
formated_values = []
+ field_name = formater.field_name
+ force_new = formater.force_new
+ if type(field_name) in (list, tuple):
+ field_name = field_name[idx_v]
+ if type(force_new) in (list, tuple):
+ force_new = force_new[idx_v]
+
if self.DB_TARGETS:
- field_name = formater.field_name
- if type(field_name) in (list, tuple):
- field_name = field_name[idx_v]
- func.reinit_db_target(
- self.DB_TARGETS["{}-{}".format(idx_col, field_name)])
+ formater.reinit_db_target(
+ self.DB_TARGETS["{}-{}".format(idx_col + 1, field_name)],
+ idx_v)
for idx, v in enumerate(values):
value = None
try:
@@ -1051,40 +1069,39 @@ class Importer(object):
c_values.append('')
return
formated_values.append(value)
+ if hasattr(func, 'match_table'):
+ if field_name not in self.match_table:
+ self.match_table[field_name] = {}
+ self.match_table[field_name].update(func.match_table)
value = formated_values
if not many_values:
value = formated_values[0]
- printed_values = value
- if type(value) not in (list, tuple):
- printed_values = [value]
- try:
- # don't reunicode - unicoded values
- c_values.append(u" ; ".join([v for v in printed_values]))
- except TypeError:
- c_values.append(u" ; ".join([unicode(v)
- for v in printed_values]))
- if value is None and formater.required:
- self.c_errors = True
- self.errors.append((idx_line + 1, idx_col + 1,
- self.ERRORS['value_required']))
- return
+ printed_values = value
+ if type(value) not in (list, tuple):
+ printed_values = [value]
+ try:
+ # don't reunicode - unicoded values
+ c_values.append(u" ; ".join([v for v in printed_values]))
+ except TypeError:
+ c_values.append(u" ; ".join([unicode(v)
+ for v in printed_values]))
+ if value is None and formater.required:
+ self.c_errors = True
+ self.errors.append((idx_line + 1, idx_col + 1,
+ self.ERRORS['value_required']))
+ return
- field_name = formater.field_name
- force_new = formater.force_new
- if type(field_name) in (list, tuple):
- field_name = field_name[idx_v]
- force_new = force_new[idx_v]
- field_names = [field_name]
- force_news = [force_new]
- for duplicate_field in formater.duplicate_fields:
- if type(duplicate_field[0]) in (list, tuple):
- duplicate_field, force_new = duplicate_field[idx_v]
- else:
- duplicate_field, force_new = duplicate_field
- field_names += [duplicate_field]
- force_news += [force_new]
+ field_names = [field_name]
+ force_news = [force_new]
+ for duplicate_field in formater.duplicate_fields:
+ if type(duplicate_field[0]) in (list, tuple):
+ duplicate_field, force_new = duplicate_field[idx_v]
+ else:
+ duplicate_field, force_new = duplicate_field
+ field_names += [duplicate_field]
+ force_news += [force_new]
if formater.through:
self._throughs.append((formater, value))
@@ -1237,6 +1254,8 @@ class Importer(object):
raise IntegrityError(e.message)
except IntegrityError as e:
raise IntegrityError(e.message)
+ except DatabaseError as e:
+ raise IntegrityError(e.message)
except cls.MultipleObjectsReturned:
created = False
obj = cls.objects.filter(**create_dict).all()[0]
@@ -1288,6 +1307,14 @@ class Importer(object):
def get_csv_result(self):
return self._get_csv(self.validity)
+ def get_csv_matches(self):
+ header = [_('field'), _('source'), _('result')]
+ values = []
+ for field in self.match_table:
+ for source in self.match_table[field]:
+ values.append((field, source, self.match_table[field][source]))
+ return self._get_csv(values, header=header)
+
@classmethod
def choices_check(cls, choices):
def function(value):