Fix warnings and other type checking issues

This commit is contained in:
2025-02-10 04:44:09 +01:00
parent fb880daea0
commit 45fa4c3c39
19 changed files with 155 additions and 97 deletions

8
.vscode/launch.json vendored
View File

@ -1,7 +1,4 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
@ -9,7 +6,10 @@
"type": "debugpy",
"request": "launch",
"module": "uvicorn",
"args": ["discord_rss_bot.main:app", "--reload"],
"args": [
"discord_rss_bot.main:app",
"--reload"
],
"jinja": true,
"justMyCode": true
}

View File

@ -3,8 +3,11 @@
"botuser",
"Genshins",
"levelname",
"Lovinator",
"markdownified",
"markdownify",
"pipx",
"thead"
]
],
"python.analysis.typeCheckingMode": "basic"
}

View File

@ -1,12 +1,16 @@
from __future__ import annotations
import urllib.parse
from functools import lru_cache
from reader import Entry, Reader
from typing import TYPE_CHECKING
from discord_rss_bot.filter.blacklist import entry_should_be_skipped, feed_has_blacklist_tags
from discord_rss_bot.filter.whitelist import has_white_tags, should_be_sent
from discord_rss_bot.settings import get_reader
if TYPE_CHECKING:
from reader import Entry, Reader
# Our reader
reader: Reader = get_reader()

View File

@ -4,7 +4,7 @@ import json
import logging
from dataclasses import dataclass
from bs4 import BeautifulSoup
from bs4 import BeautifulSoup, Tag
from markdownify import markdownify
from reader import Entry, Feed, Reader, TagNotFoundError
@ -143,8 +143,13 @@ def get_first_image(summary: str | None, content: str | None) -> str:
# TODO(TheLovinator): We should find a better way to get the image.
if content and (images := BeautifulSoup(content, features="lxml").find_all("img")):
for image in images:
if not is_url_valid(image.attrs["src"]):
logger.warning("Invalid URL: %s", image.attrs["src"])
if not isinstance(image, Tag) or "src" not in image.attrs:
logger.error("Image is not a Tag or does not have a src attribute.")
continue
src = str(image.attrs["src"])
if not is_url_valid(src):
logger.warning("Invalid URL: %s", src)
continue
# Genshins first image is a divider, so we ignore it.
@ -153,16 +158,20 @@ def get_first_image(summary: str | None, content: str | None) -> str:
"https://img-os-static.hoyolab.com/divider_config/",
"https://hyl-static-res-prod.hoyolab.com/divider_config/",
]
if not image.attrs["src"].startswith(tuple(skip_images)):
if not str(image.attrs["src"]).startswith(tuple(skip_images)):
return str(image.attrs["src"])
if summary and (images := BeautifulSoup(summary, features="lxml").find_all("img")):
for image in images:
if not is_url_valid(image.attrs["src"]):
if not isinstance(image, Tag) or "src" not in image.attrs:
logger.error("Image is not a Tag or does not have a src attribute.")
continue
if not is_url_valid(str(image.attrs["src"])):
logger.warning("Invalid URL: %s", image.attrs["src"])
continue
# Genshins first image is a divider, so we ignore it.
if not image.attrs["src"].startswith("https://img-os-static.hoyolab.com/divider_config"):
if not str(image.attrs["src"]).startswith("https://img-os-static.hoyolab.com/divider_config"):
return str(image.attrs["src"])
return ""
@ -317,8 +326,7 @@ def save_embed(custom_reader: Reader, feed: Feed, embed: CustomEmbed) -> None:
"footer_text": embed.footer_text,
"footer_icon_url": embed.footer_icon_url,
}
custom_reader.set_tag(feed, "embed", json.dumps(embed_dict)) # type: ignore
custom_reader.set_tag(feed, "embed", json.dumps(embed_dict)) # pyright: ignore[reportArgumentType]
def get_embed(custom_reader: Reader, feed: Feed) -> CustomEmbed:
@ -335,7 +343,7 @@ def get_embed(custom_reader: Reader, feed: Feed) -> CustomEmbed:
if embed:
if not isinstance(embed, str):
return get_embed_data(embed) # type: ignore
return get_embed_data(embed) # pyright: ignore[reportArgumentType]
embed_data: dict[str, str | int] = json.loads(embed)
return get_embed_data(embed_data)

View File

