diff --git a/discord_rss_bot/feeds.py b/discord_rss_bot/feeds.py index d796e0b..a25e84e 100644 --- a/discord_rss_bot/feeds.py +++ b/discord_rss_bot/feeds.py @@ -63,3 +63,5 @@ def send_to_discord(feed=None) -> None: response: Response = webhook.execute() if not response.ok: reader.set_entry_read(entry, False) + + reader.update_search() diff --git a/discord_rss_bot/main.py b/discord_rss_bot/main.py index 57a1c3c..dab4e67 100644 --- a/discord_rss_bot/main.py +++ b/discord_rss_bot/main.py @@ -37,7 +37,7 @@ from fastapi import FastAPI, Form, HTTPException, Request from fastapi.responses import FileResponse, HTMLResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates -from reader import Entry, EntryCounts, Feed, FeedCounts +from reader import Entry, EntryCounts, EntrySearchResult, Feed, FeedCounts, HighlightedString from starlette.templating import _TemplateResponse from tomlkit.toml_document import TOMLDocument @@ -100,6 +100,8 @@ async def create_feed(feed_url: str = Form(), webhook_dropdown: str = Form()) -> reader.set_tag(feed_url, "webhook", webhook_url) reader.get_tag(feed_url, "webhook") + reader.update_search() + # TODO: Go to the feed page. return {"feed_url": str(feed_url), "status": "added"} @@ -224,11 +226,70 @@ async def remove_feed(request: Request, feed_url: str = Form()): """ reader.delete_feed(feed_url) + reader.update_search() context = make_context_index(request) return templates.TemplateResponse("index.html", context) +@app.get("/search", response_class=HTMLResponse) +async def search(request: Request, query: str) -> _TemplateResponse: + """ + Get entries matching a full-text search query. + + Args: + request: The request. + query: The query to search for. + + Returns: + HTMLResponse: The HTML response. + """ + reader.update_search() + search_results = reader.search_entries(query) + search_amount = reader.search_entry_counts(query) + + def add_span_with_slice(highlighted_string: HighlightedString): + """Add a span with the highlighted string.""" + + for txt_slice in highlighted_string.highlights: + first = f"{highlighted_string.value[: txt_slice.start]}" + second = f"{highlighted_string.value[txt_slice.start: txt_slice.stop]}" + third = f"{highlighted_string.value[txt_slice.stop:]}" + return f"{first}{second}{third}" + + def create_html_for_search_results(search_results: Iterable[EntrySearchResult]) -> str: + """Create HTML for the search results. + + Args: + search_results: The search results. + + Returns: + str: The HTML. + """ + html = "" + for result in search_results: + if ".summary" in result.content: + result_summary = add_span_with_slice(result.content[".summary"]) + feed = reader.get_feed(result.feed_url) + feed_url = encode_url(feed.url) + + html += f""" + +

{result.metadata[".title"]}

+
+
+ {result_summary} +
+
+ """ + return html + + search_html = create_html_for_search_results(search_results) + return templates.TemplateResponse( + "search.html", {"request": request, "search_html": search_html, "query": query, "search_amount": search_amount} + ) + + @app.on_event("startup") def startup() -> None: """This is called when the server starts. diff --git a/discord_rss_bot/templates/feed.html b/discord_rss_bot/templates/feed.html index 7bf72b3..b8ab39f 100644 --- a/discord_rss_bot/templates/feed.html +++ b/discord_rss_bot/templates/feed.html @@ -85,7 +85,6 @@ {% endif %} - {% endfor %} {% endblock %} \ No newline at end of file diff --git a/discord_rss_bot/templates/nav.html b/discord_rss_bot/templates/nav.html index 2b5ea90..3dbd1e7 100644 --- a/discord_rss_bot/templates/nav.html +++ b/discord_rss_bot/templates/nav.html @@ -13,6 +13,14 @@ Add new feed + + {# Search #} +
+ + +
+ + {# Donate button #}