Skip to content

Commit 70f568a

Browse files
committed
feat: add smartcase and globless path search
Known issues: failing tests, sluggish autocomplete
1 parent 83b5464 commit 70f568a

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

tagstudio/src/core/library/alchemy/visitors.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
import structlog
88
from sqlalchemy import ColumnElement, and_, distinct, func, or_, select, text
99
from sqlalchemy.orm import Session
10+
from sqlalchemy.sql.operators import ilike_op
1011
from src.core.media_types import FILETYPE_EQUIVALENTS, MediaCategories
1112
from src.core.query_lang import BaseVisitor
1213
from src.core.query_lang.ast import ANDList, Constraint, ConstraintType, Not, ORList, Property
1314

1415
from .joins import TagEntry
1516
from .models import Entry, Tag, TagAlias
1617

17-
# workaround to have autocompletion in the Editor
18+
# Only import for type checking/autocompletion, will not be imported at runtime.
1819
if TYPE_CHECKING:
1920
from .library import Library
2021
else:
@@ -97,7 +98,26 @@ def visit_constraint(self, node: Constraint) -> ColumnElement[bool]:
9798
elif node.type == ConstraintType.TagID:
9899
return self.__entry_matches_tag_ids([int(node.value)])
99100
elif node.type == ConstraintType.Path:
100-
return Entry.path.op("GLOB")(node.value)
101+
smartcase = False
102+
glob = False
103+
104+
if node.value == node.value.lower():
105+
smartcase = True
106+
if "*" in node.value:
107+
glob = True
108+
109+
if smartcase and glob:
110+
logger.info("ConstraintType.Path", smartcase=True, glob=True)
111+
return Entry.path.op("GLOB")(ilike_op(Entry.path, f"%{node.value}%"))
112+
elif smartcase:
113+
logger.info("ConstraintType.Path", smartcase=True, glob=False)
114+
return ilike_op(Entry.path, f"%{node.value}%")
115+
elif glob:
116+
logger.info("ConstraintType.Path", smartcase=False, glob=True)
117+
return Entry.path.op("GLOB")(node.value)
118+
else:
119+
logger.info("ConstraintType.Path", smartcase=False, glob=False)
120+
return Entry.path.regexp_match(rf"\b{node.value}\b")
101121
elif node.type == ConstraintType.MediaType:
102122
extensions: set[str] = set[str]()
103123
for media_cat in MediaCategories.ALL_CATEGORIES:

0 commit comments

Comments
 (0)