[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