diff options
Diffstat (limited to 'ishtar_common')
| -rw-r--r-- | ishtar_common/data_importer.py | 36 | ||||
| -rw-r--r-- | ishtar_common/migrations/0019_auto__add_field_itemkey_importer.py | 249 | ||||
| -rw-r--r-- | ishtar_common/models.py | 50 | ||||
| -rw-r--r-- | ishtar_common/tests.py | 47 | 
4 files changed, 370 insertions, 12 deletions
| diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py index 3009ba17d..6848c3130 100644 --- a/ishtar_common/data_importer.py +++ b/ishtar_common/data_importer.py @@ -1,6 +1,6 @@  #!/usr/bin/env python  # -*- coding: utf-8 -*- -# Copyright (C) 2013-2014  Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2013-2015  Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet>  # This program is free software: you can redistribute it and/or modify  # it under the terms of the GNU Affero General Public License as @@ -185,6 +185,7 @@ class StrChoiceFormater(Formater):          self.equiv_dict = copy.deepcopy(equiv_dict)          self.cli = cli          self.model = model +        self.create = False          self.missings = set()          for key, value in self.choices:              value = unicode(value) @@ -206,8 +207,14 @@ class StrChoiceFormater(Formater):                             u"Which one is relevant?\n"))          for idx, choice in enumerate(self.choices):              msgstr += u"%d. %s\n" % (idx+1, choice[1]) -        msgstr += unicode(_(u"%d. None of the above")) % (idx+2) + u"\n" +        idx += 2 +        if self.create: +            msgstr += unicode(_(u"%d. None of the above - create new")) % idx \ +                    + u"\n" +            idx += 1 +        msgstr += unicode(_(u"%d. None of the above - skip")) % idx + u"\n"          for value in values: +            base_value = copy(value)              value = self.prepare(value)              if value in self.equiv_dict:                  continue @@ -215,7 +222,7 @@ class StrChoiceFormater(Formater):                  self.missings.add(value)                  continue              res = None -            while res not in range(1, len(self.choices)+2): +            while res not in range(1, idx+1):                  sys.stdout.write(msgstr % value)                  res = raw_input(">>> ")                  try: @@ -228,9 +235,18 @@ class StrChoiceFormater(Formater):                  if self.model and v:                      v = self.model.objects.get(pk=v)                  self.equiv_dict[value] = v +                self.add_key(v, value) +            elif self.create and res == len(self.choices): +                self.equiv_dict[value] = self.new(base_value)              else:                  self.equiv_dict[value] = None +    def new(self, value): +        return + +    def add_key(self, obj, value): +        return +      def format(self, value):          value = self.prepare(value)          if not self.strict: @@ -239,7 +255,9 @@ class StrChoiceFormater(Formater):              return self.equiv_dict[value]  class TypeFormater(StrChoiceFormater): -    def __init__(self, model, cli=False): +    def __init__(self, model, cli=False, defaults={}): +        self.model = model +        self.defaults = defaults          self.equiv_dict, self.choices = {}, []          for item in model.objects.all():              self.choices.append((item.pk, unicode(item))) @@ -249,6 +267,16 @@ class TypeFormater(StrChoiceFormater):      def prepare(self, value):          return slugify(unicode(value).strip()) +    def add_key(self, obj, value): +        obj.add_key(slugify(value), force=True) + +    def new(self, value): +        values = copy(self.defaults) +        values['label'] = value +        values['txt_idx'] = slugify(value) +        self.model.objects.create(**values) +        return +  class DateFormater(Formater):      def __init__(self, date_format="%d/%m/%Y"):          self.date_format = date_format diff --git a/ishtar_common/migrations/0019_auto__add_field_itemkey_importer.py b/ishtar_common/migrations/0019_auto__add_field_itemkey_importer.py new file mode 100644 index 000000000..9206279d1 --- /dev/null +++ b/ishtar_common/migrations/0019_auto__add_field_itemkey_importer.py @@ -0,0 +1,249 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + +    def forwards(self, orm): +        # Adding field 'ItemKey.importer' +        db.add_column('ishtar_common_itemkey', 'importer', +                      self.gf('django.db.models.fields.related.ForeignKey')(to=orm['ishtar_common.Import'], null=True, blank=True), +                      keep_default=False) + + +    def backwards(self, orm): +        # Deleting field 'ItemKey.importer' +        db.delete_column('ishtar_common_itemkey', 'importer_id') + + +    models = { +        'auth.group': { +            'Meta': {'object_name': 'Group'}, +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), +            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) +        }, +        'auth.permission': { +            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, +            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) +        }, +        'auth.user': { +            'Meta': {'object_name': 'User'}, +            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), +            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), +            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), +            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), +            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), +            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), +            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), +            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) +        }, +        'contenttypes.contenttype': { +            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, +            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) +        }, +        'ishtar_common.arrondissement': { +            'Meta': {'object_name': 'Arrondissement'}, +            'department': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Department']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '30'}) +        }, +        'ishtar_common.author': { +            'Meta': {'object_name': 'Author'}, +            'author_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.AuthorType']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'person': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'author'", 'to': "orm['ishtar_common.Person']"}) +        }, +        'ishtar_common.authortype': { +            'Meta': {'object_name': 'AuthorType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) +        }, +        'ishtar_common.canton': { +            'Meta': {'object_name': 'Canton'}, +            'arrondissement': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Arrondissement']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '30'}) +        }, +        'ishtar_common.department': { +            'Meta': {'ordering': "['number']", 'object_name': 'Department'}, +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'label': ('django.db.models.fields.CharField', [], {'max_length': '30'}), +            'number': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '3'}) +        }, +        'ishtar_common.documenttemplate': { +            'Meta': {'ordering': "['associated_object_name']", 'object_name': 'DocumentTemplate'}, +            'associated_object_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'template': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}) +        }, +        'ishtar_common.format': { +            'Meta': {'object_name': 'Format'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) +        }, +        'ishtar_common.globalvar': { +            'Meta': {'ordering': "['slug']", 'object_name': 'GlobalVar'}, +            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), +            'value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) +        }, +        'ishtar_common.historicalorganization': { +            'Meta': {'ordering': "('-history_date', '-history_id')", 'object_name': 'HistoricalOrganization'}, +            'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), +            'history_creator_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), +            'history_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), +            'history_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'history_modifier_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), +            'history_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), +            'history_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}), +            'id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), +            'merge_key': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '300'}), +            'organization_type_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), +            'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}) +        }, +        'ishtar_common.import': { +            'Meta': {'object_name': 'Import'}, +            'creation_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), +            'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), +            'error_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'imported_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), +            'importer_type': ('django.db.models.fields.CharField', [], {'max_length': '200'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), +            'result_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), +            'seconds_remaining': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), +            'state': ('django.db.models.fields.CharField', [], {'max_length': '2'}), +            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.IshtarUser']"}) +        }, +        'ishtar_common.ishtaruser': { +            'Meta': {'object_name': 'IshtarUser', '_ormbases': ['auth.User']}, +            'person': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ishtaruser'", 'unique': 'True', 'to': "orm['ishtar_common.Person']"}), +            'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}) +        }, +        'ishtar_common.itemkey': { +            'Meta': {'object_name': 'ItemKey'}, +            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'importer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Import']", 'null': 'True', 'blank': 'True'}), +            'key': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}) +        }, +        'ishtar_common.organization': { +            'Meta': {'object_name': 'Organization'}, +            'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), +            'history_creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}), +            'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'merge_candidate': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_candidate_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Organization']"}), +            'merge_exclusion': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_exclusion_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Organization']"}), +            'merge_key': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '300'}), +            'organization_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.OrganizationType']"}), +            'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}) +        }, +        'ishtar_common.organizationtype': { +            'Meta': {'ordering': "('label',)", 'object_name': 'OrganizationType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) +        }, +        'ishtar_common.person': { +            'Meta': {'object_name': 'Person'}, +            'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'attached_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'members'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['ishtar_common.Organization']"}), +            'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), +            'history_creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}), +            'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'merge_candidate': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_candidate_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Person']"}), +            'merge_exclusion': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_exclusion_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Person']"}), +            'merge_key': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'person_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ishtar_common.PersonType']", 'symmetrical': 'False'}), +            'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'raw_name': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'surname': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), +            'title': ('django.db.models.fields.CharField', [], {'max_length': '2'}), +            'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}) +        }, +        'ishtar_common.persontype': { +            'Meta': {'ordering': "('label',)", 'object_name': 'PersonType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) +        }, +        'ishtar_common.sourcetype': { +            'Meta': {'object_name': 'SourceType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) +        }, +        'ishtar_common.supporttype': { +            'Meta': {'object_name': 'SupportType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) +        }, +        'ishtar_common.town': { +            'Meta': {'ordering': "['numero_insee']", 'object_name': 'Town'}, +            'canton': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Canton']", 'null': 'True', 'blank': 'True'}), +            'center': ('django.contrib.gis.db.models.fields.PointField', [], {'srid': '27572', 'null': 'True', 'blank': 'True'}), +            'departement': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Department']", 'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'numero_insee': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '6'}), +            'surface': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) +        } +    } + +    complete_apps = ['ishtar_common']
\ No newline at end of file diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 90232159c..75d2ea544 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -35,7 +35,8 @@ from django.core.validators import validate_slug  from django.core.urlresolvers import reverse, NoReverseMatch  from django.db.utils import DatabaseError  from django.db.models import Q, Max, Count -from django.db.models.signals import post_save +from django.db.models.signals import post_save, pre_save +from django.dispatch import receiver  from django.utils.translation import ugettext_lazy as _, ugettext  from django.utils.safestring import SafeUnicode, mark_safe  from django.template.defaultfilters import slugify @@ -351,8 +352,36 @@ class GeneralType(models.Model):                                                          ).split('_')).title()          if not self.txt_idx:              self.txt_idx = slugify(self.label) + +        # clean old keys +        pre_label = getattr(self, 'pre_label', None) +        pre_txt_idx = getattr(self, 'pre_txt_idx', None) +        content_type = ContentType.objects.get_for_model(self.__class__) +        if pre_label and self.label != pre_label: +            ItemKey.objects.filter(object_id=self.pk, key=slugify(pre_label), +                                   content_type=content_type).delete() +        if pre_txt_idx and self.txt_idx != pre_txt_idx: +            ItemKey.objects.filter(object_id=self.pk, key=pre_txt_idx, +                                   content_type=content_type).delete() + +        self.generate_key(force=True)          return super(GeneralType, self).save(*args, **kwargs) +    def add_key(self, key, force=False): +        content_type = ContentType.objects.get_for_model(self.__class__) +        if not force and ItemKey.objects.filter(key=key, +                              content_type=content_type).count(): +            return +        if force: +            ItemKey.objects.filter(key=key, content_type=content_type).exclude( +                                                    object_id=self.pk).delete() +        ItemKey.objects.get_or_create(object_id=self.pk, key=key, +                                      content_type=content_type) + +    def generate_key(self, force=False): +        for key in (slugify(self.label), self.txt_idx): +            self.add_key(key) +      def get_keys(self):          keys = []          content_type = ContentType.objects.get_for_model(self.__class__) @@ -365,18 +394,25 @@ class GeneralType(models.Model):      def generate_keys(cls):          content_type = ContentType.objects.get_for_model(cls)          for item in cls.objects.all(): -            for key in (slugify(item.label), item.txt_idx): -                if not ItemKey.objects.filter(object_id=item.pk, key=key, -                                         content_type=content_type).count(): -                    ik = ItemKey(object_id=item.pk, key=key, -                                  content_type=content_type) -                    ik.save() +            item.generate_key() + +@receiver(pre_save) +def pre_save_general_type(sender, **kwargs): +    if not issubclass(sender, GeneralType) or not 'instance' in kwargs \ +      or not kwargs['instance']: +       return +    instance = kwargs['instance'] +    instance.pre_label = instance.label +    instance.pre_txt_idx = instance.txt_idx +  class ItemKey(models.Model):      key = models.CharField(_(u"Key"), max_length=100)      content_type = models.ForeignKey(ContentType)      object_id = models.PositiveIntegerField()      content_object = generic.GenericForeignKey('content_type', 'object_id') +    importer = models.ForeignKey('Import', null=True, blank=True, +                            help_text=_(u"Key specific to an import"))      def __unicode__(self):          return self.key diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py index 000abc268..b22d27169 100644 --- a/ishtar_common/tests.py +++ b/ishtar_common/tests.py @@ -1,6 +1,6 @@  #!/usr/bin/env python  # -*- coding: utf-8 -*- -# Copyright (C) 2014 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2015 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet>  # This program is free software: you can redistribute it and/or modify  # it under the terms of the GNU Affero General Public License as @@ -21,6 +21,8 @@ import tempfile  from zipfile import ZipFile, ZIP_DEFLATED  from django.contrib.auth.models import User +from django.contrib.contenttypes.models import ContentType +from django.template.defaultfilters import slugify  from django.test import TestCase  from ishtar_common import models, ooo_replace @@ -91,3 +93,46 @@ class MergeTest(TestCase):          self.person_3.merge(self.person_1)          # manage well empty many to many fields          self.assertTrue(self.person_types[1] in self.person_3.person_types.all()) + +class ImportKeyTest(TestCase): + +    def testKeys(self): +        content_type = ContentType.objects.get_for_model(models.OrganizationType) + +        # creation +        label = u"Ploufé" +        ot = models.OrganizationType.objects.create(label=label) +        self.assertEqual(models.ItemKey.objects.filter(object_id=ot.pk, +                                    key=slugify(label), +                                    content_type=content_type).count(), 1) +        label_2 = u"Plif" +        ot_2 = models.OrganizationType.objects.create(label=label_2) +        self.assertEqual(models.ItemKey.objects.filter(object_id=ot_2.pk, +                                    key=slugify(label_2), +                                    content_type=content_type).count(), 1) + +        # replace key +        ot_2.add_key(slugify(label), force=True) +        # one key point to only one item +        self.assertEqual(models.ItemKey.objects.filter(key=slugify(label), +                                    content_type=content_type).count(), 1) +        # this key point to the right item +        self.assertEqual(models.ItemKey.objects.filter(object_id=ot_2.pk, +                key=slugify(label), content_type=content_type).count(), 1) + +        # modification +        label_3 = "Yop" +        ot_2.label = label_3 +        ot_2.save() +        # old label not referenced anymore +        self.assertEqual(models.ItemKey.objects.filter(object_id=ot_2.pk, +                key=slugify(label_2), content_type=content_type).count(), 0) +        # forced key association is always here +        self.assertEqual(models.ItemKey.objects.filter(object_id=ot_2.pk, +                key=slugify(label), content_type=content_type).count(), 1) +        # new key is here +        self.assertEqual(models.ItemKey.objects.filter(object_id=ot_2.pk, +                key=slugify(label_3), content_type=content_type).count(), 1) + + + | 
