gc-server3 1 周之前
當前提交
476d3aa89b
共有 15 個文件被更改,包括 1180 次插入0 次删除
  1. 10 0
      .gitignore
  2. 1 0
      .python-version
  3. 114 0
      .vscode/.ropeproject/config.py
  4. 二進制
      .vscode/.ropeproject/objectdb
  5. 14 0
      .vscode/launch.json
  6. 52 0
      .vscode/settings.json
  7. 0 0
      README.md
  8. 255 0
      clients.csv
  9. 122 0
      clients.py
  10. 438 0
      clients_v1.csv
  11. 38 0
      main.py
  12. 9 0
      pyproject.toml
  13. 23 0
      samples/2026-07-30-104742_34843777.xml
  14. 5 0
      tox.ini
  15. 99 0
      uv.lock

+ 10 - 0
.gitignore

@@ -0,0 +1,10 @@
+# Python-generated files
+__pycache__/
+*.py[oc]
+build/
+dist/
+wheels/
+*.egg-info
+
+# Virtual environments
+.venv

+ 1 - 0
.python-version

@@ -0,0 +1 @@
+3.13

+ 114 - 0
.vscode/.ropeproject/config.py

@@ -0,0 +1,114 @@
+# The default ``config.py``
+# flake8: noqa
+
+
+def set_prefs(prefs):
+    """This function is called before opening the project"""
+
+    # Specify which files and folders to ignore in the project.
+    # Changes to ignored resources are not added to the history and
+    # VCSs.  Also they are not returned in `Project.get_files()`.
+    # Note that ``?`` and ``*`` match all characters but slashes.
+    # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
+    # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
+    # '.svn': matches 'pkg/.svn' and all of its children
+    # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
+    # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
+    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
+                                  '.hg', '.svn', '_svn', '.git', '.tox']
+
+    # Specifies which files should be considered python files.  It is
+    # useful when you have scripts inside your project.  Only files
+    # ending with ``.py`` are considered to be python files by
+    # default.
+    # prefs['python_files'] = ['*.py']
+
+    # Custom source folders:  By default rope searches the project
+    # for finding source folders (folders that should be searched
+    # for finding modules).  You can add paths to that list.  Note
+    # that rope guesses project source folders correctly most of the
+    # time; use this if you have any problems.
+    # The folders should be relative to project root and use '/' for
+    # separating folders regardless of the platform rope is running on.
+    # 'src/my_source_folder' for instance.
+    # prefs.add('source_folders', 'src')
+
+    # You can extend python path for looking up modules
+    # prefs.add('python_path', '~/python/')
+
+    # Should rope save object information or not.
+    prefs['save_objectdb'] = True
+    prefs['compress_objectdb'] = False
+
+    # If `True`, rope analyzes each module when it is being saved.
+    prefs['automatic_soa'] = True
+    # The depth of calls to follow in static object analysis
+    prefs['soa_followed_calls'] = 0
+
+    # If `False` when running modules or unit tests "dynamic object
+    # analysis" is turned off.  This makes them much faster.
+    prefs['perform_doa'] = True
+
+    # Rope can check the validity of its object DB when running.
+    prefs['validate_objectdb'] = True
+
+    # How many undos to hold?
+    prefs['max_history_items'] = 32
+
+    # Shows whether to save history across sessions.
+    prefs['save_history'] = True
+    prefs['compress_history'] = False
+
+    # Set the number spaces used for indenting.  According to
+    # :PEP:`8`, it is best to use 4 spaces.  Since most of rope's
+    # unit-tests use 4 spaces it is more reliable, too.
+    prefs['indent_size'] = 4
+
+    # Builtin and c-extension modules that are allowed to be imported
+    # and inspected by rope.
+    prefs['extension_modules'] = []
+
+    # Add all standard c-extensions to extension_modules list.
+    prefs['import_dynload_stdmods'] = True
+
+    # If `True` modules with syntax errors are considered to be empty.
+    # The default value is `False`; When `False` syntax errors raise
+    # `rope.base.exceptions.ModuleSyntaxError` exception.
+    prefs['ignore_syntax_errors'] = False
+
+    # If `True`, rope ignores unresolvable imports.  Otherwise, they
+    # appear in the importing namespace.
+    prefs['ignore_bad_imports'] = False
+
+    # If `True`, rope will insert new module imports as
+    # `from <package> import <module>` by default.
+    prefs['prefer_module_from_imports'] = False
+
+    # If `True`, rope will transform a comma list of imports into
+    # multiple separate import statements when organizing
+    # imports.
+    prefs['split_imports'] = False
+
+    # If `True`, rope will remove all top-level import statements and
+    # reinsert them at the top of the module when making changes.
+    prefs['pull_imports_to_top'] = True
+
+    # If `True`, rope will sort imports alphabetically by module name instead
+    # of alphabetically by import statement, with from imports after normal
+    # imports.
+    prefs['sort_imports_alphabetically'] = False
+
+    # Location of implementation of
+    # rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general
+    # case, you don't have to change this value, unless you're an rope expert.
+    # Change this value to inject you own implementations of interfaces
+    # listed in module rope.base.oi.type_hinting.providers.interfaces
+    # For example, you can add you own providers for Django Models, or disable
+    # the search type-hinting in a class hierarchy, etc.
+    prefs['type_hinting_factory'] = (
+        'rope.base.oi.type_hinting.factory.default_type_hinting_factory')
+
+
+def project_opened(project):
+    """This function is called after opening the project"""
+    # Do whatever you like here!

二進制
.vscode/.ropeproject/objectdb


+ 14 - 0
.vscode/launch.json

@@ -0,0 +1,14 @@
+{
+    // Use IntelliSense to learn about possible attributes.
+    // Hover to view descriptions of existing attributes.
+    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Python: Aktuelle Datei",
+            "type": "debugpy",
+            "request": "launch",
+            "program": "${file}"
+        }
+    ]
+}

+ 52 - 0
.vscode/settings.json

@@ -0,0 +1,52 @@
+{
+    "[python]": {
+        "editor.defaultFormatter": "ms-python.black-formatter",
+        "editor.formatOnSave": true,
+        "editor.codeActionsOnSave": {
+            "source.organizeImports": "explicit",
+        },
+    },
+    "isort.args":["--profile", "black"],
+    "black-formatter.args": ["--line-length", "120"],
+    "python.testing.pytestEnabled": true,
+    "python.testing.unittestEnabled": false,
+    "files.associations": {
+        "*.mac": "vbs"
+    },
+    "python.testing.autoTestDiscoverOnSaveEnabled": true,
+    "sqltools.connections": [
+        {
+            "mssqlOptions": {
+                "appName": "SQLTools",
+                "useUTC": true,
+                "encrypt": true
+            },
+            "previewLimit": 50,
+            "server": "localhost",
+            "port": 1433,
+            "driver": "MSSQL",
+            "name": "localhost\\GLOBALCUBE",
+            "database": "LOCOSOFT",
+            "username": "sa",
+            "password": "Mffu3011#"
+        },
+        {
+            "mssqlOptions": {
+                "appName": "SQLTools",
+                "useUTC": true,
+                "encrypt": true
+            },
+            "previewLimit": 50,
+            "server": "sievers-group",
+            "port": 1433,
+            "driver": "MSSQL",
+            "name": "sievers-group\\GLOBALCUBE",
+            "database": "GC",
+            "username": "sa",
+            "password": "Mffu3011#"
+        }
+    ],
+    "chat.tools.terminal.autoApprove": {
+        "uv": true
+    },
+}

+ 0 - 0
README.md


+ 255 - 0
clients.csv

