Update web/core/views.py

This commit is contained in:
Joshua Laymon 2025-08-16 15:53:26 +00:00
parent 698644e0b7
commit 514d2f0ef3

View File

@ -638,4 +638,95 @@ def stats_page(request):
"top_refs": top_refs, "top_refs": top_refs,
"book_distribution": book_distribution, "book_distribution": book_distribution,
}, },
) )
# -- helper: conservative subject splitter/cleaner
def _normalize_subject_line(raw: str) -> str:
"""
- Convert common separators (; |) to commas.
- Convert spaced dashes ( -, , when surrounded by spaces) to commas.
- Split on commas, trim, collapse double spaces, de-dup (case-insensitive).
- Preserve hyphenated terms like 'self-control' (we only replace dashes when spaced).
"""
if not raw:
return raw or ""
s = raw
# 1) unifying obvious separators
s = s.replace(";", ",").replace("|", ",")
# 2) dash as separator ONLY when surrounded by spaces (wont touch hyphenated words)
s = re.sub(r"\s+[–—-]\s+", ", ", s)
# 3) normalize comma spacing
s = re.sub(r"\s*,\s*", ",", s)
# 4) split, trim, collapse internal whitespace
parts = [re.sub(r"\s{2,}", " ", p.strip()) for p in s.split(",")]
parts = [p for p in parts if p]
# 5) de-dup (case-insensitive) while preserving order
seen = set()
cleaned = []
for p in parts:
key = p.lower()
if key not in seen:
cleaned.append(p)
seen.add(key)
return ", ".join(cleaned)
def _is_staff(user):
return user.is_authenticated and user.is_staff
@user_passes_test(_is_staff)
@require_http_methods(["GET", "POST"])
def normalize_subject(request):
"""
GET = dry-run preview (optional ?limit=)
POST = apply to all (optional hidden 'limit' too, but UI mirrors the other tools)
"""
dry_run = request.method == "GET"
limit_raw = request.GET.get("limit") if dry_run else request.POST.get("limit")
try:
limit = int(limit_raw) if (limit_raw and limit_raw.strip()) else 0
except ValueError:
limit = 0
qs = Entry.objects.all().order_by("id")
total_considered = qs.count()
if limit > 0:
qs = qs[:limit]
rows = []
changed_count = 0
for e in qs:
before = e.subject or ""
after = _normalize_subject_line(before)
changed = (after != before)
# For preview, list all considered entries; for apply, show only changed rows
if dry_run or changed:
rows.append({
"id": e.id,
"before": before,
"after": after,
"changed": changed,
})
if not dry_run and changed:
e.subject = after
e.save(update_fields=["subject"])
changed_count += 1
context = {
"dry_run": dry_run,
"limit": limit,
"total_considered": total_considered if limit == 0 else min(total_considered, limit),
"rows": rows,
"changed_count": changed_count,
}
return render(request, "normalize_subject_result.html", context)