olivier.massot 7 lat temu
rodzic
commit
f86d250196

+ 0 - 2
.gitignore

@@ -2,8 +2,6 @@
 .project
 .pydevproject
 .settings/
-Output/
-htmlcov/
 *.log
 *.log.1
 /work/*

+ 0 - 56
core/BufferingSMTPHandler.py

@@ -1,56 +0,0 @@
-# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose and without fee is hereby granted,
-# provided that the above copyright notice appear in all copies and that
-# both that copyright notice and this permission notice appear in
-# supporting documentation, and that the name of Vinay Sajip
-# not be used in advertising or publicity pertaining to distribution
-# of the software without specific, written prior permission.
-# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-# This file is part of the Python logging distribution. See
-# http://www.red-dove.com/python_logging.html
-#
-"""Test harness for the logging module. Tests BufferingSMTPHandler, an alternative implementation
-of SMTPHandler.
-Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
-"""
-
-from email.mime.text import MIMEText
-import logging.handlers
-import smtplib
-
-
-class BufferingSMTPHandler(logging.handlers.BufferingHandler):
-    def __init__(self, mailhost, fromaddr, toaddrs, subject, capacity):
-        logging.handlers.BufferingHandler.__init__(self, capacity)
-        self.mailhost = mailhost
-        self.mailport = None
-        self.fromaddr = fromaddr
-        self.toaddrs = toaddrs
-        self.subject = subject
-
-    def flush(self):
-        try:
-            if len(self.buffer) > 0:
-                port = self.mailport if self.mailport else smtplib.SMTP_PORT
-
-                msg = "\n".join([self.format(record) for record in self.buffer])
-                msg = MIMEText(msg.encode('utf-8'), _charset='utf-8')
-                msg['Subject'] = self.subject
-                msg['From'] = self.fromaddr
-                msg['To'] = ",".join(self.toaddrs)
-
-                smtp = smtplib.SMTP(self.mailhost, port)
-                smtp.sendmail(self.fromaddr, self.toaddrs, msg.as_string())
-                smtp.quit()
-                self.buffer = []
-        except Exception as e:
-            print(e)
-            raise

+ 7 - 24
core/cerberus_extend.py

@@ -8,18 +8,22 @@ import cerberus
 
 from core import gis
 
-
 def is_french_date(field, value, error):
     try:
         datetime.strptime(value, '%d/%m/%Y')
     except:
         error(field, 'Doit être une date au format jj/mm/aaaa')
 
-
 # Ref: http://docs.python-cerberus.org/en/stable/api.html#error-codes
 
 class GeoValidator(cerberus.validator.Validator):
-    def _validate_geom(self, geom, field, value):
+    
+    def _validate_geometry(self, geom, field, value):
+        """ Contrôle la géométrie d'un objet
+
+        The rule's arguments are validated against this schema:
+        {'type': 'list', 'items': [{'type':'integer'},{'type': 'list'}]}
+        """
         shapeType, bbox = geom
         
         if value.shapeType != shapeType:
@@ -36,27 +40,6 @@ class GeoValidator(cerberus.validator.Validator):
         except AttributeError:
             pass
             
-    def _validate_shapeType(self, shapeType, field, value):
-        """ Test the oddity of a value.
-
-        The rule's arguments are validated against this schema:
-        {'type': 'boolean'}
-        """
-        if value != shapeType:
-            self._error(field, "Le type de géométrie est incorrect")
-
-    def _validate_bbox(self, bbox, field, value):
-        """ Test the oddity of a value.
-
-        The rule's arguments are validated against this schema:
-        {'type': 'boolean'}
-        """
-        xmin, ymin, xmax, ymax = bbox
-        x1, y1, x2, y2 = value
-        
-        if any(x < xmin or x > xmax for x in (x1, x2)) or \
-           any(y < ymin or y > ymax for y in (y1, y2)):
-            self._error(field, "Certaines coordonnées hors de l'emprise autorisée")
 
 class CerberusErrorHandler(cerberus.errors.BasicErrorHandler):
     messages = {0x00: "{0}",

+ 0 - 9
core/constants.py

@@ -9,12 +9,3 @@ MAIN = Path(__file__).parent.parent.abspath()
 # Dirs
 WRKDIR = MAIN / "work"
 RSCDIR = MAIN / "resources"
-DEFAULT_LOG_DIR = MAIN / "log"
-LOG_CONFIG_FILE = MAIN / "logging.yaml"
-
-
-
-
-### ***********  Ne pas modifier en dessous   *************** ###
-
-DEFAULT_LOG_DIR.mkdir_p()

+ 20 - 3
core/gis.py

@@ -7,10 +7,27 @@ import shapefile
 POINT = 1
 POLYLINE = 3
 POLYGON = 5
-SHAPE_NAMES = {1: "POINT", 3:"POLYLIGNE", 5:"POLYGONE"}
+SHAPE_NAMES = {0: "(AUCUN)", 
+               1: "POINT", 
+               3:"POLYLIGNE", 
+               5:"POLYGONE",
+               8: "MULTI-POINT",
+               11: "POINT-Z",
+               13: "POLYLIGNE-Z",
+               15: "POLYGONE-Z",
+               18: "MULTIPOINT-Z",
+               21: "POINT-M",
+               23: "POLYLIGNE-M",
+               25: "POLYGONE-M",
+               28: "MULTIPOINT-M",
+               31: "MULTI-PATCH",
+               }
 
-class ShapeError(IOError): pass
-class SridError(IOError): pass
+
+class ShapeError(IOError): 
+    pass
+class SridError(IOError): 
+    pass
 
 class ShapeFile():
     def __init__(self, path_, srid=None):

+ 0 - 40
core/logconf.py

@@ -1,40 +0,0 @@
-'''
-Created on 6 juil. 2017
-
-@author: olivier.massot
-'''
-import logging.config
-import sys
-import traceback
-
-import yaml
-
-from core.constants import DEFAULT_LOG_DIR, LOG_CONFIG_FILE
-
-
-SYS_EXCEPT_HOOK = sys.excepthook
-
-def start(name="datachecker", level=0, filename=""):
-    # charge la configuration du logging depuis le fichier 'logging.yaml'
-    with open(LOG_CONFIG_FILE, 'rt') as f:
-        conf = yaml.load(f)
-
-    if level:
-        conf["loggers"][name]["level"] = level
-
-    if not filename:
-        filename = DEFAULT_LOG_DIR / r'{}.log'.format(name)
-    conf["handlers"]["file"]["filename"] = filename
-
-    conf["handlers"]["mail"]["fromaddr"] = conf["handlers"]["mail"]["fromaddr"].replace("%name%", name)
-    conf["handlers"]["mail"]["subject"] = conf["handlers"]["mail"]["subject"].replace("%name%", name)
-
-    logging.config.dictConfig(conf)
-
-    logger = logging.getLogger(name)
-    def _excepthook(typ, value, trace):
-        """ Remplace la gestion d'erreur standard, pour logger aussi les erreurs non gérées """
-        logger.error("{}\n{}\n{}".format(typ.__name__, value, ''.join(traceback.format_tb(trace))))
-        SYS_EXCEPT_HOOK(typ, value, trace)
-    sys.excepthook = _excepthook
-

+ 0 - 46
core/mail.py

@@ -1,46 +0,0 @@
-'''
-
-usage:
-
-    m = Mail("mail-auto@bas-rhin.fr", ["destinataire@bas-rhin.fr"], "mon mail", "mon message")
-    m.send()
-
-'''
-from email.mime.multipart import MIMEMultipart
-from email.mime.text import MIMEText
-import smtplib
-
-
-class Mail():
-    HOST = ""
-
-    def __init__(self, fromaddr, toaddrs, subject, msg):
-        self.mailport = None
-        self.fromaddr = fromaddr
-        self.toaddrs = toaddrs
-        self.subject = subject
-        self.msg = msg
-
-        self.mail = MIMEMultipart('alternative')
-        self.mail['Subject'] = self.subject
-        self.mail['From'] = self.fromaddr
-        self.mail['To'] = ",".join(self.toaddrs)
-
-        self.mail.attach(MIMEText(self.msg, 'html', _charset='utf-8'))
-
-    def send(self):
-        if not self.HOST:
-            raise ValueError("Mail.HOST has to be defined before sending any mail")
-        
-        port = self.mailport if self.mailport else smtplib.SMTP_PORT
-
-        with smtplib.SMTP(self.HOST, port) as smtp:
-            smtp.sendmail(self.fromaddr, self.toaddrs, self.mail.as_string())
-
-
-if __name__ == "__main__":
-    mail = Mail("",
-                ["olinox14@yahoo.fr"],
-                "test",
-                "test")
-    mail.send()

+ 0 - 89
core/model.py

@@ -1,89 +0,0 @@
-'''
-
-
-    @author: olivier.massot, févr. 2018
-'''
-import csv
-from datetime import datetime
-import logging
-
-import dateutil.parser
-
-from core.sqlformatter import SqlFormatter
-
-
-logger = logging.getLogger("model")
-
-Sql = SqlFormatter()
-
-csv.register_dialect('tsv', delimiter='\t', quotechar='', quoting=csv.QUOTE_NONE)
-
-class Model():
-    _mapping = {}
-
-    def __setattr__(self, name, value):
-
-        try:
-            val, type_ = value
-            if not type_ in (int, float, bool, str, datetime):
-                raise TypeError("Type de donnée invalide pour une propriété de 'Model' ('{}')".format(type(val)))
-            self.__class__._mapping[name] = type_
-        except (TypeError, ValueError):
-            val = value
-            if val is None:
-                super().__setattr__(name, val)
-                return
-            try:
-                type_ = self.__class__._mapping[name]
-            except KeyError:
-                super().__setattr__(name, val)
-                return
-
-        val = Model._cast(val, type_)
-
-        super().__setattr__(name, val)
-
-    @staticmethod
-    def _cast(value, type_):
-        if value is None:
-            return value
-        if type_ == datetime:
-            if type(value) is str:
-                return dateutil.parser.parse(value)
-            elif type(value) is datetime:
-                return value
-            else:
-                raise ValueError("'{}' ne peut pas être converti en date".format(value))
-        if type_ is bool and value in ("True", "False"):
-            return (value == "True")
-        else:
-            return type_(value)
-
-    @property
-    def _fields(self):
-        return list(self.__dict__.keys())
-
-    @property
-    def data(self):
-        return self.__dict__
-
-    def __repr__(self):
-        return "<{} => {}>".format(self.__class__.__name__, ",".join(["{}={}".format(field, value) for field, value in self.__dict__.items()]))
-
-    @classmethod
-    def from_dict(cls, data):
-        """ Retourne un objet à partir d'un dictionnaire de données """
-        model = cls()
-        for key, value in data.items():
-            setattr(model, key, value)
-        return model
-
-    @classmethod
-    def _parse(cls, field, value):
-        if value == 'None':
-            value = None
-        try:
-            return Model._cast(value, cls._mapping[field])
-        except KeyError:
-            return value
-

+ 53 - 11
core/validation.py

@@ -6,16 +6,12 @@
 import time
 import zipfile
 
-from cerberus.validator import Validator
 from path import Path, TempDir
 
 from core import gis
 from core.cerberus_extend import CerberusErrorHandler, GeoValidator
-from core.validation_errors import MissingFile, \
-    UnreadableFile, FormatError, WrongSrid
 from schemas.common import SRID
 
-
 class BaseModel():
     filename = ""
     pk = ""
@@ -23,12 +19,6 @@ class BaseModel():
     def __init__(self, **kwargs):
         self.__dict__.update(kwargs)
         
-    @classmethod
-    def index_item(cls, instance):
-        if getattr(instance, cls.pk) in cls.index:
-            raise ValueError("Duplicate PK")
-        cls.index[getattr(instance, cls.pk)] = instance
-        
 class BaseGeoModel(BaseModel):
     def __init__(self, geom, **kwargs):
         super(BaseGeoModel, self).__init__(**kwargs)
@@ -42,6 +32,57 @@ class Checkpoint():
         self.name = name
         self.valid = valid
 
+
+VALIDATION_ERROR_LEVELS = {10: "MINEURE", 20: "AVERTISSEMENT", 30: "ERREUR", 40: "CRITIQUE"}
+MINOR = 10
+WARNING = 20
+ERROR = 30
+CRITICAL = 40
+
+class BaseValidationError():
+    name = "Erreur"
+    level = ERROR
+    help = ""
+    def __init__(self, message, filename="", field=""):
+        self.message = message
+        self.filename = filename
+        self.field = field
+        
+    def __repr__(self):
+        return " - ".join(filter(None, [self.name, self.filename, self.field, self.message]))
+
+# Erreurs dans le chargement des fichiers
+
+class MissingFile(BaseValidationError):
+    level = CRITICAL
+    name = "Fichier Manquant"
+    
+class UnreadableFile(BaseValidationError):
+    level = CRITICAL
+    name = "Fichier Illisible"
+
+class WrongSrid(BaseValidationError):
+    level = CRITICAL
+    name = "Mauvais SRID"
+
+### Erreurs dans la structure des données
+class DataError(BaseValidationError):
+    name = "Erreur de format"
+    level = ERROR
+
+# Erreurs dans le contenu, erreurs métiers
+
+class TechnicalValidationError(BaseValidationError):
+    level = ERROR
+
+class DuplicatedPk(TechnicalValidationError):
+    name = "Doublons dans le champs"
+
+class RelationError(TechnicalValidationError):
+    name = "Un objet lié n'existe pas"
+
+
+
 class BaseValidator():
     schema_name = ""
     models = {}
@@ -122,11 +163,12 @@ class BaseValidator():
             v = GeoValidator(model.schema, error_handler=CerberusErrorHandler)
             
             for item in self.dataset[model]:
+
                 v.validate(item.__dict__)
             
                 for field, verrors in v.errors.items():
                     for err in verrors:
-                        self.log_error(FormatError(err, filename=model.filename, field=field))
+                        self.log_error(DataError(err, filename=model.filename, field=field))
     
     @classmethod
     def _technical_validation(cls):

+ 0 - 114
core/validation_errors.py

@@ -1,114 +0,0 @@
-'''
-
-@author: olivier.massot, 2018
-'''
-
-VALIDATION_ERROR_LEVELS = {10: "MINEURE", 20: "ATTENTION", 30: "ERREUR", 40: "CRITIQUE"}
-MINOR = 10
-WARNING = 20
-ERROR = 30
-CRITICAL = 40
-
-
-### Vérifications générales
-
-# Fichiers présents
-# Fichiers lisibles
-# SRID
-
-#### Schéma de données
-
-# Présence des champs
-# Type de données
-# Données obligatoires
-# Valeurs autorisées
-# Emprise géographique
-# Type de géométrie
-
-####
-
-# Unicité des codes
-# Vérification de la présence dans la base des code existants, et si exsitence, vérifie s'il s'agit du même
-# Vérification des cardinalités
-
-
-
-
-
-
-
-# filename, fieldname, record_id, 
-
-class BaseValidationError():
-    name = "Erreur"
-    level = ERROR
-    help = ""
-    def __init__(self, message, filename="", field="", index=""):
-        self.message = message
-        self.filename = filename
-        self.field = field
-        
-    def __repr__(self):
-        return " - ".join(filter(None, [self.name, self.filename, self.field, self.message]))
-
-# Erreurs dans le chargement des fichiers
-
-class MissingFile(BaseValidationError):
-    level = CRITICAL
-    name = "Fichier Manquant"
-    
-class UnreadableFile(BaseValidationError):
-    level = CRITICAL
-    name = "Fichier Illisible"
-
-class WrongSrid(BaseValidationError):
-    level = CRITICAL
-    name = "Mauvais SRID"
-
-
-### Erreurs dans la structure des données
-
-class StructureValidationError(BaseValidationError):
-    name = "Erreur dans la structure des données"
-    level = ERROR
-
-class MissingField(BaseValidationError):
-    name = "Champs manquant"
-    level = CRITICAL
-
-class UnknownField(BaseValidationError):
-    name = "Champs inconnu"
-    level = CRITICAL
-    
-class MissingValue(BaseValidationError):
-    name = "Valeur(s) manquante(s)"
-    level = ERROR
-    
-class FieldTypeError(BaseValidationError):
-    name = "Erreur de type"
-    level = ERROR
-
-class TooLong(BaseValidationError):
-    name = "Dépassement de taille"
-    level = ERROR
-    
-class FormatError(BaseValidationError):
-    name = "Erreur de format"
-    level = ERROR
-
-class UnauthorizedValue(BaseValidationError):
-    name="Valeur non-autorisée"
-    level = ERROR
-    
-# Erreurs dans le contenu, erreurs métiers
-
-class TechnicalValidationError(BaseValidationError):
-    level = ERROR
-
-class DuplicatedPk(TechnicalValidationError):
-    name = "Doublons dans le champs"
-
-class RelationError(TechnicalValidationError):
-    name = "Un objet lié n'existe pas"
-
-

+ 0 - 46
logging.yaml

@@ -1,46 +0,0 @@
-version: 1
-disable_existing_loggers: no
-formatters:
-    simple:
-        format: "%(asctime)s - %(levelname)s - %(message)s"
-    complete:
-        format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
-    short:
-        format: "%(levelname)s - %(message)s"
-    message_only:
-        format: "%(message)s"
-        
-handlers:
-    console:
-        class: logging.StreamHandler
-        level: INFO
-        formatter: message_only
-        stream: ext://sys.stdout
-    file:
-        class: logging.handlers.RotatingFileHandler
-        level: DEBUG
-        formatter: complete
-        filename: debug.log
-        maxBytes: 100000
-        backupCount: 1
-        encoding: utf8
-    mail:
-        class: core.BufferingSMTPHandler.BufferingSMTPHandler
-        level: INFO
-        formatter: complete
-        mailhost: 
-        fromaddr: log.%name%@manchenumerique.fr
-        toaddrs: [olivier.massot@manchenumerique.fr]
-        subject: Rapport d'execution de %name%
-        capacity: 100000000
-
-loggers:
-    datachecker:
-        level: DEBUG
-        handlers: [console]
-        propagate: no
-
-root:
-    level: DEBUG
-    handlers: [console]
-    propagate: yes

+ 0 - 6
requirements.txt

@@ -1,13 +1,7 @@
 pypyodbc
 path.py>=11.1.0
-lxml
-python-dateutil
 pyyaml
 pyshp
-python-dateutil
-requests
-requests_ntlm
-docopt
 Jinja2
 Flask
 cerberus

+ 2 - 2
schemas/common.py

@@ -2,11 +2,11 @@
 
 @author: olivier.massot, 2018
 '''
-from core.mn import ReferentielDb
+from core import mn
 
 
 XMIN, XMAX, YMIN, YMAX = 1341999, 1429750, 8147750, 8294000
 SRID = 3949
 
-with ReferentielDb() as ref_db:
+with mn.ReferentielDb() as ref_db:
     INSEE_VALIDES = [row[0] for row in ref_db.read("SELECT code_insee FROM sig_referentiel.admn_cd50_com;")]

+ 7 - 7
schemas/netgeo_2_2_doe/models.py

@@ -11,12 +11,12 @@ from schemas.common import INSEE_VALIDES, XMIN, YMIN, XMAX, YMAX
 class Artere(BaseGeoModel):
     filename = "artere_geo.shp"
     pk = "AR_CODE"
-    schema = {'geom': {'geom': (gis.POLYLINE, (XMIN, YMIN, XMAX, YMAX))}, 
+    schema = {'geom': {'geometry': (gis.POLYLINE, (XMIN, YMIN, XMAX, YMAX))}, 
               'AR_CODE': {'type': 'string', 'maxlength': 26}, 
               'AR_NOM': {'type': 'string', 'maxlength': 26}, 
               'AR_ID_INSE': {'type': 'string', 'empty': False, 'allowed': INSEE_VALIDES}, 
               'AR_LONG': {'type': 'float'}, 
-              'AR_ETAT': {'type': 'string', 'empty': False, 'empty': False, 'allowed': ['0', '1', '2', '3', '4']}, 
+              'AR_ETAT': {'type': 'string', 'empty': False, 'allowed': ['0', '1', '2', '3', '4']}, 
               'AR_OCCP': {'type': 'string', 'empty': False, 'allowed': ['0', '1.1', '1.2', '2', '3', '4']}, 
               'AR_NOEUD_A': {'type': 'string', 'maxlength': 20}, 
               'AR_NOEUD_B': {'type': 'string', 'maxlength': 20}, 
@@ -44,7 +44,7 @@ class Artere(BaseGeoModel):
 class Cable(BaseGeoModel):
     filename = "cable_geo.shp"
     pk = "CA_CODE"
-    schema = {'geom': {'geom': (gis.POLYLINE, (XMIN, YMIN, XMAX, YMAX))}, 
+    schema = {'geom': {'geometry': (gis.POLYLINE, (XMIN, YMIN, XMAX, YMAX))}, 
               'CA_CODE': {'type': 'string', 'maxlength': 18}, 
               'CA_NOM': {'type': 'string', 'maxlength': 18}, 
               'CA_NUMERO': {'type': 'string', 'maxlength': 17}, 
@@ -70,7 +70,7 @@ class Cable(BaseGeoModel):
 class Equipement(BaseGeoModel):
     filename = "equipement_passif.shp"
     pk = "EQ_CODE"
-    schema = {'geom': {'geom': (gis.POINT, (XMIN, YMIN, XMAX, YMAX))}, 
+    schema = {'geom': {'geometry': (gis.POINT, (XMIN, YMIN, XMAX, YMAX))}, 
               'EQ_CODE': {'type': 'string', 'maxlength': 18}, 
               'EQ_NOM': {'type': 'string', 'maxlength': 18}, 
               'EQ_NOM_NOE': {'type': 'string', 'maxlength': 14}, 
@@ -98,7 +98,7 @@ class Equipement(BaseGeoModel):
 class Noeud(BaseGeoModel):
     filename = "noeud_geo.shp"
     pk = "NO_CODE"
-    schema = {'geom': {'geom': (gis.POINT, (XMIN, YMIN, XMAX, YMAX))}, 
+    schema = {'geom': {'geometry': (gis.POINT, (XMIN, YMIN, XMAX, YMAX))}, 
               'NO_CODE': {'type': 'string', 'maxlength': 18}, 
               'NO_ID_INSE': {'type': 'string', 'empty': False, 'allowed': INSEE_VALIDES}, 
               'NO_NOM': {'type': 'string', 'maxlength': 20}, 
@@ -130,7 +130,7 @@ class Noeud(BaseGeoModel):
 class Tranchee(BaseGeoModel):
     filename = "tranchee_geo.shp"
     pk = "TR_CODE"
-    schema = {'geom': {'geom': (gis.POLYLINE, (XMIN, YMIN, XMAX, YMAX))}, 
+    schema = {'geom': {'geometry': (gis.POLYLINE, (XMIN, YMIN, XMAX, YMAX))}, 
               'TR_CODE': {'type': 'string', 'maxlength': 23}, 
               'TR_NOM': {'type': 'string', 'maxlength': 23}, 
               'TR_ID_INSE': {'type': 'string', 'empty': False, 'allowed': INSEE_VALIDES}, 
@@ -158,7 +158,7 @@ class Tranchee(BaseGeoModel):
 class Zapbo(BaseGeoModel):
     filename = "zapbo_geo.shp"
     pk = "ID_ZAPBO"
-    schema = {'geom': {'geom': (gis.POLYGON, (XMIN, YMIN, XMAX, YMAX))}, 
+    schema = {'geom': {'geometry': (gis.POLYGON, (XMIN, YMIN, XMAX, YMAX))}, 
               'ID_ZAPBO': {'type': 'string', 'maxlength': 10}, 
               'COMMENTAIR': {'type': 'string', 'maxlength': 254, 'empty': True}, 
               'STATUT': {'type': 'string', 'empty': False, 'allowed': ['EN ETUDE', 'EN REALISATION', 'EN SERVICE', 'HORS SERVICE']}}

+ 5 - 4
schemas/netgeo_2_2_doe/validator.py

@@ -2,8 +2,7 @@
 
 @author: olivier.massot, 2018
 '''
-from core.validation import NetgeoValidator
-from core.validation_errors import DuplicatedPk, RelationError
+from core.validation import NetgeoValidator, DuplicatedPk, RelationError
 from schemas.netgeo_2_2_doe.models import Artere, Cable, Equipement, Noeud, \
     Tranchee, Zapbo
 
@@ -67,6 +66,8 @@ class Netgeo22DoeValidator(NetgeoValidator):
     
 if __name__ == "__main__":
     from core.constants import MAIN
-    subject = MAIN / "work" / "STURNO_192AP1_REC_171211_OK"
+    subject = MAIN / "work" / "AXIANS_082AP0_REC_180920.zip"
+#     subject = MAIN / "work" / "STURNO_192AP1_REC_171211_OK"
     report = Netgeo22DoeValidator.submit(subject)
-    print(report)
+    print(report)
+