fix(search): typed text is a literal in every LIKE pattern
The feed's channel-name match and the live search's term fold built their LIKE pattern from the typed text as it was, so `_` and `%` acted as wildcards: `build_log` also matched `buildXlog`. The term fold also tested a substring, so a term already present inside a longer word (`cat` in `category`) was never folded into search_terms. It now compares whole terms, escaped. `like_escape` moves from the Plex query module to `app.utils`, beside `to_tsquery_str`, and every pattern built from typed text goes through it.
This commit is contained in:
@@ -73,6 +73,14 @@ def to_tsquery_str(q: str) -> str | None:
|
||||
return " & ".join(tokens)
|
||||
|
||||
|
||||
def like_escape(s: str) -> str:
|
||||
"""`s` as a LITERAL inside a LIKE/ILIKE pattern: `%` and `_` are wildcards there, and `\\` is
|
||||
Postgres's default escape character, so all three are escaped. Every pattern built from text a
|
||||
person typed goes through this — unescaped, a search for `100%` or `my_channel` matches rows it
|
||||
should not."""
|
||||
return s.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")
|
||||
|
||||
|
||||
def normalize_description(text: str | None) -> str | None:
|
||||
"""Strip whitespace-only lines from a CHANNEL description before storing. YouTube channel
|
||||
descriptions pad their contact/link blocks with runs of blank lines; keeping them wastes storage,
|
||||
|
||||
Reference in New Issue
Block a user