summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@proxience.com>2015-01-26 00:50:58 +0100
committerÉtienne Loks <etienne.loks@proxience.com>2015-01-26 00:50:58 +0100
commitfea70ced145dcfd326c8846bffa0004009c8daa4 (patch)
treefd3ef2bf34cff849c77c23ced9cc1ab774a9b98d
parentd0c12c279f1283a37729f33bf1d453d725623167 (diff)
downloadIshtar-fea70ced145dcfd326c8846bffa0004009c8daa4.tar.bz2
Ishtar-fea70ced145dcfd326c8846bffa0004009c8daa4.zip
Add a generic relation model to list general types keys. Reorganize imports.
-rw-r--r--archaeological_files/data_importer.py174
-rw-r--r--archaeological_operations/data_importer.py171
-rw-r--r--ishtar_common/data_importer.py61
-rw-r--r--ishtar_common/migrations/0018_auto__add_itemkey.py252
-rw-r--r--ishtar_common/models.py32
5 files changed, 517 insertions, 173 deletions
diff --git a/archaeological_files/data_importer.py b/archaeological_files/data_importer.py
index 15072834a..5504356d5 100644
--- a/archaeological_files/data_importer.py
+++ b/archaeological_files/data_importer.py
@@ -17,73 +17,18 @@
# See the file COPYING for details.
-import copy, datetime, re
import unicodecsv
from django.conf import settings
-from django.db import IntegrityError
-from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _
from ishtar_common.data_importer import *
-from ishtar_common.models import Town, Person, OrganizationType
+from ishtar_common.models import Person, OrganizationType
from ishtar_common.unicode_csv import unicode_csv_reader
from archaeological_files import models
-from archaeological_operations.models import Parcel
-from archaeological_operations.utils import parse_parcels
-
-RE_FILTER_CEDEX = re.compile("(.*) *(?: *CEDEX|cedex|Cedex|Cédex|cédex *\d*)")
-RE_PERMIT_REFERENCE = re.compile('[A-Za-z]*(.*)')
-
-class StrToBoolean(Formater):
- def __init__(self, choices={}, cli=False, strict=False):
- self.dct = copy.copy(choices)
- self.cli = cli
- self.strict= strict
- self.missings = set()
-
- def prepare(self, value):
- value = unicode(value).strip()
- if not self.strict:
- value = slugify(value)
- return value
-
- def check(self, values, output=None):
- if not output or output == 'silent':
- return
- msgstr = unicode(_(u"Choice for \"%s\" is not available. "\
- u"Which one is relevant?\n"))
- msgstr += u"1. True\n"
- msgstr += u"2. False\n"
- msgstr += u"3. Empty\n"
- for value in values:
- value = self.prepare(value)
- if value in self.dct:
- continue
- if not self.cli:
- self.missings.add(value)
- continue
- res = None
- while res not in range(1, 4):
- sys.stdout.write(msgstr % value)
- res = raw_input(">>> ")
- try:
- res = int(res)
- except ValueError:
- pass
- if res == 1:
- self.dct[value] = True
- elif res == 2:
- self.dct[value] = False
- else:
- self.dct[value] = None
-
- def format(self, value):
- value = self.prepare(value)
- if value in self.dct:
- return self.dct[value]
+from archaeological_operations.data_importer import *
class ImportClosingFormater(ImportFormater):
def post_process(self, obj, context, value, owner=None):
@@ -96,121 +41,6 @@ class ImportClosingFormater(ImportFormater):
obj.end_date = open_date + datetime.timedelta(30)
obj.save()
-class ImportParcelFormater(ImportFormater):
- NEED = ['town',]
- PARCEL_OWNER_KEY = 'associated_file'
-
- def post_process(self, obj, context, value, owner=None):
- value = value.strip()
- base_dct = {self.PARCEL_OWNER_KEY:obj, 'history_modifier':owner}
- if 'parcels' in context:
- for key in context['parcels']:
- if context['parcels'][key]:
- base_dct[key] = context['parcels'][key]
- for parcel_dct in parse_parcels(value, owner=owner):
- parcel_dct.update(base_dct)
- try:
- Parcel.objects.get_or_create(**parcel_dct)
- except IntegrityError:
- raise ImporterError("Erreur d'import parcelle, contexte : %s" \
- % unicode(parcel_dct))
-
-class ImportYearFormater(ImportFormater):
- def post_process(self, obj, context, value, owner=None):
- value = self.formater.format(value)
- if not value:
- return
- obj.year = value.year
- obj.save()
-
-class TownFormater(Formater):
- def __init__(self, town_full_dct={}, town_dct={}):
- self._town_full_dct = town_full_dct
- self._town_dct = town_dct
- self._initialized = False if not self._town_full_dct else True
-
- def town_dct_init(self):
- for town in Town.objects.all():
- key = (slugify(town.name.strip()), town.numero_insee[:2])
- if key in self._town_full_dct:
- print("Danger! %s is ambiguous with another town on the same "\
- "department."% town.name)
- continue
- self._town_full_dct[key] = town
- key = slugify(town.name.strip())
- if key in self._town_dct:
- print("Warning %s is ambiguous with no department provided" %\
- town.name)
- continue
- self._town_dct[key] = town
- self._initialized = True
-
- def format(self, value, extra=None):
- if not self._initialized:
- self.town_dct_init()
- m = RE_FILTER_CEDEX.match(value)
- if m:
- value = m.groups()[0]
- if not value:
- return None
- if extra:
- key = (slugify(value), extra)
- if key in self._town_full_dct:
- return self._town_full_dct[key]
- key = slugify(value)
- if key in self._town_dct:
- return self._town_dct[key]
-
-class TownINSEEFormater(Formater):
- def __init__(self):
- self._town_dct = {}
-
- def format(self, value, extra=None):
- value = value.strip()
- if not value:
- return None
- if value in self._town_dct:
- return self._town_dct[value]
- q = Town.objects.filter(insee_code=value)
- if not q.count():
- return
- self._town_dct[value] = q.all()[0]
- return self._town_dct[value]
-
-class SurfaceFormater(Formater):
- def test(self):
- assert self.format(u"352 123") == 352123
- assert self.format(u"456 789 m²") == 456789
- assert self.format(u"78ha") == 780000
-
- def format(self, value, extra=None):
- value = value.strip()
- if not value:
- return None
- factor = 1
- if value.endswith(u"m2") or value.endswith(u"m²"):
- value = value[:-2]
- if value.endswith(u"ha"):
- value = value[:-2]
- factor = 10000
- try:
- return int(value.replace(' ', '')) * factor
- except ValueError:
- raise ImporterError("Erreur import surface : %s" \
- % unicode(value))
-
-#RE_ADD_CD_POSTAL_TOWN = re.compile("(.*)[, ](\d{5}) (.*?) *(?: "\
-# "*CEDEX|cedex|Cedex *\d*)*")
-
-RE_NAME_ADD_CD_POSTAL_TOWN = re.compile("(.*)?[, ]*" + NEW_LINE_BREAK \
- + "(.*)?[, ]*(\d{2} *\d{3})[, ]*(.+)")
-
-RE_ADD_CD_POSTAL_TOWN = re.compile("(.*)?[, ]*(\d{2} *\d{3})[, ]*(.+)")
-
-RE_CD_POSTAL_FILTER = re.compile("(\d*) (\d*)")
-
-RE_ORGA = re.compile("([^,]*)")
-
class FileImporterSraPdL(Importer):
LINE_FORMAT = []
OBJECT_CLS = models.File
diff --git a/archaeological_operations/data_importer.py b/archaeological_operations/data_importer.py
new file mode 100644
index 000000000..4402c8b17
--- /dev/null
+++ b/archaeological_operations/data_importer.py
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# 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
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# See the file COPYING for details.
+
+import copy, datetime, re
+
+from django.db import IntegrityError
+from django.template.defaultfilters import slugify
+from django.utils.translation import ugettext_lazy as _
+
+from ishtar_common.data_importer import *
+from ishtar_common.models import Town
+
+from archaeological_operations.models import Parcel
+from archaeological_operations.utils import parse_parcels
+
+RE_PERMIT_REFERENCE = re.compile('[A-Za-z]*(.*)')
+
+class ImportParcelFormater(ImportFormater):
+ NEED = ['town',]
+ PARCEL_OWNER_KEY = 'associated_file'
+
+ def post_process(self, obj, context, value, owner=None):
+ value = value.strip()
+ base_dct = {self.PARCEL_OWNER_KEY:obj, 'history_modifier':owner}
+ if 'parcels' in context:
+ for key in context['parcels']:
+ if context['parcels'][key]:
+ base_dct[key] = context['parcels'][key]
+ for parcel_dct in parse_parcels(value, owner=owner):
+ parcel_dct.update(base_dct)
+ try:
+ Parcel.objects.get_or_create(**parcel_dct)
+ except IntegrityError:
+ raise ImporterError("Erreur d'import parcelle, contexte : %s" \
+ % unicode(parcel_dct))
+
+class ImportYearFormater(ImportFormater):
+ def post_process(self, obj, context, value, owner=None):
+ value = self.formater.format(value)
+ if not value:
+ return
+ obj.year = value.year
+ obj.save()
+
+class TownFormater(Formater):
+ def __init__(self, town_full_dct={}, town_dct={}):
+ self._town_full_dct = town_full_dct
+ self._town_dct = town_dct
+ self._initialized = False if not self._town_full_dct else True
+
+ def town_dct_init(self):
+ for town in Town.objects.all():
+ key = (slugify(town.name.strip()), town.numero_insee[:2])
+ if key in self._town_full_dct:
+ print("Danger! %s is ambiguous with another town on the same "\
+ "department."% town.name)
+ continue
+ self._town_full_dct[key] = town
+ key = slugify(town.name.strip())
+ if key in self._town_dct:
+ print("Warning %s is ambiguous with no department provided" %\
+ town.name)
+ continue
+ self._town_dct[key] = town
+ self._initialized = True
+
+ def format(self, value, extra=None):
+ if not self._initialized:
+ self.town_dct_init()
+ m = RE_FILTER_CEDEX.match(value)
+ if m:
+ value = m.groups()[0]
+ if not value:
+ return None
+ if extra:
+ key = (slugify(value), extra)
+ if key in self._town_full_dct:
+ return self._town_full_dct[key]
+ key = slugify(value)
+ if key in self._town_dct:
+ return self._town_dct[key]
+
+class TownINSEEFormater(Formater):
+ def __init__(self):
+ self._town_dct = {}
+
+ def format(self, value, extra=None):
+ value = value.strip()
+ if not value:
+ return None
+ if value in self._town_dct:
+ return self._town_dct[value]
+ q = Town.objects.filter(insee_code=value)
+ if not q.count():
+ return
+ self._town_dct[value] = q.all()[0]
+ return self._town_dct[value]
+
+class SurfaceFormater(Formater):
+ def test(self):
+ assert self.format(u"352 123") == 352123
+ assert self.format(u"456 789 m²") == 456789
+ assert self.format(u"78ha") == 780000
+
+ def format(self, value, extra=None):
+ value = value.strip()
+ if not value:
+ return None
+ factor = 1
+ if value.endswith(u"m2") or value.endswith(u"m²"):
+ value = value[:-2]
+ if value.endswith(u"ha"):
+ value = value[:-2]
+ factor = 10000
+ try:
+ return int(value.replace(' ', '')) * factor
+ except ValueError:
+ raise ImporterError("Erreur import surface : %s" \
+ % unicode(value))
+
+#RE_ADD_CD_POSTAL_TOWN = re.compile("(.*)[, ](\d{5}) (.*?) *(?: "\
+# "*CEDEX|cedex|Cedex *\d*)*")
+
+RE_NAME_ADD_CD_POSTAL_TOWN = re.compile("(.*)?[, ]*" + NEW_LINE_BREAK \
+ + "(.*)?[, ]*(\d{2} *\d{3})[, ]*(.+)")
+
+RE_ADD_CD_POSTAL_TOWN = re.compile("(.*)?[, ]*(\d{2} *\d{3})[, ]*(.+)")
+
+RE_CD_POSTAL_FILTER = re.compile("(\d*) (\d*)")
+
+RE_ORGA = re.compile("([^,]*)")
+
+
+class OperationImporterBibracte(Importer):
+ LINE_FORMAT = [
+ # CODE OPE
+ ImportFormater('operation_code',
+ IntegerFormater(),),
+ # REGION
+ None,
+ # TYPE operation
+ ImportFormater('operation_type',
+ TypeFormater(models.OperationType),),
+
+ # NOM
+ # OPERATEUR
+ # resp. lien IMPORT avec personne
+ # début
+ # fin
+ # Chronos
+ ]
+
+ OBJECT_CLS = models.Operation
+ DEFAULTS = {}
+
diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py
index 427b9f974..3009ba17d 100644
--- a/ishtar_common/data_importer.py
+++ b/ishtar_common/data_importer.py
@@ -29,6 +29,8 @@ from ishtar_common.unicode_csv import UnicodeWriter
NEW_LINE_BREAK = '#####@@@#####'
+RE_FILTER_CEDEX = re.compile("(.*) *(?: *CEDEX|cedex|Cedex|Cédex|cédex *\d*)")
+
class ImportFormater(object):
def __init__(self, field_name, formater=None, required=True, through=None,
through_key=None, through_dict=None, through_unicity_keys=None,
@@ -236,6 +238,17 @@ class StrChoiceFormater(Formater):
if value in self.equiv_dict:
return self.equiv_dict[value]
+class TypeFormater(StrChoiceFormater):
+ def __init__(self, model, cli=False):
+ self.equiv_dict, self.choices = {}, []
+ for item in model.objects.all():
+ self.choices.append((item.pk, unicode(item)))
+ for key in item.get_keys():
+ self.equiv_dict[key] = item
+
+ def prepare(self, value):
+ return slugify(unicode(value).strip())
+
class DateFormater(Formater):
def __init__(self, date_format="%d/%m/%Y"):
self.date_format = date_format
@@ -248,6 +261,54 @@ class DateFormater(Formater):
raise ValueError(_(u"\"%(value)s\" is not a valid date") % {
'value':value})
+class StrToBoolean(Formater):
+ def __init__(self, choices={}, cli=False, strict=False):
+ self.dct = copy.copy(choices)
+ self.cli = cli
+ self.strict= strict
+ self.missings = set()
+
+ def prepare(self, value):
+ value = unicode(value).strip()
+ if not self.strict:
+ value = slugify(value)
+ return value
+
+ def check(self, values, output=None):
+ if not output or output == 'silent':
+ return
+ msgstr = unicode(_(u"Choice for \"%s\" is not available. "\
+ u"Which one is relevant?\n"))
+ msgstr += u"1. True\n"
+ msgstr += u"2. False\n"
+ msgstr += u"3. Empty\n"
+ for value in values:
+ value = self.prepare(value)
+ if value in self.dct:
+ continue
+ if not self.cli:
+ self.missings.add(value)
+ continue
+ res = None
+ while res not in range(1, 4):
+ sys.stdout.write(msgstr % value)
+ res = raw_input(">>> ")
+ try:
+ res = int(res)
+ except ValueError:
+ pass
+ if res == 1:
+ self.dct[value] = True
+ elif res == 2:
+ self.dct[value] = False
+ else:
+ self.dct[value] = None
+
+ def format(self, value):
+ value = self.prepare(value)
+ if value in self.dct:
+ return self.dct[value]
+
logger = logging.getLogger(__name__)
class Importer(object):
diff --git a/ishtar_common/migrations/0018_auto__add_itemkey.py b/ishtar_common/migrations/0018_auto__add_itemkey.py
new file mode 100644
index 000000000..4de340549
--- /dev/null
+++ b/ishtar_common/migrations/0018_auto__add_itemkey.py
@@ -0,0 +1,252 @@
+# -*- 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 model 'ItemKey'
+ db.create_table('ishtar_common_itemkey', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('key', self.gf('django.db.models.fields.CharField')(max_length=100)),
+ ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
+ ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
+ ))
+ db.send_create_signal('ishtar_common', ['ItemKey'])
+
+
+ def backwards(self, orm):
+ # Deleting model 'ItemKey'
+ db.delete_table('ishtar_common_itemkey')
+
+
+ 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'}),
+ '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 a89a32991..90232159c 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2014 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2010-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
@@ -41,6 +41,8 @@ from django.utils.safestring import SafeUnicode, mark_safe
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User, Group
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.contenttypes import generic
from django.contrib.gis.db import models
from django.contrib import admin
@@ -351,6 +353,34 @@ class GeneralType(models.Model):
self.txt_idx = slugify(self.label)
return super(GeneralType, self).save(*args, **kwargs)
+ def get_keys(self):
+ keys = []
+ content_type = ContentType.objects.get_for_model(self.__class__)
+ for ik in ItemKey.objects.filter(content_type=content_type,
+ object_id=ik.pk).all():
+ keys.append(ik.key)
+ return keys
+
+ @classmethod
+ 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()
+
+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')
+
+ def __unicode__(self):
+ return self.key
+
class ImageModel(models.Model):
image = models.ImageField(upload_to="upload/", blank=True, null=True)
thumbnail = models.ImageField(upload_to='upload/thumbs/', blank=True,