[Patchew-devel] [PATCH v2 05/10] search: split _process_term into separate functions

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


This is a first step towards turning it into something like a recursive
descent parser.
---
 api/search.py | 116 +++++++++++++++++++++++++-------------------------
 1 file changed, 59 insertions(+), 57 deletions(-)

diff --git a/api/search.py b/api/search.py
index b1d20ec..355de0e 100644
--- a/api/search.py
+++ b/api/search.py
@@ -129,19 +129,70 @@ Search text keyword in the email message. Example:
         message_ids = model.objects.filter(q).values('message_id')
         return Q(id__in=message_ids)
 
+    def _make_filter_age(self, cond):
+        import datetime
+        def human_to_seconds(n, unit):
+            if unit == "d":
+                return n * 86400
+            elif unit == "w":
+                return n * 86400 * 7
+            elif unit == "m":
+                return n * 86400 * 30
+            elif unit == "y":
+                return n * 86400 * 365
+            raise Exception("No unit specified")
+
+        if cond.startswith("<"):
+            less = True
+            cond = cond[1:]
+        elif cond.startswith(">"):
+            less = False
+            cond = cond[1:]
+        else:
+            less = False
+        num, unit = cond[:-1], cond[-1].lower()
+        if not num.isdigit() or not unit in "dwmy":
+            raise InvalidSearchTerm("Invalid age string: %s" % cond)
+        sec = human_to_seconds(int(num), unit)
+        p = datetime.datetime.now() - datetime.timedelta(0, sec)
+        if less:
+            q = Q(date__gte=p)
+        else:
+            q = Q(date__lte=p)
+        return q
+
+    def _make_filter_keywords(self, t):
+        self._last_keywords.append(t)
+        return Q(subject__icontains=t)
+
+    def _make_filter_is(self, cond):
+        if cond == "complete":
+            return Q(is_complete=True)
+        elif cond == "pull":
+            return Q(subject__contains='[PULL') | Q(subject__contains='[GIT PULL')
+        elif cond == "reviewed":
+            return self._make_filter_subquery(MessageProperty, Q(name="reviewed", value=True))
+        elif cond in ("obsoleted", "old"):
+            return self._make_filter_subquery(MessageProperty,
+                                              Q(name="obsoleted-by", value__isnull=False) &
+                                              ~Q(name="obsoleted-by", value__iexact=''))
+        elif cond == "applied":
+            return self._make_filter_subquery(MessageResult, Q(name="git", status=Result.SUCCESS))
+        elif cond == "tested":
+            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)
+
     def _process_term(self, term, neg=False):
         """ Return a Q object that will be applied to the query """
-        def as_keywords(t):
-            self._last_keywords.append(t)
-            return Q(subject__icontains=t)
-
         if term.startswith("!"):
             return self._process_term(term[1:], not neg)
         if term.startswith("age:"):
             cond = term[term.find(":") + 1:]
-            q = self._process_age_term(cond)
+            q = self._make_filter_age(cond)
         elif term[0] in "<>" and len(term) > 1:
-            q = self._process_age_term(term)
+            q = self._make_filter_age(term)
         elif term.startswith("from:"):
             cond = term[term.find(":") + 1:]
             q = Q(sender__icontains=cond)
@@ -163,26 +214,9 @@ Search text keyword in the email message. Example:
             else:
                 cond = term[term.find(":") + 1:]
                 lneg = term.startswith("not:")
-            if cond == "complete":
-                q = Q(is_complete=True)
-            elif cond == "pull":
-                q = Q(subject__contains='[PULL') | Q(subject__contains='[GIT PULL')
-            elif cond == "reviewed":
-                q = self._make_filter_subquery(MessageProperty, Q(name="reviewed", value=True))
-            elif cond in ("obsoleted", "old"):
-                q = self._make_filter_subquery(MessageProperty,
-                                               Q(name="obsoleted-by", value__isnull=False) &
-                                               ~Q(name="obsoleted-by", value__iexact=''))
-            elif cond == "applied":
-                q = self._make_filter_subquery(MessageResult, Q(name="git", status=Result.SUCCESS))
-            elif cond == "tested":
-                q = self._make_filter_subquery(MessageProperty, Q(name="testing.done", value=True))
-            elif cond == "merged":
-                q = Q(is_merged=True)
-            else:
-                q = as_keywords(term)
             if lneg:
                 neg = not neg
+            q = self._make_filter_is(cond)
         elif term.startswith("has:"):
             cond = term[term.find(":") + 1:]
             if cond == "replies":
@@ -195,7 +229,7 @@ Search text keyword in the email message. Example:
             q = Q(project__name=cond) | Q(project__parent_project__name=cond)
         else:
             # Keyword in subject is the default
-            q = as_keywords(term)
+            q = self._make_filter_keywords(term)
         if neg:
             return ~q
         else:
@@ -215,35 +249,3 @@ Search text keyword in the email message. Example:
         if queryset is None:
             queryset = Message.objects.series_heads()
         return queryset.filter(q)
-
-    def _process_age_term(self, cond):
-        import datetime
-        def human_to_seconds(n, unit):
-            if unit == "d":
-                return n * 86400
-            elif unit == "w":
-                return n * 86400 * 7
-            elif unit == "m":
-                return n * 86400 * 30
-            elif unit == "y":
-                return n * 86400 * 365
-            raise Exception("No unit specified")
-
-        if cond.startswith("<"):
-            less = True
-            cond = cond[1:]
-        elif cond.startswith(">"):
-            less = False
-            cond = cond[1:]
-        else:
-            less = False
-        num, unit = cond[:-1], cond[-1].lower()
-        if not num.isdigit() or not unit in "dwmy":
-            raise InvalidSearchTerm("Invalid age string: %s" % cond)
-        sec = human_to_seconds(int(num), unit)
-        p = datetime.datetime.now() - datetime.timedelta(0, sec)
-        if less:
-            q = Q(date__gte=p)
-        else:
-            q = Q(date__lte=p)
-        return q
-- 
2.17.1





More information about the Patchew-devel mailing list