diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e3c031..d6df20c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # CHANGELOG +## v0.27.2 (2026-01-12) + +### Bug Fixes + +- Add splash screen, fix main window icon path + ([`43c4166`](https://github.com/mbari-org/vars-gridview/commit/43c41663bab43dbfb61689613a077c8fc4a6cb28)) + + ## v0.27.1 (2026-01-12) ### Bug Fixes diff --git a/pyproject.toml b/pyproject.toml index 1294fea..d9bf8b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "vars-gridview" -version = "0.27.1" +version = "0.27.2" description = "VARS GridView is a tool for reviewing and correcting VARS localizations in bulk." authors = [ { name = "Kevin Barnard", email = "kbarnard@mbari.org" }, diff --git a/src/vars_gridview/__init__.py b/src/vars_gridview/__init__.py index 16ea1d4..ae6d3ca 100644 --- a/src/vars_gridview/__init__.py +++ b/src/vars_gridview/__init__.py @@ -1 +1 @@ -__version__ = "0.27.1" +__version__ = "0.27.2" diff --git a/src/vars_gridview/lib/m3/query.py b/src/vars_gridview/lib/m3/query.py index c811250..d843793 100644 --- a/src/vars_gridview/lib/m3/query.py +++ b/src/vars_gridview/lib/m3/query.py @@ -16,6 +16,7 @@ class QueryConstraint: in_: list[str] | None = None isnull: bool | None = None like: str | None = None + notlike: str | None = None max: float | None = None min: float | None = None minmax: list[float] | None = None @@ -29,6 +30,7 @@ def to_dict(self, skip_null: bool = True) -> dict: "in": self.in_, "isnull": self.isnull, "like": self.like, + "notlike": self.notlike, "max": self.max, "min": self.min, "minmax": self.minmax, diff --git a/src/vars_gridview/ui/QueryDialog.py b/src/vars_gridview/ui/QueryDialog.py index 30755cd..0ad6ad2 100644 --- a/src/vars_gridview/ui/QueryDialog.py +++ b/src/vars_gridview/ui/QueryDialog.py @@ -199,6 +199,19 @@ def __str__(self) -> str: return "Verified" +class NotVerifiedConstraintResult(BaseResult): + """ + A constraint result that creates a constraint to check if the verifier field is NOT present (i.e., not verified). + """ + + @property + def constraints(self) -> Iterable[QueryConstraint]: + yield QueryConstraint(column="link_value", notlike='%"verifier":%') + + def __str__(self) -> str: + return "Not Verified" + + class ConceptInConstraintResult(InConstraintResult): """ A constraint result that creates an IN constraint for a list of concepts. @@ -880,6 +893,7 @@ def _create_default_filters(self) -> List[BaseFilter]: GeneratorFilter(self, "Generator", "generator", prompt="Generator"), VerifierFilter(self, "Verifier", "verifier", prompt="Verifier"), FunctionalFilter(self, "Verified", lambda: VerifiedConstraintResult()), + FunctionalFilter(self, "Not Verified", lambda: NotVerifiedConstraintResult()), ] @pyqtSlot() diff --git a/tests/test_query_constraints.py b/tests/test_query_constraints.py index a8cf84e..b2565da 100644 --- a/tests/test_query_constraints.py +++ b/tests/test_query_constraints.py @@ -51,5 +51,38 @@ def test_constraint_to_dict_skip_null(self): self.assertNotIn("equals", result_dict) +class TestLikeConstraints(unittest.TestCase): + """Test the like and notlike constraints functionality.""" + + def test_like_constraint(self): + """Test that a like constraint is created correctly.""" + constraint = QueryConstraint(column="link_value", like='%"verifier":%') + result_dict = constraint.to_dict() + + self.assertEqual(result_dict["column"], "link_value") + self.assertEqual(result_dict["like"], '%"verifier":%') + self.assertNotIn("notlike", result_dict) + + def test_notlike_constraint(self): + """Test that a notlike constraint is created correctly.""" + constraint = QueryConstraint(column="link_value", notlike='%"verifier":%') + result_dict = constraint.to_dict() + + self.assertEqual(result_dict["column"], "link_value") + self.assertEqual(result_dict["notlike"], '%"verifier":%') + self.assertNotIn("like", result_dict) + + def test_notlike_skip_null(self): + """Test that null notlike value is excluded when skip_null=True.""" + constraint = QueryConstraint( + column="link_value", + notlike=None + ) + result_dict = constraint.to_dict(skip_null=True) + + self.assertIn("column", result_dict) + self.assertNotIn("notlike", result_dict) + + if __name__ == "__main__": unittest.main()