Skip to content

Commit

Permalink
Merge pull request #26 from vaneeko/refactor-mvc-architecture
Browse files Browse the repository at this point in the history
Refactor mvc architecture
  • Loading branch information
vaneeko authored Jul 19, 2024
2 parents ec7d5dc + 0b81e8b commit e63c928
Show file tree
Hide file tree
Showing 11 changed files with 435 additions and 195 deletions.
103 changes: 103 additions & 0 deletions api/endpoints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
from flask import Blueprint, request, jsonify
from werkzeug.utils import secure_filename
import os
from controllers.conversion_controller import handle_conversion_request
from config.default_config import DEFAULT_CONFIG

# Erstellen eines Blueprint für die API
api = Blueprint('api', __name__)

# Definieren des Upload-Ordners und Erstellen, falls er nicht existiert
UPLOAD_FOLDER = '/tmp/uploads'
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)

# Globale Variable für die aktuelle Konfiguration, initialisiert mit den Standardwerten
current_config = DEFAULT_CONFIG.copy()

@api.route('/convert', methods=['POST'])
def convert():
"""
Endpunkt zum Konvertieren von XTF-Dateien zu IFC.
Akzeptiert XTF-Dateien und optionale Konfigurationsparameter.
"""
if 'xtfFiles' not in request.files:
return jsonify({'error': 'Keine Dateien ausgewählt'}), 400

files = request.files.getlist('xtfFiles')

# Erstellen einer Kopie der aktuellen Konfiguration und Aktualisieren mit Werten aus der Anfrage
config = current_config.copy()
for key in config.keys():
if key in request.form:
config[key] = type(config[key])(request.form.get(key))

# Speichern der hochgeladenen Dateien
saved_files = []
for file in files:
if file and file.filename.endswith('.xtf'):
filename = secure_filename(file.filename)
file_path = os.path.join(UPLOAD_FOLDER, filename)
file.save(file_path)
saved_files.append(file_path)

# Durchführen der Konvertierung
result = handle_conversion_request(config, saved_files)

return jsonify(result)

@api.route('/config', methods=['GET'])
def get_config():
"""
Endpunkt zum Abrufen der aktuellen Konfiguration.
"""
return jsonify(current_config)

@api.route('/config', methods=['POST'])
def update_config():
"""
Endpunkt zum Aktualisieren mehrerer Konfigurationswerte gleichzeitig.
"""
global current_config
for key, value in request.json.items():
if key in current_config:
try:
# Versuche, den Wert in den korrekten Typ zu konvertieren
current_config[key] = type(current_config[key])(value)
except ValueError:
return jsonify({'error': f'Ungültiger Wert für {key}'}), 400
return jsonify(current_config), 200

@api.route('/config/reset', methods=['POST'])
def reset_config():
"""
Endpunkt zum Zurücksetzen der Konfiguration auf die Standardwerte.
"""
global current_config
current_config = DEFAULT_CONFIG.copy()
return jsonify(current_config), 200

@api.route('/config/<key>', methods=['GET'])
def get_config_value(key):
"""
Endpunkt zum Abrufen eines spezifischen Konfigurationswerts.
"""
if key in current_config:
return jsonify({key: current_config[key]})
return jsonify({'error': 'Konfigurationsschlüssel nicht gefunden'}), 404

@api.route('/config/<key>', methods=['PUT'])
def update_config_value(key):
"""
Endpunkt zum Aktualisieren eines spezifischen Konfigurationswerts.
"""
global current_config
if key in current_config:
try:
value = request.json.get('value')
# Konvertieren des Werts in den korrekten Typ
current_config[key] = type(current_config[key])(value)
return jsonify({key: current_config[key]})
except ValueError:
return jsonify({'error': 'Ungültiger Wert'}), 400
return jsonify({'error': 'Konfigurationsschlüssel nicht gefunden'}), 404
File renamed without changes.
45 changes: 29 additions & 16 deletions controllers/xtf_to_ifc.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,64 @@
import logging
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import shutil
from models.xtf_model import XTFParser
from models.ifc_model import create_ifc
from config.default_config import DEFAULT_CONFIG

def setup_logging():
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')

def read_config(config_file='config.txt'):
config = {}
config = DEFAULT_CONFIG.copy()
script_dir = os.path.dirname(os.path.abspath(__file__))
config_path = os.path.join(script_dir, config_file)
with open(config_path, 'r') as file:
for line in file:
name, value = line.strip().split('=')
config[name.strip()] = value.strip()
if os.path.exists(config_path):
with open(config_path, 'r') as file:
for line in file:
if '=' in line:
name, value = line.strip().split('=')
name = name.strip()
value = value.strip()
if name in DEFAULT_CONFIG:
# Convert to the same type as in DEFAULT_CONFIG
config[name] = type(DEFAULT_CONFIG[name])(value)
else:
config[name] = value
else:
logging.warning(f"Config file not found: {config_path}. Using default configuration.")
return config

