diff --git a/__pycache__/fccs_verify.cpython-313.pyc b/__pycache__/fccs_verify.cpython-313.pyc new file mode 100644 index 0000000..684a9ef Binary files /dev/null and b/__pycache__/fccs_verify.cpython-313.pyc differ diff --git a/fccs_export.py b/fccs_export.py index 93e3f22..6f0784c 100755 --- a/fccs_export.py +++ b/fccs_export.py @@ -168,21 +168,63 @@ def open_send_to_file(main, app, ctrl, timeouts): return dlg -def read_manifest(dlg, log): - """Read the list of selected documents from the right-side ListView.""" +def read_manifest(dlg, drawer_id, log): + """Read the selected documents from the ListView into clean rows. + + The ListView (`List1`) has columns Drawer ID, Page Title (the document + name) and Application. `texts()` returns a flat, row-major dump led by the + control's own name ('List1'), which is why the raw capture looked messy. + + This parses it into one row per document and drops the redundant Drawer ID + column (always equal to drawer_id) and any empty columns, leaving the + document name (and Application) per line. Returns a list of rows (each a + list of cell strings), [] if empty, or None if it couldn't be read. + """ try: lv = dlg.child_window(title="List1", class_name="SysListView32") - count = lv.item_count() - if count == 0: - log(" WARNING: ListView is empty after Select") - return [] - items = lv.texts() - log(f" Manifest captured: {count} documents selected") - return items + n_rows = lv.item_count() except Exception as e: - log(f" WARNING: could not read manifest from ListView: {e}") + log(f" WARNING: could not read manifest list: {e}") return None + if n_rows == 0: + log(" WARNING: ListView is empty after Select") + return [] + + try: + n_cols = lv.column_count() + except Exception: + n_cols = 0 + if not n_cols or n_cols < 1: + n_cols = 3 # observed columns: Drawer ID, Page Title, Application + + # Read every cell. Primary: get_item(row, col). Fallback: reshape texts(). + try: + grid = [[lv.get_item(r, c).text() for c in range(n_cols)] + for r in range(n_rows)] + except Exception as e: + log(f" NOTE: get_item failed ({e}); falling back to texts().") + raw = lv.texts() + if raw and raw[0] == lv.window_text(): + raw = raw[1:] # drop the control's own name ('List1') + grid = [raw[i:i + n_cols] for i in range(0, len(raw), n_cols)] + grid = [row for row in grid if len(row) == n_cols] + + # Keep only columns that carry real, non-redundant info. + keep_cols = [] + for c in range(n_cols): + vals = [(row[c].strip() if c < len(row) else "") for row in grid] + if all(v == drawer_id for v in vals): + continue # redundant Drawer ID column + if all(v == "" for v in vals): + continue # empty column + keep_cols.append(c) + + rows = [[(row[c] if c < len(row) else "") for c in keep_cols] + for row in grid] + log(f" Manifest captured: {len(rows)} documents selected") + return rows + def save_manifest(drawer_id, items, manifest_dir, log): """Save the list of expected export items to a manifest file.""" @@ -197,8 +239,8 @@ def save_manifest(drawer_id, items, manifest_dir, log): log(f" Manifest saved: {path}") -def perform_export(dlg, ctrl, timeouts, log): - """Click Select -> then OK to start the export. Returns manifest list.""" +def perform_export(dlg, drawer_id, ctrl, timeouts, log): + """Click Select -> then OK to start the export. Returns manifest rows.""" select_btn = dlg.child_window(title=ctrl["select_btn_title"], class_name="Button") select_btn.wait("visible ready enabled", timeout=timeouts["dialog"]) select_btn.click() @@ -206,7 +248,7 @@ def perform_export(dlg, ctrl, timeouts, log): ok_btn = dlg.child_window(title=ctrl["ok_btn_title"], class_name="Button") ok_btn.wait("visible ready enabled", timeout=timeouts["select"]) - manifest = read_manifest(dlg, log) + manifest = read_manifest(dlg, drawer_id, log) ok_btn.click() return manifest @@ -319,7 +361,7 @@ def export_drawer(app, main, search_box, drawer_id, ctrl, timeouts, # 3 & 4. Select -> and OK (captures manifest before clicking OK) try: - manifest = perform_export(dlg, ctrl, timeouts, log) + manifest = perform_export(dlg, drawer_id, ctrl, timeouts, log) if manifest is not None: save_manifest(drawer_id, manifest, manifest_dir, log) except Exception as e: diff --git a/fccs_verify.py b/fccs_verify.py index 93c9009..aa633df 100644 --- a/fccs_verify.py +++ b/fccs_verify.py @@ -13,14 +13,23 @@ from fccs_config import parse_args, load_config, make_logger def load_manifest(path): - """Load a manifest file and return the list of document rows.""" - items = [] + """Load a manifest file and return one row per document. + + Handles both formats: + - New: one document per line (tab-separated columns). + - Old: a raw ListView dump led by 'List1', then row-major cells with + 3 columns per document (Drawer ID, Page Title, Application). We + reshape it so the document count is correct. + """ with open(path, "r", encoding="utf-8") as f: - for line in f: - line = line.rstrip("\n") - if line: - items.append(line.split("\t")) - return items + lines = [line.rstrip("\n") for line in f if line.strip()] + + if lines and lines[0].strip() == "List1": + cells = lines[1:] + rows = [cells[i:i + 3] for i in range(0, len(cells), 3)] + return [r for r in rows if len(r) == 3] + + return [line.split("\t") for line in lines] def main():