@ -9,7 +9,12 @@ from discord_webhook import DiscordEmbed, DiscordWebhook
from fastapi import HTTPException
from reader import Entry, EntryNotFoundError, Feed, FeedExistsError, Reader, ReaderError, StorageError, TagNotFoundError
from discord_rss_bot import custom_message
from discord_rss_bot.custom_message import (
CustomEmbed,
get_custom_message,
replace_tags_in_embed,
replace_tags_in_text_message,
)
from discord_rss_bot.filter.blacklist import entry_should_be_skipped
from discord_rss_bot.filter.whitelist import has_white_tags, should_be_sent
from discord_rss_bot.is_url_valid import is_url_valid
@ -42,10 +47,12 @@ def send_entry_to_discord(entry: Entry, custom_reader: Reader | None = None) ->
if not webhook_url:
return "No webhook URL found."
webhook_message: str = ""
# Try to get the custom message for the feed. If the user has none, we will use the default message.
# This has to be a string for some reason so don't change it to "not custom_message.get_custom_message()"
if custom_message.get_custom_message(reader, entry.feed) != "": # noqa: PLC1901
webhook_message: str = custom_message.replace_tags_in_text_message(entry=entry)
if get_custom_message(reader, entry.feed) != "": # noqa: PLC1901
webhook_message: str = replace_tags_in_text_message(entry=entry)
if not webhook_message:
webhook_message = "No message found."
@ -69,7 +76,7 @@ def send_entry_to_discord(entry: Entry, custom_reader: Reader | None = None) ->
return None
def set_description(custom_embed: custom_message.CustomEmbed, discord_embed: DiscordEmbed) -> None:
def set_description(custom_embed: CustomEmbed, discord_embed: DiscordEmbed) -> None:
"""Set the description of the embed.
Args:
@ -87,7 +94,7 @@ def set_description(custom_embed: custom_message.CustomEmbed, discord_embed: Dis
discord_embed.set_description(embed_description) if embed_description else None
def set_title(custom_embed: custom_message.CustomEmbed, discord_embed: DiscordEmbed) -> None:
def set_title(custom_embed: CustomEmbed, discord_embed: DiscordEmbed) -> None:
"""Set the title of the embed.
Args:
@ -115,7 +122,7 @@ def create_embed_webhook(webhook_url: str, entry: Entry) -> DiscordWebhook:
feed: Feed = entry.feed
# Get the embed data from the database.
custom_embed: custom_message.CustomEmbed = custom_message.replace_tags_in_embed(feed=feed, entry=entry)
custom_embed: CustomEmbed = replace_tags_in_embed(feed=feed, entry=entry)
discord_embed: DiscordEmbed = DiscordEmbed()
@ -238,8 +245,8 @@ def send_to_discord(custom_reader: Reader | None = None, feed: Feed | None = Non
else:
# If the user has set the custom message to an empty string, we will use the default message, otherwise we
# will use the custom message.
if custom_message.get_custom_message(reader, entry.feed) != "": # noqa: PLC1901
webhook_message = custom_message.replace_tags_in_text_message(entry)
if get_custom_message(reader, entry.feed) != "": # noqa: PLC1901
webhook_message = replace_tags_in_text_message(entry)
else:
webhook_message: str = str(default_custom_message)
@ -342,8 +349,12 @@ def create_feed(reader: Reader, feed_url: str, webhook_dropdown: str) -> None:
if hooks := reader.get_tag((), "webhooks", []):
# Get the webhook URL from the dropdown.
for hook in hooks:
if hook["name"] == webhook_dropdown: # type: ignore
webhook_url = hook["url"] # type: ignore
if not isinstance(hook, dict):
logger.error("Webhook is not a dict: %s", hook)
continue
if hook["name"] == webhook_dropdown: # pyright: ignore[reportArgumentType]
webhook_url = hook["url"]
break
if not webhook_url:
@ -356,7 +367,7 @@ def create_feed(reader: Reader, feed_url: str, webhook_dropdown: str) -> None:
try:
reader.get_tag(clean_feed_url, "webhook")
except TagNotFoundError:
reader.set_tag(clean_feed_url, "webhook", webhook_url) # type: ignore
reader.set_tag(clean_feed_url, "webhook", webhook_url) # pyright: ignore[reportArgumentType]
except ReaderError as e:
raise HTTPException(status_code=404, detail=f"Error adding feed: {e}") from e
@ -375,10 +386,10 @@ def create_feed(reader: Reader, feed_url: str, webhook_dropdown: str) -> None:
raise HTTPException(status_code=404, detail="Default custom message couldn't be found.")
# This is the webhook that will be used to send the feed to Discord.
reader.set_tag(clean_feed_url, "webhook", webhook_url) # type: ignore
reader.set_tag(clean_feed_url, "webhook", webhook_url) # pyright: ignore[reportArgumentType]
# This is the default message that will be sent to Discord.
reader.set_tag(clean_feed_url, "custom_message", default_custom_message) # type: ignore
reader.set_tag(clean_feed_url, "custom_message", default_custom_message) # pyright: ignore[reportArgumentType]
# Update the full-text search index so our new feed is searchable.
reader.update_search()

View File

@ -1,7 +1,12 @@
from reader import Entry, Feed, Reader
from __future__ import annotations
from typing import TYPE_CHECKING
from discord_rss_bot.filter.utils import is_word_in_text
if TYPE_CHECKING:
from reader import Entry, Feed, Reader
def feed_has_blacklist_tags(custom_reader: Reader, feed: Feed) -> bool:
"""Return True if the feed has blacklist tags.

View File

@ -1,7 +1,12 @@
from reader import Entry, Feed, Reader
from __future__ import annotations
from typing import TYPE_CHECKING
from discord_rss_bot.filter.utils import is_word_in_text
if TYPE_CHECKING:
from reader import Entry, Feed, Reader
def has_white_tags(custom_reader: Reader, feed: Feed) -> bool:
"""Return True if the feed has whitelist tags.

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import sys
import requests

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from urllib.parse import ParseResult, urlparse

View File

@ -7,7 +7,7 @@ import typing
import urllib.parse
from contextlib import asynccontextmanager
from dataclasses import dataclass
from datetime import datetime, timezone
from datetime import UTC, datetime
from functools import lru_cache
from typing import TYPE_CHECKING, Annotated, cast
@ -21,7 +21,6 @@ from fastapi.templating import Jinja2Templates
from httpx import Response
from markdownify import markdownify
from reader import Entry, EntryNotFoundError, Feed, FeedNotFoundError, Reader, TagNotFoundError
from reader.types import JSONType
from starlette.responses import RedirectResponse
from discord_rss_bot import settings
@ -45,6 +44,8 @@ from discord_rss_bot.settings import get_reader
if TYPE_CHECKING:
from collections.abc import Iterable
from reader.types import JSONType
LOGGING_CONFIG = {
"version": 1,
@ -93,7 +94,7 @@ async def lifespan(app: FastAPI) -> typing.AsyncGenerator[None]:
# Update all feeds every 15 minutes.
# TODO(TheLovinator): Make this configurable.
scheduler.add_job(send_to_discord, "interval", minutes=15, next_run_time=datetime.now(tz=timezone.utc))
scheduler.add_job(send_to_discord, "interval", minutes=15, next_run_time=datetime.now(tz=UTC))
scheduler.start()
logger.info("Scheduler started.")
yield
@ -135,7 +136,7 @@ async def post_add_webhook(
# Webhooks are stored as a list of dictionaries.
# Example: [{"name": "webhook_name", "url": "webhook_url"}]
webhooks = cast(list[dict[str, str]], webhooks)
webhooks = cast("list[dict[str, str]]", webhooks)
# Only add the webhook if it doesn't already exist.
stripped_webhook_name = webhook_name.strip()
@ -143,7 +144,7 @@ async def post_add_webhook(
# Add the new webhook to the list of webhooks.
webhooks.append({"name": webhook_name.strip(), "url": webhook_url.strip()})
reader.set_tag((), "webhooks", webhooks) # type: ignore
reader.set_tag((), "webhooks", webhooks) # pyright: ignore[reportArgumentType]
return RedirectResponse(url="/", status_code=303)
@ -172,7 +173,7 @@ async def post_delete_webhook(webhook_url: Annotated[str, Form()]) -> RedirectRe
# Webhooks are stored as a list of dictionaries.
# Example: [{"name": "webhook_name", "url": "webhook_url"}]
webhooks = cast(list[dict[str, str]], webhooks)
webhooks = cast("list[dict[str, str]]", webhooks)
# Only add the webhook if it doesn't already exist.
webhooks_to_remove: list[dict[str, str]] = [
@ -188,7 +189,7 @@ async def post_delete_webhook(webhook_url: Annotated[str, Form()]) -> RedirectRe
raise HTTPException(status_code=500, detail="Webhook could not be deleted")
# Add our new list of webhooks to the database.
reader.set_tag((), "webhooks", webhooks) # type: ignore
reader.set_tag((), "webhooks", webhooks) # pyright: ignore[reportArgumentType]
return RedirectResponse(url="/", status_code=303)
@ -263,10 +264,10 @@ async def post_set_whitelist(
RedirectResponse: Redirect to the feed page.
"""
clean_feed_url: str = feed_url.strip() if feed_url else ""
reader.set_tag(clean_feed_url, "whitelist_title", whitelist_title) # type: ignore[call-overload]
reader.set_tag(clean_feed_url, "whitelist_summary", whitelist_summary) # type: ignore[call-overload]
reader.set_tag(clean_feed_url, "whitelist_content", whitelist_content) # type: ignore[call-overload]
reader.set_tag(clean_feed_url, "whitelist_author", whitelist_author) # type: ignore[call-overload]
reader.set_tag(clean_feed_url, "whitelist_title", whitelist_title) # pyright: ignore[reportArgumentType][call-overload]
reader.set_tag(clean_feed_url, "whitelist_summary", whitelist_summary) # pyright: ignore[reportArgumentType][call-overload]
reader.set_tag(clean_feed_url, "whitelist_content", whitelist_content) # pyright: ignore[reportArgumentType][call-overload]
reader.set_tag(clean_feed_url, "whitelist_author", whitelist_author) # pyright: ignore[reportArgumentType][call-overload]
return RedirectResponse(url=f"/feed?feed_url={urllib.parse.quote(clean_feed_url)}", status_code=303)
@ -326,10 +327,10 @@ async def post_set_blacklist(
RedirectResponse: Redirect to the feed page.
"""
clean_feed_url: str = feed_url.strip() if feed_url else ""
reader.set_tag(clean_feed_url, "blacklist_title", blacklist_title) # type: ignore[call-overload]
reader.set_tag(clean_feed_url, "blacklist_summary", blacklist_summary) # type: ignore[call-overload]
reader.set_tag(clean_feed_url, "blacklist_content", blacklist_content) # type: ignore[call-overload]
reader.set_tag(clean_feed_url, "blacklist_author", blacklist_author) # type: ignore[call-overload]
reader.set_tag(clean_feed_url, "blacklist_title", blacklist_title) # pyright: ignore[reportArgumentType][call-overload]
reader.set_tag(clean_feed_url, "blacklist_summary", blacklist_summary) # pyright: ignore[reportArgumentType][call-overload]
reader.set_tag(clean_feed_url, "blacklist_content", blacklist_content) # pyright: ignore[reportArgumentType][call-overload]
reader.set_tag(clean_feed_url, "blacklist_author", blacklist_author) # pyright: ignore[reportArgumentType][call-overload]
return RedirectResponse(url=f"/feed?feed_url={urllib.parse.quote(clean_feed_url)}", status_code=303)
@ -379,10 +380,10 @@ async def post_set_custom(
RedirectResponse: Redirect to the feed page.
"""
our_custom_message: JSONType | str = custom_message.strip()
our_custom_message = typing.cast(JSONType, our_custom_message)
our_custom_message = typing.cast("JSONType", our_custom_message)
default_custom_message: JSONType | str = settings.default_custom_message
default_custom_message = typing.cast(JSONType, default_custom_message)
default_custom_message = typing.cast("JSONType", default_custom_message)
if our_custom_message:
reader.set_tag(feed_url, "custom_message", our_custom_message)
@ -406,7 +407,7 @@ async def get_custom(feed_url: str, request: Request):
"""
feed: Feed = reader.get_feed(urllib.parse.unquote(feed_url.strip()))
context = {
context: dict[str, Request | Feed | str | Entry] = {
"request": request,
"feed": feed,
"custom_message": get_custom_message(reader, feed),
@ -435,7 +436,7 @@ async def get_embed_page(feed_url: str, request: Request):
# Get previous data, this is used when creating the form.
embed: CustomEmbed = get_embed(reader, feed)
context = {
context: dict[str, Request | Feed | str | Entry | CustomEmbed] = {
"request": request,
"feed": feed,
"title": embed.title,
@ -523,7 +524,7 @@ async def post_use_embed(feed_url: Annotated[str, Form()]) -> RedirectResponse:
RedirectResponse: Redirect to the feed page.
"""
clean_feed_url: str = feed_url.strip()
reader.set_tag(clean_feed_url, "should_send_embed", True) # type: ignore
reader.set_tag(clean_feed_url, "should_send_embed", True) # pyright: ignore[reportArgumentType]
return RedirectResponse(url=f"/feed?feed_url={urllib.parse.quote(clean_feed_url)}", status_code=303)
@ -538,7 +539,7 @@ async def post_use_text(feed_url: Annotated[str, Form()]) -> RedirectResponse:
RedirectResponse: Redirect to the feed page.
"""
clean_feed_url: str = feed_url.strip()
reader.set_tag(clean_feed_url, "should_send_embed", False) # type: ignore
reader.set_tag(clean_feed_url, "should_send_embed", False) # pyright: ignore[reportArgumentType]
return RedirectResponse(url=f"/feed?feed_url={urllib.parse.quote(clean_feed_url)}", status_code=303)
@ -764,10 +765,15 @@ async def get_webhooks(request: Request):
Returns:
HTMLResponse: The add webhook page.
"""
hooks_with_data = []
hooks_with_data: list[WebhookInfo] = []
for hook in list(reader.get_tag((), "webhooks", [])):
our_hook: WebhookInfo = get_data_from_hook_url(hook_url=hook["url"], hook_name=hook["name"]) # type: ignore
webhook_list = list(reader.get_tag((), "webhooks", []))
for hook in webhook_list:
if not isinstance(hook, dict):
logger.error("Webhook is not a dict: %s", hook)
continue
our_hook: WebhookInfo = get_data_from_hook_url(hook_url=hook["url"], hook_name=hook["name"])
hooks_with_data.append(our_hook)
context = {"request": request, "hooks_with_data": hooks_with_data}
@ -796,7 +802,7 @@ def make_context_index(request: Request):
Returns:
dict: The context for the index page.
"""
hooks: list[dict] = list(reader.get_tag((), "webhooks", [])) # type: ignore
hooks: list[dict[str, str]] = cast("list[dict[str, str]]", list(reader.get_tag((), "webhooks", [])))
feed_list = []
broken_feeds = []
@ -911,7 +917,7 @@ def modify_webhook(old_hook: Annotated[str, Form()], new_hook: Annotated[str, Fo
# Webhooks are stored as a list of dictionaries.
# Example: [{"name": "webhook_name", "url": "webhook_url"}]
webhooks = cast(list[dict[str, str]], webhooks)
webhooks = cast("list[dict[str, str]]", webhooks)
for hook in webhooks:
if hook["url"] in old_hook.strip():
@ -922,7 +928,7 @@ def modify_webhook(old_hook: Annotated[str, Form()], new_hook: Annotated[str, Fo
raise HTTPException(status_code=500, detail="Webhook could not be modified")
# Add our new list of webhooks to the database.
reader.set_tag((), "webhooks", webhooks) # type: ignore
reader.set_tag((), "webhooks", webhooks) # pyright: ignore[reportArgumentType]
# Loop through all feeds and update the webhook if it
# matches the old one.
@ -934,7 +940,7 @@ def modify_webhook(old_hook: Annotated[str, Form()], new_hook: Annotated[str, Fo
continue
if webhook == old_hook.strip():
reader.set_tag(feed.url, "webhook", new_hook.strip()) # type: ignore
reader.set_tag(feed.url, "webhook", new_hook.strip()) # pyright: ignore[reportArgumentType]
# Redirect to the webhook page.
return RedirectResponse(url="/webhooks", status_code=303)

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from reader import Feed, Reader, TagNotFoundError
from discord_rss_bot.settings import default_custom_embed, default_custom_message
@ -13,8 +15,8 @@ def add_custom_message(reader: Reader, feed: Feed) -> None:
try:
reader.get_tag(feed, "custom_message")
except TagNotFoundError:
reader.set_tag(feed.url, "custom_message", default_custom_message) # type: ignore
reader.set_tag(feed.url, "has_custom_message", True) # type: ignore
reader.set_tag(feed.url, "custom_message", default_custom_message) # pyright: ignore[reportArgumentType]
reader.set_tag(feed.url, "has_custom_message", True) # pyright: ignore[reportArgumentType]
def add_has_custom_message(reader: Reader, feed: Feed) -> None:
@ -28,9 +30,9 @@ def add_has_custom_message(reader: Reader, feed: Feed) -> None:
reader.get_tag(feed, "has_custom_message")
except TagNotFoundError:
if reader.get_tag(feed, "custom_message") == default_custom_message:
reader.set_tag(feed.url, "has_custom_message", False) # type: ignore
reader.set_tag(feed.url, "has_custom_message", False) # pyright: ignore[reportArgumentType]
else:
reader.set_tag(feed.url, "has_custom_message", True) # type: ignore
reader.set_tag(feed.url, "has_custom_message", True) # pyright: ignore[reportArgumentType]
def add_if_embed(reader: Reader, feed: Feed) -> None:
@ -43,7 +45,7 @@ def add_if_embed(reader: Reader, feed: Feed) -> None:
try:
reader.get_tag(feed, "if_embed")
except TagNotFoundError:
reader.set_tag(feed.url, "if_embed", True) # type: ignore
reader.set_tag(feed.url, "if_embed", True) # pyright: ignore[reportArgumentType]
def add_custom_embed(reader: Reader, feed: Feed) -> None:
@ -56,8 +58,8 @@ def add_custom_embed(reader: Reader, feed: Feed) -> None:
try:
reader.get_tag(feed, "embed")
except TagNotFoundError:
reader.set_tag(feed.url, "embed", default_custom_embed) # type: ignore
reader.set_tag(feed.url, "has_custom_embed", True) # type: ignore
reader.set_tag(feed.url, "embed", default_custom_embed) # pyright: ignore[reportArgumentType]
reader.set_tag(feed.url, "has_custom_embed", True) # pyright: ignore[reportArgumentType]
def add_has_custom_embed(reader: Reader, feed: Feed) -> None:
@ -71,9 +73,9 @@ def add_has_custom_embed(reader: Reader, feed: Feed) -> None:
reader.get_tag(feed, "has_custom_embed")
except TagNotFoundError:
if reader.get_tag(feed, "embed") == default_custom_embed:
reader.set_tag(feed.url, "has_custom_embed", False) # type: ignore
reader.set_tag(feed.url, "has_custom_embed", False) # pyright: ignore[reportArgumentType]
else:
reader.set_tag(feed.url, "has_custom_embed", True) # type: ignore
reader.set_tag(feed.url, "has_custom_embed", True) # pyright: ignore[reportArgumentType]
def add_should_send_embed(reader: Reader, feed: Feed) -> None:
@ -86,7 +88,7 @@ def add_should_send_embed(reader: Reader, feed: Feed) -> None:
try:
reader.get_tag(feed, "should_send_embed")
except TagNotFoundError:
reader.set_tag(feed.url, "should_send_embed", True) # type: ignore
reader.set_tag(feed.url, "should_send_embed", True) # pyright: ignore[reportArgumentType]
def add_missing_tags(reader: Reader) -> None:

View File

@ -45,7 +45,7 @@ def test_has_black_tags() -> None:
def check_if_has_tag(reader: Reader, feed: Feed, blacklist_name: str) -> None:
reader.set_tag(feed, blacklist_name, "a") # type: ignore
reader.set_tag(feed, blacklist_name, "a") # pyright: ignore[reportArgumentType]
assert_msg: str = f"Feed should have blacklist tags: {blacklist_name}"
assert feed_has_blacklist_tags(custom_reader=reader, feed=feed) is True, assert_msg
@ -74,42 +74,42 @@ def test_should_be_skipped() -> None:
# Test entry without any blacklists
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"
reader.set_tag(feed, "blacklist_title", "fvnnnfnfdnfdnfd") # type: ignore
reader.set_tag(feed, "blacklist_title", "fvnnnfnfdnfdnfd") # pyright: ignore[reportArgumentType]
assert entry_should_be_skipped(reader, first_entry[0]) is True, f"Entry should be skipped: {first_entry[0]}"
reader.delete_tag(feed, "blacklist_title")
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"
reader.set_tag(feed, "blacklist_title", "åäö") # type: ignore
reader.set_tag(feed, "blacklist_title", "åäö") # pyright: ignore[reportArgumentType]
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"
reader.delete_tag(feed, "blacklist_title")
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"
reader.set_tag(feed, "blacklist_summary", "ffdnfdnfdnfdnfdndfn") # type: ignore
reader.set_tag(feed, "blacklist_summary", "ffdnfdnfdnfdnfdndfn") # pyright: ignore[reportArgumentType]
assert entry_should_be_skipped(reader, first_entry[0]) is True, f"Entry should be skipped: {first_entry[0]}"
reader.delete_tag(feed, "blacklist_summary")
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"
reader.set_tag(feed, "blacklist_summary", "åäö") # type: ignore
reader.set_tag(feed, "blacklist_summary", "åäö") # pyright: ignore[reportArgumentType]
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"
reader.delete_tag(feed, "blacklist_summary")
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"
reader.set_tag(feed, "blacklist_content", "ffdnfdnfdnfdnfdndfn") # type: ignore
reader.set_tag(feed, "blacklist_content", "ffdnfdnfdnfdnfdndfn") # pyright: ignore[reportArgumentType]
assert entry_should_be_skipped(reader, first_entry[0]) is True, f"Entry should be skipped: {first_entry[0]}"
reader.delete_tag(feed, "blacklist_content")
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"
reader.set_tag(feed, "blacklist_content", "åäö") # type: ignore
reader.set_tag(feed, "blacklist_content", "åäö") # pyright: ignore[reportArgumentType]
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"
reader.delete_tag(feed, "blacklist_content")
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"
reader.set_tag(feed, "blacklist_author", "TheLovinator") # type: ignore
reader.set_tag(feed, "blacklist_author", "TheLovinator") # pyright: ignore[reportArgumentType]
assert entry_should_be_skipped(reader, first_entry[0]) is True, f"Entry should be skipped: {first_entry[0]}"
reader.delete_tag(feed, "blacklist_author")
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"
reader.set_tag(feed, "blacklist_author", "åäö") # type: ignore
reader.set_tag(feed, "blacklist_author", "åäö") # pyright: ignore[reportArgumentType]
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"
reader.delete_tag(feed, "blacklist_author")
assert entry_should_be_skipped(reader, first_entry[0]) is False, f"Entry should not be skipped: {first_entry[0]}"

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pathlib
import tempfile
from pathlib import Path
@ -48,7 +50,7 @@ def test_entry_is_whitelisted() -> None:
custom_reader.update_feed("https://lovinator.space/rss_test.xml")
# whitelist_title
custom_reader.set_tag("https://lovinator.space/rss_test.xml", "whitelist_title", "fvnnnfnfdnfdnfd") # type: ignore
custom_reader.set_tag("https://lovinator.space/rss_test.xml", "whitelist_title", "fvnnnfnfdnfdnfd") # pyright: ignore[reportArgumentType]
for entry in custom_reader.get_entries():
if entry_is_whitelisted(entry) is True:
assert entry.title == "fvnnnfnfdnfdnfd", f"Expected: fvnnnfnfdnfdnfd, Got: {entry.title}"
@ -56,7 +58,7 @@ def test_entry_is_whitelisted() -> None:
custom_reader.delete_tag("https://lovinator.space/rss_test.xml", "whitelist_title")
# whitelist_summary
custom_reader.set_tag("https://lovinator.space/rss_test.xml", "whitelist_summary", "fvnnnfnfdnfdnfd") # type: ignore
custom_reader.set_tag("https://lovinator.space/rss_test.xml", "whitelist_summary", "fvnnnfnfdnfdnfd") # pyright: ignore[reportArgumentType]
for entry in custom_reader.get_entries():
if entry_is_whitelisted(entry) is True:
assert entry.summary == "fvnnnfnfdnfdnfd", f"Expected: fvnnnfnfdnfdnfd, Got: {entry.summary}"
@ -64,7 +66,7 @@ def test_entry_is_whitelisted() -> None:
custom_reader.delete_tag("https://lovinator.space/rss_test.xml", "whitelist_summary")
# whitelist_content
custom_reader.set_tag("https://lovinator.space/rss_test.xml", "whitelist_content", "fvnnnfnfdnfdnfd") # type: ignore
custom_reader.set_tag("https://lovinator.space/rss_test.xml", "whitelist_content", "fvnnnfnfdnfdnfd") # pyright: ignore[reportArgumentType]
for entry in custom_reader.get_entries():
if entry_is_whitelisted(entry) is True:
assert_msg = f"Expected: <p>ffdnfdnfdnfdnfdndfn</p>, Got: {entry.content[0].value}"
@ -90,7 +92,7 @@ def test_entry_is_blacklisted() -> None:
custom_reader.update_feed("https://lovinator.space/rss_test.xml")
# blacklist_title
custom_reader.set_tag("https://lovinator.space/rss_test.xml", "blacklist_title", "fvnnnfnfdnfdnfd") # type: ignore
custom_reader.set_tag("https://lovinator.space/rss_test.xml", "blacklist_title", "fvnnnfnfdnfdnfd") # pyright: ignore[reportArgumentType]
for entry in custom_reader.get_entries():
if entry_is_blacklisted(entry) is True:
assert entry.title == "fvnnnfnfdnfdnfd", f"Expected: fvnnnfnfdnfdnfd, Got: {entry.title}"
@ -98,7 +100,7 @@ def test_entry_is_blacklisted() -> None:
custom_reader.delete_tag("https://lovinator.space/rss_test.xml", "blacklist_title")
# blacklist_summary
custom_reader.set_tag("https://lovinator.space/rss_test.xml", "blacklist_summary", "fvnnnfnfdnfdnfd") # type: ignore
custom_reader.set_tag("https://lovinator.space/rss_test.xml", "blacklist_summary", "fvnnnfnfdnfdnfd") # pyright: ignore[reportArgumentType]
for entry in custom_reader.get_entries():
if entry_is_blacklisted(entry) is True:
assert entry.summary == "fvnnnfnfdnfdnfd", f"Expected: fvnnnfnfdnfdnfd, Got: {entry.summary}"
@ -106,7 +108,7 @@ def test_entry_is_blacklisted() -> None:
custom_reader.delete_tag("https://lovinator.space/rss_test.xml", "blacklist_summary")
# blacklist_content
custom_reader.set_tag("https://lovinator.space/rss_test.xml", "blacklist_content", "fvnnnfnfdnfdnfd") # type: ignore
custom_reader.set_tag("https://lovinator.space/rss_test.xml", "blacklist_content", "fvnnnfnfdnfdnfd") # pyright: ignore[reportArgumentType]
for entry in custom_reader.get_entries():
if entry_is_blacklisted(entry) is True:
assert_msg = f"Expected: <p>ffdnfdnfdnfdnfdndfn</p>, Got: {entry.content[0].value}"

View File

@ -6,7 +6,7 @@ from pathlib import Path
from typing import LiteralString
import pytest
from reader import Feed, Reader, make_reader # type: ignore
from reader import Feed, Reader, make_reader
from discord_rss_bot.feeds import send_to_discord, truncate_webhook_message
from discord_rss_bot.missing_tags import add_missing_tags
@ -45,7 +45,7 @@ def test_send_to_discord() -> None:
assert webhook_url is not None, f"The webhook URL should not be None. Got: {webhook_url}"
# Add tag to the feed and check if it is there.
reader.set_tag(feed, "webhook", webhook_url) # type: ignore
reader.set_tag(feed, "webhook", webhook_url) # pyright: ignore[reportArgumentType]
assert reader.get_tag(feed, "webhook") == webhook_url, f"The webhook URL should be '{webhook_url}'."
# Send the feed to Discord.

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import urllib.parse
from typing import TYPE_CHECKING

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import tempfile
from pathlib import Path
from typing import TYPE_CHECKING

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import pathlib
import tempfile
from pathlib import Path
@ -52,8 +54,8 @@ def test_get_webhook_for_entry() -> None:
custom_reader.update_feed("https://www.reddit.com/r/movies.rss")
# Add a webhook to the database.
custom_reader.set_tag("https://www.reddit.com/r/movies.rss", "webhook", "https://example.com") # type: ignore
our_tag: str = custom_reader.get_tag("https://www.reddit.com/r/movies.rss", "webhook") # type: ignore
custom_reader.set_tag("https://www.reddit.com/r/movies.rss", "webhook", "https://example.com") # pyright: ignore[reportArgumentType]
our_tag = custom_reader.get_tag("https://www.reddit.com/r/movies.rss", "webhook") # pyright: ignore[reportArgumentType]
assert our_tag == "https://example.com", f"The tag should be 'https://example.com'. But it was '{our_tag}'."
# Close the reader, so we can delete the directory.

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from discord_rss_bot.filter.utils import is_word_in_text

View File

@ -44,7 +44,7 @@ def test_has_white_tags() -> None:
def check_if_has_tag(reader: Reader, feed: Feed, whitelist_name: str) -> None:
reader.set_tag(feed, whitelist_name, "a") # type: ignore
reader.set_tag(feed, whitelist_name, "a") # pyright: ignore[reportArgumentType]
assert has_white_tags(custom_reader=reader, feed=feed) is True, "Feed should have whitelist tags"
reader.delete_tag(feed, whitelist_name)
assert has_white_tags(custom_reader=reader, feed=feed) is False, "Feed should not have any whitelist tags"
@ -70,42 +70,42 @@ def test_should_be_sent() -> None:
# Test entry without any whitelists
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"
reader.set_tag(feed, "whitelist_title", "fvnnnfnfdnfdnfd") # type: ignore
reader.set_tag(feed, "whitelist_title", "fvnnnfnfdnfdnfd") # pyright: ignore[reportArgumentType]
assert should_be_sent(reader, first_entry[0]) is True, "Entry should be sent"
reader.delete_tag(feed, "whitelist_title")
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"
reader.set_tag(feed, "whitelist_title", "åäö") # type: ignore
reader.set_tag(feed, "whitelist_title", "åäö") # pyright: ignore[reportArgumentType]
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"
reader.delete_tag(feed, "whitelist_title")
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"
reader.set_tag(feed, "whitelist_summary", "ffdnfdnfdnfdnfdndfn") # type: ignore
reader.set_tag(feed, "whitelist_summary", "ffdnfdnfdnfdnfdndfn") # pyright: ignore[reportArgumentType]
assert should_be_sent(reader, first_entry[0]) is True, "Entry should be sent"
reader.delete_tag(feed, "whitelist_summary")
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"
reader.set_tag(feed, "whitelist_summary", "åäö") # type: ignore
reader.set_tag(feed, "whitelist_summary", "åäö") # pyright: ignore[reportArgumentType]
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"
reader.delete_tag(feed, "whitelist_summary")
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"
reader.set_tag(feed, "whitelist_content", "ffdnfdnfdnfdnfdndfn") # type: ignore
reader.set_tag(feed, "whitelist_content", "ffdnfdnfdnfdnfdndfn") # pyright: ignore[reportArgumentType]
assert should_be_sent(reader, first_entry[0]) is True, "Entry should be sent"
reader.delete_tag(feed, "whitelist_content")
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"
reader.set_tag(feed, "whitelist_content", "åäö") # type: ignore
reader.set_tag(feed, "whitelist_content", "åäö") # pyright: ignore[reportArgumentType]
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"
reader.delete_tag(feed, "whitelist_content")
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"
reader.set_tag(feed, "whitelist_author", "TheLovinator") # type: ignore
reader.set_tag(feed, "whitelist_author", "TheLovinator") # pyright: ignore[reportArgumentType]
assert should_be_sent(reader, first_entry[0]) is True, "Entry should be sent"
reader.delete_tag(feed, "whitelist_author")
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"
reader.set_tag(feed, "whitelist_author", "åäö") # type: ignore
reader.set_tag(feed, "whitelist_author", "åäö") # pyright: ignore[reportArgumentType]
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"
reader.delete_tag(feed, "whitelist_author")
assert should_be_sent(reader, first_entry[0]) is False, "Entry should not be sent"