import csv import os import shutil from dataclasses import dataclass from datetime import datetime from pathlib import Path @dataclass(frozen=True) class MoveFilesResult: moved_count: int skipped_count: int missing_client_count: int @dataclass(frozen=True) class RefreshAndMoveResult: xml_count: int file_count: int moved_count: int skipped_count: int missing_client_count: int def default_desktop() -> Path: user_profile = Path(os.environ.get("USERPROFILE", str(Path.home()))) return user_profile / "Desktop" def read_csv(csv_path: Path) -> list[dict[str, str]]: if not csv_path.is_file(): raise ValueError(f"Die CSV-Datei existiert nicht: {csv_path}") with csv_path.open("r", newline="", encoding="latin-1") as csv_file: return list(csv.DictReader(csv_file, delimiter=";")) def rename_existing_target(target: Path) -> Path: created_at = datetime.fromtimestamp(target.stat().st_birthtime) timestamp = created_at.strftime("%Y%m%d-%H%M%S") renamed_target = target.with_name(f"{target.stem}_{timestamp}{target.suffix}") counter = 1 while renamed_target.exists(): renamed_target = target.with_name(f"{target.stem}_{timestamp}_{counter}{target.suffix}") counter += 1 target.rename(renamed_target) return renamed_target def move_files( files_csv: Path, clients_csv: Path, desktop_directory: Path | None = None, ) -> MoveFilesResult: desktop_directory = desktop_directory or default_desktop() client_rows = read_csv(clients_csv) client_names = { row.get("ParticipantName", "").strip(): row.get("Kunde", "").strip() for row in client_rows if row.get("ParticipantName", "").strip() and row.get("Kunde", "").strip() } moved_count = 0 skipped_count = 0 missing_client_count = 0 for row in read_csv(files_csv): participant_name = row.get("ParticipantName", "").strip() source = Path(row.get("FilePath", "").strip()) customer = client_names.get(participant_name) if not customer: missing_client_count += 1 continue if not source.is_file(): skipped_count += 1 continue target_directory = desktop_directory / "PC-Visit" / customer target_directory.mkdir(parents=True, exist_ok=True) target = target_directory / source.name if source.resolve() == target.resolve(): skipped_count += 1 continue if target.exists(): renamed_target = rename_existing_target(target) print(f"Vorhandene Datei umbenannt: {target} -> {renamed_target}") shutil.move(str(source), str(target)) print(f"Datei verschoben: {source} -> {target}") moved_count += 1 return MoveFilesResult( moved_count=moved_count, skipped_count=skipped_count, missing_client_count=missing_client_count, ) def refresh_and_move( directory: Path, files_csv: Path, clients_csv: Path, desktop_directory: Path | None = None, ignore_timestamp: bool = False, ) -> RefreshAndMoveResult: from files import run as run_files files_result = run_files(directory, files_csv, ignore_timestamp=ignore_timestamp) move_result = move_files(files_csv, clients_csv, desktop_directory) return RefreshAndMoveResult( xml_count=files_result.xml_count, file_count=files_result.row_count, moved_count=move_result.moved_count, skipped_count=move_result.skipped_count, missing_client_count=move_result.missing_client_count, )