Add typehints
This commit is contained in:
@ -28,7 +28,6 @@ Functions:
|
|||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
from functools import cache
|
|
||||||
from typing import Any, Iterable
|
from typing import Any, Iterable
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
@ -37,7 +36,14 @@ from fastapi import FastAPI, Form, Request
|
|||||||
from fastapi.responses import FileResponse, HTMLResponse, RedirectResponse
|
from fastapi.responses import FileResponse, HTMLResponse, RedirectResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
from reader import Entry, EntryCounts, Feed, FeedCounts
|
from reader import (
|
||||||
|
Entry,
|
||||||
|
EntryCounts,
|
||||||
|
EntrySearchCounts,
|
||||||
|
EntrySearchResult,
|
||||||
|
Feed,
|
||||||
|
FeedCounts,
|
||||||
|
)
|
||||||
from starlette.templating import _TemplateResponse
|
from starlette.templating import _TemplateResponse
|
||||||
from tomlkit.toml_document import TOMLDocument
|
from tomlkit.toml_document import TOMLDocument
|
||||||
|
|
||||||
@ -68,7 +74,7 @@ templates.env.filters["encode_url"] = encode_url
|
|||||||
|
|
||||||
|
|
||||||
@app.post("/add")
|
@app.post("/add")
|
||||||
async def create_feed(feed_url: str = Form(), webhook_dropdown: str = Form()):
|
async def create_feed(feed_url: str = Form(), webhook_dropdown: str = Form()) -> RedirectResponse:
|
||||||
"""
|
"""
|
||||||
Add a feed to the database.
|
Add a feed to the database.
|
||||||
|
|
||||||
@ -79,20 +85,20 @@ async def create_feed(feed_url: str = Form(), webhook_dropdown: str = Form()):
|
|||||||
Returns:
|
Returns:
|
||||||
dict: The feed that was added.
|
dict: The feed that was added.
|
||||||
"""
|
"""
|
||||||
feed_url = feed_url.strip()
|
clean_feed_url: str = feed_url.strip()
|
||||||
|
|
||||||
reader.add_feed(feed_url)
|
reader.add_feed(clean_feed_url)
|
||||||
reader.update_feed(feed_url)
|
reader.update_feed(clean_feed_url)
|
||||||
|
|
||||||
# Mark every entry as read, so we don't send all the old entries to Discord.
|
# Mark every entry as read, so we don't send all the old entries to Discord.
|
||||||
entries = reader.get_entries(feed=feed_url, read=False)
|
entries: Iterable[Entry] = reader.get_entries(feed=clean_feed_url, read=False)
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
reader.set_entry_read(entry, True)
|
reader.set_entry_read(entry, True)
|
||||||
|
|
||||||
settings: TOMLDocument = read_settings_file()
|
settings: TOMLDocument = read_settings_file()
|
||||||
webhook_url: str = str(settings["webhooks"][webhook_dropdown])
|
webhook_url: str = str(settings["webhooks"][webhook_dropdown])
|
||||||
reader.set_tag(feed_url, "webhook", webhook_url)
|
reader.set_tag(clean_feed_url, "webhook", webhook_url)
|
||||||
reader.get_tag(feed_url, "webhook")
|
reader.get_tag(clean_feed_url, "webhook")
|
||||||
|
|
||||||
reader.update_search()
|
reader.update_search()
|
||||||
|
|
||||||
@ -102,14 +108,13 @@ async def create_feed(feed_url: str = Form(), webhook_dropdown: str = Form()):
|
|||||||
def create_list_of_webhooks() -> list[dict[str, str]]:
|
def create_list_of_webhooks() -> list[dict[str, str]]:
|
||||||
"""List with webhooks."""
|
"""List with webhooks."""
|
||||||
settings: TOMLDocument = read_settings_file()
|
settings: TOMLDocument = read_settings_file()
|
||||||
list_of_webhooks = []
|
list_of_webhooks: list[dict[str, str]] = []
|
||||||
for hook in settings["webhooks"]:
|
for hook in settings["webhooks"]:
|
||||||
list_of_webhooks.append({"name": hook, "url": settings["webhooks"][hook]})
|
list_of_webhooks.append({"name": hook, "url": settings["webhooks"][hook]})
|
||||||
|
|
||||||
return list_of_webhooks
|
return list_of_webhooks
|
||||||
|
|
||||||
|
|
||||||
@cache
|
|
||||||
@app.get("/favicon.ico", include_in_schema=False)
|
@app.get("/favicon.ico", include_in_schema=False)
|
||||||
async def favicon() -> FileResponse:
|
async def favicon() -> FileResponse:
|
||||||
"""Return favicon."""
|
"""Return favicon."""
|
||||||
@ -144,15 +149,15 @@ async def get_feed(feed_url: str, request: Request) -> _TemplateResponse:
|
|||||||
HTMLResponse: The HTML response.
|
HTMLResponse: The HTML response.
|
||||||
"""
|
"""
|
||||||
# Make feed_url a valid URL.
|
# Make feed_url a valid URL.
|
||||||
feed_url = urllib.parse.unquote(feed_url)
|
url: str = urllib.parse.unquote(feed_url)
|
||||||
|
|
||||||
feed: Feed = reader.get_feed(feed_url)
|
feed: Feed = reader.get_feed(url)
|
||||||
|
|
||||||
# Get entries from the feed.
|
# Get entries from the feed.
|
||||||
entries: Iterable[Entry] = reader.get_entries(feed=feed_url)
|
entries: Iterable[Entry] = reader.get_entries(feed=url)
|
||||||
|
|
||||||
# Get the entries in the feed.
|
# Get the entries in the feed.
|
||||||
feed_counts: FeedCounts = reader.get_feed_counts(feed=feed_url)
|
feed_counts: FeedCounts = reader.get_feed_counts(feed=url)
|
||||||
|
|
||||||
context = {"request": request, "feed": feed, "entries": entries, "feed_counts": feed_counts}
|
context = {"request": request, "feed": feed, "entries": entries, "feed_counts": feed_counts}
|
||||||
return templates.TemplateResponse("feed.html", context)
|
return templates.TemplateResponse("feed.html", context)
|
||||||
@ -185,7 +190,7 @@ def make_context_index(request) -> dict:
|
|||||||
dict: The context.
|
dict: The context.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
hooks = create_list_of_webhooks()
|
hooks: list[dict[str, str]] = create_list_of_webhooks()
|
||||||
feed_list = []
|
feed_list = []
|
||||||
feeds: Iterable[Feed] = reader.get_feeds()
|
feeds: Iterable[Feed] = reader.get_feeds()
|
||||||
for feed in feeds:
|
for feed in feeds:
|
||||||
@ -208,7 +213,7 @@ def make_context_index(request) -> dict:
|
|||||||
|
|
||||||
|
|
||||||
@app.post("/remove", response_class=HTMLResponse)
|
@app.post("/remove", response_class=HTMLResponse)
|
||||||
async def remove_feed(request: Request, feed_url: str = Form()):
|
async def remove_feed(request: Request, feed_url: str = Form()) -> RedirectResponse:
|
||||||
"""
|
"""
|
||||||
Get a feed by URL.
|
Get a feed by URL.
|
||||||
|
|
||||||
@ -239,12 +244,17 @@ async def search(request: Request, query: str) -> _TemplateResponse:
|
|||||||
HTMLResponse: The HTML response.
|
HTMLResponse: The HTML response.
|
||||||
"""
|
"""
|
||||||
reader.update_search()
|
reader.update_search()
|
||||||
search_results = reader.search_entries(query)
|
search_results: Iterable[EntrySearchResult] = reader.search_entries(query)
|
||||||
search_amount = reader.search_entry_counts(query)
|
search_amount: EntrySearchCounts = reader.search_entry_counts(query)
|
||||||
|
|
||||||
search_html = create_html_for_search_results(search_results)
|
search_html: str = create_html_for_search_results(search_results)
|
||||||
|
|
||||||
context = {"request": request, "search_html": search_html, "query": query, "search_amount": search_amount}
|
context: dict[str, Request | str | EntrySearchCounts] = {
|
||||||
|
"request": request,
|
||||||
|
"search_html": search_html,
|
||||||
|
"query": query,
|
||||||
|
"search_amount": search_amount,
|
||||||
|
}
|
||||||
return templates.TemplateResponse("search.html", context)
|
return templates.TemplateResponse("search.html", context)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import urllib.parse
|
import urllib.parse
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
from reader import EntrySearchResult, HighlightedString
|
from reader import EntrySearchResult, Feed, HighlightedString
|
||||||
|
|
||||||
from discord_rss_bot.settings import reader
|
from discord_rss_bot.settings import reader
|
||||||
|
|
||||||
@ -15,12 +15,14 @@ def create_html_for_search_results(search_results: Iterable[EntrySearchResult])
|
|||||||
Returns:
|
Returns:
|
||||||
str: The HTML.
|
str: The HTML.
|
||||||
"""
|
"""
|
||||||
html = ""
|
# TODO: There is a .content that also contains text, we should use that if .summary is not available.
|
||||||
|
# TODO: We should also add <span> tags to the title.
|
||||||
|
html: str = ""
|
||||||
for result in search_results:
|
for result in search_results:
|
||||||
if ".summary" in result.content:
|
if ".summary" in result.content:
|
||||||
result_summary = add_span_with_slice(result.content[".summary"])
|
result_summary: str = add_span_with_slice(result.content[".summary"])
|
||||||
feed = reader.get_feed(result.feed_url)
|
feed: Feed = reader.get_feed(result.feed_url)
|
||||||
feed_url = urllib.parse.quote(feed.url)
|
feed_url: str = urllib.parse.quote(feed.url)
|
||||||
|
|
||||||
html += f"""
|
html += f"""
|
||||||
<a class="text-muted text-decoration-none" href="/feed?feed_url={feed_url}">
|
<a class="text-muted text-decoration-none" href="/feed?feed_url={feed_url}">
|
||||||
@ -41,9 +43,12 @@ def add_span_with_slice(highlighted_string: HighlightedString) -> str:
|
|||||||
Returns:
|
Returns:
|
||||||
str: The string with added <span> tags.
|
str: The string with added <span> tags.
|
||||||
"""
|
"""
|
||||||
|
# TODO: We are looping through the highlights and only using the last one. We should use all of them.
|
||||||
|
before_span, span_part, after_span = ""
|
||||||
|
|
||||||
for txt_slice in highlighted_string.highlights:
|
for txt_slice in highlighted_string.highlights:
|
||||||
before_span = f"{highlighted_string.value[: txt_slice.start]}"
|
before_span: str = f"{highlighted_string.value[: txt_slice.start]}"
|
||||||
span_part = f"<span class='bg-warning'>{highlighted_string.value[txt_slice.start: txt_slice.stop]}</span>"
|
span_part: str = f"<span class='bg-warning'>{highlighted_string.value[txt_slice.start: txt_slice.stop]}</span>"
|
||||||
after_span = f"{highlighted_string.value[txt_slice.stop:]}"
|
after_span: str = f"{highlighted_string.value[txt_slice.stop:]}"
|
||||||
|
|
||||||
return f"{before_span}{span_part}{after_span}"
|
return f"{before_span}{span_part}{after_span}"
|
||||||
|
@ -72,7 +72,7 @@ def read_settings_file(custom_name: str = "settings.toml") -> TOMLDocument:
|
|||||||
Returns:
|
Returns:
|
||||||
dict: The settings file as a dict.
|
dict: The settings file as a dict.
|
||||||
"""
|
"""
|
||||||
settings_file = os.path.join(data_dir, custom_name)
|
settings_file: str = os.path.join(data_dir, custom_name)
|
||||||
with open(settings_file, encoding="utf-8") as f:
|
with open(settings_file, encoding="utf-8") as f:
|
||||||
return parse(f.read())
|
return parse(f.read())
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user