def get_xtf_files(xtf_path):
if os.path.isdir(xtf_path):
return [os.path.join(xtf_path, file) for file in os.listdir(xtf_path) if file.endswith('.xtf')]
return [xtf_path]

def convert_xtf_to_ifc(xtf_file, ifc_file):
def convert_xtf_to_ifc(xtf_file, ifc_file, config):
parser = XTFParser()
data = parser.parse(xtf_file)
data = parser.parse(xtf_file, config)

create_ifc(ifc_file, data, data['defaults'][5])
create_ifc(ifc_file, data)
logging.info(f"IFC file saved: {ifc_file}")

def delete_pycache():
pycache_path = os.path.join(os.path.dirname(__file__), '__pycache__')
if os.path.exists(pycache_path):
shutil.rmtree(pycache_path)
logging.info(f"__pycache__ Ordner wurde gelöscht: {pycache_path}")
logging.info(f"__pycache__ folder deleted: {pycache_path}")

if __name__ == '__main__':
setup_logging()
logging.info("Programmstart")
logging.info("Program start")

config = read_config('config.txt')

xtf_path = config['xtf_files']
xtf_path = config.get('xtf_files', 'C:\\converter\\xtf\\')
xtf_files = get_xtf_files(xtf_path)
output_folder = config['output_folder']
output_folder = config.get('output_folder', 'C:\\converter\\')

if not os.path.exists(output_folder):
os.makedirs(output_folder)
Expand All @@ -55,12 +68,12 @@ def delete_pycache():
ifc_file_name = os.path.splitext(xtf_file_name)[0] + '.ifc'
ifc_file_path = os.path.join(output_folder, ifc_file_name)

logging.info(f"XTF-Dateipfad: {xtf_file_path}")
logging.info(f"IFC-Dateipfad: {ifc_file_path}")
logging.info(f"XTF file path: {xtf_file_path}")
logging.info(f"IFC file path: {ifc_file_path}")

try:
convert_xtf_to_ifc(xtf_file_path, ifc_file_path)
convert_xtf_to_ifc(xtf_file_path, ifc_file_path, config)
except Exception as e:
logging.error(f"Fehler bei der Konvertierung von XTF zu IFC: {e}", exc_info=True)
logging.error(f"Error during XTF to IFC conversion: {e}", exc_info=True)

delete_pycache()
2 changes: 1 addition & 1 deletion models/ifc_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def create_ifc_haltungen(ifc_file, data, site, context, haltungen_group):
einfaerben = data['einfaerben']

for haltung in haltungen:
innendurchmesser = haltung.get('durchmesser', default_durchmesser)
innendurchmesser = haltung.get('durchmesser')
outer_radius = (innendurchmesser / 2) + default_rohrdicke
inner_radius = innendurchmesser / 2

