fpptools 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,119 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+ MANIFEST
27
+
28
+ # PyInstaller
29
+ # Usually these files are written by a python script from a template
30
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
31
+ *.manifest
32
+ *.spec
33
+
34
+ # Installer logs
35
+ pip-log.txt
36
+ pip-delete-this-directory.txt
37
+
38
+ # Unit test / coverage reports
39
+ htmlcov/
40
+ .tox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ .hypothesis/
48
+ .pytest_cache/
49
+
50
+ # Translations
51
+ *.mo
52
+ *.pot
53
+
54
+ # Django stuff:
55
+ *.log
56
+ local_settings.py
57
+ db.sqlite3
58
+
59
+ # Flask stuff:
60
+ instance/
61
+ .webassets-cache
62
+
63
+ # Scrapy stuff:
64
+ .scrapy
65
+
66
+ # Sphinx documentation
67
+ docs/_build/
68
+
69
+ # PyBuilder
70
+ target/
71
+
72
+ # Jupyter Notebook
73
+ .ipynb_checkpoints
74
+
75
+ # pyenv
76
+ .python-version
77
+
78
+ # celery beat schedule file
79
+ celerybeat-schedule
80
+
81
+ # SageMath parsed files
82
+ *.sage.py
83
+
84
+ # Environments
85
+ .env
86
+ .venv
87
+ env/
88
+ venv/
89
+ ENV/
90
+ env.bak/
91
+ venv.bak/
92
+
93
+ # Spyder project settings
94
+ .spyderproject
95
+ .spyproject
96
+
97
+ # Rope project settings
98
+ .ropeproject
99
+
100
+ # mkdocs documentation
101
+ /site
102
+
103
+ # mypy
104
+ .mypy_cache/
105
+
106
+ # fpptools runtime output
107
+ fpptools_backups/
108
+ *.fpptools.tmp
109
+
110
+ # standalone exes (scripts/build_exe.ps1); dist/ holds only the PyPI wheel/sdist
111
+ dist_exe/
112
+
113
+ # outputs fpptools writes in the working folder, and archives
114
+ *.7z
115
+ estructuras*.xlsx
116
+ structures.csv
117
+ structures.xlsx
118
+ fittings_*.csv
119
+ fittinglist_*.csv
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 (unreleased)
4
+
5
+ Rewrite for current Python and FP Pro 11.
6
+
7
+ ### Added
8
+ - `fpptools str list`: structures with folder, name, unique code (NameStr) and description (decoded from Base64). CSV (`;`, UTF-8 BOM) or `.xlsx`, `--lang es`.
9
+ - `fpptools_estructuras.exe` / `fpptools-estructuras`: double-click export of structures to `estructuras.xlsx` next to the exe.
10
+ - `fpptools config`: show the active configuration (password hidden).
11
+ - `fpptools wipe panedefs` and `fpptools wipe kits`: simulate by default; `--apply` backs up every file first and writes a report.
12
+ - `--under`, `--match`, `--root` on every folder-scanning command; `--ini` / `FPPTOOLS_INI` on all commands.
13
+ - Tests with generic fixtures.
14
+
15
+ ### Changed
16
+ - `list_fittings` is now `fpptools fit list` (old syntax kept as a hidden, deprecated alias). Output is CSV with `;`; columns Folder, File, Fitting, Source, Note.
17
+ - Job selection uses `--job NAME` (prompted if missing).
18
+ - Rewritten files keep FP Pro's format: original XML declaration, windows-1252, CRLF.
19
+ - Packaging: uv + hatchling, Python >= 3.10, click 8, lxml 5+, PyMySQL 1.x, pyodbc 5 (Windows only).
20
+
21
+ ### Fixed
22
+ - Importing fpptools no longer reads FP_PRO.INI or connects to the database (`--help` works without FP Pro).
23
+ - MySQL now uses `DB_PORT` and `DB_CHARSET` from FP_PRO.INI (defaults 3306 and latin1 when missing or empty).
24
+ - Access kits query no longer exhausts its cursor after the first file.
25
+ - Clean error messages instead of tracebacks when the INI, folders or database are missing.
26
+
27
+ ## 0.1.1
28
+
29
+ - `list_fittings` for str/blk/job/jobs.
fpptools-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Andres Perez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,129 @@
1
+ Metadata-Version: 2.5
2
+ Name: fpptools
3
+ Version: 0.2.0
4
+ Summary: Administration and debugging CLI for emmegisoft FP Pro (structures, blocks, jobs)
5
+ Project-URL: Repository, https://github.com/andoresuperesu/fpptools
6
+ Author-email: Andres Perez <andresperezcera@gmail.com>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Environment :: Console
10
+ Classifier: Environment :: Win32 (MS Windows)
11
+ Classifier: Operating System :: Microsoft :: Windows
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
14
+ Classifier: Topic :: Utilities
15
+ Requires-Python: >=3.10
16
+ Requires-Dist: click>=8.1
17
+ Requires-Dist: lxml>=5.0
18
+ Requires-Dist: openpyxl>=3.1
19
+ Requires-Dist: pymysql>=1.1
20
+ Requires-Dist: pyodbc>=5.0; sys_platform == 'win32'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # fpptools
24
+
25
+ Administration and debugging command line for emmegisoft **FP Pro**: structures (`.STR`), blocks (`.BLK`) and job records.
26
+ It works on the configuration that is **active in FP Pro right now** (read from `%APPDATA%\Emmegisoft\FP_PRO\FP_PRO.INI`).
27
+
28
+ *Guía rápida en español más abajo.*
29
+
30
+ ## Install
31
+
32
+ ```powershell
33
+ pip install fpptools # or: uv tool install fpptools
34
+ fpptools --help
35
+ ```
36
+
37
+ Standalone exes (no Python needed) are built with `scripts\build_exe.ps1`:
38
+
39
+ - `fpptools.exe`: the full command line.
40
+ - `fpptools_estructuras.exe`: **double-click** to export the structures of the active configuration to `estructuras.xlsx` next to the exe (same as `fpptools str list --lang es -o estructuras.xlsx`). If that file is open in Excel, it writes `estructuras_<date_time>.xlsx` instead. Also installed as the `fpptools-estructuras` command.
41
+
42
+ ## Commands
43
+
44
+ | Command | What it does |
45
+ |---|---|
46
+ | `fpptools config` | Show the active configuration: folders, database (password hidden) |
47
+ | `fpptools str list` | List structures: folder, name, unique code, description |
48
+ | `fpptools fit list` | List fittings used in structures, blocks, one job or all jobs (kits expanded from the database) |
49
+ | `fpptools wipe panedefs` | Remove glass fittings, glass DXF and pane table from every pane of the structures |
50
+ | `fpptools wipe kits` | Remove every kit from structures or blocks |
51
+
52
+ Every command has `--help`.
53
+
54
+ ### Choosing files
55
+
56
+ Commands that read STR/BLK folders accept:
57
+
58
+ - `--under FOLDER`: only that folder of the tree, e.g. `--under 019_SERIE_22_PESADO`
59
+ - `--match PATTERN`: file name pattern without extension, e.g. `--match "VTA_*"` (case-insensitive)
60
+ - `--root FOLDER`: another folder instead of the one in FP_PRO.INI
61
+
62
+ ### Output
63
+
64
+ `--out file.csv` (default), `--out file.xlsx`, or `--out -` for the console.
65
+ CSV files use `;` and UTF-8 with BOM, so Excel opens them correctly with accents. `--lang es` writes Spanish headers.
66
+
67
+ ### Commands that modify files: simulate first
68
+
69
+ `wipe` commands **only simulate** by default: they report what would change and write nothing.
70
+ Add `--apply` to write. Before writing, every file is copied to `--backup-dir` (default `.\fpptools_backups\<date_time>\`, same sub-folders) together with a `report.txt`. To undo, copy the backed-up files back.
71
+
72
+ ```powershell
73
+ fpptools wipe panedefs --under "LINEA X" # simulation
74
+ fpptools wipe panedefs --under "LINEA X" --apply # backup + write
75
+ ```
76
+
77
+ Close the structures in FP Pro before applying.
78
+
79
+ ### Structure fields
80
+
81
+ | Column | Where it comes from |
82
+ |---|---|
83
+ | Folder | Folder of the file inside STR_PATH (the tree in FP Pro's structure browser) |
84
+ | Name | File name without `.STR` (the "Nombre" field in FP Pro) |
85
+ | Unique code | `FP_TREE/@NameStr` ("nombre unívoco" in FP Pro) |
86
+ | Description | `FP_TREE/FP_DESCRIPTION`, stored as Base64 inside the file |
87
+
88
+ ### Database
89
+
90
+ `fit list` reads kits from the FP Pro database of the active configuration: MySQL (`CONN_STR_FP_PRO=1`, settings in `[MYSQL]`) or Access (`Fp_Pro32.MDB` in `MDB_PATH`). Queries are read-only.
91
+ Access needs the Microsoft Access ODBC driver with the same bitness (32/64-bit) as Python. Use `--no-db` to skip the database.
92
+
93
+ ### Other options
94
+
95
+ - `--ini PATH` (or environment variable `FPPTOOLS_INI`): use another FP_PRO.INI.
96
+ - `fpptools list_fittings --searchtype str` (0.1 syntax) still works but is deprecated.
97
+
98
+ ---
99
+
100
+ ## Guía rápida (español)
101
+
102
+ `fpptools` trabaja sobre la configuración **activa en FP Pro**.
103
+
104
+ **Exportar nombre y descripción de las estructuras:**
105
+
106
+ ```powershell
107
+ fpptools str list --lang es -o estructuras.xlsx
108
+ fpptools str list --under 019_SERIE_22_PESADO --lang es -o serie22.csv
109
+ ```
110
+
111
+ Columnas: Carpeta, Nombre (nombre del archivo), Nombre único (nombre unívoco), Descripción.
112
+
113
+ **Sin línea de comandos:** doble clic en `fpptools_estructuras.exe`. Crea `estructuras.xlsx` en la misma carpeta del programa (si está abierto en Excel, crea `estructuras_<fecha_hora>.xlsx`). El programa debe estar en una carpeta donde se pueda escribir (no en `C:\Program Files`).
114
+
115
+ **Comandos que modifican archivos** (`wipe`): por defecto solo **simulan** y muestran qué cambiarían. Con `--apply` primero copian los originales a `fpptools_backups\<fecha_hora>\` y luego escriben. Cierre las estructuras en FP Pro antes de aplicar.
116
+
117
+ `fpptools config` muestra qué configuración, carpetas y base de datos está usando.
118
+
119
+ ## Development
120
+
121
+ ```powershell
122
+ uv sync
123
+ uv run pytest
124
+ uv run fpptools --help
125
+ uv build ; uv publish # PyPI
126
+ .\scripts\build_exe.ps1 # dist_exe\fpptools.exe, dist_exe\fpptools_estructuras.exe (not in dist\: that is PyPI's)
127
+ ```
128
+
129
+ License: MIT.
@@ -0,0 +1,107 @@
1
+ # fpptools
2
+
3
+ Administration and debugging command line for emmegisoft **FP Pro**: structures (`.STR`), blocks (`.BLK`) and job records.
4
+ It works on the configuration that is **active in FP Pro right now** (read from `%APPDATA%\Emmegisoft\FP_PRO\FP_PRO.INI`).
5
+
6
+ *Guía rápida en español más abajo.*
7
+
8
+ ## Install
9
+
10
+ ```powershell
11
+ pip install fpptools # or: uv tool install fpptools
12
+ fpptools --help
13
+ ```
14
+
15
+ Standalone exes (no Python needed) are built with `scripts\build_exe.ps1`:
16
+
17
+ - `fpptools.exe`: the full command line.
18
+ - `fpptools_estructuras.exe`: **double-click** to export the structures of the active configuration to `estructuras.xlsx` next to the exe (same as `fpptools str list --lang es -o estructuras.xlsx`). If that file is open in Excel, it writes `estructuras_<date_time>.xlsx` instead. Also installed as the `fpptools-estructuras` command.
19
+
20
+ ## Commands
21
+
22
+ | Command | What it does |
23
+ |---|---|
24
+ | `fpptools config` | Show the active configuration: folders, database (password hidden) |
25
+ | `fpptools str list` | List structures: folder, name, unique code, description |
26
+ | `fpptools fit list` | List fittings used in structures, blocks, one job or all jobs (kits expanded from the database) |
27
+ | `fpptools wipe panedefs` | Remove glass fittings, glass DXF and pane table from every pane of the structures |
28
+ | `fpptools wipe kits` | Remove every kit from structures or blocks |
29
+
30
+ Every command has `--help`.
31
+
32
+ ### Choosing files
33
+
34
+ Commands that read STR/BLK folders accept:
35
+
36
+ - `--under FOLDER`: only that folder of the tree, e.g. `--under 019_SERIE_22_PESADO`
37
+ - `--match PATTERN`: file name pattern without extension, e.g. `--match "VTA_*"` (case-insensitive)
38
+ - `--root FOLDER`: another folder instead of the one in FP_PRO.INI
39
+
40
+ ### Output
41
+
42
+ `--out file.csv` (default), `--out file.xlsx`, or `--out -` for the console.
43
+ CSV files use `;` and UTF-8 with BOM, so Excel opens them correctly with accents. `--lang es` writes Spanish headers.
44
+
45
+ ### Commands that modify files: simulate first
46
+
47
+ `wipe` commands **only simulate** by default: they report what would change and write nothing.
48
+ Add `--apply` to write. Before writing, every file is copied to `--backup-dir` (default `.\fpptools_backups\<date_time>\`, same sub-folders) together with a `report.txt`. To undo, copy the backed-up files back.
49
+
50
+ ```powershell
51
+ fpptools wipe panedefs --under "LINEA X" # simulation
52
+ fpptools wipe panedefs --under "LINEA X" --apply # backup + write
53
+ ```
54
+
55
+ Close the structures in FP Pro before applying.
56
+
57
+ ### Structure fields
58
+
59
+ | Column | Where it comes from |
60
+ |---|---|
61
+ | Folder | Folder of the file inside STR_PATH (the tree in FP Pro's structure browser) |
62
+ | Name | File name without `.STR` (the "Nombre" field in FP Pro) |
63
+ | Unique code | `FP_TREE/@NameStr` ("nombre unívoco" in FP Pro) |
64
+ | Description | `FP_TREE/FP_DESCRIPTION`, stored as Base64 inside the file |
65
+
66
+ ### Database
67
+
68
+ `fit list` reads kits from the FP Pro database of the active configuration: MySQL (`CONN_STR_FP_PRO=1`, settings in `[MYSQL]`) or Access (`Fp_Pro32.MDB` in `MDB_PATH`). Queries are read-only.
69
+ Access needs the Microsoft Access ODBC driver with the same bitness (32/64-bit) as Python. Use `--no-db` to skip the database.
70
+
71
+ ### Other options
72
+
73
+ - `--ini PATH` (or environment variable `FPPTOOLS_INI`): use another FP_PRO.INI.
74
+ - `fpptools list_fittings --searchtype str` (0.1 syntax) still works but is deprecated.
75
+
76
+ ---
77
+
78
+ ## Guía rápida (español)
79
+
80
+ `fpptools` trabaja sobre la configuración **activa en FP Pro**.
81
+
82
+ **Exportar nombre y descripción de las estructuras:**
83
+
84
+ ```powershell
85
+ fpptools str list --lang es -o estructuras.xlsx
86
+ fpptools str list --under 019_SERIE_22_PESADO --lang es -o serie22.csv
87
+ ```
88
+
89
+ Columnas: Carpeta, Nombre (nombre del archivo), Nombre único (nombre unívoco), Descripción.
90
+
91
+ **Sin línea de comandos:** doble clic en `fpptools_estructuras.exe`. Crea `estructuras.xlsx` en la misma carpeta del programa (si está abierto en Excel, crea `estructuras_<fecha_hora>.xlsx`). El programa debe estar en una carpeta donde se pueda escribir (no en `C:\Program Files`).
92
+
93
+ **Comandos que modifican archivos** (`wipe`): por defecto solo **simulan** y muestran qué cambiarían. Con `--apply` primero copian los originales a `fpptools_backups\<fecha_hora>\` y luego escriben. Cierre las estructuras en FP Pro antes de aplicar.
94
+
95
+ `fpptools config` muestra qué configuración, carpetas y base de datos está usando.
96
+
97
+ ## Development
98
+
99
+ ```powershell
100
+ uv sync
101
+ uv run pytest
102
+ uv run fpptools --help
103
+ uv build ; uv publish # PyPI
104
+ .\scripts\build_exe.ps1 # dist_exe\fpptools.exe, dist_exe\fpptools_estructuras.exe (not in dist\: that is PyPI's)
105
+ ```
106
+
107
+ License: MIT.
@@ -0,0 +1,3 @@
1
+ """fpptools: administration and debugging CLI for emmegisoft FP Pro."""
2
+
3
+ __version__ = "0.2.0"
@@ -0,0 +1,6 @@
1
+ """Allows `python -m fpptools` and is the PyInstaller entry script."""
2
+
3
+ from fpptools.cli import main
4
+
5
+ if __name__ == "__main__":
6
+ main()
@@ -0,0 +1,29 @@
1
+ """Shared CLI state passed to every command."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ import click
8
+
9
+ from fpptools import config
10
+
11
+
12
+ class App:
13
+ """The FP Pro configuration is loaded only when a command needs it."""
14
+
15
+ def __init__(self, ini: Path | None):
16
+ self._ini = ini
17
+ self._cfg: config.FppConfig | None = None
18
+
19
+ @property
20
+ def cfg(self) -> config.FppConfig:
21
+ if self._cfg is None:
22
+ self._cfg = config.load(self._ini)
23
+ return self._cfg
24
+
25
+ def root(self, kind: str, override: Path | None) -> Path:
26
+ return Path(override) if override else self.cfg.root_for(kind)
27
+
28
+
29
+ pass_app = click.make_pass_decorator(App)
@@ -0,0 +1,38 @@
1
+ """fpptools command line: `fpptools <group> <command>`.
2
+
3
+ Groups: config, str, fit, wipe. Run `fpptools <group> --help` for details.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from pathlib import Path
9
+
10
+ import click
11
+
12
+ from fpptools import __version__, config
13
+ from fpptools.app import App
14
+ from fpptools.commands import config_cmd, fit, str as str_cmd, wipe
15
+
16
+
17
+ @click.group(context_settings={"help_option_names": ["-h", "--help"]})
18
+ @click.version_option(__version__, prog_name="fpptools")
19
+ @click.option("--ini", type=click.Path(dir_okay=False, path_type=Path), envvar=config.ENV_INI,
20
+ help="FP_PRO.INI to use. Default: the configuration FP Pro is using now.")
21
+ @click.pass_context
22
+ def cli(ctx: click.Context, ini: Path | None):
23
+ """Administration and debugging tools for emmegisoft FP Pro.
24
+
25
+ Works on the configuration currently active in FP Pro (FP_PRO.INI).
26
+ """
27
+ ctx.obj = App(ini)
28
+
29
+
30
+ cli.add_command(config_cmd.config_show)
31
+ cli.add_command(str_cmd.str_group)
32
+ cli.add_command(fit.fit_group)
33
+ cli.add_command(fit.legacy_list_fittings)
34
+ cli.add_command(wipe.wipe_group)
35
+
36
+
37
+ def main():
38
+ cli(prog_name="fpptools")
@@ -0,0 +1,37 @@
1
+ """CLI command groups. Shared options live here."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ import click
8
+
9
+ HEADERS = {
10
+ "en": {"folder": "Folder", "name": "Name", "unique": "Unique code", "description": "Description",
11
+ "file": "File", "fitting": "Fitting", "source": "Source", "note": "Note", "error": "Error",
12
+ "job": "Job", "item": "Item"},
13
+ "es": {"folder": "Carpeta", "name": "Nombre", "unique": "Nombre único", "description": "Descripción",
14
+ "file": "Archivo", "fitting": "Accesorio", "source": "Origen", "note": "Nota", "error": "Error",
15
+ "job": "Trabajo", "item": "Ítem"},
16
+ }
17
+
18
+
19
+ def scope_options(f):
20
+ """--root / --under / --match, shared by every command that walks STR/BLK folders."""
21
+ f = click.option("--match", metavar="PATTERN",
22
+ help="Only files whose name (no extension) matches, e.g. 'VTA_*'. Case-insensitive.")(f)
23
+ f = click.option("--under", metavar="FOLDER",
24
+ help="Only inside this folder, relative to the root, e.g. '019_SERIE_22_PESADO'.")(f)
25
+ f = click.option("--root", type=click.Path(file_okay=False, exists=True, path_type=Path),
26
+ help="Folder to scan instead of the one in FP_PRO.INI.")(f)
27
+ return f
28
+
29
+
30
+ def lang_option(f):
31
+ return click.option("--lang", type=click.Choice(["en", "es"]), default="en", show_default=True,
32
+ help="Language of the column headers.")(f)
33
+
34
+
35
+ def out_option(default: str):
36
+ return click.option("--out", "-o", default=default, show_default=True,
37
+ help="Output file (.csv or .xlsx), or '-' for the console.")
@@ -0,0 +1,36 @@
1
+ """`fpptools config`: show which FP Pro configuration fpptools will use."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import click
6
+
7
+ from fpptools.app import App, pass_app
8
+
9
+
10
+ @click.command("config")
11
+ @pass_app
12
+ def config_show(app: App):
13
+ """Show the active FP Pro configuration (password hidden)."""
14
+ cfg = app.cfg
15
+
16
+ def line(label: str, value) -> None:
17
+ click.echo(f"{label:<16}{value}")
18
+
19
+ def folder(key: str) -> str:
20
+ value = cfg.get("SYSTEM", key)
21
+ if not value:
22
+ return "(not set)"
23
+ from pathlib import Path
24
+ return f"{value}" + ("" if Path(value).is_dir() else " [not found]")
25
+
26
+ line("INI", cfg.ini_path)
27
+ line("Configuration", cfg.name or "(unknown)")
28
+ line("STR_PATH", folder("STR_PATH"))
29
+ line("BLK_PATH", folder("BLK_PATH"))
30
+ line("JOB_PATH", folder("JOB_PATH"))
31
+ line("CONFIGS_PATH", folder("CONFIGS_PATH"))
32
+ if cfg.db_kind == "mysql":
33
+ s = cfg.mysql
34
+ line("Database", f"MySQL {s.host}:{s.port}/{s.database} (user {s.user}, charset {s.charset})")
35
+ else:
36
+ line("Database", f"Access {cfg.mdb_file}" + ("" if cfg.mdb_file.is_file() else " [not found]"))