From 8dac99b6d3feb53a95c99411fc894fde57d22c0a Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 20 Oct 2025 22:23:10 +0100 Subject: [PATCH] Add alert for stripped numeric references in import preview and refactor payload cleaning function --- .../sbas/partials/import_preview.html | 5 +++ sbas/views.py | 45 ++++++++++--------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/sbas/templates/sbas/partials/import_preview.html b/sbas/templates/sbas/partials/import_preview.html index eed25cec..001fd39b 100644 --- a/sbas/templates/sbas/partials/import_preview.html +++ b/sbas/templates/sbas/partials/import_preview.html @@ -20,6 +20,11 @@ Note: The following unsupported fields were dropped: {{ item.dropped_fields|join:", " }} {% endif %} + {% if item.stripped_fields %} + + {% endif %} {% if item.payload %}

Title: {{ item.payload.title|default:'(No title)'|safe }}

Stem: {{ item.payload.stem|default:''|safe }}

diff --git a/sbas/views.py b/sbas/views.py index 40a35d46..a5d190e2 100644 --- a/sbas/views.py +++ b/sbas/views.py @@ -487,6 +487,27 @@ def _resolve_m2m(model_class, value): return list(qs[:5]) return [] +def _strip_numeric_refs_in_payload(p): + """Return a copy of payload with inline numeric refs removed from any '*_feedback' or 'feedback' fields. + Also return a list of keys that were modified. + """ + if not isinstance(p, dict): + return p, [] + cleaned = dict(p) + changed = [] + # pattern matches [1], [1,2,3], or ranges like [6-9], or mixtures like [1,3-5,7] + pattern = re.compile(r"\[\s*(?:\d+(?:\s*-\s*\d+)?)(?:\s*,\s*(?:\d+(?:\s*-\s*\d+)?))*\s*\]") + for k, v in list(p.items()): + if not isinstance(v, str): + continue + if k.endswith("_feedback") or k == "feedback": + newv = pattern.sub("", v).strip() + # collapse multiple spaces + newv = re.sub(r"\s{2,}", " ", newv) + if newv != v: + cleaned[k] = newv + changed.append(k) + return cleaned, changed @login_required @user_passes_test(lambda u: u.is_superuser) @@ -570,27 +591,6 @@ def import_llm_questions(request): new_s, n = pattern.subn(r"\\\\", s) return new_s, n - def _strip_numeric_refs_in_payload(p): - """Return a copy of payload with inline numeric refs removed from any '*_feedback' or 'feedback' fields. - Also return a list of keys that were modified. - """ - if not isinstance(p, dict): - return p, [] - cleaned = dict(p) - changed = [] - # pattern matches [1] or [1,2, 3] with optional spaces - pattern = re.compile(r"\[\s*\d+(?:\s*,\s*\d+)*\s*\]") - for k, v in list(p.items()): - if not isinstance(v, str): - continue - if k.endswith("_feedback") or k == "feedback": - newv = pattern.sub("", v).strip() - # collapse multiple spaces - newv = re.sub(r"\s{2,}", " ", newv) - if newv != v: - cleaned[k] = newv - changed.append(k) - return cleaned, changed raw_text_stripped = raw_text.strip() raw_text, sanitized_count = _sanitize_backslashes(raw_text_stripped) @@ -775,6 +775,9 @@ def import_llm_questions(request): list((item_report.get("resolved_m2m") or {}).keys()), ) + # Ensure the item report payload reflects any cleaning (dropped fields / stripped refs) + item_report['payload'] = payload + # If dry-run, do not save; just report what would happen if dry_run: item_report["status"] = "would_create"