Initial commit
This commit is contained in:
229
file_management.py
Executable file
229
file_management.py
Executable file
@@ -0,0 +1,229 @@
|
||||
import os
|
||||
import dicom_processing
|
||||
import asyncio
|
||||
import aiofiles
|
||||
import subprocess
|
||||
from shutil import copyfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def get_drive_type(path):
|
||||
try:
|
||||
result = subprocess.run(["/usr/sbin/diskutil", "info", path], capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
print(f"Fehler beim Zugriff auf Laufwerksinformationen für {path}")
|
||||
return 'Unbekannt'
|
||||
|
||||
# Überprüfung auf optische Laufwerke basierend auf 'Optical Drive Type'
|
||||
optical_drive_types = [
|
||||
'CD-ROM', 'CD-R', 'CD-RW', 'DVD-ROM', 'DVD-R', 'DVD-R DL',
|
||||
'DVD-RW', 'DVD+R', 'DVD+R DL', 'DVD+RW'
|
||||
]
|
||||
# Prüfen, ob einer der optischen Laufwerkstypen in der Ausgabe vorhanden ist
|
||||
if any(drive_type in result.stdout for drive_type in optical_drive_types):
|
||||
return 'CD-ROM'
|
||||
|
||||
# Überprüfung auf SSD
|
||||
if 'Solid State: Yes' in result.stdout:
|
||||
return 'SSD'
|
||||
|
||||
# Überprüfung auf HDD
|
||||
if 'Solid State: No' in result.stdout:
|
||||
return 'HDD'
|
||||
|
||||
# Füge hier weitere spezifische Überprüfungen ein, falls nötig
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Ermitteln des Laufwerkstyps: {e}")
|
||||
|
||||
return 'Unbekannt'
|
||||
|
||||
def check_for_cd_at_start():
|
||||
volumes_path = "/Volumes"
|
||||
for volume in os.listdir(volumes_path):
|
||||
full_path = os.path.join(volumes_path, volume)
|
||||
if get_drive_type(full_path) == 'CD-ROM':
|
||||
print(f"CD-ROM gefunden: {full_path}")
|
||||
return full_path
|
||||
return None
|
||||
|
||||
def eject_cd_if_volume_path(path):
|
||||
if get_drive_type(path) == 'CD-ROM':
|
||||
try:
|
||||
# Überprüfen, ob der Pfad existiert
|
||||
if os.path.exists(path):
|
||||
print(f"Der Pfad {path} beginnt mit /Volumes. Versuche, die CD auszuwerfen...")
|
||||
# Ausführen des Befehls zum Auswerfen der CD
|
||||
subprocess.run(["/usr/bin/drutil", "tray", "eject"], check=True)
|
||||
print("CD erfolgreich ausgeworfen.")
|
||||
else:
|
||||
print(f"Der Pfad {path} existiert nicht.")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Fehler beim Auswerfen der CD: {e}")
|
||||
else:
|
||||
print(f"Der Pfad {path} beginnt nicht mit /Volumes. Keine Aktion erforderlich.")
|
||||
|
||||
def find_dicom_files(source_folder):
|
||||
dicom_files = []
|
||||
for root, dirs, files in os.walk(source_folder):
|
||||
for file in files:
|
||||
if file.upper() == 'DICOMDIR': # Überprüfung, ob der Dateiname 'DICOMDIR' entspricht
|
||||
continue # Überspringt den aktuellen Iterationsschritt im Loop, wenn der Dateiname 'DICOMDIR' ist
|
||||
file_path = os.path.join(root, file)
|
||||
# Überprüft, ob die Datei eine .dcm oder .dicom Erweiterung hat oder wenn kein Punkt im Dateinamen ist (impliziert, dass es keine Dateierweiterung gibt), wird die is_dicom_file Funktion genutzt
|
||||
if file.endswith((".dcm", ".dicom")) or ('.' not in file):
|
||||
dicom_files.append(file_path)
|
||||
if not dicom_files: # Überprüft, ob die Liste leer ist
|
||||
return 'non_found'
|
||||
return dicom_files, len(dicom_files) # Rückgabe der Liste und der Anzahl der Dateien
|
||||
|
||||
def get_files_in_folder(transfer_folder):
|
||||
file_paths = []
|
||||
# Überprüfe, ob der Ordner existiert
|
||||
if os.path.exists(transfer_folder):
|
||||
# Durchlaufe alle Dateien im Ordner und füge ihre Pfade zur Liste hinzu
|
||||
for root, _, files in os.walk(transfer_folder):
|
||||
for file in files:
|
||||
file_paths.append(os.path.join(root, file))
|
||||
return file_paths
|
||||
else:
|
||||
print(f"Der Ordner '{transfer_folder}' existiert nicht.")
|
||||
return 'no_transfer_folder'
|
||||
|
||||
|
||||
|
||||
def next_dat_folder(transfer_folder):
|
||||
existing_folders = [d for d in os.listdir(transfer_folder) if os.path.isdir(os.path.join(transfer_folder, d))]
|
||||
dat_folders = sorted([d for d in existing_folders if d.startswith('dat_') and d[4:].isdigit()], key=lambda x: int(x[4:]))
|
||||
if dat_folders:
|
||||
last_number = int(dat_folders[-1][4:])
|
||||
new_folder = f"dat_{str(last_number + 1).zfill(2)}"
|
||||
else:
|
||||
new_folder = "dat_01"
|
||||
return os.path.join(transfer_folder, new_folder)
|
||||
|
||||
def get_latest_dat_folder(transfer_folder):
|
||||
existing_folders = [d for d in os.listdir(transfer_folder) if os.path.isdir(os.path.join(transfer_folder, d))]
|
||||
dat_folders = sorted([d for d in existing_folders if d.startswith('dat_') and d[4:].isdigit()], key=lambda x: int(x[4:]))
|
||||
if dat_folders:
|
||||
latest_folder = dat_folders[-1]
|
||||
else:
|
||||
latest_folder = None # Oder: return None, um anzuzeigen, dass kein Ordner existiert
|
||||
return os.path.join(transfer_folder, latest_folder) if latest_folder else None
|
||||
|
||||
|
||||
async def copy_dicom_files(dicom_files, source_folder, transfer_folder, progress_callback=None):
|
||||
if not os.path.exists(transfer_folder):
|
||||
os.makedirs(transfer_folder)
|
||||
destination_folder = next_dat_folder(transfer_folder)
|
||||
if not os.path.exists(destination_folder):
|
||||
os.makedirs(destination_folder)
|
||||
|
||||
if progress_callback:
|
||||
progress_callback(0, len(dicom_files))
|
||||
|
||||
file_counter = {} # Ein Dictionary, um die Zählung für jeden Dateinamen zu speichern
|
||||
|
||||
async def copy_file(source, dest_base):
|
||||
nonlocal file_counter
|
||||
filename = os.path.basename(source)
|
||||
# Bestimmen Sie die neue Dateinummer, falls der Dateiname bereits existiert
|
||||
count = file_counter.get(filename, 0)
|
||||
# Neuen Dateinamen mit fortlaufender Nummer erstellen
|
||||
new_filename = f"{Path(filename).stem}-{str(count).zfill(3)}{Path(filename).suffix}"
|
||||
dest = os.path.join(dest_base, new_filename)
|
||||
# Aktualisieren Sie den Zähler für diesen Dateinamen
|
||||
file_counter[filename] = count + 1
|
||||
|
||||
print(f"Kopieren startet: {source} -> {dest}")
|
||||
async with aiofiles.open(source, 'rb') as src_file, aiofiles.open(dest, 'wb') as dest_file:
|
||||
while True:
|
||||
content = await src_file.read(1024*1024) # Lese in 1MB Chunks
|
||||
if not content:
|
||||
break
|
||||
await dest_file.write(content)
|
||||
print(f"Kopieren abgeschlossen: {source} -> {dest}")
|
||||
if progress_callback:
|
||||
progress_callback(1, len(dicom_files))
|
||||
|
||||
drive_type = get_drive_type(source_folder)
|
||||
|
||||
# Anpassung des Semaphore-Wertes basierend auf dem Laufwerkstyp
|
||||
sem_value = 1 if drive_type == 'CD-ROM' else 10
|
||||
|
||||
sem = asyncio.Semaphore(sem_value)
|
||||
|
||||
async def sem_copy_file(file_path):
|
||||
async with sem:
|
||||
await copy_file(file_path, destination_folder)
|
||||
|
||||
tasks = [asyncio.create_task(sem_copy_file(file_path)) for file_path in dicom_files]
|
||||
|
||||
await asyncio.gather(*tasks)
|
||||
|
||||
# Setze den Fortschritt zurück oder melde den Abschluss
|
||||
if progress_callback:
|
||||
progress_callback(len(dicom_files), len(dicom_files))
|
||||
|
||||
|
||||
|
||||
def format_patient_name(full_name):
|
||||
name_parts = full_name.split('^')
|
||||
name = name_parts[0] if len(name_parts) > 0 else ""
|
||||
vorname = name_parts[1] if len(name_parts) > 1 else ""
|
||||
return name, vorname
|
||||
|
||||
def format_birthdate(birthdate):
|
||||
if not birthdate:
|
||||
print("Warnung: Kein Geburtsdatum angegeben")
|
||||
return None
|
||||
|
||||
birthdate_str = str(birthdate).strip()
|
||||
if len(birthdate_str) == 8:
|
||||
return f"{birthdate_str[6:8]}.{birthdate_str[4:6]}.{birthdate_str[0:4]}"
|
||||
else:
|
||||
print(f"Ungültiges Geburtsdatum-Format: {birthdate_str}. Erwartetes Format: YYYYMMDD")
|
||||
return None
|
||||
|
||||
def compare_patient_info(name, vorname, geburtsdatum, name_source, vorname_source, geburtsdatum_source):
|
||||
# Vergleiche jede Komponente der Patienteninformationen
|
||||
is_name_match = (name == name_source)
|
||||
is_vorname_match = (vorname == vorname_source)
|
||||
is_geburtsdatum_match = (geburtsdatum == geburtsdatum_source)
|
||||
|
||||
# Überprüfe, ob alle Komponenten übereinstimmen
|
||||
is_complete_match = is_name_match and is_vorname_match and is_geburtsdatum_match
|
||||
|
||||
# Rückgabe der Ergebnisse
|
||||
return {
|
||||
'is_complete_match': is_complete_match,
|
||||
'is_name_match': is_name_match,
|
||||
'is_vorname_match': is_vorname_match,
|
||||
'is_geburtsdatum_match': is_geburtsdatum_match
|
||||
}
|
||||
|
||||
def write_to_file(acq_date, modality, filename):
|
||||
if not acq_date or not modality:
|
||||
print("Warnung: Unvollständige Daten für Ausgabedatei")
|
||||
return
|
||||
|
||||
if len(acq_date) < 8:
|
||||
print(f"Warnung: Ungültiges Datumsformat: {acq_date}")
|
||||
return
|
||||
|
||||
formatted_date = f"{acq_date[6:8]}.{acq_date[4:6]}.{acq_date[0:4]}"
|
||||
print(f"Versuche, Daten in {filename} zu schreiben...")
|
||||
|
||||
try:
|
||||
# Stelle sicher, dass das Verzeichnis existiert
|
||||
os.makedirs(os.path.dirname(filename) if os.path.dirname(filename) else '.', exist_ok=True)
|
||||
with open(filename, "a", encoding='utf-8') as file:
|
||||
file.write(f"{modality} vom {formatted_date}\n")
|
||||
print(f"Daten erfolgreich in {filename} geschrieben.")
|
||||
except IOError as e:
|
||||
print(f"Fehler beim Schreiben in die Datei {filename}: {e}")
|
||||
except OSError as e:
|
||||
print(f"OS-Fehler beim Schreiben in die Datei {filename}: {e}")
|
||||
except Exception as e:
|
||||
print(f"Ein unerwarteter Fehler ist aufgetreten: {e}")
|
||||
|
||||
Reference in New Issue
Block a user