From b9042d10f0aa079d2f5be93d19e07b4f8db2df02 Mon Sep 17 00:00:00 2001 From: VoltKraft Date: Fri, 19 Dec 2025 18:28:19 +0100 Subject: [PATCH] Fix CSV quoting for last_comment Always quote and escape last_comment while keeping other fields unquoted Update README and CHANGELOG for the adjusted CSV format Bump version to 2.10.1 --- CHANGELOG.md | 5 +++-- README.md | 3 ++- pbs_chunk_checker.py | 9 ++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f408c0a..2eaf3c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ # 📝 Changelog +- 2.10.1 + - Always quote only the `last_comment` CSV field to avoid delimiter-related parsing issues (semicolon-separated). - 2.10.0 - Add CSV reporting for full datastore scans (`--all-guests`), written atomically at the end with an ISO 8601 timestamp filename. - - Include namespace path with VM/CT ID, latest snapshot comment, and unique chunk size in GiB (fixed precision) in the CSV output. + - Include namespace path with VM/CT ID, latest snapshot comment (always quoted), and unique chunk size in GiB (fixed precision) in the CSV output. - Allow selecting the CSV output directory via `--csv-dir` and the interactive Options menu. - 2.9.0 - Add an optional `--show-comments` flag and corresponding interactive option to show a short label derived from the latest PBS snapshot comment next to each VM/CT in the per‑guest summary and interactive search‑path selector (best‑effort, using `proxmox-backup-debug api get /admin/datastore//snapshots`). @@ -21,4 +23,3 @@ - Keep `--version` as pure version output again. - 2.7.1 - Split version and update logic: `--version` prints version; `--check-updates` checks and offers updates. -+ diff --git a/README.md b/README.md index ab82042..7edce28 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It calculates the **real disk space usage** of a specific **namespace**, **VM**, This allows accurate insights into space consumption per tenant or object — useful for chargeback, reporting, and storage optimization. -**Current version:** 2.10.0 (`./pbs_chunk_checker.py --version`) +**Current version:** 2.10.1 (`./pbs_chunk_checker.py --version`) See full changes in `CHANGELOG.md`. @@ -153,6 +153,7 @@ When running with `--all-guests`, the script writes a CSV report **after** the s - Output directory: current working directory by default, or via `--csv-dir` / the Options overlay - Separator: `;` (semicolon) - Columns: `namespace_path`, `last_comment`, `unique_size_gib` +- The `last_comment` field is always quoted (other fields are not). - Size unit: GiB (1024^3 bytes), fixed 3-decimal precision - The CSV is written automically at the end so no partial file is left behind on errors diff --git a/pbs_chunk_checker.py b/pbs_chunk_checker.py index 749564d..c38dcde 100644 --- a/pbs_chunk_checker.py +++ b/pbs_chunk_checker.py @@ -18,10 +18,9 @@ - Repository: https://github.com/VoltKraft/PBS_Chunk_Checker """ -__version__ = "2.10.0" +__version__ = "2.10.1" import argparse -import csv import concurrent.futures as futures import hashlib import json @@ -2236,10 +2235,10 @@ def _write_full_scan_csv( tmp_path = Path(tmp_file.name) try: with tmp_file as handle: - writer = csv.writer(handle, delimiter=";") - writer.writerow(["namespace_path", "last_comment", "unique_size_gib"]) + handle.write("namespace_path;last_comment;unique_size_gib\n") for path_label, comment, unique_bytes in rows: - writer.writerow([path_label, comment, _bytes_to_gib(unique_bytes)]) + escaped_comment = (comment or "").replace('"', '""') + handle.write(f'{path_label};"{escaped_comment}";{_bytes_to_gib(unique_bytes)}\n') os.replace(tmp_path, final_path) except Exception: try: