Compare commits
11 Commits
02dfb69121
...
lauffähig
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc0db8496b | ||
|
|
b7730d908c | ||
|
|
bc67232628 | ||
|
|
acaaba7758 | ||
|
|
ccc764f198 | ||
|
|
aa12d099ae | ||
|
|
ccf6717e92 | ||
|
|
a2ea61e0f3 | ||
|
|
b8d90481bc | ||
|
|
2b4be16317 | ||
|
|
5d76c6b020 |
40
gui.py
40
gui.py
@@ -143,7 +143,7 @@ class GUI:
|
|||||||
self.button_frame = tk.Frame(self.root)
|
self.button_frame = tk.Frame(self.root)
|
||||||
self.button_frame.pack(side=tk.BOTTOM, fill=tk.X, pady=12)
|
self.button_frame.pack(side=tk.BOTTOM, fill=tk.X, pady=12)
|
||||||
|
|
||||||
# Durchsuchen Button (macOS-Style) - primärer Button (blau)
|
# Durchsuchen Button (macOS-Style) - primärer Standard-Button (blau)
|
||||||
self.browse_button = create_macos_button(self.button_frame, text="Durchsuchen", command=self.browse, width=14, default=True)
|
self.browse_button = create_macos_button(self.button_frame, text="Durchsuchen", command=self.browse, width=14, default=True)
|
||||||
self.browse_button.pack(side=tk.LEFT, padx=12, expand=True, pady=4)
|
self.browse_button.pack(side=tk.LEFT, padx=12, expand=True, pady=4)
|
||||||
|
|
||||||
@@ -151,7 +151,8 @@ class GUI:
|
|||||||
self.close_button = create_macos_button(self.button_frame, text="Abbruch", command=self.on_app_close, width=14)
|
self.close_button = create_macos_button(self.button_frame, text="Abbruch", command=self.on_app_close, width=14)
|
||||||
self.close_button.pack(side=tk.RIGHT, padx=12, expand=True, pady=4)
|
self.close_button.pack(side=tk.RIGHT, padx=12, expand=True, pady=4)
|
||||||
|
|
||||||
self.hint_label = tk.Label(self.root, text="Bitte wählen Sie den Ordner mit den Bilddaten aus!")
|
# Hinweis-Label mit angepasster Schriftgröße (wie Buttons: 13pt)
|
||||||
|
self.hint_label = tk.Label(self.root, text="Bitte wählen Sie den Ordner mit den Bilddaten aus!", font=('Helvetica', 13))
|
||||||
self.hint_label.pack(pady=5) # Pady hinzugefügt für etwas Abstand nach oben und unten
|
self.hint_label.pack(pady=5) # Pady hinzugefügt für etwas Abstand nach oben und unten
|
||||||
|
|
||||||
self.root.protocol("WM_DELETE_WINDOW", self.on_close)
|
self.root.protocol("WM_DELETE_WINDOW", self.on_close)
|
||||||
@@ -365,8 +366,8 @@ class JaAbbruchDialog(tk.Toplevel):
|
|||||||
self.transfer_folder = transfer_folder
|
self.transfer_folder = transfer_folder
|
||||||
|
|
||||||
self.title(title)
|
self.title(title)
|
||||||
self.geometry("900x500") # Größeres Fenster für bessere Lesbarkeit
|
self.geometry("950x520") # Größeres Fenster für bessere Lesbarkeit und passende Proportionen
|
||||||
self.minsize(850, 480) # Minimale Größe erhöht
|
self.minsize(900, 500) # Minimale Größe angepasst
|
||||||
|
|
||||||
# Hauptframe für besseres Layout
|
# Hauptframe für besseres Layout
|
||||||
main_frame = tk.Frame(self)
|
main_frame = tk.Frame(self)
|
||||||
@@ -505,8 +506,8 @@ class ConfirmKeepOriginalDialog(tk.Toplevel):
|
|||||||
self.transfer_folder = transfer_folder
|
self.transfer_folder = transfer_folder
|
||||||
|
|
||||||
self.title("Bestätigung")
|
self.title("Bestätigung")
|
||||||
self.geometry("900x620") # Größeres Fenster für vollständige Datenanzeige und bessere Lesbarkeit
|
self.geometry("1000x680") # Größeres Fenster für vollständige Datenanzeige und bessere Lesbarkeit
|
||||||
self.minsize(850, 600) # Minimale Größe erhöht
|
self.minsize(950, 650) # Minimale Größe erhöht
|
||||||
|
|
||||||
main_frame = tk.Frame(self)
|
main_frame = tk.Frame(self)
|
||||||
main_frame.pack(fill=tk.BOTH, expand=True, padx=40, pady=30)
|
main_frame.pack(fill=tk.BOTH, expand=True, padx=40, pady=30)
|
||||||
@@ -569,20 +570,20 @@ class ConfirmKeepOriginalDialog(tk.Toplevel):
|
|||||||
btn_frame = tk.Frame(main_frame)
|
btn_frame = tk.Frame(main_frame)
|
||||||
btn_frame.pack(pady=12)
|
btn_frame.pack(pady=12)
|
||||||
|
|
||||||
# Buttons (macOS-Style)
|
# Buttons (macOS-Style) - breiter für bessere Textlesbarkeit
|
||||||
# Primärer Button (blau) - empfohlene Aktion
|
# Primärer Button (blau) - empfohlene Aktion
|
||||||
tomedo_btn = create_macos_button(btn_frame, text="Tomedo-Daten verwenden",
|
tomedo_btn = create_macos_button(btn_frame, text="Tomedo-Daten verwenden",
|
||||||
command=self.on_use_tomedo, width=26, default=True)
|
command=self.on_use_tomedo, width=32, default=True)
|
||||||
tomedo_btn.pack(side=tk.LEFT, padx=8, pady=6)
|
tomedo_btn.pack(side=tk.LEFT, padx=8, pady=6)
|
||||||
|
|
||||||
# Sekundärer Button (grau)
|
# Sekundärer Button (grau)
|
||||||
keep_btn = create_macos_button(btn_frame, text="Original behalten",
|
keep_btn = create_macos_button(btn_frame, text="Original behalten",
|
||||||
command=self.on_keep_original, width=22)
|
command=self.on_keep_original, width=26)
|
||||||
keep_btn.pack(side=tk.LEFT, padx=8, pady=6)
|
keep_btn.pack(side=tk.LEFT, padx=8, pady=6)
|
||||||
|
|
||||||
# Sekundärer Button (grau)
|
# Sekundärer Button (grau)
|
||||||
cancel_btn = create_macos_button(btn_frame, text="Abbruch",
|
cancel_btn = create_macos_button(btn_frame, text="Abbruch",
|
||||||
command=self.on_cancel, width=18)
|
command=self.on_cancel, width=20)
|
||||||
cancel_btn.pack(side=tk.LEFT, padx=8, pady=6)
|
cancel_btn.pack(side=tk.LEFT, padx=8, pady=6)
|
||||||
|
|
||||||
self.center_window()
|
self.center_window()
|
||||||
@@ -651,24 +652,25 @@ class JaNeinAbbruchDialog(tk.Toplevel):
|
|||||||
|
|
||||||
self.title(title)
|
self.title(title)
|
||||||
|
|
||||||
self.geometry("420x180") # Angepasste Fenstergröße
|
self.geometry("480x190") # Kompakteres Fenster für bessere Lesbarkeit
|
||||||
tk.Label(self, text=self.message, font=('Helvetica', 13)).pack(pady=20)
|
self.minsize(450, 170) # Minimale Größe
|
||||||
|
tk.Label(self, text=self.message, font=('Helvetica', 13), wraplength=420).pack(pady=20)
|
||||||
|
|
||||||
btn_frame = tk.Frame(self)
|
btn_frame = tk.Frame(self)
|
||||||
btn_frame.pack(pady=12)
|
btn_frame.pack(pady=12)
|
||||||
|
|
||||||
# Buttons (macOS-Style)
|
# Buttons (macOS-Style) - minimale Breiten für bessere Lesbarkeit
|
||||||
# Primärer Button (blau) - Ja ist die primäre Aktion
|
# Primärer Button (blau) - Ja ist die primäre Aktion
|
||||||
ja_btn = create_macos_button(btn_frame, text="Ja", command=self.on_ja, width=16, default=True)
|
ja_btn = create_macos_button(btn_frame, text="Ja", command=self.on_ja, width=8, default=True)
|
||||||
ja_btn.pack(side=tk.LEFT, padx=10, pady=6)
|
ja_btn.pack(side=tk.LEFT, padx=8, pady=5)
|
||||||
|
|
||||||
# Sekundärer Button (grau)
|
# Sekundärer Button (grau)
|
||||||
nein_btn = create_macos_button(btn_frame, text="Nein", command=self.on_nein, width=16)
|
nein_btn = create_macos_button(btn_frame, text="Nein", command=self.on_nein, width=8)
|
||||||
nein_btn.pack(side=tk.LEFT, padx=10, pady=6)
|
nein_btn.pack(side=tk.LEFT, padx=8, pady=5)
|
||||||
|
|
||||||
# Sekundärer Button (grau)
|
# Sekundärer Button (grau)
|
||||||
abbruch_btn = create_macos_button(btn_frame, text="Abbruch", command=self.on_abbruch, width=16)
|
abbruch_btn = create_macos_button(btn_frame, text="Abbruch", command=self.on_abbruch, width=10)
|
||||||
abbruch_btn.pack(side=tk.LEFT, padx=10, pady=6)
|
abbruch_btn.pack(side=tk.LEFT, padx=8, pady=5)
|
||||||
|
|
||||||
self.center_window()
|
self.center_window()
|
||||||
|
|
||||||
|
|||||||
14
run_tests.sh
Executable file
14
run_tests.sh
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run_tests.sh - Führt die Python-Tests mit aktiviertem venv aus
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
# Aktiviere venv
|
||||||
|
if [ -d "venv" ]; then
|
||||||
|
source venv/bin/activate
|
||||||
|
python3 test_dicom2pacs.py
|
||||||
|
else
|
||||||
|
echo "FEHLER: venv nicht gefunden!"
|
||||||
|
echo "Bitte erstellen Sie ein venv: python3 -m venv venv"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -10,12 +10,46 @@ import tempfile
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# Füge Projektverzeichnis zum Python-Pfad hinzu
|
# Füge Projektverzeichnis zum Python-Pfad hinzu
|
||||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
project_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
sys.path.insert(0, project_dir)
|
||||||
|
|
||||||
|
# Versuche venv zu verwenden
|
||||||
|
venv_path = os.path.join(project_dir, 'venv')
|
||||||
|
python_version = f"{sys.version_info.major}.{sys.version_info.minor}"
|
||||||
|
|
||||||
|
if os.path.exists(venv_path):
|
||||||
|
# Füge venv site-packages zum Python-Pfad hinzu
|
||||||
|
site_packages = os.path.join(venv_path, 'lib', f'python{python_version}', 'site-packages')
|
||||||
|
if os.path.exists(site_packages):
|
||||||
|
sys.path.insert(0, site_packages)
|
||||||
|
|
||||||
|
# Versuche auch pydicom aus der gebauten App zu verwenden
|
||||||
|
app_path = os.path.join(project_dir, 'dist', 'dicom2pacs.app', 'Contents', 'Resources', 'lib', f'python{python_version}')
|
||||||
|
if os.path.exists(app_path):
|
||||||
|
sys.path.insert(0, app_path)
|
||||||
|
|
||||||
|
# Prüfe ob pydicom verfügbar ist, sonst gebe Hinweis
|
||||||
|
try:
|
||||||
|
import pydicom
|
||||||
|
except ImportError:
|
||||||
|
print("WARNUNG: pydicom nicht gefunden. Bitte venv aktivieren oder pydicom installieren:")
|
||||||
|
print(" source venv/bin/activate")
|
||||||
|
print(" pip install pydicom")
|
||||||
|
print("Oder Tests mit test_dicom2pacs.sh ausführen, das das venv automatisch aktiviert.\n")
|
||||||
|
|
||||||
def test_imports():
|
def test_imports():
|
||||||
"""Test ob alle Module importiert werden können"""
|
"""Test ob alle Module importiert werden können"""
|
||||||
print("Teste Imports...")
|
print("Teste Imports...")
|
||||||
try:
|
try:
|
||||||
|
# Versuche zuerst pydicom zu importieren, um zu prüfen ob es verfügbar ist
|
||||||
|
try:
|
||||||
|
import pydicom
|
||||||
|
except ImportError:
|
||||||
|
print("⚠ pydicom nicht gefunden - Tests können nicht vollständig ausgeführt werden")
|
||||||
|
print(" Bitte venv aktivieren: source venv/bin/activate")
|
||||||
|
print(" Oder Tests mit test_dicom2pacs.sh ausführen")
|
||||||
|
return False
|
||||||
|
|
||||||
import dicom_processing
|
import dicom_processing
|
||||||
import file_management
|
import file_management
|
||||||
import network_utils
|
import network_utils
|
||||||
@@ -24,12 +58,20 @@ def test_imports():
|
|||||||
return True
|
return True
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
print(f"✗ Import-Fehler: {e}")
|
print(f"✗ Import-Fehler: {e}")
|
||||||
|
print(" Tipp: Führen Sie die Tests mit test_dicom2pacs.sh aus, um das venv automatisch zu aktivieren")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def test_dicom_file_detection():
|
def test_dicom_file_detection():
|
||||||
"""Test DICOM-Datei-Erkennung"""
|
"""Test DICOM-Datei-Erkennung"""
|
||||||
print("\nTeste DICOM-Datei-Erkennung...")
|
print("\nTeste DICOM-Datei-Erkennung...")
|
||||||
try:
|
try:
|
||||||
|
# Prüfe ob pydicom verfügbar ist
|
||||||
|
try:
|
||||||
|
import pydicom
|
||||||
|
except ImportError:
|
||||||
|
print("⚠ pydicom nicht verfügbar - Test übersprungen")
|
||||||
|
return False
|
||||||
|
|
||||||
import dicom_processing
|
import dicom_processing
|
||||||
|
|
||||||
# Suche nach Test-DICOM-Dateien
|
# Suche nach Test-DICOM-Dateien
|
||||||
@@ -64,6 +106,13 @@ def test_file_management():
|
|||||||
"""Test Dateiverwaltung"""
|
"""Test Dateiverwaltung"""
|
||||||
print("\nTeste Dateiverwaltung...")
|
print("\nTeste Dateiverwaltung...")
|
||||||
try:
|
try:
|
||||||
|
# Prüfe ob pydicom verfügbar ist
|
||||||
|
try:
|
||||||
|
import pydicom
|
||||||
|
except ImportError:
|
||||||
|
print("⚠ pydicom nicht verfügbar - Test übersprungen")
|
||||||
|
return False
|
||||||
|
|
||||||
import file_management
|
import file_management
|
||||||
|
|
||||||
test_dir = os.path.expanduser("~/Downloads/test_dicom")
|
test_dir = os.path.expanduser("~/Downloads/test_dicom")
|
||||||
@@ -106,6 +155,13 @@ def test_patient_name_formatting():
|
|||||||
"""Test Patientenname-Formatierung"""
|
"""Test Patientenname-Formatierung"""
|
||||||
print("\nTeste Patientenname-Formatierung...")
|
print("\nTeste Patientenname-Formatierung...")
|
||||||
try:
|
try:
|
||||||
|
# Prüfe ob pydicom verfügbar ist (wird indirekt benötigt)
|
||||||
|
try:
|
||||||
|
import pydicom
|
||||||
|
except ImportError:
|
||||||
|
print("⚠ pydicom nicht verfügbar - Test übersprungen")
|
||||||
|
return False
|
||||||
|
|
||||||
import file_management
|
import file_management
|
||||||
|
|
||||||
# Test verschiedene Formate
|
# Test verschiedene Formate
|
||||||
@@ -132,6 +188,13 @@ def test_birthdate_formatting():
|
|||||||
"""Test Geburtsdatum-Formatierung"""
|
"""Test Geburtsdatum-Formatierung"""
|
||||||
print("\nTeste Geburtsdatum-Formatierung...")
|
print("\nTeste Geburtsdatum-Formatierung...")
|
||||||
try:
|
try:
|
||||||
|
# Prüfe ob pydicom verfügbar ist (wird indirekt benötigt)
|
||||||
|
try:
|
||||||
|
import pydicom
|
||||||
|
except ImportError:
|
||||||
|
print("⚠ pydicom nicht verfügbar - Test übersprungen")
|
||||||
|
return False
|
||||||
|
|
||||||
import file_management
|
import file_management
|
||||||
|
|
||||||
test_cases = [
|
test_cases = [
|
||||||
@@ -152,6 +215,81 @@ def test_birthdate_formatting():
|
|||||||
print(f"✗ Fehler: {e}")
|
print(f"✗ Fehler: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def test_upload_functionality():
|
||||||
|
"""Test Upload-Funktionalität"""
|
||||||
|
print("\nTeste Upload-Funktionalität...")
|
||||||
|
try:
|
||||||
|
import asyncio
|
||||||
|
import network_utils
|
||||||
|
|
||||||
|
# Lade Konfiguration
|
||||||
|
config_path = os.path.expanduser("~/.dicom2pacs.conf")
|
||||||
|
server_url = None
|
||||||
|
server_username = None
|
||||||
|
server_pw = None
|
||||||
|
|
||||||
|
if os.path.exists(config_path):
|
||||||
|
with open(config_path, 'r') as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if line.startswith('server_url='):
|
||||||
|
server_url = line.split('=', 1)[1]
|
||||||
|
elif line.startswith('server_username='):
|
||||||
|
server_username = line.split('=', 1)[1]
|
||||||
|
elif line.startswith('server_pw='):
|
||||||
|
server_pw = line.split('=', 1)[1]
|
||||||
|
|
||||||
|
if not server_url:
|
||||||
|
print("⚠ Keine Server-URL in Konfiguration gefunden - Upload-Test übersprungen")
|
||||||
|
print(" Bitte konfigurieren Sie die Server-URL in ~/.dicom2pacs.conf")
|
||||||
|
return True # Nicht kritisch, Test überspringen
|
||||||
|
|
||||||
|
# Test 1: Server-Verfügbarkeit prüfen
|
||||||
|
print(" Prüfe Server-Verfügbarkeit...")
|
||||||
|
try:
|
||||||
|
loop = asyncio.new_event_loop()
|
||||||
|
asyncio.set_event_loop(loop)
|
||||||
|
availability = loop.run_until_complete(network_utils.check_server_availability(server_url))
|
||||||
|
loop.close()
|
||||||
|
|
||||||
|
if availability:
|
||||||
|
print(f" ✓ Server ist erreichbar: {server_url}")
|
||||||
|
|
||||||
|
# Test 2: Prüfe ob Test-DICOM-Dateien vorhanden sind
|
||||||
|
test_dir = os.path.expanduser("~/Downloads/test_dicom")
|
||||||
|
if os.path.exists(test_dir):
|
||||||
|
import file_management
|
||||||
|
result = file_management.find_dicom_files(test_dir)
|
||||||
|
if result != 'non_found':
|
||||||
|
files, count = result
|
||||||
|
if count > 0:
|
||||||
|
print(f" ✓ {count} Test-DICOM-Dateien gefunden")
|
||||||
|
print(" ⚠ Upload-Test würde echte Dateien hochladen - wird übersprungen")
|
||||||
|
print(" (Für echten Upload-Test: Manuell mit test_dicom2pacs.sh durchführen)")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(" ⚠ Keine DICOM-Dateien im Test-Ordner")
|
||||||
|
else:
|
||||||
|
print(" ⚠ Keine DICOM-Dateien im Test-Ordner")
|
||||||
|
else:
|
||||||
|
print(" ⚠ Test-Ordner nicht gefunden: ~/Downloads/test_dicom")
|
||||||
|
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f" ⚠ Server ist nicht erreichbar: {server_url}")
|
||||||
|
print(" (Upload-Test kann nicht durchgeführt werden)")
|
||||||
|
return True # Nicht kritisch, Server könnte offline sein
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ⚠ Fehler beim Prüfen der Server-Verfügbarkeit: {e}")
|
||||||
|
return True # Nicht kritisch
|
||||||
|
|
||||||
|
except ImportError as e:
|
||||||
|
print(f"✗ Import-Fehler: {e}")
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
print(f"✗ Fehler: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Hauptfunktion für alle Tests"""
|
"""Hauptfunktion für alle Tests"""
|
||||||
print("=== dicom2pacs Automatisierte Tests ===\n")
|
print("=== dicom2pacs Automatisierte Tests ===\n")
|
||||||
@@ -163,6 +301,7 @@ def main():
|
|||||||
("Konfiguration", test_config_loading),
|
("Konfiguration", test_config_loading),
|
||||||
("Patientenname-Formatierung", test_patient_name_formatting),
|
("Patientenname-Formatierung", test_patient_name_formatting),
|
||||||
("Geburtsdatum-Formatierung", test_birthdate_formatting),
|
("Geburtsdatum-Formatierung", test_birthdate_formatting),
|
||||||
|
("Upload-Funktionalität", test_upload_functionality),
|
||||||
]
|
]
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
|
|||||||
Reference in New Issue
Block a user