fix(images): search never matches a pair's own variant title
Search covers the filename, the linked positive's text and Library title, and its tags (#249 D12). The pair title names a negative variant, so a variant name alone no longer admits the positive's images.
This commit is contained in:
+5
-3
@@ -509,9 +509,11 @@ and skip the parse.
|
||||
Filters (`mode=workspace`; anything invalid is 400 "Invalid gallery filters"):
|
||||
|
||||
- `q` (at most 500 characters). An entry passes when the case-folded relative path
|
||||
contains it, or when its linked positive's text, Library title, a tag name, or
|
||||
its pair title contains it (SQLite `LIKE` with escaping, ASCII case folding
|
||||
only). Search does not apply the card title gate, and does not search pair tags.
|
||||
contains it, or when its linked positive's text, Library title or a tag name
|
||||
contains it (SQLite `LIKE` with escaping, ASCII case folding only). A pair's own
|
||||
title names its negative variant, so it is not searched (#249 D12): a variant
|
||||
name alone matches nothing. Search does not apply the card title gate, and does
|
||||
not search pair tags.
|
||||
- `category` (exact and case-sensitive, at most 200 characters, stripped; blank
|
||||
means none) and `tags` (a comma list, blanks dropped, order-free, AND, at most 30
|
||||
tags of at most 200 characters) admit linked images only, through the linked
|
||||
|
||||
@@ -213,15 +213,15 @@ JOIN prompts p ON p.id = COALESCE(pp.positive_prompt_id, gi.prompt_id)
|
||||
WHERE gi.file_path IS NOT NULL AND CASE WHEN {admit} THEN NOT EXISTS (
|
||||
SELECT 1 FROM generated_images other
|
||||
WHERE other.file_path = gi.file_path AND other.id <> gi.id) ELSE 0 END"""
|
||||
# The positive's text, its Library title or one of its tag names, or the pair
|
||||
# title, contains :pattern (LIKE, so ASCII case is ignored as in Library search).
|
||||
_LINK_FILTER_HIT = """(p.id IN (
|
||||
# The positive's text, its Library title or one of its tag names contains
|
||||
# :pattern (LIKE, so ASCII case is ignored as in Library search). A pair's own
|
||||
# title names its negative variant and is never searched (#249 D12).
|
||||
_LINK_FILTER_HIT = """p.id IN (
|
||||
SELECT hp.id FROM prompts hp
|
||||
LEFT JOIN prompt_library_state hls ON hls.prompt_id = hp.id
|
||||
WHERE hp.text LIKE :pattern ESCAPE '\\' OR hls.title LIKE :pattern ESCAPE '\\'
|
||||
OR hp.id IN (SELECT ht.prompt_id FROM prompt_tags ht JOIN tags hn
|
||||
ON hn.id = ht.tag_id WHERE hn.name LIKE :pattern ESCAPE '\\'))
|
||||
OR pp.title LIKE :pattern ESCAPE '\\')"""
|
||||
ON hn.id = ht.tag_id WHERE hn.name LIKE :pattern ESCAPE '\\'))"""
|
||||
_LINK_FILTER_TAG = (
|
||||
"p.id IN (SELECT ft.prompt_id FROM prompt_tags ft JOIN tags fn "
|
||||
"ON fn.id = ft.tag_id WHERE fn.name = :tag{index})"
|
||||
@@ -2340,7 +2340,8 @@ class PromptDatabase(
|
||||
|
||||
Rows are limited to images whose linked positive has *category* and
|
||||
every tag in *tags* (exact names). ``hit`` says whether *q* occurs in
|
||||
the positive's text, Library title or a tag name, or in the pair title.
|
||||
the positive's text, Library title or a tag name; a pair's own title
|
||||
names its negative variant and is not searched.
|
||||
Without category or tags only hits are returned, unless *every_link*
|
||||
asks for every linked image (the rating sort and the positive count).
|
||||
The positive id is the card's linked positive. One SELECT whose rows
|
||||
|
||||
@@ -1068,8 +1068,9 @@ class TestWorkspaceImages(ImageAPITestCase):
|
||||
cases = (
|
||||
# Six unambiguous positives; the ambiguous file and unlinked count none.
|
||||
({}, 10, 6),
|
||||
# Text, title, tag, pair title (its positive) and the filename match.
|
||||
({"q": "ZEBRA"}, 6, 4),
|
||||
# Text, stored title, tag and the filename match (never a pair's
|
||||
# own variant title, D12).
|
||||
({"q": "ZEBRA"}, 5, 3),
|
||||
({"category": "Night"}, 4, 3),
|
||||
({"tags": "a,b"}, 3, 2),
|
||||
({"q": "plain_unlinked"}, 1, 0),
|
||||
@@ -1200,18 +1201,24 @@ class TestWorkspaceImages(ImageAPITestCase):
|
||||
|
||||
files = self._filter_fixtures()
|
||||
_, data = await self.get(q="ZEBRA", sort="name")
|
||||
# Text, stored title, tag, pair title and filename; never an ambiguous link.
|
||||
# Text, stored title, tag and filename; never an ambiguous link.
|
||||
self.assertEqual(
|
||||
self._names(data),
|
||||
[
|
||||
"day_ab.png",
|
||||
"night_ab.png",
|
||||
"paired.png",
|
||||
"titled.png",
|
||||
"zebra_unlinked.png",
|
||||
],
|
||||
)
|
||||
self.assertEqual(data["total"], 5)
|
||||
self.assertEqual(data["total"], 4)
|
||||
# D12: a pair's own title names its negative variant, so the variant
|
||||
# name alone matches nothing; the linked positive's text still does.
|
||||
_, data = await self.get(q="Zebra pair")
|
||||
self.assertEqual(self._names(data), [])
|
||||
self.assertEqual(data["total"], 0)
|
||||
_, data = await self.get(q="pair positive")
|
||||
self.assertEqual(self._names(data), ["paired.png"])
|
||||
_, data = await self.get(q="0% w")
|
||||
self.assertEqual(self._names(data), ["percent.png"])
|
||||
_, data = await self.get(q="%")
|
||||
@@ -1222,7 +1229,7 @@ class TestWorkspaceImages(ImageAPITestCase):
|
||||
self.api.db.get_image_paths_matching("zebra", None, []),
|
||||
{
|
||||
normalize_image_path(str(files[name]))
|
||||
for name in ("night_ab", "day_ab", "titled", "paired")
|
||||
for name in ("night_ab", "day_ab", "titled")
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user