Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ It is also possible to use various Boolean operators directly when combining tag
There are some terms that can be matched even without the need to be specifically tagged ahead of time. The following are the supported metatags:
- **untagged**/**no_tags** whether the entry has no tags at all yet.
- **empty**/**no_fields** whether the entry has no fields at all, tag or otherwise. This covers text lines, text boxes, dates, and more.
- **missing**/**no_file** whether the media file associated with the entry is gone or missing from where it was when the entry was created.
- **no_author**/**no_artist** whether the "Author" or "Artist" fields aren't present in the entry.
- **filename:** matches any portion of text in the name and subdirectory that the file is located in relative to the library's path. Here are some usage examples:
- **filename:copy.png** matches any .PNG file whose filename ends with "copy" regardless of directory, such as "shared img \- Copy.png"
Expand Down
8 changes: 1 addition & 7 deletions tagstudio/src/core/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -1379,16 +1379,11 @@ def search_library(
# to this Library, so skip the entry.
continue

# These 5 values contain all the pieces of entry-related
# These 4 values contain all the pieces of entry-related
# information that the search_query may need in order to
# evaluate the entry.
entry_has_fields = bool(entry.fields)
entry_has_author = False
entry_has_file = (
self.library_dir /
entry.path /
entry.filename
).resolve() in self.missing_files
entry_filename = str(os.path.join(entry.path, entry.filename)).lower()
entry_tag_ids: list[int] = []

Expand All @@ -1408,7 +1403,6 @@ def search_library(
if search_query.match_entry(
has_fields=entry_has_fields,
has_author=entry_has_author,
has_file=entry_has_file,
filename=entry_filename,
tag_ids=entry_tag_ids
):
Expand Down
6 changes: 0 additions & 6 deletions tagstudio/src/core/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@ def __init__(
self,
has_fields,
has_author,
has_file,
filename: str,
tag_ids: list[int]
):
self.has_fields = has_fields
self.has_author = has_author
self.has_file = has_file
self.filename = filename
self.tag_ids = tag_ids

Expand Down Expand Up @@ -244,8 +242,6 @@ def match(self, entry: _EntrySearchableData) -> bool:
return not entry.has_fields
case "no_author" | "no-author" | "noauthor" | "no_artist" | "no-artist" | "noartist":
return not entry.has_author
case "missing" | "no_file" | "no-file" | "nofile":
return not entry.has_file
case "untagged" | "no_tags" | "no-tags" | "notags":
return not entry.tag_ids

Expand Down Expand Up @@ -537,14 +533,12 @@ def match_entry(
self,
has_fields,
has_author,
has_file,
filename: str,
tag_ids: list[int]
):
return self._syntax_root.match(_EntrySearchableData(
has_fields,
has_author,
has_file,
filename,
tag_ids
))
Expand Down
79 changes: 13 additions & 66 deletions tagstudio/tests/core/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ def sqmtch(
tag_ids: list[int] = [],
has_fields=True,
has_author=True,
has_file=True,
filename="subfolder\\entry.png"
) -> bool:
return search_query.match_entry(
has_fields=has_fields,
has_author=has_author,
has_file=has_file,
filename=filename,
tag_ids=tag_ids
)
Expand Down Expand Up @@ -239,15 +237,11 @@ def test_receive_requested_lib_info_true():
def test_eval_with_no_author():
search_query = SearchQuery("", SearchMode.AND)
assert str(search_query) == "L()"
assert sqmtch(search_query, has_fields=True ,has_author=False,has_file=True )
assert sqmtch(search_query, has_fields=True ,has_author=False)
def test_eval_with_no_fields():
search_query = SearchQuery("", SearchMode.AND)
assert str(search_query) == "L()"
assert sqmtch(search_query, has_fields=False,has_author=False,has_file=True )
def test_eval_with_no_file():
search_query = SearchQuery("", SearchMode.AND)
assert str(search_query) == "L()"
assert sqmtch(search_query, has_fields=True ,has_author=True ,has_file=False)
assert sqmtch(search_query, has_fields=False,has_author=False)

def test_eval_and_mode_list():
search_query = SearchQuery("tag1 tag2 tag3", SearchMode.AND)
Expand Down Expand Up @@ -409,8 +403,7 @@ def test_eval_tag_empty_false():
"no-fields": [],
"nofields": []
})
assert not sqmtch(search_query, has_fields=True ,has_author=True ,has_file=True )
assert not sqmtch(search_query, has_fields=True ,has_author=True ,has_file=False)
assert not sqmtch(search_query, has_fields=True ,has_author=True )
def test_eval_tag_empty_true():
search_query = SearchQuery("empty no_fields no-fields nofields", SearchMode.AND)
assert str(search_query) == "L(T(empty) T(no_fields) T(no-fields) T(nofields))"
Expand All @@ -426,8 +419,7 @@ def test_eval_tag_empty_true():
"no-fields": [],
"nofields": []
})
assert sqmtch(search_query, has_fields=False,has_author=False,has_file=True )
assert sqmtch(search_query, has_fields=False,has_author=False,has_file=False)
assert sqmtch(search_query, has_fields=False,has_author=False)
def test_eval_tag_no_author_false():
search_query = SearchQuery("no_author no-author noauthor no_artist no-artist noartist", SearchMode.OR)
assert str(search_query) == "L(T(no_author) T(no-author) T(noauthor) T(no_artist) T(no-artist) T(noartist))"
Expand All @@ -447,8 +439,7 @@ def test_eval_tag_no_author_false():
"no-artist": [],
"noartist": []
})
assert not sqmtch(search_query, has_fields=True ,has_author=True ,has_file=True )
assert not sqmtch(search_query, has_fields=True ,has_author=True ,has_file=False)
assert not sqmtch(search_query, has_fields=True ,has_author=True)
def test_eval_tag_no_author_true():
search_query = SearchQuery("no_author no-author noauthor no_artist no-artist noartist", SearchMode.AND)
assert str(search_query) == "L(T(no_author) T(no-author) T(noauthor) T(no_artist) T(no-artist) T(noartist))"
Expand All @@ -468,46 +459,8 @@ def test_eval_tag_no_author_true():
"no-artist": [],
"noartist": []
})
assert sqmtch(search_query, has_fields=True ,has_author=False,has_file=True )
assert sqmtch(search_query, has_fields=True ,has_author=False,has_file=False)
assert sqmtch(search_query, has_fields=False,has_author=False,has_file=True )
assert sqmtch(search_query, has_fields=False,has_author=False,has_file=False)
def test_eval_tag_missing_false():
search_query = SearchQuery("missing no_file no-file nofile", SearchMode.OR)
assert str(search_query) == "L(T(missing) T(no_file) T(no-file) T(nofile))"
assert search_query.share_tag_requests() == [
"missing",
"no_file",
"no-file",
"nofile"
]
search_query.receive_requested_lib_info({
"missing": [],
"no_file": [],
"no-file": [],
"nofile": []
})
assert not sqmtch(search_query, has_fields=True ,has_author=True ,has_file=True )
assert not sqmtch(search_query, has_fields=True ,has_author=False,has_file=True )
assert not sqmtch(search_query, has_fields=False,has_author=False,has_file=True )
def test_eval_tag_missing_true():
search_query = SearchQuery("missing no_file no-file nofile", SearchMode.OR)
assert str(search_query) == "L(T(missing) T(no_file) T(no-file) T(nofile))"
assert search_query.share_tag_requests() == [
"missing",
"no_file",
"no-file",
"nofile"
]
search_query.receive_requested_lib_info({
"missing": [],
"no_file": [],
"no-file": [],
"nofile": []
})
assert sqmtch(search_query, has_fields=True ,has_author=True ,has_file=False)
assert sqmtch(search_query, has_fields=True ,has_author=False,has_file=False)
assert sqmtch(search_query, has_fields=False,has_author=False,has_file=False)
assert sqmtch(search_query, has_fields=True ,has_author=False)
assert sqmtch(search_query, has_fields=False,has_author=False)
def test_eval_tag_untagged_false():
search_query = SearchQuery("untagged no_tags no-tags notags", SearchMode.OR)
assert str(search_query) == "L(T(untagged) T(no_tags) T(no-tags) T(notags))"
Expand All @@ -523,12 +476,9 @@ def test_eval_tag_untagged_false():
"no-tags": [],
"notags": []
})
assert not sqmtch(search_query, tag_ids=[1],has_fields=True ,has_author=True ,has_file=True )
assert not sqmtch(search_query, tag_ids=[1],has_fields=True ,has_author=False,has_file=True )
assert not sqmtch(search_query, tag_ids=[1],has_fields=False,has_author=False,has_file=True )
assert not sqmtch(search_query, tag_ids=[1],has_fields=True ,has_author=True ,has_file=False)
assert not sqmtch(search_query, tag_ids=[1],has_fields=True ,has_author=False,has_file=False)
assert not sqmtch(search_query, tag_ids=[1],has_fields=False,has_author=False,has_file=False)
assert not sqmtch(search_query, tag_ids=[1],has_fields=True ,has_author=True )
assert not sqmtch(search_query, tag_ids=[1],has_fields=True ,has_author=False)
assert not sqmtch(search_query, tag_ids=[1],has_fields=False,has_author=False)
def test_eval_tag_untagged_true():
search_query = SearchQuery("untagged no_tags no-tags notags", SearchMode.AND)
assert str(search_query) == "L(T(untagged) T(no_tags) T(no-tags) T(notags))"
Expand All @@ -544,12 +494,9 @@ def test_eval_tag_untagged_true():
"no-tags": [],
"notags": []
})
assert sqmtch(search_query, tag_ids=[ ],has_fields=True ,has_author=True ,has_file=True )
assert sqmtch(search_query, tag_ids=[ ],has_fields=True ,has_author=False,has_file=True )
assert sqmtch(search_query, tag_ids=[ ],has_fields=False,has_author=False,has_file=True )
assert sqmtch(search_query, tag_ids=[ ],has_fields=True ,has_author=True ,has_file=False)
assert sqmtch(search_query, tag_ids=[ ],has_fields=True ,has_author=False,has_file=False)
assert sqmtch(search_query, tag_ids=[ ],has_fields=False,has_author=False,has_file=False)
assert sqmtch(search_query, tag_ids=[ ],has_fields=True ,has_author=True )
assert sqmtch(search_query, tag_ids=[ ],has_fields=True ,has_author=False)
assert sqmtch(search_query, tag_ids=[ ],has_fields=False,has_author=False)

def test_eval_tag_filename():
search_query = SearchQuery("filename:subfolder1 filename:entry1.png", SearchMode.AND)
Expand Down