From be38c1e980c4f29dd6243eb83e52e33f21be0add Mon Sep 17 00:00:00 2001 From: booosy <104043001+booosy@users.noreply.github.com> Date: Tue, 23 Aug 2022 19:54:27 -0700 Subject: [PATCH] Add title and exact boolean operators to search (#333) --- files/routes/search.py | 27 +++++++++++++++++++++++---- files/templates/search.html | 4 ++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/files/routes/search.py b/files/routes/search.py index 80982b436..410424e2b 100644 --- a/files/routes/search.py +++ b/files/routes/search.py @@ -17,6 +17,8 @@ valid_params = [ "post", "before", "after", + "title", + "exact", search_operator_hole, ] @@ -30,6 +32,7 @@ def searchparse(text): text = text.strip() if text: + criteria['full_text'] = text criteria['q'] = [] for m in search_token_regex.finditer(text): token = m[1] if m[1] else m[2] @@ -88,8 +91,19 @@ def searchposts(v): ) else: posts = posts.filter(Submission.author_id == author.id) - if 'q' in criteria: - words = [or_(Submission.title.ilike('%'+x+'%'), Submission.body.ilike('%'+x+'%')) \ + if 'exact' in criteria: + regex_str = '[[:<:]]'+criteria['full_text']+'[[:>:]]' # https://docs.oracle.com/cd/E17952_01/mysql-5.5-en/regexp.html "word boundaries" + if('title' in criteria): + words = [Submission.title.regexp_match(regex_str)] + else: + words = [or_(Submission.title.regexp_match(regex_str), Submission.body.regexp_match(regex_str))] + posts = posts.filter(*words) + elif 'q' in criteria: + if('title' in criteria): + words = [or_(Submission.title.ilike('%'+x+'%')) \ + for x in criteria['q']] + else: + words = [or_(Submission.title.ilike('%'+x+'%'), Submission.body.ilike('%'+x+'%')) \ for x in criteria['q']] posts = posts.filter(*words) @@ -196,8 +210,13 @@ def searchcomments(v): else: comments = comments.filter(Comment.author_id == author.id) - if 'q' in criteria: - words = [Comment.body.ilike('%'+x+'%') for x in criteria['q']] + if 'exact' in criteria: + regex_str = '[[:<:]]'+criteria['full_text']+'[[:>:]]' # https://docs.oracle.com/cd/E17952_01/mysql-5.5-en/regexp.html "word boundaries" + words = [Comment.body.regexp_match(regex_str)] + comments = comments.filter(*words) + elif 'q' in criteria: + words = [or_(Comment.body.ilike('%'+x+'%')) \ + for x in criteria['q']] comments = comments.filter(*words) if 'over18' in criteria: comments = comments.filter(Comment.over_18 == True) diff --git a/files/templates/search.html b/files/templates/search.html index eec44780b..1cbf1320c 100644 --- a/files/templates/search.html +++ b/files/templates/search.html @@ -48,6 +48,10 @@ {% if request.path.startswith('/search/comments') %}
  • post:504
  • {% endif %} + {% if request.path.startswith('/search/posts') %} +
  • title:true
  • + {% endif %} +
  • exact:true

  • {% endif %}