geminispace.info

Unnamed repository; edit this file 'description' to name the repository.
git clone git://code.clttr.info/geminispace.info.git
Log | Files | Refs | README | LICENSE

commit 087e227c67413185b7db0282e21333b6fbb2548d
parent a38326c3c76bd33bb7ccbfaba2ebaa7381fd4943
Author: Natalie Pendragon <natpen@natpen.net>
Date:   Thu, 14 May 2020 07:56:28 -0400

[serve] Implement paging

Diffstat:
MREADME.md | 7-------
Mgus/serve.py | 38+++++++++++++++++++++++++++++---------
2 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/README.md b/README.md @@ -34,13 +34,6 @@ as this guide to [mailing list etiquette](https://man.sr.ht/lists.sr.ht/etiquett be useful for local hacking on serve.py, so one does not need to perform a real scrape of Geminispace to do said hacking. -- **add paging functionality**: haven't fully thought through - how this would work, but I think it would be nice? Also open - to feedback though if anyone thinks a better UI would be - to simply present as many results as exist (I think that - solution will become increasingly unappealing as the amount - of content, and thus amount of search hits, in Geminispace - grows). - **exclude raw-text links**: I think there is a "raw-text block" type of construct in the Gemini spec now, so I should probably add a TODO to refactor the extract_gemini_links function to diff --git a/gus/serve.py b/gus/serve.py @@ -5,6 +5,7 @@ import asyncio from datetime import datetime import math import os +import re import sys import jetforce @@ -78,6 +79,10 @@ def _render_news(): ] news_items = [ { + "date": "2020-05-14", + "content": "Added paging functionality, which will now show up at the bottom of search result pages that have more than one page of results.", + }, + { "date": "2020-05-12", "content": "Added Known Hosts and News, both of which you can find on the GUS homepage.", }, @@ -183,9 +188,9 @@ def index(request): return Response(Status.SUCCESS, "text/gemini", "\n".join(data)) -def _search_index(query): +def _search_index(query, requested_page): query = MultifieldParser(["content", "url", "prompt"], ix.schema).parse(query) - results = searcher.search(query) + results = searcher.search_page(query, requested_page, pagelen=10) return ( len(results), [(result.score, result["url"], result["content_type"], result["prompt"] if "prompt" in result else "") for result in results] @@ -237,24 +242,39 @@ def _render_results_header(query, num_results): ] -def _render_results_footer(num_results): +def _render_results_footer(num_results, requested_page, query): data = [ "", ] num_pages = math.ceil(num_results / 10) - current_page = 1 + current_page = min(requested_page, num_pages) if num_results == 0: current_page = 0 - paging_feature_note = " (paging not implemented yet!)" - data.append("Page {} of {}{}".format(current_page, num_pages, paging_feature_note)) + data.append("Page {} of {}".format(current_page, num_pages)) + if current_page > 2: + data.append("=> /search?{} First Page".format(query)) + if current_page > 1: + data.append("=> /search/{}?{} Previous Page".format(current_page - 1, query)) + if current_page < num_pages: + data.append("=> /search/{}?{} Next Page".format(current_page + 1, query)) return data -@app.route("/search") +def compute_requested_results_page(request_path): + page = 1 + p = re.compile("^/search(/\d+)?/?") + m = p.match(request_path) + if m.group(1) is not None: + page = int(m.group(1)[1:]) + return max(page, 1) + + +@app.route("/search(/\d+)?") def search(request): data = _render_header() if request.query: - num_results, results = _search_index(request.query) + requested_page = compute_requested_results_page(request.path) + num_results, results = _search_index(request.query, requested_page) data.extend(_render_results_header(request.query, num_results)) if num_results > 0: data.extend(_render_results(results)) @@ -262,7 +282,7 @@ def search(request): search_suggestions = _get_search_suggestions(request.query) data.extend(_render_search_suggestions(search_suggestions)) - data.extend(_render_results_footer(num_results)) + data.extend(_render_results_footer(num_results, requested_page, request.query)) data.extend(_render_footer()) return Response(Status.SUCCESS, "text/gemini", "\n".join(data))