From 00cb05b9669efc165e7c1200903d60ddd0ca1391 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Tue, 24 Oct 2017 16:50:36 +0200 Subject: Add missing view permissions for operation and context record relations --- archaeological_operations/models.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'archaeological_operations') diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 54ed96cec..bc03ee387 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -848,6 +848,9 @@ class RecordRelations(GeneralRecordRelations, models.Model): verbose_name = _(u"Operation record relation") verbose_name_plural = _(u"Operation record relations") ordering = ('left_record', 'relation_type') + permissions = [ + ("view_operationrelation", u"Can view all Operation relations"), + ] post_delete.connect(post_delete_record_relation, sender=RecordRelations) -- cgit v1.2.3 From 02a784588cccb650dd2c91eebfa2853439b7102f Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 25 Oct 2017 10:42:07 +0200 Subject: Tests: specific tests for pdf show --- archaeological_operations/tests.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'archaeological_operations') diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index 67b89ce11..b75c02cae 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -19,6 +19,7 @@ import json import datetime +from subprocess import Popen, PIPE import StringIO import zipfile @@ -1043,6 +1044,32 @@ class OperationTest(TestCase, OperationInitTest): self.assertEqual(response.status_code, 200) self.assertIn('class="sheet"', response.content) + def test_show_pdf(self): + operation = self.operations[0] + c = Client() + response = c.get(reverse('show-operation', + kwargs={'pk': operation.pk, 'type': 'pdf'})) + self.assertEqual(response.status_code, 200) + # empty content when not allowed + self.assertEqual(response.content, "") + c.login(username=self.username, password=self.password) + response = c.get(reverse('show-operation', + kwargs={'pk': operation.pk, 'type': 'pdf'})) + self.assertEqual(response.status_code, 200) + f = StringIO.StringIO(response.content) + filetype = Popen("/usr/bin/file -b --mime -", shell=True, stdout=PIPE, + stdin=PIPE).communicate(f.read(1024))[0].strip() + self.assertTrue(filetype.startswith('application/pdf')) + + def test_show_odt(self): + operation = self.operations[0] + c = Client() + response = c.get(reverse('show-operation', + kwargs={'pk': operation.pk, 'type': 'pdf'})) + self.assertEqual(response.status_code, 200) + # empty content when not allowed + self.assertEqual(response.content, "") + c.login(username=self.username, password=self.password) response = c.get(reverse('show-operation', kwargs={'pk': operation.pk, 'type': 'odt'})) self.assertEqual(response.status_code, 200) -- cgit v1.2.3 From bbf8847cbb02286358213552a6e4dff3f156ef90 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 25 Oct 2017 13:29:40 +0200 Subject: Switch from pisa to weasyprint --- .../templates/ishtar/sheet_contextrecord_pdf.html | 4 --- .../ishtar/sheet_contextrecordsource_pdf.html | 4 --- .../templates/ishtar/sheet_file_pdf.html | 4 --- .../templates/ishtar/sheet_find_pdf.html | 4 --- .../templates/ishtar/sheet_findbasket_pdf.html | 4 --- .../templates/ishtar/sheet_findsource_pdf.html | 4 --- .../templates/ishtar/sheet_treatment_pdf.html | 4 --- .../templates/ishtar/sheet_treatmentfile_pdf.html | 4 --- .../ishtar/sheet_treatmentfilesource_pdf.html | 4 --- .../ishtar/sheet_treatmentsource_pdf.html | 4 --- .../ishtar/sheet_administrativeact_pdf.html | 4 --- .../templates/ishtar/sheet_operation_pdf.html | 4 --- .../ishtar/sheet_operationsource_pdf.html | 4 --- .../templates/ishtar/sheet_container_pdf.html | 4 --- .../templates/ishtar/sheet_warehouse_pdf.html | 4 --- ishtar_common/static/media/style_basic.css | 35 +++++++++++++++++-- .../templates/ishtar/sheet_organization_pdf.html | 4 --- .../templates/ishtar/sheet_person_pdf.html | 4 --- ishtar_common/views.py | 39 ++++++++++++---------- requirements.txt | 6 ++-- 20 files changed, 56 insertions(+), 92 deletions(-) (limited to 'archaeological_operations') diff --git a/archaeological_context_records/templates/ishtar/sheet_contextrecord_pdf.html b/archaeological_context_records/templates/ishtar/sheet_contextrecord_pdf.html index a0d0affcf..b91500403 100644 --- a/archaeological_context_records/templates/ishtar/sheet_contextrecord_pdf.html +++ b/archaeological_context_records/templates/ishtar/sheet_contextrecord_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_contextrecord.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/archaeological_context_records/templates/ishtar/sheet_contextrecordsource_pdf.html b/archaeological_context_records/templates/ishtar/sheet_contextrecordsource_pdf.html index 38c5d318e..c03b80a53 100644 --- a/archaeological_context_records/templates/ishtar/sheet_contextrecordsource_pdf.html +++ b/archaeological_context_records/templates/ishtar/sheet_contextrecordsource_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_contextrecordsource.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/archaeological_files/templates/ishtar/sheet_file_pdf.html b/archaeological_files/templates/ishtar/sheet_file_pdf.html index eaf2a9436..7335eaec7 100644 --- a/archaeological_files/templates/ishtar/sheet_file_pdf.html +++ b/archaeological_files/templates/ishtar/sheet_file_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_file.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/archaeological_finds/templates/ishtar/sheet_find_pdf.html b/archaeological_finds/templates/ishtar/sheet_find_pdf.html index 262bcdad7..11c39f059 100644 --- a/archaeological_finds/templates/ishtar/sheet_find_pdf.html +++ b/archaeological_finds/templates/ishtar/sheet_find_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_find.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/archaeological_finds/templates/ishtar/sheet_findbasket_pdf.html b/archaeological_finds/templates/ishtar/sheet_findbasket_pdf.html index 2b55f0f76..47a4d2bd8 100644 --- a/archaeological_finds/templates/ishtar/sheet_findbasket_pdf.html +++ b/archaeological_finds/templates/ishtar/sheet_findbasket_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_findbasket.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/archaeological_finds/templates/ishtar/sheet_findsource_pdf.html b/archaeological_finds/templates/ishtar/sheet_findsource_pdf.html index 26ef9f2d7..7ca3bd3c1 100644 --- a/archaeological_finds/templates/ishtar/sheet_findsource_pdf.html +++ b/archaeological_finds/templates/ishtar/sheet_findsource_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_findsource.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/archaeological_finds/templates/ishtar/sheet_treatment_pdf.html b/archaeological_finds/templates/ishtar/sheet_treatment_pdf.html index 08df52e97..ccd860ec9 100644 --- a/archaeological_finds/templates/ishtar/sheet_treatment_pdf.html +++ b/archaeological_finds/templates/ishtar/sheet_treatment_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_treatment.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
- – – -
{%endblock%} diff --git a/archaeological_finds/templates/ishtar/sheet_treatmentfile_pdf.html b/archaeological_finds/templates/ishtar/sheet_treatmentfile_pdf.html index be64ff7eb..c216556b3 100644 --- a/archaeological_finds/templates/ishtar/sheet_treatmentfile_pdf.html +++ b/archaeological_finds/templates/ishtar/sheet_treatmentfile_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_treatmentfile.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
- – – -
{%endblock%} diff --git a/archaeological_finds/templates/ishtar/sheet_treatmentfilesource_pdf.html b/archaeological_finds/templates/ishtar/sheet_treatmentfilesource_pdf.html index d0a0ec8e7..2ef4d63b5 100644 --- a/archaeological_finds/templates/ishtar/sheet_treatmentfilesource_pdf.html +++ b/archaeological_finds/templates/ishtar/sheet_treatmentfilesource_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_treatmentfilesource.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/archaeological_finds/templates/ishtar/sheet_treatmentsource_pdf.html b/archaeological_finds/templates/ishtar/sheet_treatmentsource_pdf.html index c38764559..4b7218a14 100644 --- a/archaeological_finds/templates/ishtar/sheet_treatmentsource_pdf.html +++ b/archaeological_finds/templates/ishtar/sheet_treatmentsource_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_treatmentsource.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/archaeological_operations/templates/ishtar/sheet_administrativeact_pdf.html b/archaeological_operations/templates/ishtar/sheet_administrativeact_pdf.html index b6d257cb0..be3e24428 100644 --- a/archaeological_operations/templates/ishtar/sheet_administrativeact_pdf.html +++ b/archaeological_operations/templates/ishtar/sheet_administrativeact_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_administrativeact.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/archaeological_operations/templates/ishtar/sheet_operation_pdf.html b/archaeological_operations/templates/ishtar/sheet_operation_pdf.html index dc3c8b46f..7d86bd924 100644 --- a/archaeological_operations/templates/ishtar/sheet_operation_pdf.html +++ b/archaeological_operations/templates/ishtar/sheet_operation_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_operation.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/archaeological_operations/templates/ishtar/sheet_operationsource_pdf.html b/archaeological_operations/templates/ishtar/sheet_operationsource_pdf.html index 1b2cd9ff3..68eb7aa2d 100644 --- a/archaeological_operations/templates/ishtar/sheet_operationsource_pdf.html +++ b/archaeological_operations/templates/ishtar/sheet_operationsource_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_operationsource.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/archaeological_warehouse/templates/ishtar/sheet_container_pdf.html b/archaeological_warehouse/templates/ishtar/sheet_container_pdf.html index 5e4947cfa..ba0e3164c 100644 --- a/archaeological_warehouse/templates/ishtar/sheet_container_pdf.html +++ b/archaeological_warehouse/templates/ishtar/sheet_container_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_container.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/archaeological_warehouse/templates/ishtar/sheet_warehouse_pdf.html b/archaeological_warehouse/templates/ishtar/sheet_warehouse_pdf.html index 260834ac6..d95efe58f 100644 --- a/archaeological_warehouse/templates/ishtar/sheet_warehouse_pdf.html +++ b/archaeological_warehouse/templates/ishtar/sheet_warehouse_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_warehouse.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/ishtar_common/static/media/style_basic.css b/ishtar_common/static/media/style_basic.css index 1d92928dc..d0f5bbe4a 100644 --- a/ishtar_common/static/media/style_basic.css +++ b/ishtar_common/static/media/style_basic.css @@ -1,7 +1,8 @@ @page { size: a4 portrait; - margin: 2.5cm 1cm 2.5cm 1cm; + margin: 2cm 1cm 2.5cm 1cm; background-image: url("images/ishtar-bg.jpg"); + background-repeat: no-repeat; @frame footer { -pdf-frame-content: pdffooter; bottom: 1cm; @@ -16,6 +17,9 @@ margin-right: 1cm; height: 1.5cm; } + @bottom-center { + content: counter(page) "/" counter(pages); + } } label{ @@ -36,6 +40,13 @@ caption, h3{ font-size:1.5em; } +a img { + display: block; + margin-left: auto; + margin-right: auto; + padding:0.5em; +} + th{ text-align:center; border-bottom:2px solid #922; @@ -72,10 +83,21 @@ td{ display:none; } +caption, hr, .tool-left, .tool-right, .display_details, .display_details_inline{ + display: None; + color: transparent; + background-color: transparent; + border-color: transparent; +} + p{ margin:0.2em; } +td{ + background-color: #ddd; +} + #pdffooter, #pdfheader{ text-align:center; } @@ -84,8 +106,15 @@ p{ font-weight:bold; width:100%; border-bottom:1px solid #922; + position: fixed; + top: -0.5cm; } -.display_details, .display_details_inline{ - display: none; +.window-refs{ + text-align:center; + padding:0; + margin:0; + font-size: 0.9em; + width:100%; + display:block; } diff --git a/ishtar_common/templates/ishtar/sheet_organization_pdf.html b/ishtar_common/templates/ishtar/sheet_organization_pdf.html index 887c7ccb2..2276aa4d1 100644 --- a/ishtar_common/templates/ishtar/sheet_organization_pdf.html +++ b/ishtar_common/templates/ishtar/sheet_organization_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_organization.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/ishtar_common/templates/ishtar/sheet_person_pdf.html b/ishtar_common/templates/ishtar/sheet_person_pdf.html index 199892d2f..9dd9e4c50 100644 --- a/ishtar_common/templates/ishtar/sheet_person_pdf.html +++ b/ishtar_common/templates/ishtar/sheet_person_pdf.html @@ -1,6 +1,5 @@ {% extends "ishtar/sheet_person.html" %} {% block header %} - {% endblock %} {% block main_head %} {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}} {% endblock %} {%block head_sheet%}{%endblock%} {%block main_foot%} -
-– – -
{%endblock%} diff --git a/ishtar_common/views.py b/ishtar_common/views.py index b8350c62a..8d475aff5 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2010-2016 Étienne Loks +# Copyright (C) 2010-2017 Étienne Loks # 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,13 +21,7 @@ from tidylib import tidy_document as tidy from copy import copy, deepcopy import csv -import cStringIO as StringIO import datetime - -import reportlab -reportlab.Version = "2.2" # stupid hack for an old library... -import ho.pisa as pisa - import json import logging from markdown import markdown @@ -35,6 +29,8 @@ import optparse import re from tempfile import NamedTemporaryFile import unicodedata +from weasyprint import HTML, CSS +from weasyprint.fonts import FontConfiguration from extra_views import ModelFormSetView @@ -42,6 +38,7 @@ from django.conf import settings from django.contrib.auth import logout from django.contrib.auth.decorators import login_required from django.contrib.postgres.search import SearchQuery +from django.contrib.staticfiles.templatetags.staticfiles import static from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import reverse, NoReverseMatch from django.db.models import Q, ImageField @@ -1333,19 +1330,25 @@ def show_item(model, name, extra_dct=None): elif doc_type == 'pdf': tpl = loader.get_template('ishtar/sheet_%s_pdf.html' % name) context_instance['output'] = 'PDF' - content = tpl.render(context_instance, request) - result = StringIO.StringIO() - html = content.encode('utf-8') - html = html.replace(" Date: Wed, 25 Oct 2017 18:47:08 +0200 Subject: Remove unused files --- archaeological_context_records/data_importer.py | 82 ------ archaeological_files/data_importer.py | 359 ------------------------ archaeological_finds/data_importer.py | 158 ----------- archaeological_operations/data_importer.py | 280 ------------------ 4 files changed, 879 deletions(-) delete mode 100644 archaeological_context_records/data_importer.py delete mode 100644 archaeological_files/data_importer.py delete mode 100644 archaeological_finds/data_importer.py delete mode 100644 archaeological_operations/data_importer.py (limited to 'archaeological_operations') diff --git a/archaeological_context_records/data_importer.py b/archaeological_context_records/data_importer.py deleted file mode 100644 index 5fdc67949..000000000 --- a/archaeological_context_records/data_importer.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (C) 2015 Étienne Loks - -# 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 . - -# See the file COPYING for details. - -from ishtar_common.data_importer import * - -from archaeological_context_records import models - - -class ContextRecordsImporterBibracte(Importer): - DESC = u"Exports Bibracte : importeur pour l'onglet UE" - OBJECT_CLS = models.ContextRecord - DEFAULTS = {} - LINE_FORMAT = [ - # ID operation - ImportFormater('operation__operation_code', IntegerFormater(), - duplicate_fields=[('parcel__operation__operation_code', - False)]), - # ID UE - ImportFormater('external_id', UnicodeFormater(120), - duplicate_fields=[('label', False)],), - # Type - ImportFormater('unit', TypeFormater(models.Unit), required=False), - # description - ImportFormater('description', UnicodeFormater(1000), required=False,), - # interprétation - ImportFormater('interpretation', UnicodeFormater(1000), - required=False,), - # date ouverture - ImportFormater('opening_date', DateFormater(['%Y/%m/%d']), - required=False,), - # date fermeture - ImportFormater('closing_date', DateFormater(['%Y/%m/%d']), - required=False,), - # lien vers parcelle - ImportFormater('parcel__external_id', UnicodeFormater(12), - required=False,), - # lien vers ID sig - None, - # commentaire - ImportFormater('comment', UnicodeFormater(1000), required=False,), - # ???? - None, - # chrono #TODO! pas de vrai création de nouvelle et en cas de modif - # c'est la zone - ImportFormater('datings__period', TypeFormater(models.Period), - required=False), - ] - - -class ContextRecordsRelationImporterBibracte(Importer): - DESC = u"Exports Bibracte : importeur pour l'onglet relations entre UE" - OBJECT_CLS = models.RecordRelations - DEFAULTS = {} - LINE_FORMAT = [ - # code OA - ImportFormater( - 'left_record__operation__operation_code', IntegerFormater(), - duplicate_fields=[('right_record__operation__operation_code', - False)],), - # identifiant UE 1 - ImportFormater('left_record__external_id', UnicodeFormater(120),), - # type relation - ImportFormater('relation_type', TypeFormater(models.RelationType),), - # identifiant UE 2 - ImportFormater('right_record__external_id', UnicodeFormater(120),), - ] diff --git a/archaeological_files/data_importer.py b/archaeological_files/data_importer.py deleted file mode 100644 index 96b2ee007..000000000 --- a/archaeological_files/data_importer.py +++ /dev/null @@ -1,359 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (C) 2013-2015 Étienne Loks - -# 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 . - -# See the file COPYING for details. - -import datetime -import unicodecsv - -from django.conf import settings - -from ishtar_common.data_importer import * -from ishtar_common.models import OrganizationType - -from archaeological_operations.data_importer import * - -from archaeological_files import models - - -class ImportClosingFormater(ImportFormater): - def post_process(self, obj, context, value, owner=None): - value = self.formater.format(value) - if not value: - return - open_date = obj.reception_date or obj.creation_date - if not open_date: - return - obj.end_date = open_date + datetime.timedelta(30) - obj.save() - - -class ImportMayorFormater(ImportFormater): - def post_process(self, obj, context, value, owner=None): - value = self.formater.format(value) - if type(self.field_name) in (list, tuple): - return # not managed - associated_obj = get_object_from_path(obj, self.field_name) - if not value or not obj.main_town or not associated_obj: - return - if slugify(value).endswith('le-maire'): - value += u" de " + obj.main_town.name - value = value[:300] - setattr(associated_obj, self.field_name.split('__')[-1], value) - associated_obj.save() - - -class FilePostProcessing(object): - def post_processing(self, item, data): - if not item.end_date: # auto-close - open_date = item.reception_date or item.creation_date - if open_date: - item.end_date = open_date + datetime.timedelta(30) - item.save() - return item - - -class FileImporterSraPdL(FilePostProcessing, Importer): - DESC = u"Exports dossiers SRA PdL : importeur Filemaker dossiers" - SLUG = "sra-pdl-files" - LINE_FORMAT = [] - OBJECT_CLS = models.File - UNICITY_KEYS = ['external_id'] - DEFAULTS = { - ('responsible_town_planning_service', 'attached_to'): { - 'organization_type': OrganizationType.objects.get( - txt_idx="planning_service")}, - ('general_contractor', 'attached_to'): { - 'organization_type': OrganizationType.objects.get( - txt_idx="general_contractor")}, - tuple(): { - 'file_type': models.FileType.objects.get( - txt_idx='preventive'), - 'creation_date': datetime.datetime.now, - }, - ('in_charge',): {'attached_to': None}, # initialized in __init__ - } - - def _init_line_format(self): - tf = TownFormater() - tf.town_dct_init() - self.line_format = [ - None, # A, 1 - ImportFormater( - ['general_contractor__attached_to__address', # B, 2 - 'general_contractor__attached_to__postal_code', - 'general_contractor__attached_to__town'], - [UnicodeFormater(500, clean=True), - UnicodeFormater(5, re_filter=RE_CD_POSTAL_FILTER), - UnicodeFormater(70, clean=True), ], - regexp=RE_ADD_CD_POSTAL_TOWN, - regexp_formater_args=[[0], [1], [2]], required=False, - comment=u"Aménageur - adresse"), - ImportMayorFormater( - # C, 3 TODO - extraire nom_prenom_titre - 'general_contractor__raw_name', - UnicodeFormater(200), - comment=u"Aménageur - nom brut", - post_processing=True, - required=False), - None, # D, 4 - ImportFormater( - "general_contractor__title", # E, 5 - TypeFormater(models.TitleType), - required=False, - comment=u"Aménageur - titre"), - None, # F, 6 - None, # G, 7 - None, # H, 8 - ImportFormater("parcels__year", # I, 9 - YearNoFuturFormater(), - required=False), - # J, 10 - ImportParcelFormater('', required=False, post_processing=True), - None, # K, 11 - ImportFormater([['main_town', 'parcels__town']], # L, 12 - tf, - required=False, - comment=u"Commune (si non définie avant)"), - ImportFormater([['main_town', 'parcels__town']], # M, 13 - tf, - required=False, - comment=u"Commune (si non définie avant)"), - ImportFormater('saisine_type', # N, 14 - TypeFormater(models.SaisineType), - required=False, - comment=u"Type de saisine"), - None, # O, 15 - ImportFormater('name', # P, 16 - UnicodeFormater(), - comment=u"Nom du dossier", - required=False), - None, # Q, 17 - ImportFormater( - [ - 'responsible_town_planning_service__raw_name', - # R, 18 service instructeur - 'responsible_town_planning_service__attached_to__address', - 'responsible_town_planning_service__' - 'attached_to__postal_code', - 'responsible_town_planning_service__attached_to__town'], - [UnicodeFormater(300, clean=True), - UnicodeFormater(300, clean=True), - UnicodeFormater(5, re_filter=RE_CD_POSTAL_FILTER), - UnicodeFormater(70, clean=True), ], - regexp=RE_NAME_ADD_CD_POSTAL_TOWN, - regexp_formater_args=[[0], [1], [2], [3]], - comment=u"Service instructeur - adresse", - required=False), - ImportFormater( - 'comment', # S, 19 - UnicodeFormater(prefix=u'* Considérants : '), - comment=u"Commentaire", - concat=True, - required=False), - ImportYearFormater('reception_date', # T, 20 - DateFormater(['%d/%m/%Y', '%d/%m/%Y']), - comment=u"Date de réception", - required=False, - duplicate_fields=[['creation_date', False]]), - None, # U, 21 - None, # V, 22 - None, # W, 23 - None, # X, 24 - None, # Y, 25 - None, # Z, 26 - None, # AA, 27 - None, # AB, 28 - None, # AC, 29 - None, # AD, 30 - None, # AE, 31 - None, # AF, 32 - None, # AG, 33 - None, # AH, 34 - ImportFormater('creation_date', # AI, 35 - DateFormater(['%d/%m/%Y', '%d/%m/%y']), - force_value=True, - comment=u"Date de création", - required=False,), - None, # AJ, 36 - ImportFormater('comment', # AK, 37 - UnicodeFormater(prefix=u"* Historique : "), - comment=u"Commentaire", - concat=True, required=False), - ImportFormater('internal_reference', # AL, 38 - UnicodeFormater(60), - comment=u"Autre référence", - required=False), - None, # AM, 39 - None, # AN, 40 - ImportFormater('comment', # AO, 41 - UnicodeFormater( - prefix=u"* Justificatif de prescription : "), - comment=u"Justificatif de prescription", - concat=True, required=False), - ImportFormater('comment', # AP, 42 - UnicodeFormater( - prefix=u"* Justificatif d'intervention : "), - comment=u"Justificatif d'intervention", - concat=True, required=False), - None, # AQ, 43 - None, # AR, 44 - None, # AS, 45 - None, # AT, 46 - ImportFormater('comment', # AU, 47 - UnicodeFormater( - prefix=u"* Méthodologie de l'opération : "), - comment=u"Méthodologie de l'opération", - concat=True, required=False), - None, # AV, 48 - ImportFormater('permit_reference', # AW, 49 - UnicodeFormater(300, clean=True), - regexp=RE_PERMIT_REFERENCE, - comment=u"Réf. du permis de construire", - required=False), - ImportFormater('comment', # AX, 50 - UnicodeFormater( - prefix=u"* Référence de dossier aménageur : "), - comment=u"Référence de dossier aménageur", - concat=True, required=False), - None, # AY, 51 - None, # AZ, 52 - ImportFormater('comment', # BA, 53 - UnicodeFormater( - prefix=u"* Numéro d'arrêté préfectoral : "), - comment=u"Numéro d'arrêté préfectoral", - concat=True, required=False), - ImportFormater('comment', # BB, 54 - UnicodeFormater( - prefix=u"* Numéro d'arrêté SRA : "), - comment=u"Numéro d'arrêté SRA", - concat=True, required=False), - ImportFormater('comment', # BC, 55 - UnicodeFormater( - prefix=u"* Numéro d'arrêté de " - u"post-diagnostic : "), - comment=u"Numéro d'arrêté de post-diagnostic", - concat=True, required=False), - None, # BD, 56 - ImportFormater([['main_town', 'parcels__town']], # BE, 57 - TownINSEEFormater(), - required=False, - comment=u"Commune (si non définie avant)"), - ImportFormater('comment', # BF, 58 - UnicodeFormater(2000), - comment=u"Commentaire", - concat=True, required=False), - None, # BG, 59 - None, # BH, 60 - None, # BI, 61 - None, # BJ, 62 - None, # BK, 63 - None, # BL, 64 - None, # BM, 65 - None, # BN, 66 - None, # BO, 67 - None, # BP, 68 - None, # BQ, 69 - None, # BR, 70 - None, # BS, 71 - ImportFormater( # BT, 72 nom service instructeur - ['responsible_town_planning_service__attached_to__name', ], - [UnicodeFormater(300, clean=True), ], - regexp=RE_ORGA, - comment=u"Service instructeur - nom", - required=False), - None, # BU, 73 - None, # BV, 74 - ImportFormater( - 'in_charge__raw_name', # BW, 75 responsable - UnicodeFormater(200), - comment=u"Responsable - nom brut", - required=False), - ImportFormater('total_surface', # BX, 76 surface totale - SurfaceFormater(), - comment=u"Surface totale", - required=False), - ImportFormater('total_developed_surface', - # BY, 77 surface totale aménagée - SurfaceFormater(), - comment=u"Surface totale aménagée", - required=False), - None, # BZ, 78 - None, # CA, 79 - None, # CB, 80 - None, # CC, 81 - None, # CD, 82 - None, # CE, 83 - None, # CF, 84 - ImportFormater('permit_type', - TypeFormater(models.PermitType), - required=False, - comment=u"Type de permis"), # CG, 85 - None, # CH, 85 - ImportFormater('year', # CI, 86 - IntegerFormater(), - comment=u"Année du dossier", - required=True), - ImportFormater('numeric_reference', # CJ, 87 - IntegerFormater(), - comment=u"Identifiant numérique", - required=True), - ImportFormater('external_id', # CK, 88 - UnicodeFormater(), - comment=u"Identifiant externe", - required=True), - ] - - def __init__(self, *args, **kwargs): - super(FileImporterSraPdL, self).__init__(*args, **kwargs) - self.DEFAULTS[('in_charge',)]['attached_to'], created = \ - models.Organization.objects.get_or_create( - name='SRA Pays de la Loire', - defaults={ - 'organization_type': - OrganizationType.objects.get(txt_idx='sra')}) - self._init_line_format() - if tuple() not in self._defaults: - self._defaults[tuple()] = {} - self._defaults[tuple()]['history_modifier'] = self.history_modifier - self._associate_db_target_to_formaters() - - -def test(filename): - importer = FileImporterSraPdL(skip_lines=3, output='cli') - with open(filename) as csv_file: - encodings = [settings.ENCODING, settings.ALT_ENCODING, 'utf-8'] - for encoding in encodings: - try: - importer.importation( - [line for line in - unicodecsv.reader(csv_file, encoding='utf-8')]) - # importer.importation(unicode_csv_reader( - # [line.decode(encoding) - # for line in csv_file.readlines()]) - print importer.get_csv_errors() - break - except ImporterError, e: - print(unicode(e)) - if e.type == ImporterError.HEADER \ - and encoding != encodings[-1]: - csv_file.seek(0) - continue - except UnicodeDecodeError: - if encoding != encodings[-1]: - csv_file.seek(0) - continue diff --git a/archaeological_finds/data_importer.py b/archaeological_finds/data_importer.py deleted file mode 100644 index e0c18d1bf..000000000 --- a/archaeological_finds/data_importer.py +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (C) 2015 Étienne Loks - -# 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 . - -# See the file COPYING for details. - -from ishtar_common.data_importer import * - -from archaeological_finds import models - - -class FindsImporterBibracte(Importer): - DESC = u"Exports Bibracte : importeur pour l'onglet mobilier" - OBJECT_CLS = models.BaseFind - DEFAULTS = {} - LINE_FORMAT = [ - # OA - ImportFormater('context_record__operation__operation_code', - IntegerFormater(),), - # external_id - ImportFormater( - 'external_id', UnicodeFormater(120, notnull=True), - duplicate_fields=[('find__external_id', False), - ('label', False), - ('find__label', False)]), - # isolé ou non (si non isolé = lot) - None, # à corriger - # ImportFormater( - # 'is_isolated', - # StrToBoolean(choices={'lot': False, 'objet': True}), - # required=False), - # ??? - None, - # A voir - None, - # cf type - None, - # Type = sous classe de matériaux = Liste hiérarchique - ImportFormater('find__material_types', - TypeFormater(models.MaterialType), required=False), - # ??? - None, - # lien avec contenant - None, - # = nombre - ImportFormater('find__find_number', IntegerFormater(), required=False), - # poids - ImportFormater('find__weight', FloatFormater(), required=False), - # unité (g par défault) - ImportFormater('find__weight_unit', - StrChoiceFormater(models.WEIGHT_UNIT), required=False), - # lien UE - ImportFormater('context_record__external_id', UnicodeFormater(120),), - # date decouverte - ImportFormater('discovery_date', DateFormater(['%Y/%m/%d']), - required=False,), - # lien parcelle (unique) - None, - # etat conservation - ImportFormater('find__conservatory_state', - TypeFormater(models.ConservatoryState), required=False), - # preservation_to_consider - ImportFormater('find__preservation_to_considers', - TypeFormater(models.TreatmentType), required=False), - # comment - ImportFormater('comment', UnicodeFormater(1000), required=False), - # lien vers plusieurs chrono (voir gestion actuelle chrono) - None, - # ImportFormater('find__datings__period', TypeFormater(Period, - # many_split="&"), required=False), - # topographic_localisation - ImportFormater('topographic_localisation', UnicodeFormater(120), - required=False), - # special_interest - ImportFormater('special_interest', UnicodeFormater(120), - required=False), - # description - ImportFormater('description', UnicodeFormater(1000), required=False), - # remontage - None - ] - - -class FindAltImporterBibracte(Importer): - DESC = u"Exports Bibracte : importeur pour l'onglet prélèvement" - OBJECT_CLS = models.BaseFind - DEFAULTS = {} - LINE_FORMAT = [ - # code OA - ImportFormater('context_record__operation__operation_code', - IntegerFormater(),), - # identifiant prelevement - ImportFormater('external_id', UnicodeFormater(120, notnull=True), - duplicate_fields=[('find__external_id', False)]), - # nature - ImportFormater('find__material_types', - TypeFormater(models.MaterialType), required=False), - # identifiant UE - ImportFormater('context_record__external_id', UnicodeFormater(120),), - # identifiant materiel - None, - # commentaire - ImportFormater('comment', UnicodeFormater(1000), required=False), - ] - - -class ImportTreatmentFormater(ImportFormater): - def post_process(self, obj, context, value, owner=None): - if obj.upstream_treatment.count(): - return - ope_code = context['upstream_treatment'][ - 'base_finds']['context_record']['operation']['operation_code'] - ope_code = int(ope_code) - downstream = models.Find.objects.filter( - external_id=value, - base_finds__context_record__operation__operation_code=ope_code) - if not downstream.count(): - return - downstream = downstream.all()[0] - downstream.upstream_treatment = obj - downstream.save() - upstream = downstream.duplicate(owner) - upstream.downstream_treatment = obj - upstream.save() - return - - -class TreatmentImporterBibracte(Importer): - DESC = u"Exports Bibracte : importeur pour l'onglet traitement" - OBJECT_CLS = models.Treatment - DEFAULTS = {} - LINE_FORMAT = [ - # code OA - ImportFormater( - 'upstream_treatment__base_finds__context_record__operation__' - 'operation_code', - UnicodeFormater(120, notnull=True)), - # identifiant - ImportTreatmentFormater( - 'external_id', - UnicodeFormater(120, notnull=True), post_processing=True), - None, - # traitement - ImportFormater('treatment_type', TypeFormater(models.TreatmentType),), - ] diff --git a/archaeological_operations/data_importer.py b/archaeological_operations/data_importer.py deleted file mode 100644 index b4cd2f0d0..000000000 --- a/archaeological_operations/data_importer.py +++ /dev/null @@ -1,280 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (C) 2015 Étienne Loks - -# 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 . - -# See the file COPYING for details. - -import re - -from django.db import IntegrityError -from django.template.defaultfilters import slugify - -from ishtar_common.data_importer import * -from ishtar_common.models import Town, OrganizationType, SourceType, \ - SupportType, Format, AuthorType - -from archaeological_operations import models -from archaeological_operations.forms import OPERATOR -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: - models.Parcel.objects.get_or_create(**parcel_dct) - except IntegrityError: - try: - p = unicode(parcel_dct) - except UnicodeDecodeError: - try: - p = str(parcel_dct).decode('utf-8') - except UnicodeDecodeError: - p = u"" - raise ImporterError(u"Erreur d'import parcelle, contexte : %s" - % p) - - -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(numero_insee=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("([^,\n]*)") - - -class OperationImporterBibracte(Importer): - OBJECT_CLS = models.Operation - DESC = u"Exports Bibracte : importeur pour l'onglet opération" - DEFAULTS = { - ('operator',): { - 'organization_type': OPERATOR - }, - } - LINE_FORMAT = [ - # CODE OPE - ImportFormater('operation_code', IntegerFormater(),), - # REGION - None, - # TYPE operation - ImportFormater('operation_type', TypeFormater(models.OperationType),), - # NOM - ImportFormater('common_name', UnicodeFormater(120),), - # OPERATEUR - ImportFormater('operator__name', UnicodeFormater(120),), - # resp. lien IMPORT avec personne - ImportFormater('in_charge__raw_name', UnicodeFormater(300),), - # début - ImportFormater('start_date', DateFormater(['%Y/%m/%d']),), - # fin - ImportFormater('excavation_end_date', DateFormater(['%Y/%m/%d']),), - # Chronos - ImportFormater('periods', TypeFormater(models.Period, many_split="&"), - required=False), - ] - -RE_PARCEL_SECT_NUM = re.compile("([A-Za-z]*)([0-9]*)") -RE_NUM_INSEE = re.compile("([0-9]*)") - - -class ParcelImporterBibracte(Importer): - OBJECT_CLS = models.Parcel - DESC = u"Exports Bibracte : importeur pour l'onglet parcelles" - DEFAULTS = { - ('operator',): { - 'organization_type': OrganizationType.objects.get( - txt_idx="operator")}, - } - LINE_FORMAT = [ - # code OA - ImportFormater('operation__operation_code', IntegerFormater(),), - # identifiant parcelle - ImportFormater( - ['section', 'parcel_number'], - [UnicodeFormater(4), UnicodeFormater(6), ], - regexp=RE_PARCEL_SECT_NUM, - regexp_formater_args=[[0], [1]], required=False, - duplicate_fields=[('external_id', False)],), - # numero parcelle - ImportFormater('parcel_number', UnicodeFormater(6), - required=False,), - # section cadastre - ImportFormater('section', UnicodeFormater(4), - required=False,), - # annee cadastre - ImportFormater('year', YearFormater(), required=False,), - # nom commune - None, - # numero INSEE commune - ImportFormater('town__numero_insee', UnicodeFormater(6), - regexp=RE_NUM_INSEE, required=False,), - # nom departement - None, - # lieu dit adresse - ImportFormater('address', UnicodeFormater(500), - required=False,), - ] - -MAIN_AUTHOR, created = AuthorType.objects.get_or_create(txt_idx='main_author') - - -class DocImporterBibracte(Importer): - OBJECT_CLS = models.OperationSource - DEFAULTS = { - ('authors',): {'author_type': MAIN_AUTHOR}, - } - DESC = u"Exports Bibracte : importeur pour l'onglet documentation" - LINE_FORMAT = [ - # code OA - ImportFormater('operation__operation_code', IntegerFormater(),), - # identifiant documentation - ImportFormater('external_id', UnicodeFormater(12),), - # type - ImportFormater('source_type', TypeFormater(SourceType), - required=False), - # nature support - ImportFormater('support_type', TypeFormater(SupportType), - required=False), - # nombre element - ImportFormater('item_number', IntegerFormater(), required=False), - # auteur - ImportFormater('authors__person__raw_name', UnicodeFormater(300), - required=False), - # annee - ImportFormater('creation_date', DateFormater(['%Y']),), - # format - ImportFormater('format_type', TypeFormater(Format), required=False), - # description legende - ImportFormater('description', UnicodeFormater(1000), required=False), - # type contenant - None, - # numero contenant - None, - # commentaire - ImportFormater('comment', UnicodeFormater(1000), required=False), - # echelle - ImportFormater('scale', UnicodeFormater(30), required=False), - # type sous contenant - None, - # numero sous contenant - None, - # informations complementaires - ImportFormater('additional_information', UnicodeFormater(1000), - required=False), - ] -- cgit v1.2.3