diff options
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 |
commit | 4b1211e355370b0904dbc6a7fa9e23bb02622034 (patch) | |
tree | fd3ef2bf34cff849c77c23ced9cc1ab774a9b98d | |
parent | eae7d043a96387310cc8f7ee88a1a2568692b021 (diff) | |
download | Ishtar-4b1211e355370b0904dbc6a7fa9e23bb02622034.tar.bz2 Ishtar-4b1211e355370b0904dbc6a7fa9e23bb02622034.zip |
Add a generic relation model to list general types keys. Reorganize imports.
-rw-r--r-- | archaeological_files/data_importer.py | 174 | ||||
-rw-r--r-- | archaeological_operations/data_importer.py | 171 | ||||
-rw-r--r-- | ishtar_common/data_importer.py | 61 | ||||
-rw-r--r-- | ishtar_common/migrations/0018_auto__add_itemkey.py | 252 | ||||
-rw-r--r-- | ishtar_common/models.py | 32 |
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, |