#131 EGON export

* finishes egon compatible (tested) data export
* moves egon export into celery process
* adds export of data in case of intervention recording
* adds _RABBITMQ_ settings for intervention/settings.py
* adds new dependency for requirements.txt
This commit is contained in:
mpeltriaux 2022-03-21 12:14:55 +01:00
parent 17c954e844
commit 7689e0b80d
5 changed files with 120 additions and 23 deletions

View File

@ -13,6 +13,7 @@ from django.db.models.fields.files import FieldFile
from django.urls import reverse
from django.utils import timezone
from intervention.tasks import celery_export_to_egon
from user.models import User
from django.db import models, transaction
from django.db.models import QuerySet
@ -131,9 +132,20 @@ class Intervention(BaseObject, ShareableObjectMixin, RecordableObjectMixin, Chec
self.add_log_entry_to_compensations(log_entry)
return log_entry
def send_data_to_egon(self):
""" Performs the export to rabbitmq of this intervention's data
FOLLOWING BACKWARDS COMPATIBILITY LOGIC
Returns:
"""
celery_export_to_egon.delay(self.id)
def set_recorded(self, user: User) -> UserActionLogEntry:
log_entry = super().set_recorded(user)
self.add_log_entry_to_compensations(log_entry)
self.send_data_to_egon()
return log_entry
def add_log_entry_to_compensations(self, log_entry: UserActionLogEntry):

View File

@ -7,3 +7,10 @@ Created on: 30.11.20
"""
INTERVENTION_IDENTIFIER_LENGTH = 6
INTERVENTION_IDENTIFIER_TEMPLATE = "EIV-{}"
# EGON connection settings via rabbitmq
# NEEDED FOR BACKWARDS COMPATIBILITY
EGON_RABBITMQ_HOST = "CHANGE_ME"
EGON_RABBITMQ_PORT = "CHANGE_ME"
EGON_RABBITMQ_USER = "CHANGE_ME"
EGON_RABBITMQ_PW = "CHANGE_ME"

18
intervention/tasks.py Normal file
View File

@ -0,0 +1,18 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 21.03.22
"""
from celery import shared_task
from intervention.utils.egon_export import EgonExporter
@shared_task
def celery_export_to_egon(intervention_id: str):
from intervention.models import Intervention
intervention = Intervention.objects.get(id=intervention_id)
egon_exporter = EgonExporter(intervention)
egon_exporter.export_to_rabbitmq()

View File

@ -6,12 +6,14 @@ Created on: 07.03.22
"""
import base64
import json
import pika
import xmltodict
from django.db.models import Sum
from django.utils import formats
from intervention.models import Intervention
from intervention.settings import EGON_RABBITMQ_HOST, EGON_RABBITMQ_USER, EGON_RABBITMQ_PW, EGON_RABBITMQ_PORT
from konova.sub_settings.django_settings import DEFAULT_DATE_FORMAT
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
@ -26,12 +28,36 @@ class EgonExporter:
intervention = None
gml_builder = None
def __init__(self, intervention: Intervention):
def __init__(self, intervention):
self.intervention = intervention
self.gml_builder = EgonGmlBuilder(intervention)
def export_to_rabbitmq(self):
raise NotImplementedError("ToDo!")
""" Sends the exporter gml to message broker rabbitmq to be fetched by EGON application from there
Returns:
"""
msg = {
"nachricht": self.gml_builder.gml,
}
msg = json.dumps(msg)
print(msg)
credentials = pika.PlainCredentials(EGON_RABBITMQ_USER, EGON_RABBITMQ_PW)
params = pika.ConnectionParameters(
EGON_RABBITMQ_HOST,
EGON_RABBITMQ_PORT,
"/",
credentials
)
conn = pika.BlockingConnection(params)
channel = conn.channel()
channel.basic_publish(
exchange="",
routing_key="KSP_EGON",
body=msg.encode("utf-8"),
)
conn.close()
class EgonGmlBuilder:
@ -41,7 +67,7 @@ class EgonGmlBuilder:
intervention = None
gml = None
def __init__(self, intervention: Intervention):
def __init__(self, intervention):
self.intervention = intervention
self.gml = self.build_gml()
@ -66,11 +92,13 @@ class EgonGmlBuilder:
)["summed"]
return all_payments
def _gen_kompensationsArt(self):
def _gen_kompensationsArt(self) -> (str, int):
comp_type = "Ersatzzahlung"
comp_type_code = 774898901
if self.intervention.compensations.exists():
comp_type += " und Kompensation"
return comp_type
comp_type_code = 771655351
return comp_type, comp_type_code
def _gen_geometry_list(self):
geom = self.intervention.geometry.geom
@ -80,7 +108,7 @@ class EgonGmlBuilder:
"gml:Polygon": {
"gml:exterior": {
"gml:LinearRing": {
"gml:posList": " ".join([f"{str(coord[0])},{str(coord[1])}" for coord in coords[0]])
"gml:posList": " ".join([f"{str(coord[0])} {str(coord[1])}" for coord in coords[0]])
}
}
}
@ -95,9 +123,15 @@ class EgonGmlBuilder:
"oneo:datumAbgleich": None,
"oneo:ortsangabe": {
"oneo:Ortsangaben": {
"oneo:kreisSchluessel": parcel.district.krs,
"oneo:gemeindeSchluessel": parcel.district.gmnd,
"oneo:verbandsgemeindeSchluessel": parcel.gmrkng,
"oneo:kreisSchluessel": {
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/588/{parcel.district.krs}",
},
"oneo:gemeindeSchluessel": {
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/910/{parcel.district.gmnd}",
},
"oneo:verbandsgemeindeSchluessel": {
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/589/{parcel.gmrkng}",
},
"oneo:flurstuecksKennzeichen": self._gen_flurstuecksKennzeichen(parcel),
}
},
@ -110,7 +144,7 @@ class EgonGmlBuilder:
docs_list = [
{
"oneo:Foto": {
"oneo:aufnahmezeitpunkt": formats.localize(doc.date_of_creation),
"oneo:aufnahmezeitpunkt": doc.date_of_creation.strftime(DEFAULT_DATE_FORMAT),
"oneo:bemerkung": doc.comment,
"oneo:fotoverweis": base64.b64encode(doc.file.read()).decode("utf-8"),
"oneo:dateiname": doc.title,
@ -121,23 +155,48 @@ class EgonGmlBuilder:
return docs_list
def build_gml(self):
comp_type, comp_type_code = self._gen_kompensationsArt()
xml_dict = {
"wfs:FeatureCollection": {
"@xmlns:wfs": "http://www.opengis.net/wfs",
"@xmlns:xlink": "http://www.w3.org/1999/xlink",
"@xmlns:oneo": "http://www.osiris-projekt.rlp.de/oneo",
"@xmlns:gmlexr": "http://www.opengis.net/gml/3.3/exr",
"@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"@xmlns:gml": "http://www.opengis.net/gml/3.2",
"oneo:Eingriffsverfahren": {
"@gml:id": self.intervention.identifier,
"oneo:azEintragungsstelle": self.intervention.responsible.conservation_file_number,
"oneo:azZulassungsstelle": self.intervention.responsible.registration_file_number,
"oneo:bemerkungZulassungsstelle": None,
"oneo:eintragungsstelle": self.intervention.responsible.conservation_office.long_name,
"oneo:zulassungsstelle": self.intervention.responsible.registration_office.long_name,
"oneo:eintragungsstelle": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/907/{self.intervention.responsible.conservation_office.atom_id}",
"#text": self.intervention.responsible.conservation_office.long_name
},
"oneo:zulassungsstelle": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{self.intervention.responsible.registration_office.atom_id}",
"#text": self.intervention.responsible.registration_office.long_name
},
"oneo:ersatzzahlung": self._sum_all_payments(),
"oneo:kompensationsart": self._gen_kompensationsArt(),
"oneo:verfahrensrecht": self.intervention.legal.laws.first().short_name,
"oneo:verfahrenstyp": self.intervention.legal.process_type.long_name,
"oneo:kompensationsart": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/88140/{comp_type_code}",
"#text": comp_type
},
"oneo:verfahrensrecht": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1048/{self.intervention.legal.laws.first().atom_id}",
"#text": self.intervention.legal.laws.first().short_name
},
"oneo:verfahrenstyp": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/44382/{self.intervention.legal.process_type.atom_id}",
"#text": self.intervention.legal.process_type.long_name,
},
"oneo:eingreifer": {
"oneo:Eingreifer": {
"oneo:art": self.intervention.responsible.handler.type.long_name,
"oneo:bemerkung": self.intervention.responsible.handler.type.long_name,
"oneo:art": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{self.intervention.responsible.handler.type.atom_id}",
"#text": self.intervention.responsible.handler.type.long_name,
},
"oneo:bemerkung": self.intervention.responsible.handler.detail,
}
},
"oneo:erfasser": {
@ -148,9 +207,9 @@ class EgonGmlBuilder:
},
"oneo:zulassung": {
"oneo:Zulassungstermin": {
"oneo:bauBeginn": formats.localize(self.intervention.payments.first().due_on),
"oneo:erlass": formats.localize(self.intervention.legal.registration_date),
"oneo:rechtsKraft": formats.localize(self.intervention.legal.binding_date),
"oneo:bauBeginn": self.intervention.payments.first().due_on.strftime(DEFAULT_DATE_FORMAT),
"oneo:erlass": self.intervention.legal.registration_date.strftime(DEFAULT_DATE_FORMAT),
"oneo:rechtsKraft": self.intervention.legal.binding_date.strftime(DEFAULT_DATE_FORMAT),
}
},
"oneo:geometrie": {

View File

@ -28,6 +28,7 @@ kombu==5.2.3
openpyxl==3.0.9
OWSLib==0.25.0
packaging==21.3
pika==1.2.0
prompt-toolkit==3.0.24
psycopg2-binary==2.9.1
pyparsing==3.0.6