utils.py mit eingecheckt. Beispieldatei aus Config erzeugen.
This commit is contained in:
+191
@@ -0,0 +1,191 @@
|
||||
"""
|
||||
Common utility functions for the cable routing system.
|
||||
|
||||
This module contains frequently used helper functions for:
|
||||
- File and path operations
|
||||
- Environment variable handling
|
||||
- JSON operations
|
||||
- DXF file handling
|
||||
- Dictionary operations
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any, Tuple
|
||||
|
||||
import ezdxf
|
||||
from ezdxf.lldxf.const import DXFStructureError
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# File Operations
|
||||
# ============================================================================
|
||||
|
||||
def check_file_in_work(work_dir, filename) -> Tuple[Path, bool]:
|
||||
"""
|
||||
Check if a file exists, either at the given path or in the work directory.
|
||||
|
||||
Args:
|
||||
work_dir: Working directory to check if file not found at filename path (str or Path)
|
||||
filename: Path to the file to check (str or Path)
|
||||
|
||||
Returns:
|
||||
Tuple of (resolved_path, exists_flag)
|
||||
- resolved_path: Path where file was found (or would be)
|
||||
- exists_flag: True if file exists, False otherwise
|
||||
"""
|
||||
work_dir = Path(work_dir)
|
||||
filename = Path(filename)
|
||||
|
||||
fexists = True
|
||||
if not filename.exists():
|
||||
mypath = work_dir.joinpath(filename)
|
||||
if not mypath.exists():
|
||||
fexists = False
|
||||
else:
|
||||
mypath = filename
|
||||
return mypath, fexists
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Environment Variable Operations
|
||||
# ============================================================================
|
||||
|
||||
def check_environment_var(env_str: str) -> Path:
|
||||
"""
|
||||
Get and validate an environment variable as a Path.
|
||||
|
||||
Args:
|
||||
env_str: Name of the environment variable
|
||||
|
||||
Returns:
|
||||
Path object from the environment variable
|
||||
|
||||
Exits:
|
||||
Exits the program if the environment variable is not set or empty
|
||||
"""
|
||||
out_path = os.environ.get(env_str)
|
||||
if out_path:
|
||||
return Path(out_path)
|
||||
else:
|
||||
print(f"Umgebungsvariable {env_str} ist nicht gesetzt oder leer.")
|
||||
exit()
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# JSON Operations
|
||||
# ============================================================================
|
||||
|
||||
def to_json(d: Any, pretty: bool = True) -> str:
|
||||
"""
|
||||
Convert a Python object to a JSON string.
|
||||
|
||||
Args:
|
||||
d: Object to convert to JSON
|
||||
pretty: If True, format with indentation for readability
|
||||
|
||||
Returns:
|
||||
JSON string representation of the object
|
||||
|
||||
Note:
|
||||
Uses ensure_ascii=False to properly display German umlauts (ä, ö, ü)
|
||||
"""
|
||||
return json.dumps(d, indent=2 if pretty else None, ensure_ascii=False, default=str)
|
||||
|
||||
|
||||
def load_json(jsonfilename: str) -> dict:
|
||||
"""
|
||||
Load JSON data from a file.
|
||||
|
||||
Args:
|
||||
jsonfilename: Path to the JSON file
|
||||
|
||||
Returns:
|
||||
Parsed JSON data as a dictionary
|
||||
"""
|
||||
with open(jsonfilename, encoding='utf-8') as fh:
|
||||
return json.load(fh)
|
||||
|
||||
|
||||
def write_results(jsn_results: str, out_dir: Path, filename: str) -> None:
|
||||
"""
|
||||
Write JSON results to a file.
|
||||
|
||||
Args:
|
||||
jsn_results: JSON string to write
|
||||
out_dir: Output directory path
|
||||
filename: Name of the output file
|
||||
"""
|
||||
print("writing results to a json file ...")
|
||||
outfile = Path(out_dir) / filename
|
||||
with open(outfile, 'w', encoding='utf-8') as fh:
|
||||
fh.write(jsn_results)
|
||||
print("done")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# DXF File Operations
|
||||
# ============================================================================
|
||||
|
||||
def dxf_is_binary(dxf_path: Path) -> bool:
|
||||
"""
|
||||
Check if a DXF file is in binary format.
|
||||
|
||||
Args:
|
||||
dxf_path: Path to the DXF file
|
||||
|
||||
Returns:
|
||||
True if the file is a binary DXF, False otherwise
|
||||
"""
|
||||
with open(dxf_path, 'rb') as f:
|
||||
header = f.read(22)
|
||||
return b'AutoCAD Binary DXF' in header
|
||||
|
||||
|
||||
def get_dxf_file(filepath: Path):
|
||||
"""
|
||||
Load a DXF file using ezdxf.
|
||||
|
||||
Args:
|
||||
filepath: Path to the DXF file
|
||||
|
||||
Returns:
|
||||
ezdxf Drawing object
|
||||
|
||||
Exits:
|
||||
Exits with code 1 for I/O errors
|
||||
Exits with code 2 for invalid/corrupted DXF files
|
||||
"""
|
||||
try:
|
||||
print("reading file ..", end='')
|
||||
doc = ezdxf.filemanagement.readfile(filepath)
|
||||
print("done")
|
||||
except IOError:
|
||||
print("Not a DXF file or a generic I/O error.")
|
||||
sys.exit(1)
|
||||
except DXFStructureError:
|
||||
print("Invalid or corrupted DXF file.")
|
||||
sys.exit(2)
|
||||
return doc
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Dictionary Operations
|
||||
# ============================================================================
|
||||
|
||||
def merge_two_dicts(x: dict, y: dict) -> dict:
|
||||
"""
|
||||
Merge two dictionaries, with values from y overwriting those in x.
|
||||
|
||||
Args:
|
||||
x: First dictionary (base)
|
||||
y: Second dictionary (override values)
|
||||
|
||||
Returns:
|
||||
New dictionary with merged values
|
||||
"""
|
||||
z = x.copy()
|
||||
z.update(y)
|
||||
return z
|
||||
Reference in New Issue
Block a user