diff options
| -rw-r--r-- | ishtar_common/data_importer.py | 3 | ||||
| -rw-r--r-- | ishtar_common/migrations/0036_auto_20180323_2053.py | 27 | ||||
| -rw-r--r-- | ishtar_common/models_imports.py | 36 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/import_step_by_step.html | 10 | ||||
| -rw-r--r-- | ishtar_common/views.py | 25 | 
5 files changed, 96 insertions, 5 deletions
diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py index 3bcd62415..3ee173a1f 100644 --- a/ishtar_common/data_importer.py +++ b/ishtar_common/data_importer.py @@ -1145,6 +1145,9 @@ class Importer(object):          if self.simulate:              return data +        if self.import_instance: +            self.import_instance.add_imported_line(self.idx_line) +          if self.import_instance and hasattr(obj, 'imports') \             and created:              obj.imports.add(self.import_instance) diff --git a/ishtar_common/migrations/0036_auto_20180323_2053.py b/ishtar_common/migrations/0036_auto_20180323_2053.py new file mode 100644 index 000000000..e6e38d577 --- /dev/null +++ b/ishtar_common/migrations/0036_auto_20180323_2053.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-03-23 20:53 +from __future__ import unicode_literals + +import django.core.validators +from django.db import migrations, models +import re + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0035_auto_20180308_1828'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='import', +            name='imported_line_numbers', +            field=models.TextField(blank=True, null=True, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z'), code='invalid', message='Enter only digits separated by commas.')], verbose_name='Imported line numbers'), +        ), +        migrations.AddField( +            model_name='import', +            name='number_of_line', +            field=models.IntegerField(blank=True, null=True, verbose_name='Number of line'), +        ), +    ] diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py index 10124b024..cd8865eca 100644 --- a/ishtar_common/models_imports.py +++ b/ishtar_common/models_imports.py @@ -32,6 +32,7 @@ from django.conf import settings  from django.contrib.gis.db import models  from django.core.exceptions import SuspiciousOperation  from django.core.files.base import ContentFile +from django.core.validators import validate_comma_separated_integer_list  from django.db.models.base import ModelBase  from django.db.models.signals import pre_delete  from django.template.defaultfilters import slugify @@ -831,6 +832,12 @@ class Import(models.Model):      # used by step by step import      current_line = models.IntegerField(_(u"Current line"), blank=True,                                         null=True) +    number_of_line = models.IntegerField(_(u"Number of line"), blank=True, +                                         null=True) +    imported_line_numbers = models.TextField( +        _(u"Imported line numbers"), blank=True, null=True, +        validators=[validate_comma_separated_integer_list] +    )      class Meta:          verbose_name = _(u"Import") @@ -856,6 +863,35 @@ class Import(models.Model):                  errors.append(row)          return errors +    def get_number_of_lines(self): +        if self.number_of_line: +            return self.number_of_line +        if not self.imported_file or not self.imported_file.path: +            return +        filename = self.imported_file.path +        with open(filename, 'r') as f: +            reader = unicodecsv.reader( +                f, encoding=self.encoding) +            nb = sum(1 for row in reader) - self.skip_lines +        self.number_of_line = nb +        self.save() +        return nb + +    def add_imported_line(self, idx_line): +        if self.imported_line_numbers and \ +                idx_line in self.imported_line_numbers.split(','): +            return +        if self.imported_line_numbers: +            self.imported_line_numbers += "," +        else: +            self.imported_line_numbers = "" +        self.imported_line_numbers += str(idx_line) +        self.save() + +    def line_is_imported(self, idx_line): +        return self.imported_line_numbers and \ +               str(idx_line) in self.imported_line_numbers.split(',') +      def get_actions(self):          """          Get available action relevant with the current status diff --git a/ishtar_common/templates/ishtar/import_step_by_step.html b/ishtar_common/templates/ishtar/import_step_by_step.html index 293ce3dce..2d80f2386 100644 --- a/ishtar_common/templates/ishtar/import_step_by_step.html +++ b/ishtar_common/templates/ishtar/import_step_by_step.html @@ -21,6 +21,13 @@  <h2>{% trans "Import step by step" %} – {{import.name}} – {% trans "line " %} {{line_number_displayed}}</h2> + +{% if line_is_imported %} +<div class="alert alert-warning" role="alert"> +    <p>{% trans "This line have been already imported." %}</p> +</div> +{% endif %} +  {% if errors %}  <div class="alert alert-danger" role="alert">      <p>{% trans "The following error(s) has been encountered while parsing the source file:" %}</p> @@ -68,6 +75,7 @@          <div id="validation-bar" class="row text-center">              <div class="col-sm">                  <button type="submit" name="valid" id="btn-change-csv" +                        onclick="long_wait();return true;"                          value="change-csv" class="btn btn-success">                      {% trans "Update source file" %}                  </button> @@ -233,12 +241,14 @@              <div class="col-sm">                  <button type="submit" name="valid" id="btn-change-csv"                          value="change-csv" class="btn btn-success" +                        onclick="long_wait();return true;"                          disabled="disabled">                      {% trans "Update source file" %}                  </button>              </div>              <div class="col-sm">                  <button type="submit" name="valid" id="btn-import" +                        onclick="long_wait();return true;"                          value="import" class="btn btn-success">                      {% trans "Import this line" %}                  </button> diff --git a/ishtar_common/views.py b/ishtar_common/views.py index d6d16568a..9ff53e89a 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -1857,7 +1857,8 @@ class ImportStepByStepView(IshtarMixin, LoginRequiredMixin, TemplateView):              user = models.IshtarUser.objects.get(pk=self.request.user.pk)              if self.imprt_obj.user != user:                  raise Http404 -        self.current_line_number = int(self.kwargs['line_number']) - 1 +        if not hasattr(self, 'current_line_number'): +            self.current_line_number = int(self.kwargs['line_number']) - 1      def update_csv(self, request):          prefix = 'col-' @@ -1889,6 +1890,15 @@ class ImportStepByStepView(IshtarMixin, LoginRequiredMixin, TemplateView):              self.errors = [e.message]              return super(ImportStepByStepView, self).get(request, *args,                                                           **kwargs) +        is_current = self.current_line_number == self.imprt_obj.current_line +        if self.imprt_obj.get_number_of_lines() >= self.current_line_number: +            self.current_line_number += 1 +        else: +            self.current_line_number = None +        if is_current: +            self.imprt_obj.current_line = self.current_line_number +            self.imprt_obj.save() +        return self.current_line_number      def post(self, request, *args, **kwargs):          if not request.POST or request.POST.get('valid', None) not in ( @@ -1899,9 +1909,12 @@ class ImportStepByStepView(IshtarMixin, LoginRequiredMixin, TemplateView):          if request.POST.get('valid') == 'change-csv':              self.update_csv(request)              return self.get(request, *args, **kwargs) -        self.import_line(request, *args, **kwargs) -        # todo redirect to next -        return self.get(request, *args, **kwargs) +        if not self.import_line(request, *args, **kwargs): +            return HttpResponseRedirect(reverse('current_imports')) +        else: +            return HttpResponseRedirect( +                reverse('import_step_by_step', +                        args=[self.imprt_obj.pk, self.current_line_number + 1]))      def get(self, request, *args, **kwargs):          self.get_import() @@ -1926,7 +1939,9 @@ class ImportStepByStepView(IshtarMixin, LoginRequiredMixin, TemplateView):      def get_context_data(self, **kwargs):          dct = super(ImportStepByStepView, self).get_context_data(**kwargs)          dct['import'] = self.imprt_obj -        dct['line_number_displayed'] = self.kwargs['line_number'] +        dct['line_number_displayed'] = self.current_line_number + 1 +        dct['line_is_imported'] = self.imprt_obj.line_is_imported( +            self.current_line_number)          dct['errors'] = self.errors          if self.errors:              if self.imprt.current_csv_line:  | 
