diff options
41 files changed, 925 insertions, 1043 deletions
| diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 53b4d7d88..fb2d4e824 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@  before_script:    - apt-get update -  - apt-get install -q -y git python-pip libpq-dev python-dev libjpeg-dev zlib1g-dev libxml2-dev libxslt1-dev libgeos-dev tidy binutils libproj-dev gdal-bin -  - pip install -q -r requirements.txt +  - apt-get install -q -y git python-pip libpq-dev python-dev libjpeg-dev zlib1g-dev libxml2-dev libxslt1-dev libgeos-dev python-cairocffi tidy binutils libproj-dev gdal-bin libpangocairo-1.0-0 +  - pip install -r requirements.txt    - cp Makefile.example Makefile    - cp example_project/local_settings.py.gitlab-ci example_project/local_settings.py diff --git a/Makefile.example b/Makefile.example index 8c79c209f..c3b40b6df 100644 --- a/Makefile.example +++ b/Makefile.example @@ -51,10 +51,10 @@ coverage: clean  			archaeological_context_records,archaeological_files,archaeological_finds,archaeological_warehouse,\  			archaeological_files_pdl" ./manage.py test $(apps) && coverage report -build_gitlab: +build_gitlab: clean collectstatic  	cd $(project); $(PYTHON) ./manage.py migrate -test_gitlab: clean +test_gitlab: build_gitlab  	cd $(project); $(PYTHON) manage.py test $(apps)  pep8: 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  <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. - -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_context_records/models.py b/archaeological_context_records/models.py index a8517ed26..925a48597 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -578,6 +578,10 @@ class RecordRelations(GeneralRecordRelations, models.Model):      class Meta:          verbose_name = _(u"Record relation")          verbose_name_plural = _(u"Record relations") +        permissions = [ +            ("view_recordrelation", u"Can view all Context record relations"), +        ] +  post_delete.connect(post_delete_record_relation, sender=RecordRelations) @@ -626,6 +630,9 @@ class RecordRelationView(models.Model):          managed = False          db_table = 'record_relations'          unique_together = ('id', 'right_record') +        permissions = [ +            ("view_recordrelation", u"Can view all record relations - view"), +        ]      def __unicode__(self):          return u"{} \"{}\"".format(self.relation_type, self.right_record) 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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%endblock%} diff --git a/archaeological_context_records/views.py b/archaeological_context_records/views.py index 3bfe544be..242ccadec 100644 --- a/archaeological_context_records/views.py +++ b/archaeological_context_records/views.py @@ -81,11 +81,11 @@ get_contextrecordsource = get_item(  get_contextrecordrelation = get_item(      models.RecordRelationView, 'get_contextrecordrelation', -    'contextrecordrelation') +    'contextrecordrelation', specific_perms=['view_recordrelation'])  get_contextrecordrelationdetail = get_item(      models.RecordRelations, 'get_contextrecordrelationdetail', -    'contextrecordrelationdetail') +    'contextrecordrelationdetail', specific_perms=['view_recordrelation'])  record_search_wizard = SearchWizard.as_view([      ('general-record_search', RecordFormSelection)], 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  <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 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_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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%endblock%} 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  <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. - -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_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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -    – <pdf:pagenumber/> – -</div>  </body>  </html>  {%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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -    – <pdf:pagenumber/> – -</div>  </body>  </html>  {%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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%endblock%} 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  <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 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), -    ] diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index dd3e65534..70c1c02ba 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -853,6 +853,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) 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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%endblock%} 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) diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 71f31981a..fdd3a5e63 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -262,6 +262,11 @@ class Container(LightHistorizedItem, ImageModel):          'location': 'location__pk',          'container_type': 'container_type__pk',          'reference': 'reference__icontains', +        'finds__base_finds__context_record__operation': +            'finds__base_finds__context_record__operation', +        'finds__base_finds__context_record': +            'finds__base_finds__context_record', +        'finds': 'finds',      }      SHOW_URL = 'show-container'      COL_LABELS = { 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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%endblock%} diff --git a/example_project/.coveragerc b/example_project/.coveragerc index 43462778f..ff9237bdd 100644 --- a/example_project/.coveragerc +++ b/example_project/.coveragerc @@ -6,4 +6,5 @@ exclude_lines =  [run]  omit =      */migrations/* +    */old_migrations/* diff --git a/fixtures/initial_data-auth-fr.json b/fixtures/initial_data-auth-fr.json index 43d11248b..4fa4af0e1 100644 --- a/fixtures/initial_data-auth-fr.json +++ b/fixtures/initial_data-auth-fr.json @@ -4807,6 +4807,226 @@      }  },  { +    "model": "auth.permission", +    "fields": { +        "name": "Can add Importer - Target key group", +        "content_type": [ +            "ishtar_common", +            "targetkeygroup" +        ], +        "codename": "add_targetkeygroup" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can change Importer - Target key group", +        "content_type": [ +            "ishtar_common", +            "targetkeygroup" +        ], +        "codename": "change_targetkeygroup" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can delete Importer - Target key group", +        "content_type": [ +            "ishtar_common", +            "targetkeygroup" +        ], +        "codename": "delete_targetkeygroup" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can view all Containers", +        "content_type": [ +            "archaeological_warehouse", +            "container" +        ], +        "codename": "view_container" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can view own Container", +        "content_type": [ +            "archaeological_warehouse", +            "container" +        ], +        "codename": "view_own_container" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can add own Container", +        "content_type": [ +            "archaeological_warehouse", +            "container" +        ], +        "codename": "add_own_container" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can change own Container", +        "content_type": [ +            "archaeological_warehouse", +            "container" +        ], +        "codename": "change_own_container" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can delete own Container", +        "content_type": [ +            "archaeological_warehouse", +            "container" +        ], +        "codename": "delete_own_container" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can add Treatment emergency type", +        "content_type": [ +            "archaeological_finds", +            "treatmentemergencytype" +        ], +        "codename": "add_treatmentemergencytype" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can change Treatment emergency type", +        "content_type": [ +            "archaeological_finds", +            "treatmentemergencytype" +        ], +        "codename": "change_treatmentemergencytype" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can delete Treatment emergency type", +        "content_type": [ +            "archaeological_finds", +            "treatmentemergencytype" +        ], +        "codename": "delete_treatmentemergencytype" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can add Alteration type", +        "content_type": [ +            "archaeological_finds", +            "alterationtype" +        ], +        "codename": "add_alterationtype" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can change Alteration type", +        "content_type": [ +            "archaeological_finds", +            "alterationtype" +        ], +        "codename": "change_alterationtype" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can delete Alteration type", +        "content_type": [ +            "archaeological_finds", +            "alterationtype" +        ], +        "codename": "delete_alterationtype" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can add Alteration cause type", +        "content_type": [ +            "archaeological_finds", +            "alterationcausetype" +        ], +        "codename": "add_alterationcausetype" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can change Alteration cause type", +        "content_type": [ +            "archaeological_finds", +            "alterationcausetype" +        ], +        "codename": "change_alterationcausetype" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can delete Alteration cause type", +        "content_type": [ +            "archaeological_finds", +            "alterationcausetype" +        ], +        "codename": "delete_alterationcausetype" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can view all Operation relations", +        "content_type": [ +            "archaeological_operations", +            "recordrelations" +        ], +        "codename": "view_operationrelation" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can view all Context record relations", +        "content_type": [ +            "archaeological_context_records", +            "recordrelations" +        ], +        "codename": "view_recordrelation" +    } +}, +{ +    "model": "auth.permission", +    "fields": { +        "name": "Can view all record relations - view", +        "content_type": [ +            "archaeological_context_records", +            "recordrelationview" +        ], +        "codename": "view_recordrelation" +    } +}, +{      "model": "auth.group",      "fields": {          "name": "Op\u00e9rations : lecture", @@ -4815,6 +5035,11 @@                  "view_operation",                  "archaeological_operations",                  "operation" +            ], +            [ +                "view_operationrelation", +                "archaeological_operations", +                "recordrelations"              ]          ]      } @@ -4841,6 +5066,16 @@                  "view_contextrecord",                  "archaeological_context_records",                  "contextrecord" +            ], +            [ +                "view_recordrelation", +                "archaeological_context_records", +                "recordrelations" +            ], +            [ +                "view_recordrelation", +                "archaeological_context_records", +                "recordrelationview"              ]          ]      } @@ -5050,6 +5285,11 @@                  "add_operation",                  "archaeological_operations",                  "operation" +            ], +            [ +                "add_recordrelations", +                "archaeological_operations", +                "recordrelations"              ]          ]      } @@ -5068,6 +5308,16 @@                  "delete_operation",                  "archaeological_operations",                  "operation" +            ], +            [ +                "change_recordrelations", +                "archaeological_operations", +                "recordrelations" +            ], +            [ +                "delete_recordrelations", +                "archaeological_operations", +                "recordrelations"              ]          ]      } @@ -5112,6 +5362,11 @@                  "add_contextrecord",                  "archaeological_context_records",                  "contextrecord" +            ], +            [ +                "add_recordrelations", +                "archaeological_context_records", +                "recordrelations"              ]          ]      } @@ -5130,6 +5385,16 @@                  "delete_contextrecord",                  "archaeological_context_records",                  "contextrecord" +            ], +            [ +                "change_recordrelations", +                "archaeological_context_records", +                "recordrelations" +            ], +            [ +                "delete_recordrelations", +                "archaeological_context_records", +                "recordrelations"              ]          ]      } @@ -6235,5 +6500,49 @@              ]          ]      } +}, +{ +    "model": "auth.group", +    "fields": { +        "name": "Contenants : ajout", +        "permissions": [ +            [ +                "add_container", +                "archaeological_warehouse", +                "container" +            ] +        ] +    } +}, +{ +    "model": "auth.group", +    "fields": { +        "name": "Contenants : lecture", +        "permissions": [ +            [ +                "view_container", +                "archaeological_warehouse", +                "container" +            ] +        ] +    } +}, +{ +    "model": "auth.group", +    "fields": { +        "name": "Contenants : modification/suppression", +        "permissions": [ +            [ +                "change_container", +                "archaeological_warehouse", +                "container" +            ], +            [ +                "delete_container", +                "archaeological_warehouse", +                "container" +            ] +        ] +    }  }  ] diff --git a/install/ishtar-install b/install/ishtar-install index 36b937388..a34b1984c 100755 --- a/install/ishtar-install +++ b/install/ishtar-install @@ -118,16 +118,11 @@ do_install() {          ;;          debian) -            MAINBACKS=`cat /etc/apt/sources.list | grep jessie-backports |grep -v "^#"` -            ALLBACKS='' -            if [ "$(ls -A /etc/apt/sources.list.d/)" ]; then -                ALLBACKS=`cat /etc/apt/sources.list.d/* | grep jessie-backports |grep -v "^#"` -            fi -            if [ "$ALLBACKS" != '' ] || [ "$MAINBACKS" != '' ]; then -                backports_activated='true'; -            fi              dist_version="$(cat /etc/debian_version | sed 's/\/.*//' | sed 's/\..*//')"              case "$dist_version" in +                9) +                    dist_version="stretch" +                ;;                  8)                      dist_version="jessie"                  ;; @@ -135,6 +130,16 @@ do_install() {                      dist_version="wheezy"                  ;;              esac +            set +e +            MAINBACKS=`cat /etc/apt/sources.list | grep $dist_version'-backports' |grep -v "^#"` +            ALLBACKS='' +            if [ "$(ls -A /etc/apt/sources.list.d/)" ]; then +                ALLBACKS=`cat /etc/apt/sources.list.d/* | grep $dist_version'-backports' |grep -v "^#"` +            fi +            set -e +            if [ "$ALLBACKS" != '' ] || [ "$MAINBACKS" != '' ]; then +                backports_activated='true'; +            fi          ;;          oracleserver) @@ -282,7 +287,7 @@ EOF      # Run setup for each distro accordingly      case "$lsb_dist" in          ubuntu|debian) -            if [ "$dist_version" != "jessie" ] && [ "$dist_version" != "wheezy" ]; then +            if [ "$dist_version" != "stretch" ] &&  [ "$dist_version" != "jessie" ] && [ "$dist_version" != "wheezy" ]; then                  echo ""                  cecho r " Sorry this script cannot manage your version of Debian/Ubuntu."                  echo "" @@ -372,9 +377,9 @@ EOF                  cecho y "Installing Ishtar dependencies"                  echo "";                  ( set -x; $sh_c 'sleep 3; apt-get install -t jessie-backports -y -q python python-django\ -                      python-django-registration' ) +                      python-django-registration python-cffi' )                  ( set -x; $sh_c 'sleep 3; apt-get install -y -q \ -                      python-pisa python-bs4 python-django-formtools\ +                      python-bs4 python-django-formtools libpangocairo-1.0-0 \                        python-tidylib python-lxml python-imaging python-html5lib \                        python-psycopg2 python-gdal gettext python-unicodecsv memcached \                        python-django-extra-views python-memcache python-dbf python-markdown' ) @@ -389,6 +394,53 @@ EOF                  cecho y "Installing python-ajax-select (available version in Debian is not compatible with backported Django)"                  echo "";                  ( set -x; $sh_c 'pip install django-ajax-selects==1.4.3' ) +                cecho y "Installing weasyprint" +                echo ""; +                ( set -x; $sh_c 'pip install WeasyPrint==0.41' ) + +            fi + +            if [ "$dist_version" == "stretch" ]; then +                if [ "$backports_activated" != 'true' ]; then +                    echo "" +                    cecho r "  In order to install Ishtar you have to activate Debian backports." +                    echo "  To do that:" +                    echo "" +                    echo "    echo 'deb http://ftp.debian.org/debian stretch-backports main contrib' >> /etc/apt/sources.list" +                    echo "" +                    cecho p "  Run again Ishtar installation script after that." +                    exit 1 +                fi + +                if [ "$default_db" == '127.0.0.1' ]; then +                    echo "-------------------------------------------------------------------------------"; +                    cecho y "Installing postgresql" +                    echo "" +                    POSTGIS=postgresql-9.6-postgis-2.3 +                    ( set -x; $sh_c 'sleep 3; apt-get install -y -q postgresql '$POSTGIS ) +                fi +                echo "-------------------------------------------------------------------------------"; +                cecho y "Installing Ishtar dependencies" +                echo ""; +                ( set -x; $sh_c 'sleep 3; apt-get install -t stretch-backports -y -q  python-django' ) +                ( set -x; $sh_c 'sleep 3; apt-get install -y -q \ +                      python-django-registration libpangocairo-1.0-0 \ +                      python-bs4 python-django-formtools python-cffi \ +                      python-tidylib python-lxml python-imaging python-html5lib \ +                      python-psycopg2 python-gdal gettext python-unicodecsv memcached \ +                      python-django-extra-views python-memcache python-dbf python-markdown \ +                      python-reportlab django-ajax-selects python-django-extensions' ) +                echo "-------------------------------------------------------------------------------"; +                cecho y "Installing django-simple-history" +                echo ""; +                ( set -x; $sh_c 'pip install git+https://github.com/treyhunner/django-simple-history.git@1.8.2#egg=django-simple-history' ) +                echo "-------------------------------------------------------------------------------"; +                cecho y "Installing python-secretary" +                echo ""; +                ( set -x; $sh_c 'pip install secretary==0.2.14' ) +                cecho y "Installing weasyprint" +                echo ""; +                ( set -x; $sh_c 'pip install WeasyPrint==0.41' )              fi              ;; diff --git a/ishtar_common/fixtures/initial_data-fr.json b/ishtar_common/fixtures/initial_data-fr.json index d9026cf49..4045094d9 100644 --- a/ishtar_common/fixtures/initial_data-fr.json +++ b/ishtar_common/fixtures/initial_data-fr.json @@ -839,6 +839,9 @@              ],              [                  "Documents op\u00e9ration : lecture" +            ], +            [ +                "Contenants : lecture"              ]          ]      } diff --git a/ishtar_common/fixtures/initial_importtypes-fr.json b/ishtar_common/fixtures/initial_importtypes-fr.json index 4386b6de7..438a023e0 100644 --- a/ishtar_common/fixtures/initial_importtypes-fr.json +++ b/ishtar_common/fixtures/initial_importtypes-fr.json @@ -119,6 +119,13 @@      }  },  { +    "model": "ishtar_common.importermodel", +    "fields": { +        "name": "Relation entre Op\u00e9ration", +        "klass": "archaeological_operations.models.RecordRelations" +    } +}, +{      "model": "ishtar_common.importertype",      "fields": {          "name": "MCC - Op\u00e9rations", @@ -129,6 +136,7 @@          ],          "is_template": true,          "unicity_keys": "code_patriarche", +        "available": true,          "users": [],          "created_models": []      } @@ -144,6 +152,7 @@          ],          "is_template": true,          "unicity_keys": "external_id", +        "available": true,          "users": [],          "created_models": []      } @@ -159,6 +168,7 @@          ],          "is_template": true,          "unicity_keys": "", +        "available": true,          "users": [],          "created_models": []      } @@ -174,6 +184,7 @@          ],          "is_template": true,          "unicity_keys": "external_id", +        "available": true,          "users": [],          "created_models": []      } @@ -189,6 +200,7 @@          ],          "is_template": true,          "unicity_keys": "external_id", +        "available": true,          "users": [],          "created_models": []      } @@ -204,6 +216,7 @@          ],          "is_template": true,          "unicity_keys": "code_patriarche", +        "available": true,          "users": [],          "created_models": [              [ @@ -229,6 +242,7 @@          ],          "is_template": true,          "unicity_keys": "external_id", +        "available": true,          "users": [],          "created_models": [              [ @@ -251,6 +265,7 @@          ],          "is_template": true,          "unicity_keys": "external_id", +        "available": true,          "users": [],          "created_models": []      } @@ -266,6 +281,7 @@          ],          "is_template": true,          "unicity_keys": "external_id", +        "available": true,          "users": [],          "created_models": []      } @@ -281,6 +297,7 @@          ],          "is_template": true,          "unicity_keys": "", +        "available": true,          "users": [],          "created_models": [              [ @@ -300,6 +317,7 @@          ],          "is_template": true,          "unicity_keys": "external_id", +        "available": true,          "users": [],          "created_models": [              [ @@ -325,6 +343,7 @@          ],          "is_template": true,          "unicity_keys": "external_id", +        "available": true,          "users": [],          "created_models": [              [ @@ -343,6 +362,26 @@      }  },  { +    "model": "ishtar_common.importertype", +    "fields": { +        "name": "Ishtar - Relations entre op\u00e9rations", +        "slug": "ishtar-operations-relations", +        "description": null, +        "associated_models": [ +            "archaeological_operations.models.RecordRelations" +        ], +        "is_template": true, +        "unicity_keys": null, +        "available": true, +        "users": [], +        "created_models": [ +            [ +                "archaeological_operations.models.RecordRelations" +            ] +        ] +    } +}, +{      "model": "ishtar_common.regexp",      "fields": {          "name": "Num\u00e9ro INSEE", @@ -2595,11 +2634,11 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 25, +        "col_number": 26,          "description": "Marquage visible sur le mobilier. Exemple : \"id1234 la Roche aux F\u00e9es\", \"MTX-45\", etc.\r\nCeci reproduit d'ordinaire un marquage r\u00e9alis\u00e9 par un arch\u00e9ologue. Il ne s'agit pas ici de reproduire une \u00e9pigraphie ou tout autre inscription arch\u00e9ologique (graffito, d\u00e9dicaces, defixio, etc.) , mais vous pouvez l'utiliser pour cela si vous n'avez pas \u00e0 utiliser de marquage arch\u00e9ologique.",          "regexp_pre_filter": null,          "required": false, -        "export_field_name": null +        "export_field_name": ""      }  },  { @@ -2609,11 +2648,11 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 26, +        "col_number": 27,          "description": "Commentaire g\u00e9n\u00e9ral libre. Exemple : \"habillage en nid d'abeille, poli g\u00e9n\u00e9ralis\u00e9, encoche emmanchement lat\u00e9ral ouvert sur la face sup\u00e9rieure\", \"1 bord + bec tubulaire\", \"fibule de Langton Down\", etc.",          "regexp_pre_filter": null,          "required": false, -        "export_field_name": null +        "export_field_name": ""      }  },  { @@ -2623,11 +2662,11 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 27, +        "col_number": 28,          "description": "Commentaire g\u00e9n\u00e9ral sur les datations, si besoin. Exemple : \"plut\u00f4t fin IIe s. ou d\u00e9but IIIe s.\", \"Datation \u00e0 pr\u00e9ciser avant publication\", \" Datation rapide faite par M. Dupont\", etc.",          "regexp_pre_filter": null,          "required": false, -        "export_field_name": null +        "export_field_name": ""      }  },  { @@ -2637,11 +2676,11 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 28, +        "col_number": 29,          "description": "Valeur estim\u00e9e (\u20ac), sous la forme d'un nombre d\u00e9cimal. Exemple : \"4500\", \"0.2\", etc.\r\nUtile essentiellement pour les probl\u00e8mes de partage, vente, assurance etc.",          "regexp_pre_filter": null,          "required": false, -        "export_field_name": null +        "export_field_name": ""      }  },  { @@ -2651,11 +2690,11 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 29, +        "col_number": 30,          "description": "Nom exact du fichier image, sous la forme XXXXX.jpg.\r\nAttention au respect strict des caract\u00e8res et majuscules lors d'un import de ce type, \".JPG\" ou \"*.jpg\", etc.\r\nExemple : \"P1030831.JPG\", \"IMG_6485.JPG\", \"fibule.jpg\", etc.\r\nLors de l'import il faut ajouter ces images sous la forme d'un fichier zip (joint au csv import\u00e9) pour que les images soient automatiquement int\u00e9gr\u00e9es.\r\n",          "regexp_pre_filter": null,          "required": false, -        "export_field_name": null +        "export_field_name": ""      }  },  { @@ -2665,7 +2704,7 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 30, +        "col_number": 31,          "description": "Chronologies associ\u00e9es (plusieurs possibles s\u00e9par\u00e9es par &). Exemple : \"Gallo-romain & M\u00e9di\u00e9val\", \"GR&MED\", \"M\u00e9solithique final & M\u00e9so moyen & Epipal\", etc.",          "regexp_pre_filter": null,          "required": false, @@ -2679,11 +2718,11 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 31, +        "col_number": 32,          "description": "Coordonn\u00e9e X pour cet objet.",          "regexp_pre_filter": null,          "required": false, -        "export_field_name": null +        "export_field_name": ""      }  },  { @@ -2693,11 +2732,11 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 32, +        "col_number": 33,          "description": "Coordonn\u00e9e Y pour cet objet.",          "regexp_pre_filter": null,          "required": false, -        "export_field_name": null +        "export_field_name": ""      }  },  { @@ -2707,11 +2746,11 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 33, +        "col_number": 34,          "description": "Coordonn\u00e9e Z pour cet objet (altitude NGF ou arbitraire).",          "regexp_pre_filter": null,          "required": false, -        "export_field_name": null +        "export_field_name": ""      }  },  { @@ -2721,11 +2760,11 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 34, +        "col_number": 35,          "description": "Code permettant de qualifier le mode de projection des donn\u00e9es (SRS /EPSG). Exemple : \"2154\" pour le Lambert 93.",          "regexp_pre_filter": null,          "required": false, -        "export_field_name": null +        "export_field_name": ""      }  },  { @@ -2791,7 +2830,7 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 36, +        "col_number": 37,          "description": "Identifiant textuel du d\u00e9p\u00f4t. Cet identifiant doit correspondre \u00e0 un d\u00e9p\u00f4t existant en base de donn\u00e9es.",          "regexp_pre_filter": null,          "required": false, @@ -2805,7 +2844,7 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 37, +        "col_number": 38,          "description": "",          "regexp_pre_filter": null,          "required": false, @@ -2819,7 +2858,7 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 38, +        "col_number": 39,          "description": "Champ n\u00e9cessaire si vous indiquez une caisse",          "regexp_pre_filter": null,          "required": false, @@ -3169,7 +3208,7 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 35, +        "col_number": 36,          "description": "Date au format JJ/MM/AAAA ou AAAA-MM-JJ. Par exemple : 2017-07-31 ou 31/07/2017.",          "regexp_pre_filter": null,          "required": false, @@ -3183,7 +3222,7 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 39, +        "col_number": 40,          "description": "Localisation dans le d\u00e9p\u00f4t : r\u00e9f\u00e9rence de la premi\u00e8re localisation. Par exemple si la premi\u00e8re localisation du d\u00e9p\u00f4t concern\u00e9 est \u00ab b\u00e2timent \u00bb mettre : \u00ab A \u00bb pour b\u00e2timent A.",          "regexp_pre_filter": null,          "required": false, @@ -3197,7 +3236,7 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 40, +        "col_number": 41,          "description": "Localisation dans le d\u00e9p\u00f4t : r\u00e9f\u00e9rence de la seconde localisation.",          "regexp_pre_filter": null,          "required": false, @@ -3211,7 +3250,7 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 41, +        "col_number": 42,          "description": "Localisation dans le d\u00e9p\u00f4t : r\u00e9f\u00e9rence de la troisi\u00e8me localisation.",          "regexp_pre_filter": null,          "required": false, @@ -3225,7 +3264,7 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 42, +        "col_number": 43,          "description": "Localisation dans le d\u00e9p\u00f4t : r\u00e9f\u00e9rence de la quatri\u00e8me localisation.",          "regexp_pre_filter": null,          "required": false, @@ -3239,7 +3278,7 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 43, +        "col_number": 44,          "description": "Localisation dans le d\u00e9p\u00f4t : r\u00e9f\u00e9rence de la cinqui\u00e8me localisation.",          "regexp_pre_filter": null,          "required": false, @@ -3253,7 +3292,7 @@          "importer_type": [              "ishtar-finds"          ], -        "col_number": 44, +        "col_number": 45,          "description": "Localisation dans le d\u00e9p\u00f4t : r\u00e9f\u00e9rence de la sixi\u00e8me localisation. ",          "regexp_pre_filter": null,          "required": false, @@ -3261,6 +3300,62 @@      }  },  { +    "model": "ishtar_common.importercolumn", +    "fields": { +        "label": "NMI", +        "importer_type": [ +            "ishtar-finds" +        ], +        "col_number": 25, +        "description": "Nombre minimum d'individu(s) li\u00e9(s) \u00e0 cet enregistrement (entier). Exemple : \"12\".", +        "regexp_pre_filter": null, +        "required": false, +        "export_field_name": "" +    } +}, +{ +    "model": "ishtar_common.importercolumn", +    "fields": { +        "label": "Op\u00e9ration (identifiant externe) - membre de gauche", +        "importer_type": [ +            "ishtar-operations-relations" +        ], +        "col_number": 1, +        "description": "", +        "regexp_pre_filter": null, +        "required": true, +        "export_field_name": null +    } +}, +{ +    "model": "ishtar_common.importercolumn", +    "fields": { +        "label": "Type de relation entre op\u00e9ration", +        "importer_type": [ +            "ishtar-operations-relations" +        ], +        "col_number": 2, +        "description": "", +        "regexp_pre_filter": null, +        "required": true, +        "export_field_name": null +    } +}, +{ +    "model": "ishtar_common.importercolumn", +    "fields": { +        "label": "Op\u00e9ration (identifiant externe) - membre de droite", +        "importer_type": [ +            "ishtar-operations-relations" +        ], +        "col_number": 3, +        "description": "", +        "regexp_pre_filter": null, +        "required": true, +        "export_field_name": null +    } +}, +{      "model": "ishtar_common.formatertype",      "fields": {          "formater_type": "IntegerFormater", @@ -3669,6 +3764,38 @@      }  },  { +    "model": "ishtar_common.formatertype", +    "fields": { +        "formater_type": "TypeFormater", +        "options": "archaeological_operations.models.RelationType", +        "many_split": null +    } +}, +{ +    "model": "ishtar_common.formatertype", +    "fields": { +        "formater_type": "TypeFormater", +        "options": "archaeological_finds.models.AlterationType", +        "many_split": "&" +    } +}, +{ +    "model": "ishtar_common.formatertype", +    "fields": { +        "formater_type": "TypeFormater", +        "options": "archaeological_finds.models.AlterationCauseType", +        "many_split": "&" +    } +}, +{ +    "model": "ishtar_common.formatertype", +    "fields": { +        "formater_type": "TypeFormater", +        "options": "archaeological_finds.models.TreatmentEmergencyType", +        "many_split": null +    } +}, +{      "model": "ishtar_common.importerduplicatefield",      "fields": {          "column": [ @@ -4154,7 +4281,7 @@      "fields": {          "column": [              "ishtar-finds", -            36 +            37          ],          "field_name": "container__location__external_id",          "force_new": false, @@ -4167,7 +4294,7 @@      "fields": {          "column": [              "ishtar-finds", -            36 +            37          ],          "field_name": "container__external_id",          "force_new": false, @@ -4180,7 +4307,7 @@      "fields": {          "column": [              "ishtar-finds", -            37 +            38          ],          "field_name": "container__external_id",          "force_new": false, @@ -7466,7 +7593,7 @@      "fields": {          "column": [              "ishtar-finds", -            25 +            26          ],          "target": "mark",          "regexp_filter": null, @@ -7486,7 +7613,7 @@      "fields": {          "column": [              "ishtar-finds", -            26 +            27          ],          "target": "comment",          "regexp_filter": null, @@ -7506,7 +7633,7 @@      "fields": {          "column": [              "ishtar-finds", -            27 +            28          ],          "target": "dating_comment",          "regexp_filter": null, @@ -7526,7 +7653,7 @@      "fields": {          "column": [              "ishtar-finds", -            28 +            29          ],          "target": "estimated_value",          "regexp_filter": null, @@ -7546,7 +7673,7 @@      "fields": {          "column": [              "ishtar-finds", -            29 +            30          ],          "target": "image",          "regexp_filter": null, @@ -7566,7 +7693,7 @@      "fields": {          "column": [              "ishtar-finds", -            30 +            31          ],          "target": "datings__period",          "regexp_filter": null, @@ -7606,7 +7733,7 @@      "fields": {          "column": [              "ishtar-finds", -            31 +            32          ],          "target": "base_finds__x",          "regexp_filter": null, @@ -7626,7 +7753,7 @@      "fields": {          "column": [              "ishtar-finds", -            32 +            33          ],          "target": "base_finds__y",          "regexp_filter": null, @@ -7646,7 +7773,7 @@      "fields": {          "column": [              "ishtar-finds", -            33 +            34          ],          "target": "base_finds__z",          "regexp_filter": null, @@ -7666,7 +7793,7 @@      "fields": {          "column": [              "ishtar-finds", -            34 +            35          ],          "target": "base_finds__spatial_reference_system",          "regexp_filter": null, @@ -7766,7 +7893,7 @@      "fields": {          "column": [              "ishtar-finds", -            36 +            37          ],          "target": "container__responsible__external_id",          "regexp_filter": null, @@ -7786,7 +7913,7 @@      "fields": {          "column": [              "ishtar-finds", -            37 +            38          ],          "target": "container__reference",          "regexp_filter": null, @@ -7806,7 +7933,7 @@      "fields": {          "column": [              "ishtar-finds", -            38 +            39          ],          "target": "container__container_type",          "regexp_filter": null, @@ -8326,7 +8453,7 @@      "fields": {          "column": [              "ishtar-finds", -            35 +            36          ],          "target": "base_finds__discovery_date",          "regexp_filter": null, @@ -8346,7 +8473,7 @@      "fields": {          "column": [              "ishtar-finds", -            39 +            40          ],          "target": "set_localisation_1",          "regexp_filter": null, @@ -8366,7 +8493,7 @@      "fields": {          "column": [              "ishtar-finds", -            40 +            41          ],          "target": "set_localisation_2",          "regexp_filter": null, @@ -8386,7 +8513,7 @@      "fields": {          "column": [              "ishtar-finds", -            41 +            42          ],          "target": "set_localisation_3",          "regexp_filter": null, @@ -8406,7 +8533,7 @@      "fields": {          "column": [              "ishtar-finds", -            42 +            43          ],          "target": "set_localisation_4",          "regexp_filter": null, @@ -8426,7 +8553,7 @@      "fields": {          "column": [              "ishtar-finds", -            43 +            44          ],          "target": "set_localisation_5",          "regexp_filter": null, @@ -8446,7 +8573,7 @@      "fields": {          "column": [              "ishtar-finds", -            44 +            45          ],          "target": "set_localisation_6",          "regexp_filter": null, @@ -8460,5 +8587,85 @@          "concat_str": "",          "comment": ""      } +}, +{ +    "model": "ishtar_common.importtarget", +    "fields": { +        "column": [ +            "ishtar-finds", +            25 +        ], +        "target": "min_number_of_individuals", +        "regexp_filter": null, +        "formater_type": [ +            "IntegerFormater", +            "", +            "" +        ], +        "force_new": false, +        "concat": false, +        "concat_str": "", +        "comment": "" +    } +}, +{ +    "model": "ishtar_common.importtarget", +    "fields": { +        "column": [ +            "ishtar-operations-relations", +            1 +        ], +        "target": "left_record__external_id", +        "regexp_filter": null, +        "formater_type": [ +            "UnicodeFormater", +            "", +            "" +        ], +        "force_new": false, +        "concat": false, +        "concat_str": null, +        "comment": "" +    } +}, +{ +    "model": "ishtar_common.importtarget", +    "fields": { +        "column": [ +            "ishtar-operations-relations", +            2 +        ], +        "target": "relation_type", +        "regexp_filter": null, +        "formater_type": [ +            "TypeFormater", +            "archaeological_operations.models.RelationType", +            null +        ], +        "force_new": false, +        "concat": false, +        "concat_str": null, +        "comment": "" +    } +}, +{ +    "model": "ishtar_common.importtarget", +    "fields": { +        "column": [ +            "ishtar-operations-relations", +            3 +        ], +        "target": "right_record__external_id", +        "regexp_filter": null, +        "formater_type": [ +            "UnicodeFormater", +            "", +            "" +        ], +        "force_new": false, +        "concat": false, +        "concat_str": null, +        "comment": "" +    }  }  ] diff --git a/ishtar_common/static/gentium/GentiumPlus-I.ttf b/ishtar_common/static/gentium/GentiumPlus-I.ttfBinary files differ new file mode 100644 index 000000000..7bc1b3d8b --- /dev/null +++ b/ishtar_common/static/gentium/GentiumPlus-I.ttf diff --git a/ishtar_common/static/gentium/GentiumPlus-R.ttf b/ishtar_common/static/gentium/GentiumPlus-R.ttfBinary files differ new file mode 100644 index 000000000..c1194dd35 --- /dev/null +++ b/ishtar_common/static/gentium/GentiumPlus-R.ttf diff --git a/ishtar_common/static/gentium/OFL.txt b/ishtar_common/static/gentium/OFL.txt new file mode 100644 index 000000000..4f7540787 --- /dev/null +++ b/ishtar_common/static/gentium/OFL.txt @@ -0,0 +1,94 @@ +Copyright (c) 2003-2014 SIL International (http://www.sil.org/),
 +with Reserved Font Names "Gentium" and "SIL".
 +
 +This Font Software is licensed under the SIL Open Font License, Version 1.1.
 +This license is copied below, and is also available with a FAQ at:
 +http://scripts.sil.org/OFL
 +
 +
 +-----------------------------------------------------------
 +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
 +-----------------------------------------------------------
 +
 +PREAMBLE
 +The goals of the Open Font License (OFL) are to stimulate worldwide
 +development of collaborative font projects, to support the font creation
 +efforts of academic and linguistic communities, and to provide a free and
 +open framework in which fonts may be shared and improved in partnership
 +with others.
 +
 +The OFL allows the licensed fonts to be used, studied, modified and
 +redistributed freely as long as they are not sold by themselves. The
 +fonts, including any derivative works, can be bundled, embedded, 
 +redistributed and/or sold with any software provided that any reserved
 +names are not used by derivative works. The fonts and derivatives,
 +however, cannot be released under any other type of license. The
 +requirement for fonts to remain under this license does not apply
 +to any document created using the fonts or their derivatives.
 +
 +DEFINITIONS
 +"Font Software" refers to the set of files released by the Copyright
 +Holder(s) under this license and clearly marked as such. This may
 +include source files, build scripts and documentation.
 +
 +"Reserved Font Name" refers to any names specified as such after the
 +copyright statement(s).
 +
 +"Original Version" refers to the collection of Font Software components as
 +distributed by the Copyright Holder(s).
 +
 +"Modified Version" refers to any derivative made by adding to, deleting,
 +or substituting -- in part or in whole -- any of the components of the
 +Original Version, by changing formats or by porting the Font Software to a
 +new environment.
 +
 +"Author" refers to any designer, engineer, programmer, technical
 +writer or other person who contributed to the Font Software.
 +
 +PERMISSION & CONDITIONS
 +Permission is hereby granted, free of charge, to any person obtaining
 +a copy of the Font Software, to use, study, copy, merge, embed, modify,
 +redistribute, and sell modified and unmodified copies of the Font
 +Software, subject to the following conditions:
 +
 +1) Neither the Font Software nor any of its individual components,
 +in Original or Modified Versions, may be sold by itself.
 +
 +2) Original or Modified Versions of the Font Software may be bundled,
 +redistributed and/or sold with any software, provided that each copy
 +contains the above copyright notice and this license. These can be
 +included either as stand-alone text files, human-readable headers or
 +in the appropriate machine-readable metadata fields within text or
 +binary files as long as those fields can be easily viewed by the user.
 +
 +3) No Modified Version of the Font Software may use the Reserved Font
 +Name(s) unless explicit written permission is granted by the corresponding
 +Copyright Holder. This restriction only applies to the primary font name as
 +presented to the users.
 +
 +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
 +Software shall not be used to promote, endorse or advertise any
 +Modified Version, except to acknowledge the contribution(s) of the
 +Copyright Holder(s) and the Author(s) or with their explicit written
 +permission.
 +
 +5) The Font Software, modified or unmodified, in part or in whole,
 +must be distributed entirely under this license, and must not be
 +distributed under any other license. The requirement for fonts to
 +remain under this license does not apply to any document created
 +using the Font Software.
 +
 +TERMINATION
 +This license becomes null and void if any of the above conditions are
 +not met.
 +
 +DISCLAIMER
 +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
 +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
 +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
 +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
 +OTHER DEALINGS IN THE FONT SOFTWARE.
 diff --git a/ishtar_common/static/gentium/README.txt b/ishtar_common/static/gentium/README.txt new file mode 100644 index 000000000..bc17a8cb7 --- /dev/null +++ b/ishtar_common/static/gentium/README.txt @@ -0,0 +1,88 @@ +README 
 +Gentium Plus
 +========================
 +
 +Thank you for your interest in the Gentium Plus fonts.
 +We hope you find them useful!
 +
 +Gentium Plus supports a wide range of Latin, Greek and Cyrillic 
 +characters. Documentation for the fonts is available on Gentium website
 +(http://scripts.sil.org/Gentium), including details on what ranges are
 +supported. 
 +
 +Gentium Plus is released under the SIL Open Font License.
 +
 +See the OFL and OFL-FAQ for details of the SIL Open Font License.
 +See the FONTLOG for information on this and previous releases.
 +See the GENTIUM-FAQ for answers to common questions about the Gentium fonts
 +See the website (http://scripts.sil.org/Gentium) for further documentation.
 +See the SIL Unicode Roman FAQ (http://scripts.sil.org/ComplexRomanFontFAQ)
 +for frequently asked questions and their answers regarding SIL's Roman fonts.
 +
 +
 +TIPS
 +====
 +
 +As this font is distributed at no cost, we are unable to provide a 
 +commercial level of personal technical support. The font has, however, 
 +been through some testing on various platforms to be sure it works in most
 +situations. In particular, it has been tested and shown to work on Windows
 +XP, Windows Vista and Windows 7. Graphite capabilities have been tested 
 +on Graphite-supported platforms.
 +
 +If you do find a problem, please do report it to fonts@sil.org.
 +We can't guarantee any direct response, but will try to fix reported bugs in
 +future versions. Make sure you read through the 
 +SIL Unicode Roman FAQ (http://scripts.sil.org/ComplexRomanFontFAQ).
 +
 +Many problems can be solved, or at least explained, through an understanding
 +of the encoding and use of the fonts. Here are some basic hints:
 +
 +Encoding: 
 +The fonts are encoded according to Unicode, so your application must support
 +Unicode text in order to access letters other than the standard alphabet.
 +Most Windows applications provide basic Unicode support. You will, however,
 +need some way of entering Unicode text into your document.
 +
 +Keyboarding:
 +This font does not include any keyboarding helps or utilities. It uses the
 +built-in keyboards of the operating system. You will need to install the
 +appropriate keyboard and input method for the characters of the language you
 +wish to use. If you want to enter characters that are not supported by any
 +system keyboard, the Keyman program (www.tavultesoft.com) can be helpful
 +on Windows systems. Also available for Windows is MSKLC 
 +(http://www.microsoft.com/globaldev/tools/msklc.mspx). 
 +For Linux systems such as Ubuntu, KMFL (http://kmfl.sourceforge.net/)
 +is available. Ukelele (http://scripts.sil.org/ukelele) is available for
 +Mac OS X versions 10.2 and later.
 +
 +For other platforms, KMFL (http://kmfl.sourceforge.net/), 
 +XKB (http://www.x.org/wiki/XKB) or Ukelele (http://scripts.sil.org/ukelele) 
 +can be helpful.
 +
 +If you want to enter characters that are not supported by any system
 +keyboard, and to access the full Unicode range, we suggest you use
 +gucharmap, kcharselect on Ubuntu or similar software.
 +
 +Another method of entering some symbols is provided by a few applications such
 +as Adobe InDesign or OpenOffice.org. They can display a glyph palette or input
 +dialog that shows all the glyphs (symbols) in a font and allow you to enter
 +them by clicking on the glyph you want.
 +
 +Rendering:
 +This font is designed to work with Graphite or Opentype advanced font 
 +technologies. To take advantage of the advanced typographic 
 +capabilities of this font, you must be using applications that provide an
 +adequate level of support for Graphite or OpenType. See "Applications
 +that provide an adequate level of support for SIL Unicode Roman fonts" 
 +(http://scripts.sil.org/Complex_AdLvSup).
 +
 +
 +CONTACT
 +========
 +For more information please visit the Gentium page on SIL International's
 +Computers and Writing systems website:
 +http://scripts.sil.org/Gentium
 +
 +Support through the website: http://scripts.sil.org/Support
 +
 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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%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 %} -<link rel="stylesheet" href="{{STATIC_URL}}/media/style_basic.css?ver={{VERSION}}" />  {% endblock %}  {% block main_head %}  {{ block.super }} @@ -10,9 +9,6 @@ Ishtar – {{APP_NAME}} – {{item}}  {% endblock %}  {%block head_sheet%}{%endblock%}  {%block main_foot%} -<div id="pdffooter"> -– <pdf:pagenumber/> – -</div>  </body>  </html>  {%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  <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2010-2017  Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet>  # This program is free software: you can redistribute it and/or modify  # it under the terms of the GNU Affero General Public License as @@ -21,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("<table", "<pdf:nextpage/><table repeat='1'") -            pdf = pisa.pisaDocument(StringIO.StringIO(html), result, -                                    encoding='utf-8') -            response = HttpResponse(result.getvalue(), -                                    content_type='application/pdf') +            html = tpl.render(context_instance, request) +            font_config = FontConfiguration() +            css = CSS(string=''' +            @font-face { +                font-family: Gentium; +                src: url(%s); +            } +            body{ +                font-family: Gentium +            } +            ''' % (static("gentium/GentiumPlus-R.ttf"))) +            css2 = CSS(filename=settings.STATIC_ROOT + '/media/style_basic.css') +            pdf = HTML(string=html, base_url=request.build_absolute_uri() +                       ).write_pdf(stylesheets=[css, css2], +                                   font_config=font_config) +            response = HttpResponse(pdf, content_type='application/pdf')              response['Content-Disposition'] = 'attachment; filename=%s.pdf' % \                                                filename -            if not pdf.err: -                return response -            return HttpResponse(content, content_type="application/xhtml") +            return response          else:              tpl = loader.get_template('ishtar/sheet_%s_window.html' % name)              content = tpl.render(context_instance, request) diff --git a/requirements.txt b/requirements.txt index 7ef1b5ce2..1e62d3e29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,19 +1,20 @@ +six>=1.9  psycopg2==2.5.4  django-registration==2.2  django==1.11  Pillow==3.4.2 -pisa==3.0.33 -reportlab==3.1.8 +WeasyPrint==0.41 +html5lib==0.999999999 +  dbf==0.96.003  python-memcached==1.57  unicodecsv==0.14.1  pytidylib==0.2.1  lxml==3.4.0 -html5lib==0.999  django-extra-views==0.2.4 -beautifulsoup4==4.3.2 +beautifulsoup4==4.5.3  markdown==2.5.1  django-ajax-selects==1.6.0  django-compressor==2.1 diff --git a/version.py b/version.py index 42b630409..38f3d146e 100644 --- a/version.py +++ b/version.py @@ -1,5 +1,5 @@ -# 1.99.10 -VERSION = (1, 99, 10) +# 1.99.11 +VERSION = (1, 99, 11)  def get_version(): | 
