Update web/core/views.py
This commit is contained in:
parent
698644e0b7
commit
514d2f0ef3
@ -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 (won’t 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)
|
||||||
Loading…
Reference in New Issue
Block a user