@@ -0,0 +1,255 @@
+ParticipantName;ClientName;StartTime;Kunde
+adglobalcube (gwmis1);Güma Wertheim C7 Filaks WS19 (gwmis1);2024-05-29T17:56:46;Guema Wertheim C7
+adm-gaps (MZSGAPS);Delta C7 OPTIMA WS22 (MZSGAPS);2026-07-15T13:40:15;Delta C7
+admin.ebber (SRV-WIN-KOMSRV1);Ebber C7 Audev WS25 (SRV-WIN-KOMSRV1);2026-08-10T15:17:20;Ebber C7
+adminclaris (SERVER07);Cordes C7 Optima WS19 (SERVER07#50);2026-07-15T12:25:53;Cordes C7
+admingc (SRVMVCGC01);MVC Wien C7 neuer Server SRVMVCGC01;2026-07-15T17:16:10;MVC Wien C7
+Administrator (AHK-HRF);Kieschnick C7 Optima WS16 (AHK-HRF);2026-07-15T17:00:02;Kieschnick C7
+administrator (AHMS-GC);Schmidt Starnberg C7/C11 Navision/ARI WS19 (AHMS-GC);2025-10-22T18:10:22;Schmidt Starnberg C7
+administrator (AHN-APP01);Neustadt C7 Carlo WS19 (AHN-APP01#9);2024-06-07T09:15:38;Neustadt C7
+administrator (App);Tretter C7 CARLO/DATEV WS22 (App#28);2026-01-21T19:36:30;Tretter C7
+administrator (appl157102);Fluegel C7 Optima WS12 (appl157102#6);2023-11-29T09:45:28;Fluegel C7
+administrator (APPL157122);Fluegel C7 OPTIMA WS19 (APPL157122);2026-07-15T14:04:16;Fluegel C7
+administrator (APPL194612);König & Partner C7 Optima WS19 (APPL194612);2023-11-02T14:09:27;Koenig u. Partner C7
+administrator (APPL203621);Barbarossa OPTIMA C7 WS22 (APPL203621);2026-07-15T12:24:40;Barbarossa OPTIMA C7
+Administrator (AWDE014511);Schmidt Wilhelmshafen C7 Optima WS12 (AWDE014511#1);2023-11-24T11:07:20;Schmidt Wilhelmshafen C7
+administrator (AWDE117801);Meures C7 Optima WS22 (AWDE117801#0);2023-11-23T18:13:45;Meures C7
+administrator (CODE192901);Hannuschka C7 Optima WS08 (CODE192901#0);2023-11-24T09:54:19;Hannuschka C7
+Administrator (cognos-12-0-2);cognos-12-0-2;2024-10-10T11:41:46;cognos-12-0-2
+Administrator (Cube-New);Zobjack C7 Optima WS19;2024-10-22T12:41:58;Zobjack C7
+Administrator (CZ-WN-ClobalCube);Czeczelits C7 Optima WS16 (CZ-WN-ClobalCube#8);2023-10-10T15:22:15;Czeczelits C7
+administrator (CZ-WN-GlobalMgmt);Czeczelits C11 OPTIMA WS16;2026-06-08T12:12:25;Czeczelits C11
+Administrator (DADE195101);Altermann C7 Optima WS16 (DADE195101);2024-05-28T13:04:11;Altermann C7
+administrator (DC2);Arndt C7 Optima/Dracar+ WS19 (DC2#14);2026-07-15T12:20:56;Arndt C7
+administrator (DE0289N3);Bieling C7 Optima WS16 (DE0289N3#4);2023-12-11T12:21:08;Bieling C7
+administrator (DE0509-GAPS);Siebrecht C7 Optima WS16 (DE0509-GAPS#2);2024-02-01T09:55:53;Siebrecht C7
+administrator (DE1165T1);Guenther & Schmitt C7 Carlo WS12 (DE1165T1#2);2021-06-23T10:03:28;Guenther u. Schmitt C7
+Administrator (de1673n1);Limburg C7 Optima WS08 (de1673n1#4);2023-12-13T08:41:36;Limburg C7
+Administrator (EADE072411);Röll C7 Optima WS12 (EADE072411#6);2024-07-08T15:00:42;Roell C7
+Administrator (FINDE112741);König Berlin C7 Optima WS19 (FINDE112741);2022-06-23T17:10:41;Koenig Berlin C7
+administrator (GAPSDE444401);Dresen C7 Optima WS08 (GAPSDE444401#4);2022-08-01T10:31:17;Dresen C7
+administrator (GAPSDE444441);Dresen C7 Optima WS19(GAPSDE444441);2023-11-20T10:45:53;Dresen C7
+Administrator (GAPSDE444441);Dresen C7 Optima WS19(GAPSDE444441);2026-07-20T13:58:31;Dresen C7
+administrator (GC-SRV-01);Jonas C7 Optima WS22 (GC-SRV-01);2023-11-24T10:00:45;Jonas C7
+administrator (GC01);Ulmen C7 Carlo WS12 (GC01#5);2024-04-24T11:29:56;Ulmen C7
+Administrator (GCDE073502);Brass C11 OPTIMA Win10 (GCDE073502);2022-06-03T10:57:41;Brass C11
+administrator (Global-Cube);Hermann C11 WERWISO WS19;2024-01-19T09:46:42;Hermann C11
+Administrator (global-cube);Ley Bergneustadt C11 OPTIMA Win10 NUC;2025-08-13T10:44:11;Ley Bergneustadt C11
+administrator (Global-Cube-VM);Barth & Frey C11 OPTIMA_SKR51 WS16  (Global-Cube-VM#8);2025-04-17T09:38:11;Barth u. Frey C11
+Administrator (Global-Cube-VM);Barth & Frey C11 OPTIMA_SKR51 WS16  (Global-Cube-VM#8);2023-12-12T09:18:31;Barth u. Frey C11
+Administrator (global-cube1);Greiner C11 LOCOSOFT WS12;2024-03-28T18:45:33;Greiner C11
+administrator (global-cube2);Guenther u. Schmitt C11 CARLO WS16;2026-06-11T15:40:02;Guenther u. Schmitt C11
+administrator (global-cube6);Auto Epple Opel SKR51 C11 CARLO WS22;2025-11-19T14:19:07;Auto Epple Opel SKR51 C11
+administrator (globalcube);Aurego C7 Optima WS22 (globalcube#0);2024-06-03T11:25:05;Aurego C7
+Administrator (GlobalCube);Gottwald C7 Autosys/Dagosoft Win10 (GlobalCube#7);2026-07-15T14:27:36;Gottwald C7
+Administrator (globalcube);Aurego C7 Optima WS22 (globalcube#0);2025-07-17T20:38:06;Aurego C7
+Administrator (GMExchange);Fricke C7 Optima WS12 (GMExchange);2026-07-15T14:08:57;Fricke C7
+Administrator (MGS-BI);MGS  C7 Autosys Win10;2024-02-01T09:51:37;MGS  C7
+Administrator (PC121);Hannuschka Interims-PC (PC121#004);2024-05-21T09:55:27;Hannuschka Interims-PC (PC121#004)
+administrator (PCP-vApp);Premium Cars C7 Autosys WS12 (PCP-vApp);2025-02-12T14:38:50;Premium Cars C7
+Administrator (SERVER07);Cordes C7 Optima WS19 (SERVER07#50);2023-12-13T08:36:30;Cordes C7
+Administrator (SERVER16);Tobaben C7 Optima WS19 (SERVER16#8);2026-03-18T14:10:36;Tobaben C7
+administrator (SRV-APP4);Müller Freising C11 WERWISO WS16;2024-03-06T16:18:26;Mueller Freising C11
+Administrator (SRV-Locosoft);Hoefler C7 Locosoft WS19 (SRV-Locosoft)#95;2023-09-14T09:38:45;Hoefler C7
+administrator (SRV03);Griesbeck Deggendorf AUTOSYS WS22 (SRV03#225);2024-02-28T10:11:29;Griesbeck Deggendorf AUTOSYS WS22 (SRV03#225)
+Administrator (SrvAPP01);Greiner C11 LOCOSOFT WS22 (SrvAPP01);2024-03-28T18:22:05;Greiner C11
+Administrator (SRVMVC21IAS);MVC Wien C7 Optima WS03 (SRVMVC21IAS#4);2021-06-10T09:59:12;MVC Wien C7
+Administrator (TOSCON1);Timmermanns C7/C11 Navision/ARI WS19 (TOSCON1);2024-05-08T11:42:51;Timmermanns C7
+Administrator (TSDE021811);Zumbuelt C7 Optima WS19 (TSDE021811);2023-12-20T10:31:00;Zumbuelt C7
+administrator (TSDE195312);Russig C7 Optima WS12 (TSDE195312);2022-06-29T14:08:26;Russig C7
+Administrator (TSDE209712);Arnhölter C7 Optima WS16 (TSDE209712#2);2023-12-20T16:53:49;Arnhoelter C7
+administrator (TSDE209712);Arnhölter C7 Optima WS16 (TSDE209712#2);2026-07-15T12:23:04;Arnhoelter C7
+administrator (w16daten01);Auto Epple Opel SKR C7 CARLO WS16 (w16daten01);2024-03-14T14:44:09;Auto Epple Opel SKR C7
+AÜKPLUS (K-APPS01);Förster C7 Autosys WS22 (K-APPS01);2026-07-15T14:13:59;Foerster C7
+Besitzer (Besitzer-PC);Löbau C7 Autosys Win10 (Besitzer-PC#6865);2023-11-23T18:12:26;Loebau C7
+cdkadmin (WEL01APP01);Weller Bietigheim C7 OPTIMA WS22 (WEL01APP01);2025-12-12T10:35:28;Weller Bietigheim C7
+Christina Winkler;VM Toni (VPN-DK, Van Eupen, Winter, Elspass, Schneider-Gruppe);2022-05-20T15:09:39;VM Toni (VPN-DK, Van Eupen, Winter, Elspass, Schneider-Gruppe)
+Cognos (Easy);Linck C11 CARLO  WS19 (Easy#3);2024-02-01T16:38:11;Linck C11
+Console (1120GlobalCube);Vogl C11 ARI WS19;2026-07-15T11:54:03;Vogl C11
+Console (2322GlobalCube);Weis C11 LOCOSOFT WS19 (2322GlobalCube#5);2026-07-20T14:47:30;Weis C11
+Console (AB-GlobalCube);Bichmann C11 OPTIMA_SKR51 WS22;2024-02-29T17:32:26;Bichmann C11
+Console (ABA-SRV-APP01);Bieling C11 LOCOSOFT WS22;2025-01-29T14:02:52;Bieling C11
+Console (AHK-CUBE);Kleinemeier C11 WERWISO Win10 (AHK-CUBE);2024-08-23T08:47:25;Kleinemeier C11
+Console (AHMS-GC);Schmidt Starnberg C7/C11 Navision/ARI WS19 (AHMS-GC);2026-07-15T11:34:45;Schmidt Starnberg C7
+Console (AHN-APP01);Neustadt C7 Carlo WS19 (AHN-APP01#9);2023-12-20T14:55:10;Neustadt C7
+Console (AHRAAP03);gekündigt - Rastetter WERWISO/DATEV WS19 (AHRAAP03#1);2026-03-04T21:35:04;gekuendigt - Rastetter WERWISO_DATEV WS19 (AHRAAP03#1)
+Console (AHT-S-GCBS-01);Tabor C11 OPTIMA WS19;2026-07-15T11:43:02;Tabor C11
+Console (APDE148111);Englhart C7 Optima WS12 (APDE148111#1);2023-11-24T10:01:57;Englhart C7
+Console (APDE148121);Englhart C7 Optima WS22 (APDE148121);2026-07-15T13:58:36;Englhart C7
+Console (App);Tretter C7 CARLO/DATEV WS22 (App#28);2026-03-04T21:29:31;Tretter C7
+Console (APP039);Brass/Jacob C11 OPTIMA WS25;2026-01-14T16:45:40;Brass_Jacob C11
+Console (appl170711);Hinz C7 Optima WS12 (appl170711#4);2023-11-24T10:55:14;Hinz C7
+Console (appl170722);Hinz C7 OPTIMA WS22 (appl170722);2026-07-15T15:20:48;Hinz C7
+Console (APPL194612);König & Partner C7 Optima WS19 (APPL194612);2025-04-17T16:36:22;Koenig u. Partner C7
+Console (ASHKSCUBE01);Schmid C11 LOCOSOFT WS19 (ASHKSCUBE01);2026-06-11T16:18:15;Schmid C11
+Console (AWDE014511);Schmidt Wilhelmshafen C7 Optima WS12 (AWDE014511#1);2024-02-08T09:09:42;Schmidt Wilhelmshafen C7
+Console (AWDE117801);Meures C7 Optima WS22 (AWDE117801#0);2026-07-15T17:13:00;Meures C7
+Console (azebber-bi);Ebber C7 Audev WS16 (azebber-bi);2026-07-15T13:44:02;Ebber C7
+Console (berkem-bi-01);Berkemeier_C11;2026-01-26T08:51:58;Berkemeier_C11
+Console (C00046);Becker-Tiemann Bielefeld C11 ARI WS19;2026-07-23T15:51:15;Becker-Tiemann Bielefeld C11
+Console (cognos-12-0-2);cognos-12-0-2;2024-05-17T14:19:27;cognos-12-0-2
+Console (CS-S-GC);Croll & Sondermann  C7 Optima Win10 (CS-S-GC);2026-07-15T13:37:52;Croll u. Sondermann  C7
+Console (Cube);Liegert C11 LOCOSOFT Win10;2026-07-15T09:15:15;Liegert C11
+Console (Cube-New);Zobjack C7 Optima WS19;2024-05-31T09:27:32;Zobjack C7
+Console (CZ-WN-ClobalCube);Czeczelits C7 Optima WS16 (CZ-WN-ClobalCube#8);2025-11-25T11:41:04;Czeczelits C7
+Console (CZ-WN-GlobalMgmt);Czeczelits C11 OPTIMA WS16;2025-09-12T09:08:10;Czeczelits C11
+Console (DADE195101);Altermann C7 Optima WS16 (DADE195101);2024-01-31T08:47:02;Altermann C7
+Console (DE0017GC);Böttche C11 CARLO WS19 (DE0017GC);2021-06-16T10:40:18;Boettche C11
+Console (de0328n2);Jonas C7 Optima WS16 (de0328n2#56);2023-11-24T09:58:22;Jonas C7
+Console (DE0509-GAPS);Siebrecht C7 Optima WS16 (DE0509-GAPS#2);2024-06-03T11:46:14;Siebrecht C7
+Console (DE0825A1);Greiner C7 Carlo (DE0825A1#1);2022-08-17T09:44:27;Greiner C7
+Console (DE1303TS01);3H Rheindorf C7 Carlo WS12 (DE1303TS01)#9;2026-07-10T10:01:36;3H Rheindorf C7
+Console (DE212070S00027);Berkemeier C11 CARLO/DATEV WS16;2026-01-14T15:42:33;Berkemeier C11
+Console (E1-PRG-01);Echterstrasse C7 Optima WS16 (E1-PRG-01);2023-12-13T08:37:22;Echterstrasse C7
+Console (Easy);Linck C11 CARLO  WS19 (Easy#3);2023-12-18T14:40:10;Linck C11
+Console (EPC2);Griesbeck Oberpfalz C7 Optima WS19 (Cham) (EPC2#2);2026-07-15T14:31:40;Griesbeck Oberpfalz C7
+Console (FBCMSRV);Holz C7 Optima Win10 (FBCMSRV#5);2026-07-15T16:15:56;Holz C7
+Console (gc-server6);gc-server6;2024-08-15T15:37:34;gc-server6
+Console (GC-SRV-01);Jonas C7 Optima WS22 (GC-SRV-01);2026-07-15T16:42:30;Jonas C7
+Console (GC01PICH);Pichel Chemnitz Dracar+ WS19 (GC01PICH);2026-07-16T07:59:38;Pichel Chemnitz Dracar+ WS19 (GC01PICH)
+Console (GC01PIHD);Pichel Hartmannsdorf Dracar+ WS19 (GC01PIHD#1);2025-05-08T10:08:27;Pichel Hartmannsdorf Dracar+ WS19 (GC01PIHD#1)
+Console (GCDE073501);Brass C7 Optima WS12 (GCDE073501);2021-06-02T13:52:21;Brass C7
+Console (GCDE073502);Brass C11 OPTIMA_SKR51 Win10 (GCDE073502);2026-03-26T12:29:25;Brass C11
+Console (GCUDE028621);Lackermann C11 LOCOSOFT WS22 (GCUDE028621);2024-03-18T08:46:50;Lackermann C11
+Console (gierathsgc01);Gieraths C11 LOCOSOFT WS19 (gierathsgc01);2026-06-11T15:26:02;Gieraths C11
+Console (global-cube);Ley Bergneustadt C11 OPTIMA Win11 NUC;2026-07-15T09:12:41;Ley Bergneustadt C11
+Console (Global-Cube);Hermann C11 WERWISO WS19;2024-03-06T15:42:07;Hermann C11
+Console (global-cube-neu);SundK Hamburg C12 WERWISO/DATEV WS25;2026-07-06T10:02:09;SundK Hamburg C12 WERWISO_DATEV WS25
+Console (Global-Cube-VM);Barth & Frey C11 OPTIMA_SKR51 WS16  (Global-Cube-VM#8);2026-07-06T12:01:04;Barth u. Frey C11
+Console (global-cube1);Greiner C11 LOCOSOFT WS12;2023-11-17T10:51:12;Greiner C11
+Console (global-cube2);Willi Mueller C11 AUDEV/Dagosoft WS16 ford-mueller.de;2026-07-30T10:47:42;Willi Mueller C11
+Console (global-cube3);Linck C11 CARLO WS19 (global-cube3);2026-07-15T09:25:36;Linck C11
+Console (global-cube4);Boehm C11 AUDEV/LOCOSOFT Win10 NUC;2026-07-06T12:05:40;Boehm C11
+Console (global-cube6);Auto Epple Opel SKR51 C11 CARLO WS22;2025-11-19T11:56:05;Auto Epple Opel SKR51 C11
+Console (GlobalCube);Lutz C11 LOCOSOFT/DATEV Win11 (GlobalCube#38);2026-07-15T09:27:33;Lutz C11
+Console (globalcube);Günther u Sustrate C11 OPTIMA_SKR51 WS19;2026-07-15T08:51:05;Guenther u Sustrate C11
+Console (GLOBALCUBE);Jacob C11 OPTIMA WS16;2025-12-15T12:14:26;Jacob C11
+Console (Globalcube-PC);Müller Strausberg C7 Autosys/Dagosoft Win10 (Globalcube-PC);2026-07-16T07:51:54;Mueller Strausberg C7
+Console (GlobalCube01);Rueschkamp C11 OPTIMA/LOCOSOFT WS16;2026-07-15T10:09:14;Rueschkamp C11
+Console (GlobalCube2012);Lausse C7 Optima Win10;2023-11-24T10:56:20;Lausse C7
+Console (GlobalCube2025);La Linea C7 Autosys/Dagosoft W11 (GlobalCube2025);2026-07-15T17:07:16;La Linea C7
+Console (GlobalCubeNUC);Jöst C11 OPTIMA/LOCOSOFT Win10 NUC;2023-07-25T10:11:19;Joest C11
+Console (gwmis1);Güma Wertheim C7 Filaks WS19 (gwmis1);2026-07-15T14:47:40;Guema Wertheim C7
+Console (he-apps03);global-cube7 (Server 2025) WS25;2025-11-06T12:36:36;global-cube7 (Server 2025) WS25
+Console (hs-21743);Winter Bretnig C11 OPTIMA WS19 (hs-21743#5);2026-05-26T10:28:37;Winter Bretnig C11
+Console (hs-53364);VCRR LUEG C11 OPTIMA (hs-53364 - van Eupen);2026-07-15T11:50:55;VCRR LUEG C11
+Console (HS-55551);König Berlin C7 Optima WS19 (Rechenzentrum);2024-08-08T09:42:54;Koenig Berlin C7
+Console (HS-55552);König Berlin C11 OPTIMA WS19 Rechenzentrum;2026-04-07T09:45:30;Koenig Berlin C11
+Console (Jansen-GC2);Jansen C11 AUDEV/Dagosoft WS16;2026-07-30T10:46:46;Jansen C11
+Console (KERBIc);Konrad C7 Autosys Win7 (KERBIc);2024-01-31T08:59:59;Konrad C7
+Console (lax-mis);Automag C11 ARI WS19 (lax-mis);2026-07-20T15:40:03;Automag C11
+Console (PC121);Hannuschka Interims-PC (PC121#004);2025-02-04T14:41:45;Hannuschka Interims-PC (PC121#004)
+Console (ruo-apache);Reichstein & Opitz C7 Autosys WS19 (ruo-apache#5);2024-03-14T14:16:50;Reichstein u. Opitz C7
+Console (RUO-GlobalCube);Reichstein & Opitz C11 OPTIMA WS19 (RUO-GlobalCube);2026-07-15T10:01:22;Reichstein u. Opitz C11
+Console (S-Cube);von der Weppen C11 WERWISO WS16 (S-Cube);2024-01-30T10:06:00;von der Weppen C11
+Console (SERVER16);Tobaben C7 Optima WS19 (SERVER16#8);2026-07-16T08:36:18;Tobaben C7
+Console (SGBIWH01);Hasler C11 AUTOLINE WS22;2026-07-15T08:54:21;Hasler C11
+Console (sievers-group);Sievers-Group C11 WERWISO Win10 Testumgebung;2021-06-22T13:37:34;Sievers-Group C11
+Console (SMMMIS01);Reisacher C7 Navision WS12 (SMMMIS01#2);2026-03-25T09:32:01;Reisacher C7
+Console (SMMMIS02);Reisacher C11 NAVISION WS22 (SMMMIS02#7);2025-01-07T08:54:54;Reisacher C11
+Console (SNDGAPS);Nefzger C11 ARI/NAVISION WS19 (SNDGAPS);2026-07-15T09:41:47;Nefzger C11
+Console (SRV-APP01-Ford);Wahl-Group C7 Optima WS22 (SRV-APP01-Ford);2024-06-03T12:08:38;Wahl-Group C7
+Console (SRV-APP4);Müller Freising C11 WERWISO WS16 ahm.gmbh;2026-07-02T16:13:56;Mueller Freising C11
+Console (SRV-FILE01);Schmelter C7 Optima WS16 (SRV-FILE01#79);2026-07-16T08:31:41;Schmelter C7
+Console (SRV01);Elspass C7 Locosoft WS12;2026-07-15T13:55:37;Elspass C7
+Console (SRVAP04);Hoffmann Saalfeld C7 Optima WS19 (SRVAP04);2026-07-15T15:25:44;Hoffmann Saalfeld C7
+Console (SrvGC01);Greiner C11 LOCOSOFT WS22 (SrvGC01);2026-06-11T15:30:41;Greiner C11
+Console (SRVMVCGC01);MVC Wien C7 neuer Server SRVMVCGC01;2023-12-19T10:48:00;MVC Wien C7
+Console (Station55);Gerds C11 CARLO Win10;2025-08-28T14:53:59;Gerds C11
+Console (svahl142);Luchtenberg C7 Optima WS19 (svahl142);2024-06-03T11:24:27;Luchtenberg C7
+Console (SVBLGC02);Schachtschneider C11 LOCOSOFT WS19 (SVBLGC02);2025-01-15T12:06:58;Schachtschneider C11
+Console (TSDE021811);Zumbuelt C7 Optima WS19 (TSDE021811);2025-02-07T16:01:42;Zumbuelt C7
+Console (TSDE195312);Russig C7 Optima WS12 (TSDE195312);2026-07-16T08:09:01;Russig C7
+Console (TSDE209712);Arnhölter C7 Optima WS16 (TSDE209712#2);2023-11-29T10:00:03;Arnhoelter C7
+Console (vmgc);Rau Brunsbüttel C7 Optima Win10 (vmgc#6);2026-07-16T08:07:16;Rau Brunsbuettel C7
+Console (VPN2);VPN2 (VPN-DK, Iveco, Hymer);2026-01-26T17:14:41;VPN2 (VPN-DK, Iveco, Hymer)
+Console (VPN_DK);VM Toni (VPN-DK, Van Eupen, Winter, Elspass, Schneider-Gruppe);2024-01-11T13:24:31;VM Toni (VPN-DK, Van Eupen, Winter, Elspass, Schneider-Gruppe)
+Console (w16daten01);Auto Epple C7 CARLO WS16 (w16daten01);2023-10-19T13:54:38;Auto Epple C7
+Console (W2K19GLOBALCUBE);Körner C11 LOCOSOFT WS19 (W2K19GLOBALCUBE);2026-06-08T10:10:18;Koerner C11
+Console (w2k22app05);Göndle C11 ARI (w2k22app05);2026-07-15T08:47:22;Goendle C11
+Console (WEL01GC01);Weller Bietigheim OPTIMA C11 WS22 (WEL01GC01);2025-11-14T08:53:03;Weller Bietigheim OPTIMA C11
+Console (win-bcm);Weller Wetzlar C7 Autosys/Dagosoft WS19 (win-bcm);2026-07-16T09:04:06;Weller Wetzlar C7
+Console (WINSV3);ABL Service C7 Optima WS08 (WINSV3);2026-07-15T12:16:38;ABL Service C7
+dracaradmin (GC01PICH);Pichel Chemnitz Dracar+ WS19 (GC01PICH);2023-11-24T11:25:13;Pichel Chemnitz Dracar+ WS19 (GC01PICH)
+dracaradmin (GC01PIHD);Pichel Hartmannsdorf Dracar+ WS19 (GC01PIHD#1);2026-07-16T08:02:42;Pichel Hartmannsdorf Dracar+ WS19 (GC01PIHD#1)
+ecatsrv (APP01);Förster C7 Autosys WS12 (APP01#9);2023-11-24T10:52:15;Foerster C7
+ellad (LAPTOP-IBBBGQC1);Ella;2026-01-27T11:48:59;Ella
+GAPS (DE212070S00027);Berkemeier Saerbeck C11 CARLO WS16;2026-03-04T09:42:16;Berkemeier Saerbeck C11
+GAPS (global-cube);Hedtke alt C11 HS/P2 WS16 (global-cube#7);2025-11-06T16:15:39;Hedtke alt C11
+gcadm (1120GlobalCube);Vogl C11 ARI WS19;2026-07-20T14:40:43;Vogl C11
+gcube (TPDE121311);Elmer  C7 Optima WS12;2023-12-11T14:39:01;Elmer  C7
+global (SMMMIS01);Reisacher C7 Navision WS12 (SMMMIS01#2);2026-03-12T16:31:44;Reisacher C7
+global (SMMMIS02);Reisacher C11 NAVISION/ARI WS22 (SMMMIS02#7);2026-08-12T09:30:42;Reisacher C11
+Global (TOSCON1);Timmermanns C7/C11 Navision/ARI WS19 (TOSCON1);2026-07-06T11:37:32;Timmermanns C7
+Global Cube (2322GlobalCube);Weis C11 LOCOSOFT WS19 (2322GlobalCube#5);2024-03-06T18:31:05;Weis C11
+Global Cube (AB-GlobalCube);Bichmann C11 OPTIMA_SKR51 WS22;2026-07-06T12:02:44;Bichmann C11
+Global Cube (ABA-SRV-APP01);Bieling C11 LOCOSOFT WS22;2026-07-06T12:04:37;Bieling C11
+Global Cube (AHK-CUBE);Kleinemeier C11 WERWISO Win10 (AHK-CUBE);2024-03-11T10:37:51;Kleinemeier C11
+Global Cube (AHRAAP03);gekündigt - Rastetter WERWISO/DATEV WS19 (AHRAAP03#1);2025-01-14T20:46:51;gekuendigt - Rastetter WERWISO_DATEV WS19 (AHRAAP03#1)
+Global Cube (AHT-S-GCBS-01);Tabor C11 OPTIMA WS19;2024-08-19T10:40:53;Tabor C11
+Global Cube (AMD-GCube-01);Darmas /Tiemeyer C11 CARLO/LOCOSOFT/SAP WS22 (AMD-GCube-01);2026-07-06T10:03:55;Darmas _Tiemeyer C11
+Global Cube (APP039);Brass/Jacob C11 OPTIMA WS25;2026-03-26T12:25:34;Brass_Jacob C11
+Global Cube (ASHKSCUBE01);Schmid C11 LOCOSOFT WS19 (ASHKSCUBE01);2026-07-15T11:33:08;Schmid C11
+Global Cube (berkem-bi-01);Berkemeier Münster C11 DATEV/ATTRIBUT/(CARLO) WS25;2026-07-06T09:59:22;Berkemeier Muenster C11
+Global Cube (COGNOS11);Toennemann C11 CARLO Win10 (COGNOS11#0);2026-07-20T14:36:54;Toennemann C11
+Global Cube (Cube);Liegert C11 LOCOSOFT Win10;2026-07-15T09:25:06;Liegert C11
+Global Cube (CZ-WN-GlobalMgmt);Czeczelits C11 OPTIMA WS16;2026-07-06T12:28:16;Czeczelits C11
+Global Cube (DE0017GC);Böttche C11 CARLO WS19 (DE0017GC);2026-07-06T12:23:01;Boettche C11
+Global Cube (gc-server6);gc-server6;2026-01-14T13:45:11;gc-server6
+Global Cube (GCDE073502);Brass C11 OPTIMA_SKR51 Win10 (GCDE073502);2025-12-15T13:41:41;Brass C11
+Global Cube (GCUDE028621);Lackermann C11 LOCOSOFT WS22 (GCUDE028621);2025-04-30T11:22:08;Lackermann C11
+Global Cube (gierathsgc01);Gieraths C11 LOCOSOFT WS25 (gierathsgc01);2026-07-15T08:38:29;Gieraths C11
+Global Cube (Global-Cube);Hermann C11 WERWISO/DATEV WS19;2026-07-15T08:56:03;Hermann C11
+Global Cube (global-cube);Nolte C11 OPTIMA_SKR51 Win10;2026-08-03T13:11:43;Nolte C11
+Global Cube (global-cube-neu);SundK Hamburg C12 WERWISO/DATEV WS25;2026-08-05T16:07:21;SundK Hamburg C12 WERWISO_DATEV WS25
+Global Cube (Global-Cube-VM);Barth & Frey C11 OPTIMA_SKR51 WS16  (Global-Cube-VM#8);2025-02-04T18:42:20;Barth u. Frey C11
+Global Cube (global-cube1);Greiner C11 LOCOSOFT WS12;2023-12-19T10:32:22;Greiner C11
+Global Cube (global-cube2);Guenther u. Schmitt C11 CARLO WS16;2026-07-15T08:45:26;Guenther u. Schmitt C11
+Global Cube (global-cube3);Ulmen C11 CARLO WS19;2026-07-20T14:35:16;Ulmen C11
+Global Cube (global-cube4);global-cube4 (Win 10);2026-01-20T13:22:02;global-cube4 (Win 10)
+Global Cube (global-cube6);Premium Cars Peters C11 LOCOSOFT/DATEV (WS22);2026-07-15T10:00:11;Premium Cars Peters C11
+Global Cube (global-cube7);Stange C11 LOCOSOFT WS25;2026-06-11T16:30:07;Stange C11
+Global Cube (globalcube);Häusler C11 CARLO WS12;2024-05-24T17:06:21;Haeusler C11
+Global Cube (GlobalCube);Peter Nordhessen (ehem. Heidenreich) C11 OPTIMA WS19 (GlobalCube#8);2026-07-15T09:55:41;Peter Nordhessen (ehem. Heidenreich) C11
+Global Cube (GLOBALCUBE);Jacob C11 OPTIMA WS16;2025-09-03T15:46:21;Jacob C11
+Global Cube (GlobalCube01);Rueschkamp C11 OPTIMA/LOCOSOFT WS16;2026-06-11T16:12:45;Rueschkamp C11
+Global Cube (GlobalCubeNUC);Jöst C11 OPTIMA/LOCOSOFT Win11 NUC;2026-07-15T09:04:36;Joest C11
+Global Cube (GSGlobalCube);Gottstein C11 ARI WS19 (GSGlobalCube);2026-07-15T08:40:22;Gottstein C11
+Global Cube (he-apps03);Hedtke C11 HS/P2 WS25 (he-apps03);2025-11-17T17:01:54;Hedtke C11
+Global Cube (Jansen-GC2);Jansen C11 AUDEV WS16;2026-06-10T09:18:54;Jansen C11
+Global Cube (RUO-GlobalCube);Reichstein & Opitz C11 OPTIMA WS19 (RUO-GlobalCube);2023-10-11T18:52:10;Reichstein u. Opitz C11
+Global Cube (SGBIWH01);Hasler C11 AUTOLINE WS22;2026-02-09T08:36:49;Hasler C11
+Global Cube (shcgc01);Heinen Dortmund C11 LOCOSOFT WS22 heinen-nrw.de;2026-07-20T16:02:16;Heinen Dortmund C11
+Global Cube (sievers-group);sievers-group C11 Win10 (Testumgebung);2023-09-14T10:36:08;sievers-group C11
+Global Cube (SRV-APP4);Müller Freising C11 WERWISO/DATEV WS16 ahm.gmbh;2026-07-06T10:06:42;Mueller Freising C11
+Global Cube (SrvGC01);Greiner C11 LOCOSOFT WS22 (SrvGC01);2026-07-15T08:43:14;Greiner C11
+Global Cube (Station55);Gerds C11 CARLO Win10;2026-07-15T08:37:23;Gerds C11
+Global Cube (SVBLGC02);Schachtschneider C11 LOCOSOFT WS25 (SVBLGC02);2026-07-15T10:26:49;Schachtschneider C11
+Global Cube (test-c12);test-c12;2024-03-25T06:34:36;test-c12
+Global Cube (W2K19GLOBALCUBE);Körner C11 LOCOSOFT WS19 (W2K19GLOBALCUBE);2026-06-16T15:14:29;Koerner C11
+Global Cube (w2k22app05);Göndle AT C11 NAVISION WS22 (w2k22app05);2025-02-27T11:02:31;Goendle AT C11
+Global Cube (WEL01GC01);Weller Bietigheim OPTIMA C11 WS22 (WEL01GC01);2026-07-15T12:00:54;Weller Bietigheim OPTIMA C11
+Global1 (COGNOS11);Toennemann C11 CARLO Win10 (COGNOS11#0);2024-09-09T10:24:51;Toennemann C11
+Global1 (VPN2);VPN2 (VPN-DK, Iveco, Hymer);2026-02-19T10:37:19;VPN2 (VPN-DK, Iveco, Hymer)
+Global1 (VPN_DK);VM Toni (VPN-DK, Van Eupen, Winter, Elspass, Schneider-Gruppe);2025-09-08T17:18:36;VM Toni (VPN-DK, Van Eupen, Winter, Elspass, Schneider-Gruppe)
+Globalcube (APP01);Förster C7 Autosys WS12 (APP01#9);2024-05-29T15:13:35;Foerster C7
+globalcube (azebber-bi);Ebber C7 Audev WS16 (azebber-bi);2024-05-31T10:22:21;Ebber C7
+globalcube (berkem-bi-01);Berkemeier Münster C11 DATEV/ATTRIBUT/(CARLO) WS25;2026-04-26T15:45:49;Berkemeier Muenster C11
+globalcube (C00046);Becker-Tiemann Bielefeld C11 ARI WS19;2026-07-24T11:19:07;Becker-Tiemann Bielefeld C11
+globalcube (CS-S-GC);Croll & Sondermann  C7 Optima Win10 (CS-S-GC);2024-02-20T15:32:40;Croll u. Sondermann  C7
+GlobalCube (DE0017GQ);Boettche C7 Carlo WS08 (DE0017GQ);2023-11-24T10:47:05;Boettche C7
+GlobalCube (global-cube4);Lausse C11 OPTIMA Win10;2024-03-06T16:05:31;Lausse C11
+globalcube (global-cube6);Sirch C11 WERWISO/DATEV WS22(global-cube6#4);2026-07-20T15:37:35;Sirch C11
+globalcube (globalcube);Haeusler C11 CARLO WS22 ( globalcube#9);2026-07-15T08:52:52;Haeusler C11
+globalcube (hs-21743);Winter Bretnig C11 OPTIMA WS19 (hs-21743#5);2026-07-15T12:07:26;Winter Bretnig C11
+globalcube (hs-53364);VCRR LUEG C11 OPTIMA (hs-53364 - van Eupen);2026-07-02T15:41:28;VCRR LUEG C11
+GlobalCube (HS-55551);König Berlin C7 Optima WS19 (Rechenzentrum);2024-08-16T11:54:40;Koenig Berlin C7
+globalcube (HS-55552);König Berlin C11 OPTIMA WS19 Rechenzentrum;2026-07-15T09:07:28;Koenig Berlin C11
+Globalcube (S-Cube);von der Weppen C11 WERWISO WS16 (S-Cube);2023-11-13T18:25:56;von der Weppen C11
+gocuadmin (DE0509-GAPS);Siebrecht C7 Optima WS16 (DE0509-GAPS#2);2026-07-16T08:34:25;Siebrecht C7
+Matthias Winter;Reisacher C7 Navision WS12 (SMMMIS01#2);2022-06-30T14:10:20;Reisacher C7
+MISadm (lax-mis);Automag C11 ARI WS19 (lax-mis);2026-08-19T09:58:20;Automag C11
+nzw (GlobalCube);Loeffler C11 LOCOSOFT Win10 NUC;2023-11-23T11:03:37;Loeffler C11
+Psotka (YLTH714162);Psotka C7 Optima Win10 (YLTH714162#3);2026-07-16T08:06:33;Psotka C7
+Stat50 (Station50);Dresen C7 Optima WS19(GAPSDE444441);2025-08-20T15:53:51;Dresen C7
+verkauf (EPC4);Nolte (EPC4#6);2024-01-31T09:15:36;Nolte (EPC4#6)

+ 122 - 0
clients.py

@@ -0,0 +1,122 @@
+import csv
+import re
+import xml.etree.ElementTree as ET
+from datetime import datetime
+from pathlib import Path
+
+
+def extract_clients(xml_path: Path) -> list[dict[str, str]]:
+    root = ET.parse(xml_path).getroot()
+    session = root.find("Session")
+    if session is None:
+        return []
+
+    client_description = session.find("SessionDescription[@Name='ClientName']")
+    client_name = "" if client_description is None else client_description.get("Description", "")
+    start_time = session.get("StartTime", "")
+
+    return [
+        {
+            "ParticipantName": participant.get("Name", ""),
+            "ClientName": client_name,
+            "StartTime": start_time,
+        }
+        for participant in session.findall("Participant")
+        if participant.get("Role") not in {"ROLE_SUPPORTER", "ROLE_UNKNOWN"}
+        and participant.get("Name", "").strip()
+        and client_name.strip()
+    ]
+
+
+def calculate_customer(client_name: str) -> str:
+    match = re.search(r"\bC(?:7|11)\b", client_name, re.IGNORECASE)
+    customer = client_name[: match.end()] if match else client_name
+    customer = (
+        customer.replace("&", "u.")
+        .replace("ä", "ae")
+        .replace("ö", "oe")
+        .replace("ü", "ue")
+        .replace("Ä", "Ae")
+        .replace("Ö", "Oe")
+        .replace("Ü", "Ue")
+        .replace("ß", "ss")
+    )
+    customer = re.sub(r'[<>:"/\\|?*\x00-\x1f]', "_", customer)
+    customer = customer.rstrip(" .")
+    return customer or "_"
+
+
+def write_clients_csv(rows: list[dict[str, str]], csv_path: Path) -> None:
+    fieldnames = ["ParticipantName", "ClientName", "StartTime", "Kunde"]
+    with csv_path.open("w", newline="", encoding="latin-1", errors="replace") as csv_file:
+        writer = csv.DictWriter(csv_file, fieldnames=fieldnames, delimiter=";")
+        writer.writeheader()
+        writer.writerows(rows)
+
+
+def read_clients_csv(csv_path: Path) -> list[dict[str, str]]:
+    if not csv_path.exists():
+        return []
+
+    with csv_path.open("r", newline="", encoding="latin-1") as csv_file:
+        reader = csv.DictReader(csv_file, delimiter=";")
+        return [
+            {
+                "ParticipantName": row.get("ParticipantName", "").strip(),
+                "ClientName": row.get("ClientName", ""),
+                "StartTime": row.get("StartTime", ""),
+            }
+            for row in reader
+            if row.get("ParticipantName", "").strip() and row.get("ClientName", "").strip()
+        ]
+
+
+def parse_start_time(start_time: str) -> datetime:
+    if not start_time:
+        return datetime.min
+    try:
+        return datetime.fromisoformat(start_time.replace("Z", "+00:00")).replace(tzinfo=None)
+    except ValueError:
+        return datetime.min
+
+
+def merge_clients(existing_rows: list[dict[str, str]], new_rows: list[dict[str, str]]) -> list[dict[str, str]]:
+    newest_rows: dict[str, dict[str, str]] = {}
+    for row in [*existing_rows, *new_rows]:
+        participant_name = row["ParticipantName"].strip()
+        client_name = row["ClientName"].strip()
+        if not participant_name or not client_name:
+            continue
+
+        normalized_row = {
+            "ParticipantName": participant_name,
+            "ClientName": client_name,
+            "StartTime": row.get("StartTime", ""),
+        }
+        current = newest_rows.get(participant_name)
+        if current is None or parse_start_time(normalized_row["StartTime"]) >= parse_start_time(current["StartTime"]):
+            newest_rows[participant_name] = normalized_row
+
+    return [
+        {**row, "Kunde": calculate_customer(row["ClientName"])}
+        for row in sorted(newest_rows.values(), key=lambda row: row["ParticipantName"].casefold())
+    ]
+
+
+def find_xml_files(directory: Path) -> list[Path]:
+    return sorted(
+        path
+        for path in directory.rglob("*")
+        if path.is_file() and path.suffix.lower() == ".xml" and not path.name.lower().startswith("sessions")
+    )
+
+
+def run(directory: Path, output: Path) -> tuple[int, int]:
+    if not directory.is_dir():
+        raise ValueError(f"Das Verzeichnis existiert nicht: {directory}")
+
+    xml_files = find_xml_files(directory)
+    new_rows = [row for xml_file in xml_files for row in extract_clients(xml_file)]
+    rows = merge_clients(read_clients_csv(output), new_rows)
+    write_clients_csv(rows, output)
+    return len(xml_files), len(rows)

+ 438 - 0
clients_v1.csv

@@ -0,0 +1,438 @@
+ParticipantName;ClientName
+adglobalcube (gwmis1);G�ma Wertheim C7 Filaks WS19 (gwmis1)
+adm-gaps (MZSGAPS);Delta C7 OPTIMA WS22 (MZSGAPS)
+admin-mh (appl004321);
+admin.ebber (SRV-WIN-KOMSRV1);Ebber C7 Audev WS25 (SRV-WIN-KOMSRV1)
+adminclaris (SERVER07);Cordes C7 Optima WS19 (SERVER07#50)
+admingc (SRVMVCGC01);MVC Wien C7 neuer Server SRVMVCGC01
+admingc (SRVMVCGC01);
+Administrator (AHK-HRF);Kieschnick C7 Optima WS16 (AHK-HRF)
+administrator (AHMS-GC);Schmidt Starnberg C7 Navision WS19 (AHMS-GC)
+administrator (AHMS-GC);Schmidt Starnberg C7/C11 Navision/ARI WS19 (AHMS-GC)
+administrator (AHMS-GC);
+administrator (AHN-APP01);Neustadt C7 Carlo WS19 (AHN-APP01#9)
+administrator (App);Tretter C7 CARLO Ws22 (App#28)
+administrator (App);Tretter C7 CARLO/DATEV WS22 (App#28)
+administrator (appl157102);Fluegel C7 Optima WS12 (appl157102#6)
+administrator (APPL157122);Fluegel C7 OPTIMA WS19 (APPL157122)
+administrator (APPL194612);K�nig & Partner C7 Optima WS19 (APPL194612)
+administrator (APPL203621);Barbarossa OPTIMA C7 WS22 (APPL203621)
+Administrator (AWDE014511);Schmidt Wilhelmshafen C7 Optima WS12 (AWDE014511#1)
+administrator (AWDE014511);
+administrator (AWDE117801);Meures C7 Optima WS22 (AWDE117801#0)
+administrator (CODE192901);Hannuschka C7 Optima WS08 (CODE192901#0)
+Administrator (cognos-12-0-2);
+Administrator (cognos-12-0-2);cognos-12-0-2
+Administrator (Cube-New);Zobjack C7 Optima WS19
+Administrator (CZ-WN-ClobalCube);Czeczelits C7 Optima WS16 (CZ-WN-ClobalCube#8)
+administrator (CZ-WN-GlobalMgmt);Czeczelits C11 OPTIMA WS16
+Administrator (DADE195101);Altermann C7 Optima WS16 (DADE195101)
+administrator (DC2);Arndt C7 Optima/Dracar+ WS19 (DC2#14)
+administrator (DE0289N3);Bieling C7 Optima WS16 (DE0289N3#4)
+administrator (DE0509-GAPS);Siebrecht C7 Optima WS16 (DE0509-GAPS#2)
+administrator (DE1165T1);Guenther & Schmitt C7 Carlo WS12 (DE1165T1#2)
+Administrator (DE1303TS01);
+Administrator (de1673n1);Limburg C7 Optima WS08 (de1673n1#4)
+Administrator (EADE072411);R�ll C7 Optima WS12 (EADE072411#6)
+Administrator (FINDE112741);K�nig Berlin C7 Optima WS19 (FINDE112741)
+administrator (GAPSDE444401);Dresen C7 Optima WS08 (GAPSDE444401#4)
+administrator (GAPSDE444441);Dresen C7 Optima WS19(GAPSDE444441)
+Administrator (GAPSDE444441);Dresen C7 Optima WS19(GAPSDE444441)
+Administrator (GAPSDE444441);
+administrator (GC-SRV-01);Jonas C7 Optima WS22 (GC-SRV-01)
+administrator (GC01);Ulmen C7 Carlo WS12 (GC01#5)
+Administrator (GCDE073502);Brass C11 OPTIMA Win10 (GCDE073502)
+administrator (Global-Cube);Hermann C11 WERWISO WS19
+Administrator (global-cube);Ley Bergneustadt C11 OPTIMA Win10 NUC
+administrator (Global-Cube-VM);Barth & Frey C11 OPTIMA_SKR51 WS16  (Global-Cube-VM#8)
+Administrator (Global-Cube-VM);Barth & Frey C11 OPTIMA_SKR51 WS16  (Global-Cube-VM#8)
+Administrator (global-cube1);Greiner C11 LOCOSOFT WS12
+administrator (global-cube2);Guenther u. Schmitt C11 CARLO WS16
+administrator (global-cube6);Auto Epple Opel SKR51 C11 CARLO WS22
+administrator (globalcube);Aurego C7 Optima WS22 (globalcube#0)
+Administrator (GlobalCube);Schwarz C7 Optima Win7 (GlobalCube#3)
+Administrator (GlobalCube);Gottwald C7 Autosys Win10 (GlobalCube#7)
+Administrator (globalcube);Aurego C7 Optima WS22 (globalcube#0)
+Administrator (GlobalCube);Gottwald C7 Autosys/Dagosoft Win10 (GlobalCube#7)
+Administrator (GMExchange);Fricke C7 Optima WS12 (GMExchange)
+Administrator (MGS-BI);MGS  C7 Autosys Win10
+Administrator (PC121);Hannuschka Interims-PC (PC121#004)
+administrator (PCP-vApp);Premium Cars WS12 (PCP-vApp)
+administrator (PCP-vApp);Premium Cars C7 Autosys WS12 (PCP-vApp)
+Administrator (SERVER07);Cordes C7 Optima WS19 (SERVER07#50)
+Administrator (SERVER16);Tobaben C7 Optima WS19 (SERVER16#8)
+administrator (SRV-APP4);M�ller Freising C11 WERWISO WS16
+Administrator (SRV-Locosoft);Hoefler C7 Locosoft WS19 (SRV-Locosoft)#95
+administrator (SRV03);Griesbeck Deggendorf AUTOSYS WS22 (SRV03#225)
+Administrator (SrvAPP01);Greiner C11 LOCOSOFT WS22 (SrvAPP01)
+Administrator (SRVMVC21IAS);MVC Wien C7 Optima WS03 (SRVMVC21IAS#4)
+Administrator (TOSCON1);Timmermanns C7/C11 Navision/ARI WS19 (TOSCON1)
+Administrator (TSDE021811);Zumbuelt C7 Optima WS19 (TSDE021811)
+administrator (TSDE195312);Russig C7 Optima WS12 (TSDE195312)
+Administrator (TSDE209712);Arnh�lter C7 Optima WS16 (TSDE209712#2)
+administrator (TSDE209712);Arnh�lter C7 Optima WS16 (TSDE209712#2)
+Administrator (TSDE231205);
+administrator (w16daten01);Auto Epple C7 CARLO WS16 (w16daten01)
+administrator (w16daten01);
+administrator (w16daten01);Auto Epple Opel SKR C7 CARLO WS16 (w16daten01)
+Administrator (WIN-O3D0O2OH88T);
+alra (bhalra);
+A�KPLUS (K-APPS01);F�rster C7 Autosys WS22 (K-APPS01)
+Besitzer (Besitzer-PC);L�bau C7 Autosys Win10 (Besitzer-PC#6865)
+C232 (TS-Office02);
+caar (LAP1703);
+cdkadmin (WEL01APP01);Weller Bietigheim C7 OPTIMA WS22 (WEL01APP01)
+Christina Winkler;
+Christina Winkler;VM Toni (VPN-DK, Van Eupen, Winter, Elspass, Schneider-Gruppe)
+Cognos (Easy);Linck C11 CARLO  WS19 (Easy#3)
+Console (1120GlobalCube);Vogl C11 ARI WS19
+Console (2322GlobalCube);Weis C11 LOCOSOFT WS19 (2322GlobalCube#5)
+Console (AB-GlobalCube);Bichmann C11 OPTIMA_SKR51 WS22
+Console (ABA-SRV-APP01);Bieling C11 LOCOSOFT WS22
+Console (AHK-CUBE);Kleinemeier C11 WERWISO Win10 (AHK-CUBE)
+Console (AHMS-GC);Schmidt Starnberg C7 Navision WS19 (AHMS-GC)
+Console (AHMS-GC);Schmidt Starnberg C7/C11 Navision/ARI WS19 (AHMS-GC)
+Console (AHN-APP01);Neustadt C7 Carlo WS19 (AHN-APP01#9)
+Console (AHRAAP03);gek�ndigt - Rastetter WERWISO WS19 (AHRAAP03#1)
+Console (AHRAAP03);gek�ndigt - Rastetter WERWISO/DATEV WS19 (AHRAAP03#1)
+Console (AHT-S-GCBS-01);Tabor C11 OPTIMA WS19
+Console (APDE148111);Englhart C7 Optima WS12 (APDE148111#1)
+Console (APDE148121);Englhart C7 Optima WS22 (APDE148121)
+Console (App);Tretter C7 CARLO Ws22 (App#28)
+Console (App);Tretter C7 CARLO/DATEV WS22 (App#28)
+Console (APP039);Brass/Jacob C11 OPTIMA WS25
+Console (appl170711);Hinz C7 Optima WS12 (appl170711#4)
+Console (appl170722);Hinz C7 OPTIMA WS22 (appl170722)
+Console (APPL194612);K�nig & Partner C7 Optima WS19 (APPL194612)
+Console (ASHKSCUBE01);Schmid C11 LOCOSOFT WS19 (ASHKSCUBE01)
+Console (AWDE014511);Schmidt Wilhelmshafen C7 Optima WS12 (AWDE014511#1)
+Console (AWDE117801);Meures C7 Optima WS22 (AWDE117801#0)
+Console (azebber-bi);Ebber C7 Audev WS16 (azebber-bi)
+Console (berkem-bi-01);Berkemeier_C11
+Console (C00046);
+Console (C00046);Becker-Tiemann Bielefeld C11 ARI WS19
+Console (cognos-12-0-2);cognos-12-0-2
+Console (CS-S-GC);Croll & Sondermann  C7 Optima Win10 (CS-S-GC)
+Console (Cube);Liegert C11 LOCOSOFT Win10
+Console (Cube-New);Zobjack C7 Optima WS19
+Console (CZ-WN-ClobalCube);Czeczelits C7 Optima WS16 (CZ-WN-ClobalCube#8)
+Console (CZ-WN-GlobalMgmt);Czeczelits C11 OPTIMA WS16
+Console (DADE195101);Altermann C7 Optima WS16 (DADE195101)
+Console (DE0017GC);B�ttche C11 CARLO WS19 (DE0017GC)
+Console (de0328n2);Jonas C7 Optima WS16 (de0328n2#56)
+Console (DE0509-GAPS);Siebrecht C7 Optima WS16 (DE0509-GAPS#2)
+Console (DE0825A1);Greiner C7 Carlo (DE0825A1#1)
+Console (DE1303TS01);3H Rheindorf C7 Carlo WS12 (DE1303TS01)#9
+Console (DE212070S00027);Berkemeier C11 CARLO WS16
+Console (DE212070S00027);Berkemeier C11 CARLO/DATEV WS16
+Console (E1-PRG-01);Echterstrasse C7 Optima WS16 (E1-PRG-01)
+Console (Easy);Linck C11 CARLO  WS19 (Easy#3)
+Console (EPC2);Griesbeck Oberpfalz C7 Optima WS19 (Cham) (EPC2#2)
+Console (FBCMSRV);Holz C7 Optima Win10 (FBCMSRV#5)
+Console (gc-server6);gc-server6
+Console (GC-SRV-01);Jonas C7 Optima WS22 (GC-SRV-01)
+Console (GC01PICH);Pichel Chemnitz Dracar+ WS19 (GC01PICH)
+Console (GC01PIHD);Pichel Hartmannsdorf Dracar+ WS19 (GC01PIHD#1)
+Console (GCDE073501);Brass C7 Optima WS12 (GCDE073501)
+Console (GCDE073502);Brass C11 OPTIMA Win10 (GCDE073502)
+Console (GCDE073502);Brass C11 OPTIMA_SKR51 Win10 (GCDE073502)
+Console (GCUDE028621);Lackermann C11 LOCOSOFT WS22 (GCUDE028621)
+Console (gierathsgc01);Gieraths C11 LOCOSOFT WS19 (gierathsgc01)
+Console (global-cube);Hedtke C11 HS WS16 (global-cube#7)
+Console (Global-Cube);Hermann C11 WERWISO WS19
+Console (global-cube);Ley Bergneustadt C11 OPTIMA Win10 NUC
+Console (Global-Cube);
+Console (global-cube);global-cube-demo
+Console (global-cube);
+Console (global-cube);Hedtke C11 HS/P2 WS16 (global-cube#7)
+Console (global-cube);Ley Bergneustadt C11 OPTIMA Win11 NUC
+Console (global-cube-neu);
+Console (global-cube-neu);global-cube7 (Server 2025) WS25
+Console (global-cube-neu);SundK Hamburg C12 WERWISO/DATEV WS25
+Console (Global-Cube-VM);Barth & Frey C11 OPTIMA WS16 (Global-Cube-VM)
+Console (Global-Cube-VM);Barth & Frey C11 OPTIMA_SKR51 WS16  (Global-Cube-VM#8)
+Console (Global-Cube-VM);
+Console (global-cube1);Greiner C11 LOCOSOFT WS12
+Console (global-cube2);Willi Mueller C11 AUDEV/Dagosoft WS16 ford-mueller.de
+Console (global-cube2);global-cube2 (Server 2016) WS16
+Console (global-cube2);Bunk C11 WERWISO/DATEV WS16
+Console (global-cube2);Willi Mueller C11 AUDEV WS16 ford-mueller.de
+Console (global-cube3);Ulmen C11 CARLO WS19
+Console (global-cube3);Linck C11 CARLO WS19 (global-cube3)
+Console (global-cube3);Moll C11 LOCOSOFT WS19
+Console (global-cube3);SundK C11 WERWISO WS19
+Console (global-cube3);Bekirovski C11 LOCOSOFT WS19
+Console (global-cube3);Linck C12 CARLO WS19 (global-cube3)
+Console (global-cube3);
+Console (global-cube3);Becker-Tiemann Bielefeld C11 ARI WS19
+Console (global-cube3);SundK Hamburg C11 WERWISO/DATEV WS19
+Console (global-cube3);K�nig Berlin C12 Eisenhut (global-cube3#84)
+Console (global-cube3);SundK alt Hamburg C11 WERWISO/DATEV WS19
+Console (global-cube4);Zumbuelt C11 LOCOSOFT Win10
+Console (global-cube4);Lausse C11 OPTIMA Win10
+Console (global-cube4);Boehm C11 AUDEV Win10 NUC
+Console (global-cube4);test-c12
+Console (global-cube4);Gerds C11 CARLO Win10
+Console (global-cube4);Boehm C11 AUDEV/LOCOSOFT Win10 NUC
+Console (global-cube6);global-cube6 (Server 2022) WS22
+Console (global-cube6);Auto Epple Opel SKR51 C11 CARLO WS22
+Console (GlobalCube);Zschernitz C11 CARLO Win10
+Console (globalcube);HIRO C11 LOCOSOFT WS19 (globalcube)
+Console (GLOBALCUBE);Jacob C11 OPTIMA WS16
+Console (globalcube);G�nther u Sustrate C11 OPTIMA_SKR51 WS19
+Console (GlobalCube);Gottwald C7 Autosys Win10 (GlobalCube#7)
+Console (GlobalCube);Lutz C11 LOCOSOFT Win10 (GlobalCube#38)
+Console (GlobalCube);
+Console (GlobalCube);Lutz C11 LOCOSOFT/DATEV Win10 (GlobalCube#38)
+Console (globalcube);
+Console (globalcube);Haeusler C11 CARLO WS12 ( globalcube#9)
+Console (GlobalCube);Lutz C11 LOCOSOFT/DATEV Win11 (GlobalCube#38)
+Console (Globalcube-PC);M�ller Strausberg C7 Autosys/Dagosoft Win10 (Globalcube-PC)
+Console (GlobalCube01);Rueschkamp C11 OPTIMA WS16
+Console (GlobalCube01);Rueschkamp C11 OPTIMA/LOCOSOFT WS16
+Console (GlobalCube2012);Lausse C7 Optima Win10
+Console (GlobalCube2025);La Linea C7 Autosys/Dagosoft W11 (GlobalCube2025)
+Console (GlobalCubeNUC);J�st C11 OPTIMA/LOCOSOFT Win10 NUC
+Console (gwmis1);G�ma Wertheim C7 Filaks WS19 (gwmis1)
+Console (he-apps03);global-cube7 (Server 2025) WS25
+Console (hs-21743);Winter Bretnig C11 OPTIMA WS19 (hs-21743#5)
+Console (hs-53364);VCRR LUEG C11 OPTIMA (hs-53364 - van Eupen)
+Console (HS-55551);K�nig Berlin C7 OPTIMA WS19 (Rechenzentrum)
+Console (HS-55551);K�nig Berlin C7 Optima WS19 (Rechenzentrum)
+Console (HS-55552);K�nig Berlin C11 OPTIMA WS19 Rechenzentrum
+Console (HS-55552);
+Console (Jansen-GC2);Jansen C11 AUDEV WS16
+Console (Jansen-GC2);Jansen C11 AUDEV/Dagosoft WS16
+Console (KERBIc);Konrad C7 Autosys Win7 (KERBIc)
+Console (lax-mis);Automag C11 ARI WS19 (lax-mis)
+Console (PC121);Hannuschka Interims-PC (PC121#004)
+Console (ruo-apache);Reichstein & Opitz C7 Autosys WS19 (ruo-apache#5)
+Console (RUO-GlobalCube);Reichstein & Opitz C11 OPTIMA WS19 (RUO-GlobalCube)
+Console (S-Cube);von der Weppen C11 WERWISO WS16 (S-Cube)
+Console (SERVER16);Tobaben C7 Optima WS19 (SERVER16#8)
+Console (SGBIWH01);Hasler C11 AUTOLINE WS22
+Console (sievers-group);Sievers-Group C11 WERWISO Win10 Testumgebung
+Console (SMMMIS01);Reisacher C7 Navision WS12 (SMMMIS01#2)
+Console (SMMMIS01);
+Console (SMMMIS02);Reisacher C11 NAVISION WS22 (SMMMIS02#7)
+Console (SNDGAPS);Nefzger C11 NAVISION WS19 (SNDGAPS)
+Console (SNDGAPS);Nefzger C11 ARI/NAVISION WS19 (SNDGAPS)
+Console (SRV-APP01-Ford);Wahl-Group C7 Optima WS22 (SRV-APP01-Ford)
+Console (SRV-APP4);M�ller Freising C11 WERWISO WS16
+Console (SRV-APP4);M�ller Freising C11 WERWISO WS16 ahm.gmbh
+Console (SRV-FILE01);Schmelter C7 Optima WS16 (SRV-FILE01#79)
+Console (SRV01);Elspass C7 Locosoft WS12
+Console (SRVAP04);Hoffmann, Saalfeld C7 optima WS19 (SRVAP04)
+Console (SRVAP04);Hoffmann Saalfeld C7 Optima WS19 (SRVAP04)
+Console (SrvGC01);Greiner C11 LOCOSOFT WS22 (SrvGC01)
+Console (SRVMVCGC01);MVC Wien C7 neuer Server SRVMVCGC01
+Console (Station55);Gerds C11 CARLO Win10
+Console (svahl142);Luchtenberg C7 Optima WS19 (svahl142)
+Console (SVBLGC02);Schachtschneider C11 LOCOSOFT WS19 (SVBLGC02)
+Console (TSDE021811);Zumbuelt C7 Optima WS19 (TSDE021811)
+Console (TSDE195312);Russig C7 Optima WS12 (TSDE195312)
+Console (TSDE209712);Arnh�lter C7 Optima WS16 (TSDE209712#2)
+Console (vmgc);Rau Brunsb�ttel C7 Optima Win10 (vmgc#6)
+Console (VPN2);VPN2 (VPN-DK, Iveco, Hymer)
+Console (VPN_DK);VM Toni (VPN-DK, Van Eupen, Winter, Elspass, Schneider-Gruppe)
+Console (w16daten01);Auto Epple C7 CARLO WS16 (w16daten01)
+Console (W2K19GLOBALCUBE);K�rner C11 LOCOSOFT WS19 (W2K19GLOBALCUBE)
+Console (w2k22app05);G�ndle C11 ARI (w2k22app05)
+Console (WEL01GC01);Weller Bietigheim OPTIMA C11 WS22 (WEL01GC01)
+Console (win-bcm);Weller Wetzlar C7 Autosys/Dagosoft WS19 (win-bcm)
+Console (WINSV3);ABL Service C7 Optima WS08 (WINSV3)
+dracaradmin (GC01PICH);Pichel Chemnitz Dracar+ WS19 (GC01PICH)
+dracaradmin (GC01PIHD);Pichel Hartmannsdorf Dracar+ WS19 (GC01PIHD#1)
+e555inho (TS-13DR53);
+ecatsrv (APP01);F�rster C7 Autosys WS12 (APP01#9)
+ellad (LAPTOP-IBBBGQC1);
+ellad (LAPTOP-IBBBGQC1);Ella
+fib1 (TSDE555813);
+GAPS (DE212070S00027);Berkemeier C11 CARLO WS16
+GAPS (DE212070S00027);Berkemeier C11 CARLO/DATEV WS16
+GAPS (DE212070S00027);Berkemeier Saerbeck C11 CARLO WS16
+GAPS (global-cube);Hedtke C11 HS WS16 (global-cube#7)
+GAPS (global-cube);Hedtke C11 HS/P2 WS16 (global-cube#7)
+GAPS (global-cube);Hedtke alt C11 HS/P2 WS16 (global-cube#7)
+gcadm (1120GlobalCube);Vogl C11 ARI WS19
+gcube (TPDE121311);Elmer  C7 Optima WS12
+giha (0935wsw02);
+global (SMMMIS01);Reisacher C7 Navision WS12 (SMMMIS01#2)
+global (SMMMIS01);
+global (SMMMIS02);Reisacher C11 NAVISION WS22 (SMMMIS02#7)
+global (SMMMIS02);
+global (SMMMIS02);Reisacher C11 NAVISION/ARI WS22 (SMMMIS02#7)
+Global (TOSCON1);Timmermanns C7 Navision WS19 (TOSCON)
+Global (TOSCON1);Timmermanns C7 Navision WS19 (TOSCON1)
+Global (TOSCON1);Timmermanns C7/C11 Navision/ARI WS19 (TOSCON1)
+Global Cube (2322GlobalCube);Weis C11 LOCOSOFT WS19 (2322GlobalCube#5)
+Global Cube (AB-GlobalCube);Bichmann C11 OPTIMA WS22
+Global Cube (AB-GlobalCube);Bichmann C11 OPTIMA_SKR51 WS22
+Global Cube (ABA-SRV-APP01);Bieling C11
+Global Cube (ABA-SRV-APP01);
+Global Cube (ABA-SRV-APP01);Bieling C11 LOCOSOFT WS22
+Global Cube (AHK-CUBE);Kleinemeier C11 WERWISO Win10 (AHK-CUBE)
+Global Cube (AHRAAP03);Rastetter C11 WERWISO WS19 (AHRAAP03)
+Global Cube (AHRAAP03);Rastetter WERWISO WS19 (AHRAAP03#1)
+Global Cube (AHRAAP03);gek�ndigt - Rastetter WERWISO/DATEV WS19 (AHRAAP03#1)
+Global Cube (AHT-S-GCBS-01);Tabor C11 OPTIMA WS19
+Global Cube (AMD-GCube-01);Darmas C11 CARLO WS22 (AMD-GCube-01)
+Global Cube (AMD-GCube-01);Darmas C11 CARLO/LOCOSOFT WS22 (AMD-GCube-01)
+Global Cube (AMD-GCube-01);Darmas C11 CARLO/LOCOSOFT/SAP WS22 (AMD-GCube-01)
+Global Cube (AMD-GCube-01);Darmas /Tiemeyer C11 CARLO/LOCOSOFT/SAP WS22 (AMD-GCube-01)
+Global Cube (APP039);Brass C11 OPTIMA WS25 (global-cube7)
+Global Cube (APP039);Brass/Jacob C11 OPTIMA WS25
+Global Cube (ASHKSCUBE01);Schmid C11 LOCOSOFT WS19 (ASHKSCUBE01)
+Global Cube (berkem-bi-01);Berkemeier M�nster C11 DATEV/ATTRIBUT/(CARLO) WS25
+Global Cube (COGNOS11);Toennemann C11 CARLO Win10 (COGNOS11#0)
+Global Cube (Cube);Liegert C11 LOCOSOFT Win10
+Global Cube (CZ-WN-GlobalMgmt);Czeczelits C11 OPTIMA WS16
+Global Cube (DE0017GC);B�ttche C11 CARLO WS19 (DE0017GC)
+Global Cube (gc-server6);gc-server6
+Global Cube (GCDE073502);Brass C11 OPTIMA Win10 (GCDE073502)
+Global Cube (GCDE073502);Brass C11 OPTIMA_SKR51 Win10 (GCDE073502)
+Global Cube (GCDE073502);
+Global Cube (GCUDE028621);Lackermann C11 LOCOSOFT WS22 (GCUDE028621)
+Global Cube (gierathsgc01);Gieraths C11 LOCOSOFT WS19 (gierathsgc01)
+Global Cube (gierathsgc01);Gieraths C11 LOCOSOFT WS25 (gierathsgc01)
+Global Cube (Global-Cube);Hermann C11 WERWISO WS19
+Global Cube (global-cube);Ley Bergneustadt C11 OPTIMA Win10 NUC
+Global Cube (global-cube);
+Global Cube (global-cube);Nolte C11 OPTIMA_SKR51 WS22
+Global Cube (global-cube);Nolte C11 OPTIMA_SKR51 WS10
+Global Cube (global-cube);Nolte C11 OPTIMA_SKR51 W10
+Global Cube (Global-Cube);Hermann C11 WERWISO/DATEV WS19
+Global Cube (global-cube);Nolte C11 OPTIMA_SKR51 Win10
+Global Cube (global-cube-neu);SundK Hamburg C12 WERWISO/DATEV WS25
+Global Cube (Global-Cube-VM);Barth & Frey C11 OPTIMA WS16 (Global-Cube-VM)
+Global Cube (Global-Cube-VM);Barth & Frey C11 OPTIMA WS16  (Global-Cube-VM#8)
+Global Cube (Global-Cube-VM);Barth & Frey C11 OPTIMA_SKR51 WS16  (Global-Cube-VM#8)
+Global Cube (Global-Cube-VM);
+Global Cube (global-cube1);Greiner C11 LOCOSOFT WS12
+Global Cube (global-cube2);Guenther & Schmitt C11 CARLO WS16
+Global Cube (global-cube2);Willi Mueller C11 AUDEV WS16
+Global Cube (global-cube2);Bunk C11 WERWISO WS16
+Global Cube (global-cube2);Guenther u. Schmitt C11 CARLO WS16
+Global Cube (global-cube2);Bunk C11 WERWISO/DATEV WS16
+Global Cube (global-cube2);Willi Mueller C11 AUDEV WS16 ford-mueller.de
+Global Cube (global-cube3);Ulmen C11 CARLO WS19
+Global Cube (global-cube3);Moll C11 LOCOSOFT WS19
+Global Cube (global-cube3);global-cube3 (Server2019) WS19
+Global Cube (global-cube3);
+Global Cube (global-cube3);SundK C11 WERWISO WS19
+Global Cube (global-cube3);Linck C11 CARLO WS19 (global-cube3)
+Global Cube (global-cube3);Linck C12 CARLO WS19 (global-cube3)
+Global Cube (global-cube3);Bekirovski C11 LOCOSOFT WS19
+Global Cube (global-cube3);K�nig C12 Eisenhut (global-cube3#84)
+Global Cube (global-cube3);K�nig Berlin C12 Eisenhut (global-cube3#84)
+Global Cube (global-cube3);SundK C11 WERWISO/DATEV WS19
+Global Cube (global-cube3);Becker-Tiemann Bielefeld C11 ARI WS19
+Global Cube (global-cube3);SundK Hamburg C11 WERWISO/DATEV WS19
+Global Cube (global-cube3);SundK alt Hamburg C11 WERWISO/DATEV WS19
+Global Cube (global-cube4);Boehm C11 AUDEV Win10 NUC
+Global Cube (global-cube4);Zumbuelt C11 LOCOSOFT Win10
+Global Cube (global-cube4);global-cube4 (Win 10)
+Global Cube (global-cube4);
+Global Cube (global-cube4);Boehm C11 AUDEV/LOCOSOFT Win10 NUC
+Global Cube (global-cube4);Nolte C11
+Global Cube (global-cube6);
+Global Cube (global-cube6);Premium Cars Peters C11 LOCOSOFT (WS22)
+Global Cube (global-cube6);Premium Cars Peters C11 LOCOSOFT/DATEV (WS22)
+Global Cube (global-cube6);Aurego C11 OPTIMA WS22 (globalcube6)
+Global Cube (global-cube6);Auto Epple Opel SKR51 C11 CARLO WS22
+Global Cube (global-cube7);
+Global Cube (global-cube7);Stange C11
+Global Cube (global-cube7);Stange C11 LOCOSOFT WS25
+Global Cube (globalcube);HIRO C11 LOCOSOFT WS19 (globalcube)
+Global Cube (globalcube);H�usler C11 CARLO WS12
+Global Cube (GlobalCube);Loeffler C11 LOCOSOFT Win10 NUC
+Global Cube (GlobalCube);Heidenreich C11 OPTIMA WS19 (GlobalCube#8)
+Global Cube (GLOBALCUBE);Jacob C11 OPTIMA WS16
+Global Cube (GlobalCube);Lutz C11 LOCOSOFT Win10
+Global Cube (GlobalCube);Lutz C11 LOCOSOFT Win10 (GlobalCube#38)
+Global Cube (GlobalCube);Lutz C11 LOCOSOFT/DATEV Win10 (GlobalCube#38)
+Global Cube (GlobalCube);Peter Nordhessen (ehem. Heidenreich) C11 OPTIMA WS19 (GlobalCube#8)
+Global Cube (GlobalCube01);Rueschkamp C11 OPTIMA WS16
+Global Cube (GlobalCube01);Rueschkamp C11 OPTIMA/LOCOSOFT WS16
+Global Cube (GlobalCube01);
+Global Cube (GlobalCubeNUC);J�st C11 OPTIMA/LOCOSOFT Win10 NUC
+Global Cube (GlobalCubeNUC);J�st C11 OPTIMA/LOCOSOFT Win11 NUC
+Global Cube (GSGlobalCube);Gottstein C11 ARI WS19 (GSGlobalCube)
+Global Cube (GSGlobalCube);
+Global Cube (GSGlobalCube);Gottstein C12 ARI WS19 (GSGlobalCube)
+Global Cube (he-apps03);Hedtke C11 HS/P2 WS25 (he-apps03)
+Global Cube (he-apps03);
+Global Cube (Jansen-GC2);Jansen C11 AUDEV WS16
+Global Cube (Jansen-GC2);
+Global Cube (RUO-GlobalCube);Reichstein & Opitz C11 AUTOSYS WS19 (RUO-GlobalCube)
+Global Cube (RUO-GlobalCube);Reichstein & Opitz C11 OPTIMA WS19 (RUO-GlobalCube)
+Global Cube (SGBIWH01);Hasler C11 AUTOLINE WS22
+Global Cube (shcgc01);Motor Center Heinen C11
+Global Cube (shcgc01);Heinen Dortmund C11 LOCOSOFT WS22 heinen-nrw.de
+Global Cube (shcgc01);
+Global Cube (sievers-group);sievers-group C11 Win10 (Testumgebung)
+Global Cube (SRV-APP4);M�ller Freising C11 WERWISO WS16
+Global Cube (SRV-APP4);M�ller Freising C11 WERWISO/DATEV WS16 ahm.gmbh
+Global Cube (SrvGC01);Greiner C11 LOCOSOFT WS22 (SrvGC01)
+Global Cube (Station55);Gerds C11 CARLO Win10
+Global Cube (Station55);
+Global Cube (SVBLGC02);Schachtschneider C11 LOCOSOFT WS19 (SVBLGC02)
+Global Cube (SVBLGC02);Schachtschneider C11 LOCOSOFT WS25 (SVBLGC02)
+Global Cube (test-c12);test-c12
+Global Cube (W2K19GLOBALCUBE);K�rner C11 LOCOSOFT WS19 (W2K19GLOBALCUBE)
+Global Cube (w2k22app05);G�ndle AT C11 NAVISION WS22 (w2k22app05)
+Global Cube (WEL01GC01);
+Global Cube (WEL01GC01);Weller Bietigheim OPTIMA C11 WS22 (WEL01GC01)
+Global1 (COGNOS11);Toennemann C11 CARLO Win10 (COGNOS11#0)
+Global1 (VPN2);VPN2 (VPN-DK, Iveco, Hymer)
+Global1 (VPN_DK);VM Toni (VPN-DK, Van Eupen, Winter, Elspass, Schneider-Gruppe)
+Globalcube (APP01);F�rster C7 Autosys WS12 (APP01#9)
+globalcube (azebber-bi);Ebber C7 Audev WS16
+globalcube (azebber-bi);Ebber C7 Audev WS16 (azebber-bi)
+globalcube (berkem-bi-01);
+globalcube (berkem-bi-01);Berkemeier M�nster C11 DATEV/ATTRIBUT/(CARLO) WS25
+globalcube (berkem-bi-01);Berkemeier M??nster C11 DATEV/ATTRIBUT/(CARLO) WS25
+globalcube (C00046);Becker-Tiemann Bielefeld C11 ARI WS19
+globalcube (C00046);
+globalcube (CS-S-GC);Croll & Sondermann  C7 Optima Win10 (CS-S-GC)
+GlobalCube (DE0017GQ);Boettche C7 Carlo WS08 (DE0017GQ)
+GlobalCube (global-cube4);Lausse C11 OPTIMA Win10
+globalcube (global-cube6);Sirch C11 WERWISO WS22(global-cube6#4)
+globalcube (global-cube6);Sirch C11 WERWISO/DATEV WS22(global-cube6#4)
+globalcube (globalcube);Haeusler C11 CARLO WS19 ( globalcube#9)
+globalcube (globalcube);Haeusler C11 CARLO WS12 ( globalcube#9)
+globalcube (globalcube);Haeusler C11 CARLO WS22 ( globalcube#9)
+globalcube (hs-21743);Winter Bretnig C11 OPTIMA WS19 (hs-21743#5)
+globalcube (hs-21743);
+globalcube (hs-53364);VCRR LUEG C11 OPTIMA (hs-53364 - van Eupen)
+GlobalCube (HS-55551);K�nig Berlin C7 OPTIMA WS19 (Rechenzentrum)
+GlobalCube (HS-55551);K�nig Berlin C7 Optima WS19 (Rechenzentrum)
+globalcube (HS-55552);K�nig Berlin C11 OPTIMA WS19 Rechenzentrum
+globalcube (HS-55552);
+globalcube (HS-55552);K??nig Berlin C11 OPTIMA WS19 Rechenzentrum
+Globalcube (S-Cube);von der Weppen C11 WERWISO WS16 (S-Cube)
+gocuadmin (DE0509-GAPS);Siebrecht C7 Optima WS16 (DE0509-GAPS#2)
+hjkl (BF-PC07);
+Mangler (HG-NB2004);
+Mangler (HY-NB0734);
+Margit Bedner (bsb03);
+matth (Matthias_Lenovo);
+Matthias Winter;Reisacher C7 Navision WS12 (SMMMIS01#2)
+mika (WSW08);
+MISadm (lax-mis);Automag C11 ARIntelligence WS19 (lax-mis)
+MISadm (lax-mis);Automag C11 ARI WS19 (lax-mis)
+MISadm (lax-mis);
+NOM-LEITUNG01 (WTS0-2019);
+nzw (GlobalCube);Loeffler C11 LOCOSOFT Win10 NUC
+Psotka (YLTH714162);Psotka C7 Optima Win10 (YLTH714162#3)
+QT10668 (WNWI906362);
+rog (wsw05);
+sbrueckner (AHP01S0007);
+Stat50 (Station50);
+Stat50 (Station50);Dresen C7 Optima WS19(GAPSDE444441)
+t1.rhein (global-cube-neu);
+thme (wse17);
+verkauf (EPC4);Nolte (EPC4#6)
+verkauf (wsw00);
+winkler (GONZO);
+woscadm (1045serv90);

+ 38 - 0
main.py

@@ -0,0 +1,38 @@
+import os
+from pathlib import Path
+
+import typer
+
+from clients import run
+
+app = typer.Typer(help="PC-Visit Filetracker")
+
+
+def default_session_history() -> Path:
+    user_profile = Path(os.environ.get("USERPROFILE", str(Path.home())))
+    return user_profile / "AppData" / "Roaming" / "pcvisit Data" / "Session History"
+
+
+@app.callback(invoke_without_command=True)
+def app_callback(context: typer.Context) -> None:
+    """Verwalten der PC-Visit-Filetracker-Befehle."""
+    if context.invoked_subcommand is None:
+        typer.echo(context.get_help())
+
+
+@app.command()
+def clients(
+    directory: Path | None = typer.Argument(None, help="Verzeichnis mit XML-Dateien"),
+    output: Path = typer.Option(Path("clients.csv"), "--output", "-o", help="Zielpfad der CSV-Datei"),
+) -> None:
+    """Importiert Client-Daten aus Session-XML-Dateien."""
+    directory = directory or default_session_history()
+    try:
+        xml_count, row_count = run(directory, output)
+    except ValueError as error:
+        raise typer.BadParameter(str(error), param_hint="directory") from error
+    typer.echo(f"{xml_count} XML-Dateien gelesen, {row_count} Einträge nach {output} geschrieben.")
+
+
+if __name__ == "__main__":
+    app()

+ 9 - 0
pyproject.toml

@@ -0,0 +1,9 @@
+[project]
+name = "pc-visit-filetracker"
+version = "0.1.0"
+description = "Add your description here"
+readme = "README.md"
+requires-python = ">=3.13"
+dependencies = [
+    "typer>=0.27.1",
+]

+ 23 - 0
samples/2026-07-30-104742_34843777.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SessionLog lang="de-DE">
+	<Session HostName="Robert Burghard" StartTime="2026-07-30T10:47:42" SessionID="34843777" Duration="80683">
+		<Participant Name="Robert Burghard" Role="ROLE_SUPPORTER"/>
+		<UserActivity Name="Robert Burghard" Activity="Robert Burghard hat die Fernwartung begonnen." Type="SupportAndPresentationMode" DateTime="2026-07-30T10:47:42"/>
+		<Participant Name="Console (global-cube2)" Role="ROLE_REMOTE_HOST"/>
+		<UserActivity Name="Robert Burghard" Activity="Console (global-cube2) ist der Fernwartung beigetreten." Type="SessionAndUsers" DateTime="2026-07-30T10:47:43"/>
+		<UserActivity Name="Robert Burghard" Activity="Console (global-cube2) zeigt seinen Bildschirm." Type="SupportAndPresentationMode" DateTime="2026-07-30T10:47:43"/>
+		<UserActivity Name="Robert Burghard" Activity="Robert Burghard steuert das System von Console (global-cube2) fern." Type="SupportAndPresentationMode" DateTime="2026-07-30T10:47:43"/>
+		<UserActivity Name="Robert Burghard" Activity="Console (global-cube2) zeigt seinen Bildschirm." Type="SupportAndPresentationMode" DateTime="2026-07-30T10:47:54"/>
+		<UserActivity Name="Robert Burghard" Activity="C:/Users/Administrator/Desktop/dagocar ODBC/zwingend notwendige Java Version für ODBC Treiber.txt wird von Robert Burghard zum Supporter übertragen." Type="FileTransfer" DateTime="2026-07-30T10:53:45"/>
+		<ReceivedFile Sender="Robert Burghard" Receiver="Robert Burghard" Name="C:/Users/Administrator/Desktop/dagocar ODBC/zwingend notwendige Java Version für ODBC Treiber.txt" DateTime="2026-07-30T10:53:45"/>
+		<UserActivity Name="Robert Burghard" Activity="Die Übertragung von C:/Users/Administrator/Desktop/dagocar ODBC/zwingend notwendige Java Version für ODBC Treiber.txt wurde beendet." Type="FileTransfer" DateTime="2026-07-30T10:53:45"/>
+		<UserActivity Name="Robert Burghard" Activity="C:/Users/Administrator/Desktop/dagocar ODBC/BBjODBC19_12-12-2019_1445.7z wird von Robert Burghard zum Supporter übertragen." Type="FileTransfer" DateTime="2026-07-30T10:53:45"/>
+		<ReceivedFile Sender="Robert Burghard" Receiver="Robert Burghard" Name="C:/Users/Administrator/Desktop/dagocar ODBC/BBjODBC19_12-12-2019_1445.7z" DateTime="2026-07-30T10:53:53"/>
+		<UserActivity Name="Robert Burghard" Activity="Die Übertragung von C:/Users/Administrator/Desktop/dagocar ODBC/BBjODBC19_12-12-2019_1445.7z wurde beendet." Type="FileTransfer" DateTime="2026-07-30T10:53:53"/>
+		<UserActivity Name="Robert Burghard" Activity="Console (global-cube2) zeigt seinen Bildschirm." Type="SupportAndPresentationMode" DateTime="2026-07-31T04:01:04"/>
+		<UserActivity Name="Robert Burghard" Activity="Robert Burghard hat die Fernwartung beendet." Type="SupportAndPresentationMode" DateTime="2026-07-31T09:12:25"/>
+		<UserActivity Name="Robert Burghard" Activity="Console (global-cube2) wurde aufgefordert die Fernwartung zu verlassen." Type="SessionAndUsers" DateTime="2026-07-31T09:12:25"/>
+		<SessionDescription Name="ClientName" Description="Willi Mueller C11 AUDEV/Dagosoft WS16 ford-mueller.de" Index="13"/>
+	</Session>
+</SessionLog>
+

+ 5 - 0
tox.ini

@@ -0,0 +1,5 @@
+[flake8]
+ignore = E203, E712, W503, W504
+max-line-length = 140
+# exclude = tests/*
+# max-complexity = 10

+ 99 - 0
uv.lock

@@ -0,0 +1,99 @@
+version = 1
+revision = 3
+requires-python = ">=3.13"
+
+[[package]]
+name = "annotated-doc"
+version = "0.0.5"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/5a/8e/38aa427ed5402449e226975b649c5dc73ccadfefeb95e6aecb8f8ea4b6b6/annotated_doc-0.0.5.tar.gz", hash = "sha256:c7e58ce09192557605d8bbd92836d7e1d520ac9580096042c0bfd197efacf1bb", size = 10758, upload-time = "2026-07-28T13:50:58.129Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/3e/30/e900b21425a860e195f32e37657aa1f7c7f2b1bfb26f03ca209b90933c06/annotated_doc-0.0.5-py3-none-any.whl", hash = "sha256:117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101", size = 5302, upload-time = "2026-07-28T13:50:57.239Z" },
+]
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
+]
+
+[[package]]
+name = "markdown-it-py"
+version = "4.2.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "mdurl" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" },
+]
+
+[[package]]
+name = "mdurl"
+version = "0.1.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
+]
+
+[[package]]
+name = "pc-visit-filetracker"
+version = "0.1.0"
+source = { virtual = "." }
+dependencies = [
+    { name = "typer" },
+]
+
+[package.metadata]
+requires-dist = [{ name = "typer", specifier = ">=0.27.1" }]
+
+[[package]]
+name = "pygments"
+version = "2.21.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" },
+]
+
+[[package]]
+name = "rich"
+version = "15.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "markdown-it-py" },
+    { name = "pygments" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" },
+]
+
+[[package]]
+name = "shellingham"
+version = "1.5.4"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" },
+]
+
+[[package]]
+name = "typer"
+version = "0.27.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "annotated-doc" },
+    { name = "colorama", marker = "sys_platform == 'win32'" },
+    { name = "rich" },
+    { name = "shellingham" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ae/40/4a3db7990d1f62a53182aa96eaef57aeb2886a27f90a195bc66713565d31/typer-0.27.1.tar.gz", hash = "sha256:a79bef8469a79c45498e7b814ecf8d603cc7644e9acbd9e19cac0334240b18df", size = 203994, upload-time = "2026-08-03T14:41:03.438Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/43/89/9518bc0c3929bee36b3a4a8e3daddd6e03f92f9961c66d4983b837160543/typer-0.27.1-py3-none-any.whl", hash = "sha256:53150287edd11baeb4e4722c8e394fcdf8181c0ae89485cba8d25c778d5edd56", size = 122874, upload-time = "2026-08-03T14:41:04.391Z" },
+]