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
_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel