From: Michael Tremer Date: Tue, 13 Nov 2018 00:11:55 +0000 (+0000) Subject: wiki: Implement search X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9523790aa2677f948653e0079c77fed1734fe977;p=ipfire.org.git wiki: Implement search Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index b6c8025c..a7d21571 100644 --- a/Makefile.am +++ b/Makefile.am @@ -259,7 +259,8 @@ templates_wiki_DATA = \ src/templates/wiki/edit.html \ src/templates/wiki/page.html \ src/templates/wiki/recent-changes.html \ - src/templates/wiki/revisions.html + src/templates/wiki/revisions.html \ + src/templates/wiki/search-results.html templates_wikidir = $(templatesdir)/wiki diff --git a/src/backend/blog.py b/src/backend/blog.py index 034fd4c1..e9eac9f8 100644 --- a/src/backend/blog.py +++ b/src/backend/blog.py @@ -8,6 +8,7 @@ import textile import unicodedata from . import misc +from . import util from .decorators import * # Used to automatically link some things @@ -88,7 +89,7 @@ class Blog(misc.Object): ORDER BY COALESCE(updated_at, created_at) DESC LIMIT %s", limit) def search(self, query, limit=None): - query = self._parse_search_query(query) + query = util.parse_search_query(query) return self._get_posts("SELECT blog.* FROM blog \ LEFT JOIN blog_search_index search_index ON blog.id = search_index.post_id \ @@ -96,25 +97,6 @@ class Blog(misc.Object): ORDER BY ts_rank(search_index.document, to_tsquery('english', %s)) DESC \ LIMIT %s", query, query, limit) - def _parse_search_query(self, query): - q = [] - for word in query.split(): - # Is this lexeme negated? - negated = word.startswith("!") - - # Remove any special characters - word = re.sub(r"\W+", "", word, flags=re.UNICODE) - if not word: - continue - - # Restore negation - if negated: - word = "!%s" % word - - q.append(word) - - return " & ".join(q) - def create_post(self, title, text, author, tags=[], lang="markdown"): """ Creates a new post and returns the resulting Post object diff --git a/src/backend/util.py b/src/backend/util.py index ea7692a0..ff8248ea 100644 --- a/src/backend/util.py +++ b/src/backend/util.py @@ -1,8 +1,28 @@ -#!/usr/bin/python +#!/usr/bin/python3 import random +import re import string +def parse_search_query(query): + q = [] + for word in query.split(): + # Is this lexeme negated? + negated = word.startswith("!") + + # Remove any special characters + word = re.sub(r"\W+", "", word, flags=re.UNICODE) + if not word: + continue + + # Restore negation + if negated: + word = "!%s" % word + + q.append(word) + + return " & ".join(q) + def format_size(s, max_unit=None): units = ("B", "kB", "MB", "GB", "TB") diff --git a/src/backend/wiki.py b/src/backend/wiki.py index 651887a8..50748e98 100644 --- a/src/backend/wiki.py +++ b/src/backend/wiki.py @@ -5,6 +5,7 @@ import os.path import re from . import misc +from . import util from .decorators import * class Wiki(misc.Object): @@ -67,6 +68,23 @@ class Wiki(misc.Object): return ret + def search(self, query, limit=None): + query = util.parse_search_query(query) + + res = self._get_pages("SELECT wiki.* FROM wiki_search_index search_index \ + LEFT JOIN wiki ON search_index.wiki_id = wiki.id \ + WHERE search_index.document @@ to_tsquery('english', %s) \ + ORDER BY ts_rank(search_index.document, to_tsquery('english', %s)) DESC \ + LIMIT %s", query, query, limit) + + return list(res) + + def refresh(self): + """ + Needs to be called after a page has been changed + """ + self.db.execute("REFRESH MATERIALIZED VIEW wiki_search_index") + class Page(misc.Object): def init(self, id, data=None): diff --git a/src/templates/wiki/search-results.html b/src/templates/wiki/search-results.html new file mode 100644 index 00000000..5e514734 --- /dev/null +++ b/src/templates/wiki/search-results.html @@ -0,0 +1,13 @@ +{% extends "../base.html" %} + +{% block title %}{{ _("Search results for '%s'") % q }}{% end block %} + +{% block content %} +
+
+
{{ _("Search results for '%s'") % q }}
+ + {% module WikiList(pages) %} +
+
+{% end block %} diff --git a/src/web/wiki.py b/src/web/wiki.py index 12aa9c07..a3d4e65b 100644 --- a/src/web/wiki.py +++ b/src/web/wiki.py @@ -72,6 +72,10 @@ class PageHandler(auth.CacheMixin, base.BaseHandler): else: self.redirect(page.url) + # Update the search index + with self.db.transaction(): + self.backend.wiki.refresh() + class SearchHandler(auth.CacheMixin, base.BaseHandler): @base.blacklisted @@ -79,8 +83,6 @@ class SearchHandler(auth.CacheMixin, base.BaseHandler): q = self.get_argument("q") pages = self.backend.wiki.search(q, limit=50) - if not pages: - raise tornado.web.HTTPError(404, "Nothing found") self.render("wiki/search-results.html", q=q, pages=pages)