[Patchew-devel] [PATCH v2 06/10] search: split handling of anything but +/-/! to a separate function, simplify !

Paolo Bonzini pbonzini at redhat.com
Fri Sep 28 14:45:33 UTC 2018


Define "+" as "imply an is: if there is no colon" and "-" as "imply a not:
if there is no colon".  It is possible however to write "-has:replies"
for example.

For simplicity, only allow one of +/-/!.  It is not possible anymore to
write "!!x" to mean "x".

The advantage is that _make_filter can just return the Q object directly.

Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
 api/search.py | 59 ++++++++++++++++++++++++++++-----------------------
 1 file changed, 33 insertions(+), 26 deletions(-)

diff --git a/api/search.py b/api/search.py
index 355de0e..90e6596 100644
--- a/api/search.py
+++ b/api/search.py
@@ -78,6 +78,9 @@ Example:
 
     is:reviewed
 
+"not:X" is the opposite of "is:X". "+X" and "-X" are shorter synonyms of "is:X"
+and "not:X" respectively.
+
 ---
 
 ### Search addresses
@@ -182,54 +185,58 @@ Search text keyword in the email message. Example:
             return self._make_filter_subquery(MessageProperty, Q(name="testing.done", value=True))
         elif cond == "merged":
             return Q(is_merged=True)
-        return self._make_filter_keywords(cond)
+        return None
 
-    def _process_term(self, term, neg=False):
-        """ Return a Q object that will be applied to the query """
-        if term.startswith("!"):
-            return self._process_term(term[1:], not neg)
+    def _make_filter(self, term):
         if term.startswith("age:"):
             cond = term[term.find(":") + 1:]
-            q = self._make_filter_age(cond)
+            return self._make_filter_age(cond)
         elif term[0] in "<>" and len(term) > 1:
-            q = self._make_filter_age(term)
+            return self._make_filter_age(term)
         elif term.startswith("from:"):
             cond = term[term.find(":") + 1:]
-            q = Q(sender__icontains=cond)
+            return Q(sender__icontains=cond)
         elif term.startswith("to:"):
             cond = term[term.find(":") + 1:]
-            q = Q(recipients__icontains=cond)
+            return Q(recipients__icontains=cond)
         elif term.startswith("subject:"):
             cond = term[term.find(":") + 1:]
-            q = Q(subject__icontains=cond)
+            return Q(subject__icontains=cond)
         elif term.startswith("id:"):
             cond = term[term.find(":") + 1:]
             if cond[0] == "<" and cond[-1] == ">":
                 cond = cond[1:-1]
-            q = Q(message_id=cond)
-        elif term.startswith("is:") or term.startswith("not:") or term[0] in "+-":
-            if term[0] in "+-":
-                cond = term[1:]
-                lneg = term[0] == "-"
-            else:
-                cond = term[term.find(":") + 1:]
-                lneg = term.startswith("not:")
-            if lneg:
-                neg = not neg
-            q = self._make_filter_is(cond)
+            return Q(message_id=cond)
+        elif term.startswith("is:"):
+            return self._make_filter_is(term[3:]) or self._make_filter_keywords(term)
+        elif term.startswith("not:"):
+            return ~self._make_filter_is(term[4:]) or self._make_filter_keywords(term)
         elif term.startswith("has:"):
             cond = term[term.find(":") + 1:]
             if cond == "replies":
-                q = Q(last_comment_date__isnull=False)
+                return Q(last_comment_date__isnull=False)
             else:
-                q = Q(properties__name=cond)
+                return Q(properties__name=cond)
         elif term.startswith("project:"):
             cond = term[term.find(":") + 1:]
             self._projects.add(cond)
-            q = Q(project__name=cond) | Q(project__parent_project__name=cond)
+            return Q(project__name=cond) | Q(project__parent_project__name=cond)
+
+        # Keyword in subject is the default
+        return self._make_filter_keywords(term)
+
+    def _process_term(self, term):
+        """ Return a Q object that will be applied to the query """
+        is_plusminus = neg = False
+        if term[0] in "+-!":
+            neg = (term[0] != "+")
+            is_plusminus = (term[0] != "!")
+            term = term[1:]
+
+        if is_plusminus and ":" not in term:
+            q = self._make_filter_is(term) or self._make_filter_keywords(term)
         else:
-            # Keyword in subject is the default
-            q = self._make_filter_keywords(term)
+            q = self._make_filter(term)
         if neg:
             return ~q
         else:
-- 
2.17.1





More information about the Patchew-devel mailing list