From acd985432e2333d9a207b28102bcd8e8b5c6c1ef Mon Sep 17 00:00:00 2001 From: dat972 Date: Thu, 9 Jul 2026 16:44:19 -0500 Subject: [PATCH] auto generate the ignore list then we can manually adjust for locked drawers --- README.md | 9 ++- __pycache__/fccs_scan.cpython-313.pyc | Bin 0 -> 5893 bytes fccs_scan.py | 79 ++++++++++++++++++++++---- 3 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 __pycache__/fccs_scan.cpython-313.pyc diff --git a/README.md b/README.md index d9de38d..7d98f84 100644 --- a/README.md +++ b/README.md @@ -36,10 +36,15 @@ python fccs_scan.py Reads the restored FCCS backup directory and writes all drawer IDs (subfolder names) to `drawer_ids.txt`. It also: -- **Flags prefix clashes** — if one drawer ID is a prefix of another (e.g. `02218` and `02218A`), searching the shorter ID in FCCS pops up a selection box that breaks automated navigation. These are reported so you can export them manually or ignore the shorter ID. +- **Flags prefix clashes** — if one drawer ID is a prefix of another (e.g. `02218` and `02218A`), searching the shorter ID in FCCS pops up a selection box that breaks automated navigation. These clashes are reported, and the shorter (prefix) IDs are auto-seeded into `ignore.txt` for review. - **Reports ignored drawers** — any IDs listed in `ignore.txt` that exist in this backup are shown as ones the export will skip. -**Ignoring drawers:** To exclude specific drawers from export (e.g. password-protected folders that would stall the automation), add their IDs to the file at `ignore_file` (default `C:\Migration\ignore.txt`), one per line. `drawer_ids.txt` stays a full inventory; the export skips anything in the ignore list. Lines starting with `#` are treated as comments. +**Ignoring drawers:** The scan creates `ignore.txt` (at `ignore_file`, default `C:\Migration\ignore.txt`) if it doesn't exist and pre-fills it with the clash prefixes — searching those in FCCS shows a selection box that stalls the automation, so they're skipped by default. Open the file and: + +- **Delete or comment out** any clash prefix you actually want exported (then handle it manually in FCCS). +- **Add** any other drawers to skip (e.g. password-protected folders), one ID per line. + +Re-running the scan never overwrites your edits — it only appends newly-discovered clashes. `drawer_ids.txt` stays a full inventory; the export skips anything active in the ignore list. Lines starting with `#` are comments. ### Step 2: Export Documents diff --git a/__pycache__/fccs_scan.cpython-313.pyc b/__pycache__/fccs_scan.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b210fde3536e5426c9764c0a72bfafd808b83a63 GIT binary patch literal 5893 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 literal 0 HcmV?d00001 diff --git a/fccs_scan.py b/fccs_scan.py index 666cc6d..597e548 100644 --- a/fccs_scan.py +++ b/fccs_scan.py @@ -13,6 +13,61 @@ from fccs_config import ( ) +_IGNORE_HEADER = [ + "# Drawer IDs to SKIP during export (one ID per line).", + "# Lines starting with # are comments and are ignored.", + "#", + "# Add password-protected or otherwise-excluded drawers here.", + "#", + "# The IDs auto-added below are prefix clashes: searching them in FCCS", + "# pops a selection box that breaks the automation, so they're skipped by", + "# default. DELETE or comment out any you actually DO want exported (then", + "# handle them manually), and keep the rest.", + "", +] + + +def update_ignore_file(ignore_file, clashes, log): + """Create ignore.txt if missing and seed it with clash prefix IDs. + + Never overwrites existing entries — only appends clash prefixes that + aren't already present. The shorter (prefix) ID of each clash is the one + that triggers the FCCS selection box, so it's the candidate to skip. + Returns the list of IDs that were added. + """ + existing = set(load_lines(ignore_file)) + file_exists = os.path.exists(ignore_file) + + to_add = [(short, matches) for short, matches in clashes + if short not in existing] + + # Existing file already covers every clash — leave it untouched. + if file_exists and not to_add: + return [] + + lines = [] + if not file_exists: + lines.extend(_IGNORE_HEADER) + + for short, matches in to_add: + lines.append(f"# clashes with: {', '.join(matches)}") + lines.append(short) + + mode = "a" if file_exists else "w" + with open(ignore_file, mode, encoding="utf-8") as f: + if file_exists: + f.write("\n") # separate the new block from prior content + f.write("\n".join(lines) + "\n") + + added = [short for short, _ in to_add] + if not file_exists: + log(f"Created ignore file: {ignore_file}") + if added: + log(f"Added {len(added)} clash prefix ID(s) to ignore list: " + f"{', '.join(added)}") + return added + + def main(): args = parse_args() cfg = load_config(args.config) @@ -37,14 +92,6 @@ def main(): log(f"Found {len(drawer_ids)} drawers, written to {output_file}") - # Report which drawers are set to be ignored (skipped by the export). - ignored = set(load_lines(ignore_file)) - if ignored: - present = sorted(ignored & set(drawer_ids)) - log(f"Ignore list ({ignore_file}): {len(ignored)} IDs, " - f"{len(present)} present in this backup — these will be SKIPPED " - f"by fccs_export.py: {', '.join(present) if present else '(none present)'}") - # Flag prefix clashes: FCCS search on the shorter ID pops a selection box. clashes = check_for_clashes(drawer_ids) if clashes: @@ -52,15 +99,23 @@ def main(): log(f"WARNING: {len(clashes)} potential drawer ID clash(es) found.") log("Searching the shorter ID in FCCS may show a selection box " "instead of navigating directly, which breaks the export.") - log("Consider exporting these manually, or add the shorter ID to " - f"the ignore list ({ignore_file}).") for short, matches in clashes: - flag = " [ignored]" if short in ignored else "" - log(f" {short}{flag} -> also matches: {', '.join(matches)}") + log(f" {short} -> also matches: {', '.join(matches)}") + # Seed ignore.txt with the clash prefixes for review (never overwrites). + update_ignore_file(ignore_file, clashes, log) + log(f"Review the ignore list: {ignore_file}") log("-" * 60) else: log("No drawer ID prefix clashes found.") + # Report which drawers will be skipped by the export. + ignored = set(load_lines(ignore_file)) + if ignored: + present = sorted(ignored & set(drawer_ids)) + log(f"Ignore list ({ignore_file}): {len(ignored)} IDs listed, " + f"{len(present)} present in this backup — these will be SKIPPED " + f"by fccs_export.py: {', '.join(present) if present else '(none present)'}") + if __name__ == "__main__": main()