Expand Down
59 changes: 51 additions & 8 deletions utils/graphics_ns.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,39 @@ def create_ifc_normschacht(ifc_file, ns, abwasserknoten, facility, context, abwa
properties = {
"Bezeichnung": ns.get('bezeichnung', ''),
"Standortname": ns.get('standortname', ''),
"Höhe": str(hoehe),
"Durchmesser": str(breite),
"Höhe": '',
"Durchmesser": '',
"Funktion": ns.get('funktion', ''),
"Material": ns.get('material', ''),
"Sohlenkote": str(z_mitte)
"Sohlenkote": ''
}

# Fülle Höhe und Durchmesser nur, wenn sie vorhanden und nicht '0' sind
if ns.get('dimorg1') and ns.get('dimorg1') != '0':
properties["Höhe"] = ns['dimorg1']
if ns.get('dimorg2') and ns.get('dimorg2') != '0':
properties["Durchmesser"] = ns['dimorg2']

# Fülle die Sohlenkote nur, wenn sie in den originalen Daten vorhanden und gültig ist
if abwasserknoten:
kote = abwasserknoten.get('kote')
if kote is not None and kote != '' and kote != '0':
try:
float_kote = float(kote)
if float_kote != 0 and float_kote != data.get('default_sohlenkote', 0):
properties["Sohlenkote"] = str(float_kote)
except ValueError:
pass # Ungültiger Wert, ignorieren


# Erstelle Property Set
property_set = ifc_file.create_entity("IfcPropertySet",
GlobalId=generate_guid(),
Name="TBAKTZH STRE Schacht",
HasProperties=[create_property_single_value(ifc_file, key, value) for key, value in properties.items()]
)

# Verknüpfe das Property Set mit dem Schacht
ifc_file.create_entity("IfcRelDefinesByProperties",
GlobalId=generate_guid(),
RelatingPropertyDefinition=property_set,
Expand All @@ -114,15 +134,38 @@ def create_ifc_normschacht(ifc_file, ns, abwasserknoten, facility, context, abwa
fehlende_werte = 0
farbe = "Blau"
if einfaerben:
if ns.get('dimorg1') == '0' or ns.get('dimorg2') == '0':
# Prüfe Dimension1 (Höhe)
if ns.get('dimorg1') == '0' or not ns.get('dimorg1'):
fehlende_werte += 1
if not abwasserknoten or float(abwasserknoten.get('kote', 0)) == 0:

# Prüfe Dimension2 (Durchmesser)
if ns.get('dimorg2') == '0' or not ns.get('dimorg2'):
fehlende_werte += 1

# Prüfe Sohlenkote
if abwasserknoten:
kote = abwasserknoten.get('kote')
if kote is None or kote == '' or kote == '0':
fehlende_werte += 1
else:
try:
float_kote = float(kote)
if float_kote == 0 or float_kote == data.get('default_sohlenkote', 0):
fehlende_werte += 1
except ValueError:
fehlende_werte += 1
else:
# Wenn kein Abwasserknoten vorhanden ist
fehlende_werte += 1

farbe = "Grün"
if fehlende_werte == 1:
# Bestimme die Farbe basierend auf fehlenden Werten
if fehlende_werte == 0:
farbe = "Grün"
elif fehlende_werte == 1:
farbe = "Orange"
elif fehlende_werte >= 2:
else: # fehlende_werte >= 2
farbe = "Rot"

print(f"Fehlende Werte: {fehlende_werte}, Farbe: {farbe}") # Debugging-Ausgabe

add_color(ifc_file, schacht, farbe, context)
20 changes: 20 additions & 0 deletions views/static/css/Styles3.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ body {
text-shadow: 3px 3px 0 #FF0000, 6px 6px 0 #FF7F00, 9px 9px 0 #FFFF00, 12px 12px 0 #00FF00, 15px 15px 0 #0000FF, 18px 18px 0 #4B0082, 21px 21px 0 #8B00FF;
}

.switch-theme-buttons {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
}

.switch-theme-buttons .pixel-button {
padding: 8px 16px;
font-size: 0.8em; /* Kleinere Schriftgröße */
font-family: 'Press Start 2P', cursive;
color: white;
border: none;
background-color: #FF0000; /* Red */
transition: all 0.3s ease;
box-shadow: 0 4px 0 #C2185B, 0 8px 0 #880E4F;
position: relative;
top: 0;
}

.pixel-button {
padding: 15px 30px;
font-family: 'Press Start 2P', cursive;
Expand Down
20 changes: 20 additions & 0 deletions views/static/css/styles1.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ body {
text-shadow: 3px 3px 0 #2196F3, 6px 6px 0 #1565C0;
}

.switch-theme-buttons {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
}

.switch-theme-buttons .pixel-button {
padding: 8px 16px;
font-size: 0.8em; /* Kleinere Schriftgröße */
font-family: 'Press Start 2P', cursive;
color: white;
border: none;
background-color: #FF4081;
transition: all 0.3s ease;
box-shadow: 0 4px 0 #C2185B, 0 8px 0 #880E4F;
position: relative;
top: 0;
}

.pixel-button {
padding: 15px 30px;
font-family: 'Press Start 2P', cursive;
Expand Down
20 changes: 20 additions & 0 deletions views/static/css/styles2.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ body {
text-shadow: 3px 3px 0 #2196F3, 6px 6px 0 #1565C0;
}

.switch-theme-buttons {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
}

.switch-theme-buttons .pixel-button {
padding: 8px 16px;
font-size: 0.8em; /* Kleinere Schriftgröße */
font-family: 'Press Start 2P', cursive;
color: white;
border: none;
background-color: #E91E63;
transition: all 0.3s ease;
box-shadow: 0 4px 0 #C2185B, 0 8px 0 #880E4F;
position: relative;
top: 0;
}

.pixel-button {
padding: 15px 30px;
font-family: 'Press Start 2P', cursive;
Expand Down
Loading

0 comments on commit e63c928

Please sign in to comment.