Testrun-Export nach tests/output umbiegen, Sivas-Bezeichner-Datei optional, Sivas-Merkmalzuordnung in Config
SSG_RUN_ALL_TESTS_EXPORT setzte *export-test-override* nicht, dadurch landeten CSV/Sivas-Exporte trotz Automatik-Modus in DXFM_RESULTS statt in tests/output wie die DXF/DWG-Dateien selbst - jetzt analog zu TEST_EXPORT_ALL behoben. EXPORTSIVAS schrieb bisher immer zusaetzlich eine "_mit_bezeichnung.csv" (Klartext-Kopie). Neuer Schalter "Sivas Export mit Bezeichner" im Dialog CSV_EXPORT_KONFIG (Standard aus) macht das optional. Die Attribut->Sivas-Merkmal-Zuordnung der build_*_details-Funktionen in export_sivas.py (Gefaellestrecke/Kreisel/Eckrad/Geruest/VarioFoerderer, soweit nicht von der Segmentanzahl abhaengig) liegt jetzt deklarativ in cfg/sivas.cfg statt hartcodiert im Python - neuer Loader lib/sivas_mapping.py. Ablauflogik (Gruppierung, Automation-Summenzeile, Segment-Zaehlung) bleibt Code. Gegen den alten Code mit synthetischen Testblöcken verifiziert: identische Ausgabe. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+21
-1
@@ -116,6 +116,18 @@
|
|||||||
(defun csv:gefrorene-ausschliessen-setzen (an)
|
(defun csv:gefrorene-ausschliessen-setzen (an)
|
||||||
(setq *csv-gefrorene-ausschliessen* (if an T nil)))
|
(setq *csv-gefrorene-ausschliessen* (if an T nil)))
|
||||||
|
|
||||||
|
;; --- Sivas-Export zusaetzlich mit Klartext-Bezeichnung schreiben ---
|
||||||
|
;; Standard aus (nil): EXPORTSIVAS schreibt nur die eigentliche <name>_sivas.csv
|
||||||
|
;; (fuer den Sivas-Import). Nur bei eingeschaltetem Schalter schreibt
|
||||||
|
;; lib/export_sivas.py zusaetzlich <name>_sivas_mit_bezeichnung.csv (Merkmal-
|
||||||
|
;; Keys durch Klartext aus cfg/Merkmalsstamm_in_Sivas.xlsx ersetzt, reine
|
||||||
|
;; Lesehilfe zur manuellen Pruefung, wird von Sivas selbst nicht eingelesen).
|
||||||
|
;; Bedienbar im Dialog CSV_EXPORT_KONFIG ("Sivas Export mit Bezeichner").
|
||||||
|
(if (not (boundp '*csv-sivas-mit-bezeichnung*)) (setq *csv-sivas-mit-bezeichnung* nil))
|
||||||
|
(defun csv:sivas-mit-bezeichnung-p () (if *csv-sivas-mit-bezeichnung* T nil))
|
||||||
|
(defun csv:sivas-mit-bezeichnung-setzen (an)
|
||||||
|
(setq *csv-sivas-mit-bezeichnung* (if an T nil)))
|
||||||
|
|
||||||
;; Hilfsobjekte (car eines Records), deren Wrapper (nth 1) gefroren-fn
|
;; Hilfsobjekte (car eines Records), deren Wrapper (nth 1) gefroren-fn
|
||||||
;; erfuellt. records = Record-Listen der Form (hilfsobjekt wrapper ...), wie
|
;; erfuellt. records = Record-Listen der Form (hilfsobjekt wrapper ...), wie
|
||||||
;; sie csv:sep-proxies-erzeugen, csv:element-proxies-erzeugen,
|
;; sie csv:sep-proxies-erzeugen, csv:element-proxies-erzeugen,
|
||||||
@@ -2622,8 +2634,14 @@
|
|||||||
;; Synchron ausfuehren und Exitcode auswerten - ein stiller
|
;; Synchron ausfuehren und Exitcode auswerten - ein stiller
|
||||||
;; Fehlschlag (z.B. WindowsApps-Platzhalter statt Interpreter)
|
;; Fehlschlag (z.B. WindowsApps-Platzhalter statt Interpreter)
|
||||||
;; darf nicht mehr als "Export gestartet" durchgehen.
|
;; darf nicht mehr als "Export gestartet" durchgehen.
|
||||||
|
;; --mit-bezeichnung nur an export_sivas.py anhaengen (Schalter
|
||||||
|
;; *csv-sivas-mit-bezeichnung*, Dialog CSV_EXPORT_KONFIG) - export_csv.py
|
||||||
|
;; kennt dieses Argument nicht.
|
||||||
(setq rc (export:run-python py-exe py-skript
|
(setq rc (export:run-python py-exe py-skript
|
||||||
(list out-pfad (getenv "DXFM_DATA") ergebnis-pfad)
|
(append (list out-pfad (getenv "DXFM_DATA") ergebnis-pfad)
|
||||||
|
(if (and (= py-name (export:filename "sivas_script"))
|
||||||
|
(csv:sivas-mit-bezeichnung-p))
|
||||||
|
(list "--mit-bezeichnung")))
|
||||||
log-pfad))
|
log-pfad))
|
||||||
(cond
|
(cond
|
||||||
((null rc)
|
((null rc)
|
||||||
@@ -2786,6 +2804,7 @@
|
|||||||
(set_tile "modus" (itoa idx))
|
(set_tile "modus" (itoa idx))
|
||||||
(set_tile "hilfskopien_behalten" (if (csv:hilfskopien-behalten-p) "1" "0"))
|
(set_tile "hilfskopien_behalten" (if (csv:hilfskopien-behalten-p) "1" "0"))
|
||||||
(set_tile "gefrorene_ausschliessen" (if (csv:gefrorene-ausschliessen-p) "1" "0"))
|
(set_tile "gefrorene_ausschliessen" (if (csv:gefrorene-ausschliessen-p) "1" "0"))
|
||||||
|
(set_tile "sivas_mit_bezeichnung" (if (csv:sivas-mit-bezeichnung-p) "1" "0"))
|
||||||
)
|
)
|
||||||
|
|
||||||
(defun csv:export-konfig-accept ( / idx modus)
|
(defun csv:export-konfig-accept ( / idx modus)
|
||||||
@@ -2794,6 +2813,7 @@
|
|||||||
(if modus (csv:export-modus-setzen modus))
|
(if modus (csv:export-modus-setzen modus))
|
||||||
(csv:hilfskopien-behalten-setzen (= (get_tile "hilfskopien_behalten") "1"))
|
(csv:hilfskopien-behalten-setzen (= (get_tile "hilfskopien_behalten") "1"))
|
||||||
(csv:gefrorene-ausschliessen-setzen (= (get_tile "gefrorene_ausschliessen") "1"))
|
(csv:gefrorene-ausschliessen-setzen (= (get_tile "gefrorene_ausschliessen") "1"))
|
||||||
|
(csv:sivas-mit-bezeichnung-setzen (= (get_tile "sivas_mit_bezeichnung") "1"))
|
||||||
)
|
)
|
||||||
|
|
||||||
(defun c:CSV_EXPORT_KONFIG ()
|
(defun c:CSV_EXPORT_KONFIG ()
|
||||||
|
|||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
# ============================================================
|
||||||
|
# sivas.cfg - Attribut->Sivas-Merkmal-Zuordnung fuer lib/export_sivas.py
|
||||||
|
#
|
||||||
|
# Deckt NUR die "einfachen" Faelle ab: eine Sivas-Merkmalnummer entspricht
|
||||||
|
# genau einem (ggf. per Fallback alternativen) Block-Attribut, optional mit
|
||||||
|
# festem Default und/oder einer benannten Transform-Funktion. Berechnete
|
||||||
|
# Werte, die von der Anzahl vorhandener Segmente abhaengen oder mehrere
|
||||||
|
# Attribute kombinieren (VarioFoerderer-Gefaelle-/Vario-Segmentpaare 4312-
|
||||||
|
# 4392/4353-4386, die ILS-Automation-Summenzeile) bleiben bewusst Python-Code
|
||||||
|
# in export_sivas.py - ein flaches Attribut-Mapping kann bedingte/berechnete
|
||||||
|
# Werte nicht abbilden.
|
||||||
|
#
|
||||||
|
# Format je Zeile (Abschnitt = Elementtyp, Key = Sivas-Merkmalnummer):
|
||||||
|
# merkmal = attribut
|
||||||
|
# merkmal = attribut : default
|
||||||
|
# merkmal = attribut | alt_attribut : default
|
||||||
|
# merkmal = attribut : default | transform
|
||||||
|
#
|
||||||
|
# attribut - Name des Block-Attributs (ssg-attrib-*, siehe jeweiliges
|
||||||
|
# .lsp-Modul). Fehlt es in der Zeichnung, greift default.
|
||||||
|
# | alt_attribut - optionaler Fallback-Attributname (aeltere Zeichnungen mit
|
||||||
|
# abweichendem Attributnamen, z.B. N_SEPARATOREN vor der
|
||||||
|
# Umbenennung zu ANZAHL_SEPARATOR). Wird nur genutzt, wenn
|
||||||
|
# attribut selbst fehlt.
|
||||||
|
# : default - Vorgabewert, falls weder attribut noch alt_attribut in
|
||||||
|
# der Zeichnung gesetzt sind. Fehlt ":", ist default "".
|
||||||
|
# | transform - Name einer Python-Funktion in export_sivas.py
|
||||||
|
# (TRANSFORMS-Dict), die den ermittelten Rohwert
|
||||||
|
# (Attribut- oder Default-Wert) in die Sivas-Anzeige
|
||||||
|
# umwandelt (z.B. "0"/"1" -> "Ja"/"Nein"). Bekannte Namen:
|
||||||
|
# ja_nein, geruest_typ_anzeige. Ein unbekannter Name
|
||||||
|
# bricht NICHT ab, der Rohwert wird unveraendert
|
||||||
|
# uebernommen (siehe sivas_mapping.anwenden).
|
||||||
|
#
|
||||||
|
# Abschnittsnamen entsprechen den bisherigen build_*_details-Funktionen in
|
||||||
|
# export_sivas.py: [gefaellestrecke], [kreisel], [eckrad], [geruest]. Die
|
||||||
|
# geruest-typ-Anzeige-Tabelle (ASCII-Attributwert -> Sivas-Klartext mit
|
||||||
|
# Umlauten) UND SEPARATOR_BEARBEITUNG_ANZEIGE bleiben eigene, kleine
|
||||||
|
# Abschnitte weiter unten.
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
[gefaellestrecke]
|
||||||
|
2950= MONTAGEHOEHE_m : 0
|
||||||
|
4384= : Gefällestrecke
|
||||||
|
4318= L_GF_m
|
||||||
|
4391= GF_WINKEL
|
||||||
|
4337= ANZAHL_SEPARATOR : 0
|
||||||
|
4338= : ohne HARTCOAT HRC 50 ± 5
|
||||||
|
4339= ANZAHL_SCANNER : 0
|
||||||
|
3992= GERUEST_EINZELMODUL : 0 | ja_nein
|
||||||
|
3993= GERUEST_TYP : Schoenenberger Geruest | geruest_typ_anzeige
|
||||||
|
# 4300 (Streckengruppe "ein Objekt"/"mehrere Objekte") und 4311 (Anzahl der
|
||||||
|
# gruppierten Bloecke) bleiben Code (streckengruppe_objekt_text, anzahl-Param.).
|
||||||
|
|
||||||
|
[kreisel]
|
||||||
|
2952= MONTAGEHOEHE_m : 0
|
||||||
|
3511= : 1
|
||||||
|
3515= ANZAHL_SEPARATOR | N_SEPARATOREN : 2
|
||||||
|
3517= ANZAHL_SCANNER | N_SCANNER : 0
|
||||||
|
3519= ANZAHL_RAMPEN | N_RAMPEN : 0
|
||||||
|
3992= GERUEST_EINZELMODUL : 0 | ja_nein
|
||||||
|
3993= GERUEST_TYP : Schoenenberger Geruest | geruest_typ_anzeige
|
||||||
|
# 3510 (Kreiselart-Anzeigetext) und 3512 (Abstand in m, gerundet) bleiben
|
||||||
|
# Code (bedingte Umbenennung bzw. Umrechnung mm->m).
|
||||||
|
|
||||||
|
[eckrad]
|
||||||
|
# Bewusst (noch) beschreibende Klartext-Keys statt Merkmalnummern (kein
|
||||||
|
# bekanntes Sivas-Merkmal fuer Eckrad-Geruest hinterlegt) - details_mit_
|
||||||
|
# bezeichnung() in export_sivas.py laesst nicht-numerische Keys unveraendert.
|
||||||
|
# "ist_eins" liefert ein ECHTES bool (True/False), NICHT "Ja"/"Nein" wie
|
||||||
|
# ja_nein bei Kreisel/Gefaellestrecke - json.dumps schreibt dann true/false
|
||||||
|
# ohne Anfuehrungszeichen (bisheriges Verhalten von build_eckrad_details).
|
||||||
|
Geruest fuer Einzelmodul= GERUEST_EINZELMODUL : 0 | ist_eins
|
||||||
|
Geruestoption fuer Einzelmodul= GERUEST_TYP : Schoenenberger Geruest
|
||||||
|
|
||||||
|
[geruest]
|
||||||
|
Farbe= FARBE
|
||||||
|
|
||||||
|
[variofoerderer]
|
||||||
|
# Nur die von der Segmentanzahl UNABHAENGIGEN Top-Level-Felder einer VF_N-
|
||||||
|
# Streckengruppe (siehe build_variofoerderer_details in export_sivas.py).
|
||||||
|
# Die Gefaelle-/Vario-Segmentpaare (4312-4392, 4353/4354/4386) haengen an der
|
||||||
|
# Listenlaenge von L_GF_m/L_VF_m und bleiben Code.
|
||||||
|
2950= MONTAGEHOEHE_m : 0
|
||||||
|
4329= GF_Bogen_L_90 : 0
|
||||||
|
4330= GF_Bogen_L_60 : 0
|
||||||
|
4331= GF_Bogen_L_30 : 0
|
||||||
|
4332= GF_Bogen_R_90 : 0
|
||||||
|
4333= GF_Bogen_R_60 : 0
|
||||||
|
4334= GF_Bogen_R_30 : 0
|
||||||
|
4373= VF_Bogen_A_90 : 0
|
||||||
|
4374= VF_Bogen_A_60 : 0
|
||||||
|
4375= VF_Bogen_A_30 : 0
|
||||||
|
4376= VF_Bogen_I_90 : 0
|
||||||
|
4377= VF_Bogen_I_60 : 0
|
||||||
|
4378= VF_Bogen_I_30 : 0
|
||||||
|
4381= ANZAHL_SEPARATOR : 0
|
||||||
|
4382= : ohne HARTCOAT HRC 50 ± 5
|
||||||
|
4383= ANZAHL_SCANNER : 0
|
||||||
|
3992= GERUEST_EINZELMODUL : 0 | ja_nein
|
||||||
|
3993= GERUEST_TYP : Schoenenberger Geruest | geruest_typ_anzeige
|
||||||
|
|
||||||
|
[geruest_typ_anzeige]
|
||||||
|
# ASCII-Attributwert (GERUEST_TYP) -> Sivas-Klartext mit Umlauten/Sonder-
|
||||||
|
# zeichen (Attribute selbst bleiben ASCII, siehe CLAUDE.md-Konvention).
|
||||||
|
Schoenenberger Geruest= Schönenberger-Gerüst
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
// csv_export_konfig.dcl - CSV-Export Konfiguration (c:CSV_EXPORT_KONFIG,
|
// csv_export_konfig.dcl - CSV-Export Konfiguration (c:CSV_EXPORT_KONFIG,
|
||||||
// export.lsp). Steuert *csv-export-modus* (Combobox mit drei sich
|
// export.lsp). Steuert *csv-export-modus* (Combobox mit drei sich
|
||||||
// gegenseitig ausschliessenden Eintraegen) sowie den Debug-Schalter
|
// gegenseitig ausschliessenden Eintraegen), *csv-gefrorene-ausschliessen*
|
||||||
// csv_leave_proxies (Hilfskopien nach dem Export stehen lassen) und
|
// (gefrorene Layer nicht exportieren), *csv-sivas-mit-bezeichnung* (Sivas-
|
||||||
// *csv-gefrorene-ausschliessen* (gefrorene Layer nicht exportieren).
|
// Export zusaetzlich mit Klartext-Bezeichnung schreiben) sowie den
|
||||||
|
// Debug-Schalter csv_leave_proxies (Hilfskopien nach dem Export stehen lassen).
|
||||||
//
|
//
|
||||||
// popup_list statt radio_column: set_tile/get_tile auf einer
|
// popup_list statt radio_column: set_tile/get_tile auf einer
|
||||||
// boxed_radio_column liefern/erwarten den KEY des gewaehlten radio_button
|
// boxed_radio_column liefern/erwarten den KEY des gewaehlten radio_button
|
||||||
@@ -29,6 +30,11 @@ csv_export_konfig : dialog {
|
|||||||
label = "Bloecke auf gefrorenen Layern nicht exportieren";
|
label = "Bloecke auf gefrorenen Layern nicht exportieren";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
: toggle {
|
||||||
|
key = "sivas_mit_bezeichnung";
|
||||||
|
label = "Sivas Export mit Bezeichner";
|
||||||
|
}
|
||||||
|
|
||||||
spacer;
|
spacer;
|
||||||
|
|
||||||
: boxed_column {
|
: boxed_column {
|
||||||
|
|||||||
+93
-97
@@ -31,7 +31,7 @@ Neues CSV-Format:
|
|||||||
cfg/Merkmalsstamm_in_Sivas.xlsx fuer die Bezeichnung je Nummer.
|
cfg/Merkmalsstamm_in_Sivas.xlsx fuer die Bezeichnung je Nummer.
|
||||||
|
|
||||||
Aufruf:
|
Aufruf:
|
||||||
python export_sivas.py <export_raw.json> <data_dir> <output.csv>
|
python export_sivas.py <export_raw.json> <data_dir> <output.csv> [--mit-bezeichnung]
|
||||||
|
|
||||||
Argumente:
|
Argumente:
|
||||||
export_raw.json - JSON-Datei mit allen INSERT-Entities aus der Zeichnung
|
export_raw.json - JSON-Datei mit allen INSERT-Entities aus der Zeichnung
|
||||||
@@ -39,13 +39,15 @@ Argumente:
|
|||||||
fuer den Aufrufer export.lsp erhalten)
|
fuer den Aufrufer export.lsp erhalten)
|
||||||
output.csv - Ziel-CSV-Datei (reine Merkmalnummern, fuer den
|
output.csv - Ziel-CSV-Datei (reine Merkmalnummern, fuer den
|
||||||
Sivas-Import)
|
Sivas-Import)
|
||||||
|
--mit-bezeichnung - optional. Nur dann wird zusaetzlich zu output.csv
|
||||||
Zusaetzlich zu output.csv wird immer eine zweite Datei
|
eine zweite Datei "<output>_mit_bezeichnung.csv"
|
||||||
"<output>_mit_bezeichnung.csv" geschrieben: gleicher Inhalt, aber jeder
|
geschrieben: gleicher Inhalt, aber jeder Merkmalnummer-
|
||||||
Merkmalnummer-Key im details-JSON wird durch die zugehoerige Klartext-
|
Key im details-JSON wird durch die zugehoerige Klartext-
|
||||||
Bezeichnung aus cfg/Merkmalsstamm_in_Sivas.xlsx ersetzt (Wert bleibt
|
Bezeichnung aus cfg/Merkmalsstamm_in_Sivas.xlsx ersetzt
|
||||||
unveraendert) - reine Lesehilfe zur Pruefung, wird von Sivas selbst nicht
|
(Wert bleibt unveraendert) - reine Lesehilfe zur
|
||||||
eingelesen.
|
Pruefung, wird von Sivas selbst nicht eingelesen.
|
||||||
|
Schalter im Dialog CSV_EXPORT_KONFIG
|
||||||
|
("Sivas Export mit Bezeichner"), Standard aus.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
@@ -54,6 +56,7 @@ import os
|
|||||||
|
|
||||||
from export_blockpatterns import load_patterns, matches_any, csv_quote, safe_float, safe_int
|
from export_blockpatterns import load_patterns, matches_any, csv_quote, safe_float, safe_int
|
||||||
from merkmalstamm import lade_merkmalstamm, bezeichnung_fuer
|
from merkmalstamm import lade_merkmalstamm, bezeichnung_fuer
|
||||||
|
import sivas_mapping
|
||||||
|
|
||||||
BLOCKPATTERNS = load_patterns()
|
BLOCKPATTERNS = load_patterns()
|
||||||
|
|
||||||
@@ -81,11 +84,10 @@ def get_id(block):
|
|||||||
# --- Sivas-Merkmalnummern: Anzeigetexte, die nicht 1:1 aus dem Attribut
|
# --- Sivas-Merkmalnummern: Anzeigetexte, die nicht 1:1 aus dem Attribut
|
||||||
# uebernommen werden koennen (Attribute bleiben ASCII, siehe CLAUDE.md-
|
# uebernommen werden koennen (Attribute bleiben ASCII, siehe CLAUDE.md-
|
||||||
# Konvention "Alle Texte in Dateien ohne Umlaute" - Sivas erwartet aber die
|
# Konvention "Alle Texte in Dateien ohne Umlaute" - Sivas erwartet aber die
|
||||||
# deutsche Schreibweise mit Umlauten/Sonderzeichen). Nur hier zentral, nicht
|
# deutsche Schreibweise mit Umlauten/Sonderzeichen). Tabelle kommt aus
|
||||||
# ueber die uebliche ssg-text-Sprachdatei, da rein Sivas-seitig.
|
# cfg/sivas.cfg [geruest_typ_anzeige], nicht ueber die uebliche ssg-text-
|
||||||
GERUEST_TYP_ANZEIGE = {
|
# Sprachdatei, da rein Sivas-seitig.
|
||||||
"Schoenenberger Geruest": "Schönenberger-Gerüst",
|
GERUEST_TYP_ANZEIGE = sivas_mapping.load_flat_mapping("geruest_typ_anzeige")
|
||||||
}
|
|
||||||
|
|
||||||
SEPARATOR_BEARBEITUNG_ANZEIGE = "ohne HARTCOAT HRC 50 ± 5"
|
SEPARATOR_BEARBEITUNG_ANZEIGE = "ohne HARTCOAT HRC 50 ± 5"
|
||||||
|
|
||||||
@@ -100,6 +102,20 @@ def ja_nein(flag_1_0):
|
|||||||
return "Ja" if flag_1_0 == "1" else "Nein"
|
return "Ja" if flag_1_0 == "1" else "Nein"
|
||||||
|
|
||||||
|
|
||||||
|
def ist_eins(flag_1_0):
|
||||||
|
"""Wandelt ein "0"/"1"-Attribut in ein echtes bool um (True/False im
|
||||||
|
JSON, NICHT "Ja"/"Nein" wie ja_nein - siehe build_eckrad_details)."""
|
||||||
|
return flag_1_0 == "1"
|
||||||
|
|
||||||
|
|
||||||
|
# --- Transform-Namen, wie sie in cfg/sivas.cfg hinter "|" stehen koennen ---
|
||||||
|
TRANSFORMS = {
|
||||||
|
"ja_nein": ja_nein,
|
||||||
|
"geruest_typ_anzeige": geruest_typ_anzeige,
|
||||||
|
"ist_eins": ist_eins,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def streckengruppe_objekt_text(attribs):
|
def streckengruppe_objekt_text(attribs):
|
||||||
"""Merkmal 4300 "Streckengruppe": "mehrere Objekte", wenn der Block ein
|
"""Merkmal 4300 "Streckengruppe": "mehrere Objekte", wenn der Block ein
|
||||||
kombinierter Streckengruppe-Block (Gefaelle+Vario, TYP-Attribut
|
kombinierter Streckengruppe-Block (Gefaelle+Vario, TYP-Attribut
|
||||||
@@ -108,27 +124,24 @@ def streckengruppe_objekt_text(attribs):
|
|||||||
return "mehrere Objekte" if typ == "Streckengruppe" else "ein Objekt"
|
return "mehrere Objekte" if typ == "Streckengruppe" else "ein Objekt"
|
||||||
|
|
||||||
|
|
||||||
|
SIVAS_MAPPING_GEFAELLESTRECKE = sivas_mapping.load_section_mapping("gefaellestrecke")
|
||||||
|
|
||||||
|
|
||||||
def build_gefaellestrecke_details(block, anzahl=1):
|
def build_gefaellestrecke_details(block, anzahl=1):
|
||||||
"""Merkmale-Dict (Sivas-Merkmalnummern) fuer eine Gruppe gleichartiger
|
"""Merkmale-Dict (Sivas-Merkmalnummern) fuer eine Gruppe gleichartiger
|
||||||
ILS Gefaellestrecken (GF_N-Bloecke). anzahl ist die Anzahl der in dieser
|
ILS Gefaellestrecken (GF_N-Bloecke). anzahl ist die Anzahl der in dieser
|
||||||
Zeile zusammengefassten, baugleichen Bloecke (4311) - anders als bei
|
Zeile zusammengefassten, baugleichen Bloecke (4311) - anders als bei
|
||||||
Kreisel steht hier auf der Sivas-Hauptzeile selbst immer Anzahl=1 (siehe
|
Kreisel steht hier auf der Sivas-Hauptzeile selbst immer Anzahl=1 (siehe
|
||||||
process_blocks), die reale Stueckzahl steckt nur in 4311."""
|
process_blocks), die reale Stueckzahl steckt nur in 4311.
|
||||||
attribs = block.get("attribs", {})
|
|
||||||
|
|
||||||
return {
|
Die reine Attribut->Merkmal-Zuordnung kommt aus cfg/sivas.cfg
|
||||||
"2950": attribs.get("MONTAGEHOEHE_m", "0"),
|
[gefaellestrecke]; 4300 (Streckengruppe-Text) und 4311 (Anzahl-Parameter)
|
||||||
"4300": streckengruppe_objekt_text(attribs),
|
sind berechnete/parametrisierte Werte und bleiben hier Code."""
|
||||||
"4384": "Gefällestrecke",
|
attribs = block.get("attribs", {})
|
||||||
"4311": str(anzahl),
|
details = sivas_mapping.anwenden(SIVAS_MAPPING_GEFAELLESTRECKE, attribs, TRANSFORMS)
|
||||||
"4318": attribs.get("L_GF_m", ""),
|
details["4300"] = streckengruppe_objekt_text(attribs)
|
||||||
"4391": attribs.get("GF_WINKEL", ""),
|
details["4311"] = str(anzahl)
|
||||||
"4337": attribs.get("ANZAHL_SEPARATOR", "0"),
|
return details
|
||||||
"4338": SEPARATOR_BEARBEITUNG_ANZEIGE,
|
|
||||||
"4339": attribs.get("ANZAHL_SCANNER", "0"),
|
|
||||||
"3992": ja_nein(attribs.get("GERUEST_EINZELMODUL", "0")),
|
|
||||||
"3993": geruest_typ_anzeige(attribs.get("GERUEST_TYP", "Schoenenberger Geruest")),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def kreisel_signature(block):
|
def kreisel_signature(block):
|
||||||
@@ -203,6 +216,9 @@ def parse_str_list(csv_str):
|
|||||||
return [p.strip() for p in str(csv_str or "").split(",") if p.strip()]
|
return [p.strip() for p in str(csv_str or "").split(",") if p.strip()]
|
||||||
|
|
||||||
|
|
||||||
|
SIVAS_MAPPING_VARIOFOERDERER = sivas_mapping.load_section_mapping("variofoerderer")
|
||||||
|
|
||||||
|
|
||||||
def build_variofoerderer_details(block):
|
def build_variofoerderer_details(block):
|
||||||
"""
|
"""
|
||||||
Merkmale-Dict (Sivas-Merkmalnummern) fuer eine VF_N-Streckengruppe
|
Merkmale-Dict (Sivas-Merkmalnummern) fuer eine VF_N-Streckengruppe
|
||||||
@@ -216,12 +232,14 @@ def build_variofoerderer_details(block):
|
|||||||
ausstehenden Neuzuordnung von Separator/Scanner zum jeweiligen
|
ausstehenden Neuzuordnung von Separator/Scanner zum jeweiligen
|
||||||
Streckenabschnitt) - bis dahin steht 4337/4339 fest auf "0" und der volle
|
Streckenabschnitt) - bis dahin steht 4337/4339 fest auf "0" und der volle
|
||||||
Attributwert steht auf 4381/4383.
|
Attributwert steht auf 4381/4383.
|
||||||
|
|
||||||
|
Die von der Segmentanzahl UNABHAENGIGEN Felder (2950, GF_Bogen_*/
|
||||||
|
VF_Bogen_*-Zaehler, 4381-4383, 3992/3993) kommen aus cfg/sivas.cfg
|
||||||
|
[variofoerderer]. Die Gefaelle-/Vario-Segmentpaare (4312-4392, 4353/
|
||||||
|
4354/4386, abhaengig von len(gf_laengen)/len(vf_laengen)) bleiben Code.
|
||||||
"""
|
"""
|
||||||
attribs = block.get("attribs", {})
|
attribs = block.get("attribs", {})
|
||||||
|
|
||||||
def to_int(key):
|
|
||||||
return safe_int(attribs.get(key, "0") or "0")
|
|
||||||
|
|
||||||
gf_laengen = parse_float_list(attribs.get("L_GF_m", ""))
|
gf_laengen = parse_float_list(attribs.get("L_GF_m", ""))
|
||||||
gf_winkel = parse_float_list(attribs.get("GF_WINKEL", ""))
|
gf_winkel = parse_float_list(attribs.get("GF_WINKEL", ""))
|
||||||
vf_laengen = parse_float_list(attribs.get("L_VF_m", ""))
|
vf_laengen = parse_float_list(attribs.get("L_VF_m", ""))
|
||||||
@@ -229,11 +247,9 @@ def build_variofoerderer_details(block):
|
|||||||
vf_richtung = parse_str_list(attribs.get("ANTRIEBFAHRTRICHTUNG", ""))
|
vf_richtung = parse_str_list(attribs.get("ANTRIEBFAHRTRICHTUNG", ""))
|
||||||
motorseiten = parse_str_list(attribs.get("MOTORSEITE", ""))
|
motorseiten = parse_str_list(attribs.get("MOTORSEITE", ""))
|
||||||
|
|
||||||
details = {
|
details = sivas_mapping.anwenden(SIVAS_MAPPING_VARIOFOERDERER, attribs, TRANSFORMS)
|
||||||
"2950": attribs.get("MONTAGEHOEHE_m", "0"),
|
details["4300"] = "mehrere Objekte"
|
||||||
"4300": "mehrere Objekte",
|
details["4311"] = "1"
|
||||||
"4311": "1",
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(gf_laengen) >= 1:
|
if len(gf_laengen) >= 1:
|
||||||
details["4312"] = "Ja"
|
details["4312"] = "Ja"
|
||||||
@@ -249,85 +265,62 @@ def build_variofoerderer_details(block):
|
|||||||
else:
|
else:
|
||||||
details["4314"] = "Nein"
|
details["4314"] = "Nein"
|
||||||
|
|
||||||
details.update({
|
details["4337"] = "0"
|
||||||
"4329": to_int("GF_Bogen_L_90"),
|
details["4338"] = SEPARATOR_BEARBEITUNG_ANZEIGE
|
||||||
"4330": to_int("GF_Bogen_L_60"),
|
details["4339"] = "0"
|
||||||
"4331": to_int("GF_Bogen_L_30"),
|
details["4340"] = "Ja" if vf_laengen else "Nein"
|
||||||
"4332": to_int("GF_Bogen_R_90"),
|
details["4341"] = sum(1 for seite in motorseiten if seite.lower() == "links")
|
||||||
"4333": to_int("GF_Bogen_R_60"),
|
details["4342"] = sum(1 for seite in motorseiten if seite.lower() == "rechts")
|
||||||
"4334": to_int("GF_Bogen_R_30"),
|
|
||||||
"4337": "0",
|
|
||||||
"4338": SEPARATOR_BEARBEITUNG_ANZEIGE,
|
|
||||||
"4339": "0",
|
|
||||||
"4340": "Ja" if vf_laengen else "Nein",
|
|
||||||
"4341": sum(1 for seite in motorseiten if seite.lower() == "links"),
|
|
||||||
"4342": sum(1 for seite in motorseiten if seite.lower() == "rechts"),
|
|
||||||
})
|
|
||||||
|
|
||||||
if vf_laengen:
|
if vf_laengen:
|
||||||
details["4353"] = vf_laengen[0]
|
details["4353"] = vf_laengen[0]
|
||||||
details["4354"] = vf_richtung[0].lower() if vf_richtung else ""
|
details["4354"] = vf_richtung[0].lower() if vf_richtung else ""
|
||||||
details["4386"] = str(int(vf_winkel[0])) if vf_winkel else ""
|
details["4386"] = str(int(vf_winkel[0])) if vf_winkel else ""
|
||||||
|
|
||||||
details.update({
|
|
||||||
"4373": to_int("VF_Bogen_A_90"),
|
|
||||||
"4374": to_int("VF_Bogen_A_60"),
|
|
||||||
"4375": to_int("VF_Bogen_A_30"),
|
|
||||||
"4376": to_int("VF_Bogen_I_90"),
|
|
||||||
"4377": to_int("VF_Bogen_I_60"),
|
|
||||||
"4378": to_int("VF_Bogen_I_30"),
|
|
||||||
"4381": attribs.get("ANZAHL_SEPARATOR", "0"),
|
|
||||||
"4382": SEPARATOR_BEARBEITUNG_ANZEIGE,
|
|
||||||
"4383": attribs.get("ANZAHL_SCANNER", "0"),
|
|
||||||
"3992": ja_nein(attribs.get("GERUEST_EINZELMODUL", "0")),
|
|
||||||
"3993": geruest_typ_anzeige(attribs.get("GERUEST_TYP", "Schoenenberger Geruest")),
|
|
||||||
})
|
|
||||||
return {k: str(v) for k, v in details.items()}
|
return {k: str(v) for k, v in details.items()}
|
||||||
|
|
||||||
|
|
||||||
|
SIVAS_MAPPING_KREISEL = sivas_mapping.load_section_mapping("kreisel")
|
||||||
|
SIVAS_MAPPING_ECKRAD = sivas_mapping.load_section_mapping("eckrad")
|
||||||
|
SIVAS_MAPPING_GERUEST = sivas_mapping.load_section_mapping("geruest")
|
||||||
|
|
||||||
|
|
||||||
def build_kreisel_details(block):
|
def build_kreisel_details(block):
|
||||||
"""Merkmale-Dict (Sivas-Merkmalnummern) fuer eine Gruppe gleichartiger
|
"""Merkmale-Dict (Sivas-Merkmalnummern) fuer eine Gruppe gleichartiger
|
||||||
ILS Kreisel. 3511 ("Kreisel - zu fertigende Menge") steht bewusst fest
|
ILS Kreisel. 3511 ("Kreisel - zu fertigende Menge") steht bewusst fest
|
||||||
auf "1" - die reale Stueckzahl der Gruppe steht auf der Sivas-Hauptzeile
|
auf "1" - die reale Stueckzahl der Gruppe steht auf der Sivas-Hauptzeile
|
||||||
selbst (Anzahl-Spalte, siehe kreisel_groups in process_blocks)."""
|
selbst (Anzahl-Spalte, siehe kreisel_groups in process_blocks).
|
||||||
|
|
||||||
|
Die reine Attribut->Merkmal-Zuordnung kommt aus cfg/sivas.cfg [kreisel];
|
||||||
|
3510 (Kreiselart-Anzeigetext) und 3512 (Abstand mm->m, gerundet) sind
|
||||||
|
berechnete Werte und bleiben hier Code."""
|
||||||
attribs = block.get("attribs", {})
|
attribs = block.get("attribs", {})
|
||||||
abstand_m = str(round(safe_float(attribs.get("ABSTAND", "2300"), 2300.0) / 1000.0, 2))
|
abstand_m = str(round(safe_float(attribs.get("ABSTAND", "2300"), 2300.0) / 1000.0, 2))
|
||||||
kreiselart = "Kreisel mit PINBAND" if attribs.get("KREISELART", "STANDARD") == "PIN" else "Kreisel"
|
kreiselart = "Kreisel mit PINBAND" if attribs.get("KREISELART", "STANDARD") == "PIN" else "Kreisel"
|
||||||
return {
|
details = sivas_mapping.anwenden(SIVAS_MAPPING_KREISEL, attribs, TRANSFORMS)
|
||||||
"2952": attribs.get("MONTAGEHOEHE_m", "0"),
|
details["3510"] = kreiselart
|
||||||
"3510": kreiselart,
|
details["3512"] = abstand_m
|
||||||
"3511": "1",
|
return details
|
||||||
"3512": abstand_m,
|
|
||||||
"3515": attribs.get("ANZAHL_SEPARATOR", attribs.get("N_SEPARATOREN", "2")),
|
|
||||||
"3517": attribs.get("ANZAHL_SCANNER", attribs.get("N_SCANNER", "0")),
|
|
||||||
"3519": attribs.get("ANZAHL_RAMPEN", attribs.get("N_RAMPEN", "0")),
|
|
||||||
"3992": ja_nein(attribs.get("GERUEST_EINZELMODUL", "0")),
|
|
||||||
"3993": geruest_typ_anzeige(attribs.get("GERUEST_TYP", "Schoenenberger Geruest")),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def build_eckrad_details(block):
|
def build_eckrad_details(block):
|
||||||
"""Merkmale-Dict fuer ein ILS Eckrad."""
|
"""Merkmale-Dict fuer ein ILS Eckrad. Vollstaendig aus cfg/sivas.cfg
|
||||||
|
[eckrad] (keine berechneten Werte)."""
|
||||||
attribs = block.get("attribs", {})
|
attribs = block.get("attribs", {})
|
||||||
return {
|
return sivas_mapping.anwenden(SIVAS_MAPPING_ECKRAD, attribs, TRANSFORMS)
|
||||||
"Geruest fuer Einzelmodul": attribs.get("GERUEST_EINZELMODUL", "0") == "1",
|
|
||||||
"Geruestoption fuer Einzelmodul": attribs.get("GERUEST_TYP", "Schoenenberger Geruest"),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def build_geruest_details(block):
|
def build_geruest_details(block):
|
||||||
"""Merkmale-Dict fuer eine GR_-Geruest-Baugruppe (siehe pattern_geruest in
|
"""Merkmale-Dict fuer eine GR_-Geruest-Baugruppe (siehe pattern_geruest in
|
||||||
cfg/export.cfg, GeruestInsert.lsp *geruest-attrib-defs*). ARTINR/
|
cfg/export.cfg, GeruestInsert.lsp *geruest-attrib-defs*). ARTINR/
|
||||||
BEZEICHNUNG/TEILEART/LAENGE wandern in feste Sivas-Spalten (sivasnr/
|
BEZEICHNUNG/TEILEART/LAENGE wandern in feste Sivas-Spalten (sivasnr/
|
||||||
bezeichnung/teileart/laenge_mm), FARBE bleibt als Rest-Attribut hier.
|
bezeichnung/teileart/laenge_mm), FARBE bleibt als Rest-Attribut hier
|
||||||
LAYER ist reine BricsCAD-Zeichnungsinformation ohne Sivas-Bedeutung und
|
(cfg/sivas.cfg [geruest]). LAYER ist reine BricsCAD-Zeichnungsinformation
|
||||||
wird bewusst NICHT mit exportiert (anders als im CSV-Export
|
ohne Sivas-Bedeutung und wird bewusst NICHT mit exportiert (anders als im
|
||||||
export_csv.py, wo sie fuer die Zuordnung in der Zeichnung nuetzlich
|
CSV-Export export_csv.py, wo sie fuer die Zuordnung in der Zeichnung
|
||||||
bleibt)."""
|
nuetzlich bleibt)."""
|
||||||
attribs = block.get("attribs", {})
|
attribs = block.get("attribs", {})
|
||||||
return {
|
return sivas_mapping.anwenden(SIVAS_MAPPING_GERUEST, attribs, TRANSFORMS)
|
||||||
"Farbe": attribs.get("FARBE", ""),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# --- Bekannte Bloecke ignorieren ---
|
# --- Bekannte Bloecke ignorieren ---
|
||||||
@@ -890,7 +883,7 @@ def lesbarer_dateiname(output_csv):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
if len(sys.argv) < 4:
|
if len(sys.argv) < 4:
|
||||||
print("Aufruf: python export_sivas.py <export_raw.json> <data_dir> <output.csv>")
|
print("Aufruf: python export_sivas.py <export_raw.json> <data_dir> <output.csv> [--mit-bezeichnung]")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
raw_json_path = sys.argv[1]
|
raw_json_path = sys.argv[1]
|
||||||
@@ -898,6 +891,7 @@ def main():
|
|||||||
# kommen aus ARTINR, nicht mehr aus dem Katalog. Argument bleibt fuer
|
# kommen aus ARTINR, nicht mehr aus dem Katalog. Argument bleibt fuer
|
||||||
# den Aufrufer (export.lsp) bestehen.
|
# den Aufrufer (export.lsp) bestehen.
|
||||||
output_csv = sys.argv[3]
|
output_csv = sys.argv[3]
|
||||||
|
mit_bezeichnung = "--mit-bezeichnung" in sys.argv[4:]
|
||||||
|
|
||||||
blocks = load_json(raw_json_path)
|
blocks = load_json(raw_json_path)
|
||||||
print(f"[export_sivas] {len(blocks)} Bloecke geladen.")
|
print(f"[export_sivas] {len(blocks)} Bloecke geladen.")
|
||||||
@@ -914,14 +908,16 @@ def main():
|
|||||||
# Zweite, lesbare Kopie fuer die manuelle Pruefung (Merkmalnummer +
|
# Zweite, lesbare Kopie fuer die manuelle Pruefung (Merkmalnummer +
|
||||||
# Bezeichnung aus cfg/Merkmalsstamm_in_Sivas.xlsx) - wird von Sivas
|
# Bezeichnung aus cfg/Merkmalsstamm_in_Sivas.xlsx) - wird von Sivas
|
||||||
# selbst NICHT eingelesen, nur output_csv ist der eigentliche Import.
|
# selbst NICHT eingelesen, nur output_csv ist der eigentliche Import.
|
||||||
merkmalstamm = lade_merkmalstamm()
|
# Nur bei explizitem --mit-bezeichnung-Schalter (Dialog CSV_EXPORT_KONFIG).
|
||||||
output_csv_lesbar = lesbarer_dateiname(output_csv)
|
if mit_bezeichnung:
|
||||||
with open(output_csv_lesbar, "w", encoding="utf-8") as f:
|
merkmalstamm = lade_merkmalstamm()
|
||||||
f.write(header + "\n")
|
output_csv_lesbar = lesbarer_dateiname(output_csv)
|
||||||
for item in items:
|
with open(output_csv_lesbar, "w", encoding="utf-8") as f:
|
||||||
details = details_mit_bezeichnung(item["details"], merkmalstamm)
|
f.write(header + "\n")
|
||||||
f.write(format_csv_line(item, details=details) + "\n")
|
for item in items:
|
||||||
print(f"[export_sivas] Lesbare Kopie geschrieben: {output_csv_lesbar}")
|
details = details_mit_bezeichnung(item["details"], merkmalstamm)
|
||||||
|
f.write(format_csv_line(item, details=details) + "\n")
|
||||||
|
print(f"[export_sivas] Lesbare Kopie geschrieben: {output_csv_lesbar}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -0,0 +1,132 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
sivas_mapping.py - Liest die Attribut->Sivas-Merkmal-Zuordnung aus
|
||||||
|
cfg/sivas.cfg und wendet sie auf ein Block-Attribut-Dict an.
|
||||||
|
|
||||||
|
Einzige Quelle fuer die "einfachen" build_*_details-Zuordnungen in
|
||||||
|
export_sivas.py (siehe cfg/sivas.cfg fuer das Zeilenformat und die
|
||||||
|
Begruendung, warum nur die einfachen Faelle hier landen).
|
||||||
|
"""
|
||||||
|
|
||||||
|
import configparser
|
||||||
|
import functools
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def cfg_path_from_env(default_dir=None):
|
||||||
|
"""Pfad zu sivas.cfg: DXFM_CFG env var, sonst <repo>/cfg."""
|
||||||
|
dxfm_cfg = os.environ.get("DXFM_CFG")
|
||||||
|
if dxfm_cfg:
|
||||||
|
return os.path.join(dxfm_cfg, "sivas.cfg")
|
||||||
|
base = default_dir or os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
return os.path.join(base, "cfg", "sivas.cfg")
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_wert(roh):
|
||||||
|
"""Zerlegt eine Config-Wertzeile "attribut|alt_attribut:default|transform"
|
||||||
|
in (attribut, alt_attribut_oder_None, default, transform_oder_None).
|
||||||
|
|
||||||
|
Reihenfolge beim Parsen: erst am ":" in (attributteil, defaultteil)
|
||||||
|
trennen (nur der erste ":" zaehlt, ein Default-Text soll selbst keinen
|
||||||
|
":" enthalten muessen), danach im defaultteil am LETZTEN "|" den
|
||||||
|
Transform-Namen abtrennen (ein Default-Text wie "ohne HARTCOAT..."
|
||||||
|
enthaelt kein "|"). attributteil wird am ERSTEN "|" in Attribut/
|
||||||
|
Fallback-Attribut gesplittet.
|
||||||
|
"""
|
||||||
|
roh = roh.strip()
|
||||||
|
if ":" in roh:
|
||||||
|
attribut_teil, rest = roh.split(":", 1)
|
||||||
|
else:
|
||||||
|
attribut_teil, rest = roh, ""
|
||||||
|
|
||||||
|
transform = None
|
||||||
|
default = rest.strip()
|
||||||
|
if "|" in rest:
|
||||||
|
default_teil, transform_teil = rest.rsplit("|", 1)
|
||||||
|
default = default_teil.strip()
|
||||||
|
transform = transform_teil.strip() or None
|
||||||
|
|
||||||
|
attribut_teil = attribut_teil.strip()
|
||||||
|
alt_attribut = None
|
||||||
|
if "|" in attribut_teil:
|
||||||
|
attribut, alt_attribut = (p.strip() for p in attribut_teil.split("|", 1))
|
||||||
|
else:
|
||||||
|
attribut = attribut_teil
|
||||||
|
alt_attribut = alt_attribut or None
|
||||||
|
|
||||||
|
return (attribut or None, alt_attribut, default, transform)
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=None)
|
||||||
|
def load_sivas_cfg(cfg_path):
|
||||||
|
"""Liest sivas.cfg einmal je Pfad (Prozess-Cache)."""
|
||||||
|
parser = configparser.ConfigParser(inline_comment_prefixes=None)
|
||||||
|
parser.optionxform = str # Keys (Merkmalnummern/Klartext-Keys) case-sensitive erhalten
|
||||||
|
parser.read(cfg_path, encoding="utf-8")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def load_section_mapping(section, cfg_path=None):
|
||||||
|
"""Liest einen Abschnitt aus sivas.cfg.
|
||||||
|
|
||||||
|
Rueckgabe: dict merkmal -> (attribut, alt_attribut, default, transform),
|
||||||
|
wie von _parse_wert geliefert. Bei fehlender Datei/Sektion: leeres dict -
|
||||||
|
Aufrufer bekommt dann einfach keine Merkmale aus der Config (bisheriges
|
||||||
|
Verhalten vor der Config-Einfuehrung, kein harter Fehler).
|
||||||
|
"""
|
||||||
|
if cfg_path is None:
|
||||||
|
cfg_path = cfg_path_from_env()
|
||||||
|
parser = load_sivas_cfg(cfg_path)
|
||||||
|
mapping = {}
|
||||||
|
if parser.has_section(section):
|
||||||
|
for merkmal, roh in parser.items(section):
|
||||||
|
mapping[merkmal] = _parse_wert(roh)
|
||||||
|
return mapping
|
||||||
|
|
||||||
|
|
||||||
|
def load_flat_mapping(section, cfg_path=None):
|
||||||
|
"""Liest einen Abschnitt als einfaches dict key -> value (z.B.
|
||||||
|
[geruest_typ_anzeige]: ASCII-Wert -> Sivas-Klartext), ohne das
|
||||||
|
attribut/default/transform-Format von load_section_mapping."""
|
||||||
|
if cfg_path is None:
|
||||||
|
cfg_path = cfg_path_from_env()
|
||||||
|
parser = load_sivas_cfg(cfg_path)
|
||||||
|
if parser.has_section(section):
|
||||||
|
return {k: v.strip() for k, v in parser.items(section)}
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
def anwenden(section_mapping, attribs, transforms):
|
||||||
|
"""Wendet eine per load_section_mapping() gelesene Zuordnung auf ein
|
||||||
|
Block-Attribut-Dict an.
|
||||||
|
|
||||||
|
transforms: dict transform_name -> Funktion(wert) -> wert. Ein in der
|
||||||
|
Config genannter, aber hier unbekannter Transform-Name wird ignoriert
|
||||||
|
(Rohwert bleibt unveraendert) statt abzubrechen - ein Tippfehler in
|
||||||
|
sivas.cfg darf den Export nicht zum Stillstand bringen.
|
||||||
|
|
||||||
|
Rueckgabe: dict merkmal -> wert. Ohne Transform wird der Rohwert zu str()
|
||||||
|
gewandelt (bisheriges Verhalten der build_*_details-Funktionen: alles
|
||||||
|
Merkmalnummer-Werte sind Strings). Ein Transform liefert seinen
|
||||||
|
Rueckgabewert UNVERAENDERT (z.B. build_eckrad_details erwartet fuer
|
||||||
|
"Geruest fuer Einzelmodul" ein echtes bool, kein "True"/"False"-String -
|
||||||
|
json.dumps schreibt dann true/false statt eines Strings).
|
||||||
|
"""
|
||||||
|
ergebnis = {}
|
||||||
|
for merkmal, (attribut, alt_attribut, default, transform) in section_mapping.items():
|
||||||
|
if attribut is not None:
|
||||||
|
wert = attribs.get(attribut)
|
||||||
|
if wert is None and alt_attribut is not None:
|
||||||
|
wert = attribs.get(alt_attribut)
|
||||||
|
if wert is None:
|
||||||
|
wert = default
|
||||||
|
else:
|
||||||
|
wert = default
|
||||||
|
if transform:
|
||||||
|
fn = transforms.get(transform)
|
||||||
|
if fn is not None:
|
||||||
|
ergebnis[merkmal] = fn(wert)
|
||||||
|
continue
|
||||||
|
ergebnis[merkmal] = str(wert)
|
||||||
|
return ergebnis
|
||||||
@@ -185,6 +185,16 @@
|
|||||||
(setq auto-export nil)
|
(setq auto-export nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
;; *export-test-override* (Lisp/export.lsp, csv:run-export) fuer die Dauer
|
||||||
|
;; des Automatik-Laufs setzen, damit c:EXPORTCSV/c:EXPORTSIVAS nach
|
||||||
|
;; tests/output statt in den normalen Ergebnisordner (DXFM_RESULTS)
|
||||||
|
;; schreiben - ein Testrun soll vollstaendig in tests/output landen.
|
||||||
|
;; Analog zu TEST_EXPORT_ALL (tests/test_export_all.lsp). WICHTIG:
|
||||||
|
;; Absichtlich KEIN (setenv "DXFM_RESULTS" ...), siehe dortiger Kommentar.
|
||||||
|
(if auto-export
|
||||||
|
(setq *export-test-override* tests-out-dir)
|
||||||
|
)
|
||||||
|
|
||||||
(princ "\n")
|
(princ "\n")
|
||||||
(princ "\n================================================================")
|
(princ "\n================================================================")
|
||||||
(princ "\n SSG_RUN_ALL_TESTS")
|
(princ "\n SSG_RUN_ALL_TESTS")
|
||||||
@@ -412,6 +422,8 @@
|
|||||||
;; GUI wieder einschalten (Batch fertig).
|
;; GUI wieder einschalten (Batch fertig).
|
||||||
(if (car (atoms-family 1 '("SSG-GUI-AN"))) (ssg-gui-an))
|
(if (car (atoms-family 1 '("SSG-GUI-AN"))) (ssg-gui-an))
|
||||||
|
|
||||||
|
(setq *export-test-override* nil)
|
||||||
|
|
||||||
(princ "\n\n================================================================")
|
(princ "\n\n================================================================")
|
||||||
(princ "\n SSG_RUN_ALL_TESTS abgeschlossen.")
|
(princ "\n SSG_RUN_ALL_TESTS abgeschlossen.")
|
||||||
(princ (strcat "\n Ergebnisse in: " (getenv "DXFMAKRO") "/tests/output/"))
|
(princ (strcat "\n Ergebnisse in: " (getenv "DXFMAKRO") "/tests/output/"))
|
||||||
|
|||||||
Reference in New Issue
Block a user