From efb902f3f293db4aac6e57b9f3a84143d84a90e9 Mon Sep 17 00:00:00 2001 From: Gareth Coles Date: Sun, 6 May 2018 18:21:34 +0100 Subject: [Wiki] Misc improvements, plus a beta search feature --- pysite/views/wiki/search.py | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 pysite/views/wiki/search.py (limited to 'pysite/views/wiki/search.py') diff --git a/pysite/views/wiki/search.py b/pysite/views/wiki/search.py new file mode 100644 index 00000000..1c920e15 --- /dev/null +++ b/pysite/views/wiki/search.py @@ -0,0 +1,66 @@ +import html +import re + +from flask import redirect, request, url_for +from werkzeug.exceptions import BadRequest + +from pysite.base_route import RouteView +from pysite.decorators import csrf +from pysite.mixins import DBMixin + +STRIP_REGEX = re.compile(r"<[^<]+?>") + + +class SearchView(RouteView, DBMixin): + path = "/search" # "path" means that it accepts slashes + name = "search" + table_name = "wiki" + revision_table_name = "wiki_revisions" + + def get(self): + return self.render("wiki/search.html") + + @csrf + def post(self): + given_query = request.form.get("query") + + if not given_query or not given_query.strip(): + raise BadRequest() + + query = f"({re.escape(given_query)})" + + pages = self.db.filter( + self.table_name, + lambda doc: doc["text"].match(query) + ) + + if len(pages) == 1: + slug = pages[0]["slug"] + return redirect(url_for("wiki.page", page=slug), code=303) + + for obj in pages: + text = obj["text"] + + matches = re.finditer(query, text) + snippets = [] + + for match in matches: + start = match.start() - 50 + + if start < 0: + start = 0 + + end = match.end() + 50 + + if end > len(text): + end = len(text) + + match_text = text[start:end] + match_text = re.sub(query, r"\1", html.escape(match_text)) + + snippets.append(match_text.replace("\n", "
")) + + obj["matches"] = snippets + + pages = sorted(pages, key=lambda d: d["title"]) + return self.render("wiki/search_results.html", pages=pages, query=given_query) -- cgit v1.2.3