Update web/core/utils.py
This commit is contained in:
parent
445da3523b
commit
d52b89ee3f
@ -7,7 +7,56 @@ from typing import Dict, Any
|
|||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from core.models import Entry
|
from core.models import Entry
|
||||||
|
|
||||||
|
# --- Search helpers restored -------------------------------------------------
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
def terms(q: str) -> List[str]:
|
||||||
|
"""
|
||||||
|
Split a query string into search terms.
|
||||||
|
- Quoted phrases are kept together: `"good shepherd"`
|
||||||
|
- Unquoted text splits on whitespace.
|
||||||
|
- Empty/whitespace-only input returns [].
|
||||||
|
"""
|
||||||
|
if not q:
|
||||||
|
return []
|
||||||
|
# capture "quoted phrases" OR bare tokens
|
||||||
|
rx = re.compile(r'"([^"]+)"|(\S+)')
|
||||||
|
out = []
|
||||||
|
for m in rx.finditer(q):
|
||||||
|
phrase = m.group(1) if m.group(1) is not None else m.group(2)
|
||||||
|
t = (phrase or "").strip()
|
||||||
|
if t:
|
||||||
|
out.append(t)
|
||||||
|
return out
|
||||||
|
|
||||||
|
def has_wildcards(s: str) -> bool:
|
||||||
|
"""
|
||||||
|
True if user supplied * or ? wildcards (FileMaker-style).
|
||||||
|
We also treat SQL wildcards % and _ as wildcards if present.
|
||||||
|
"""
|
||||||
|
if not s:
|
||||||
|
return False
|
||||||
|
return any(ch in s for ch in ("*", "?", "%", "_"))
|
||||||
|
|
||||||
|
def wildcard_to_regex(s: str) -> str:
|
||||||
|
"""
|
||||||
|
Convert * and ? to a case-insensitive regex fragment suitable for Django's iregex.
|
||||||
|
- Escapes regex meta first, then replaces \* -> .* and \? -> .
|
||||||
|
- Wraps with '.*' so it matches anywhere (like icontains).
|
||||||
|
Example: 'lov* you?' -> '(?i).*lov.* you..*'
|
||||||
|
(The view should use iregex so (?i) or case-insensitive flag applies.)
|
||||||
|
"""
|
||||||
|
if s is None:
|
||||||
|
s = ""
|
||||||
|
# Escape regex specials, then un-escape our wildcards into regex
|
||||||
|
pat = re.escape(s)
|
||||||
|
pat = pat.replace(r"\*", ".*").replace(r"\?", ".")
|
||||||
|
# Match anywhere by default
|
||||||
|
pat = f".*{pat}.*"
|
||||||
|
# collapse consecutive ".*.*"
|
||||||
|
pat = re.sub(r"(?:\.\*){2,}", ".*", pat)
|
||||||
|
return pat
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
# ==============================
|
# ==============================
|
||||||
# Helpers
|
# Helpers
|
||||||
# ==============================
|
# ==============================
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user