main.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import os
  2. from pathlib import Path
  3. import typer
  4. from archive_logs import run as run_archive_logs
  5. from clients import run
  6. from files import run as run_files
  7. from move_files import default_desktop, refresh_and_move
  8. from summary import run as run_summary
  9. from watch import run as run_watch
  10. app = typer.Typer(help="PC-Visit Filetracker")
  11. DATA_DIRECTORY = Path("data")
  12. def default_session_history() -> Path:
  13. user_profile = Path(os.environ.get("USERPROFILE", str(Path.home())))
  14. return user_profile / "AppData" / "Roaming" / "pcvisit Data" / "Session History"
  15. @app.callback(invoke_without_command=True)
  16. def app_callback(context: typer.Context) -> None:
  17. """Verwalten der PC-Visit-Filetracker-Befehle."""
  18. if context.invoked_subcommand is None:
  19. typer.echo(context.get_help())
  20. @app.command("clients")
  21. def clients_command(
  22. directory: Path | None = typer.Argument(None, help="Verzeichnis mit XML-Dateien"),
  23. output: Path = typer.Option(DATA_DIRECTORY / "clients.csv", "--output", "-o", help="Zielpfad der CSV-Datei"),
  24. ) -> None:
  25. """Importiert Client-Daten aus Session-XML-Dateien."""
  26. directory = directory or default_session_history()
  27. try:
  28. result = run(directory, output)
  29. except ValueError as error:
  30. raise typer.BadParameter(str(error), param_hint="directory") from error
  31. typer.echo(f"{result.xml_count} XML-Dateien gelesen, {result.row_count} Einträge nach {output} geschrieben.")
  32. @app.command("files")
  33. def files_command(
  34. directory: Path | None = typer.Argument(None, help="Verzeichnis mit XML-Dateien"),
  35. output: Path = typer.Option(DATA_DIRECTORY / "files.csv", "--output", "-o", help="Zielpfad der CSV-Datei"),
  36. ignore_timestamp: bool = typer.Option(
  37. False,
  38. "--ignore-timestamp",
  39. help="Ignoriert den Abgleich des Erstellungsdatums mit der Session.",
  40. ),
  41. ) -> None:
  42. """Importiert vorhandene Dateien aus ReceivedFile-Elementen."""
  43. directory = directory or default_session_history()
  44. try:
  45. result = run_files(directory, output, ignore_timestamp=ignore_timestamp)
  46. except ValueError as error:
  47. raise typer.BadParameter(str(error), param_hint="directory") from error
  48. typer.echo(
  49. f"{result.xml_count} XML-Dateien gelesen, {result.row_count} vorhandene Dateien nach {output} geschrieben."
  50. )
  51. @app.command("move-files")
  52. def move_files_command(
  53. directory: Path | None = typer.Argument(None, help="Verzeichnis mit XML-Dateien"),
  54. files_csv: Path = typer.Option(
  55. DATA_DIRECTORY / "files.csv", "--files-csv", help="CSV-Datei mit den gefundenen Dateien"
  56. ),
  57. clients_csv: Path = typer.Option(DATA_DIRECTORY / "clients.csv", "--clients-csv", help="CSV-Datei mit den Kunden"),
  58. desktop: Path | None = typer.Option(None, "--desktop", help="Desktop-Verzeichnis als Zielbasis"),
  59. ignore_timestamp: bool = typer.Option(
  60. False,
  61. "--ignore-timestamp",
  62. help="Ignoriert den Abgleich des Erstellungsdatums mit der Session.",
  63. ),
  64. ) -> None:
  65. """Verschiebt gefundene Dateien in Desktop/PC-Visit/Kunde."""
  66. directory = directory or default_session_history()
  67. try:
  68. result = refresh_and_move(
  69. directory,
  70. files_csv,
  71. clients_csv,
  72. desktop or default_desktop(),
  73. ignore_timestamp,
  74. )
  75. except ValueError as error:
  76. raise typer.BadParameter(str(error)) from error
  77. typer.echo(
  78. f"{result.moved_count} Dateien verschoben, {result.skipped_count} übersprungen, "
  79. f"{result.missing_client_count} ohne Kunde."
  80. )
  81. @app.command("archive-logs")
  82. def archive_logs_command(
  83. directory: Path | None = typer.Argument(None, help="Verzeichnis mit XML-Dateien"),
  84. ) -> None:
  85. """Archiviert Session-XML-Dateien nach Jahr."""
  86. directory = directory or default_session_history()
  87. try:
  88. result = run_archive_logs(directory)
  89. except ValueError as error:
  90. raise typer.BadParameter(str(error), param_hint="directory") from error
  91. typer.echo(
  92. f"{result.checked_count} XML-Dateien geprüft, {result.archived_count} archiviert, "
  93. f"{result.skipped_count} übersprungen."
  94. )
  95. @app.command("summary")
  96. def summary_command(
  97. directory: Path | None = typer.Argument(None, help="Verzeichnis mit XML-Dateien"),
  98. output: Path = typer.Option(DATA_DIRECTORY / "summary.csv", "--output", "-o", help="Zielpfad der CSV-Datei"),
  99. ) -> None:
  100. """Erstellt eine Sitzungs- und Dauersumme pro Kunde."""
  101. directory = directory or default_session_history()
  102. try:
  103. result = run_summary(directory, output)
  104. except ValueError as error:
  105. raise typer.BadParameter(str(error), param_hint="directory") from error
  106. typer.echo(f"{result.xml_count} XML-Dateien geprüft, {result.customer_count} Kunden nach {output} geschrieben.")
  107. @app.command("watch")
  108. def watch_command(
  109. directory: Path | None = typer.Argument(None, help="Verzeichnis mit XML-Dateien"),
  110. files_csv: Path = typer.Option(
  111. DATA_DIRECTORY / "files.csv", "--files-csv", help="CSV-Datei mit den gefundenen Dateien"
  112. ),
  113. clients_csv: Path = typer.Option(DATA_DIRECTORY / "clients.csv", "--clients-csv", help="CSV-Datei mit den Kunden"),
  114. desktop: Path | None = typer.Option(None, "--desktop", help="Desktop-Verzeichnis als Zielbasis"),
  115. ignore_timestamp: bool = typer.Option(
  116. False,
  117. "--ignore-timestamp",
  118. help="Ignoriert den Abgleich des Erstellungsdatums mit der Session.",
  119. ),
  120. ) -> None:
  121. """Überwacht XML-Dateien und führt bei Änderungen move-files aus."""
  122. directory = directory or default_session_history()
  123. try:
  124. run_watch(directory, files_csv, clients_csv, desktop or default_desktop(), ignore_timestamp)
  125. except ValueError as error:
  126. raise typer.BadParameter(str(error), param_hint="directory") from error
  127. if __name__ == "__main__":
  128. app()