Fix warnings and other type checking issues
This commit is contained in:
		
							
								
								
									
										8
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							| @@ -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 | ||||
|     } | ||||
|   | ||||
							
								
								
									
										5
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @@ -3,8 +3,11 @@ | ||||
|     "botuser", | ||||
|     "Genshins", | ||||
|     "levelname", | ||||
|     "Lovinator", | ||||
|     "markdownified", | ||||
|     "markdownify", | ||||
|     "pipx", | ||||
|     "thead" | ||||
|   ] | ||||
|   ], | ||||
|   "python.analysis.typeCheckingMode": "basic" | ||||
| } | ||||
|   | ||||
| @@ -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() | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|  | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
| @@ -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. | ||||
|   | ||||
| @@ -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. | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| from __future__ import annotations | ||||
|  | ||||
| import sys | ||||
|  | ||||
| import requests | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| from __future__ import annotations | ||||
|  | ||||
| from urllib.parse import ParseResult, urlparse | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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: | ||||
|   | ||||
| @@ -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]}" | ||||
|   | ||||
| @@ -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}" | ||||
|   | ||||
| @@ -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. | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| from __future__ import annotations | ||||
|  | ||||
| import urllib.parse | ||||
| from typing import TYPE_CHECKING | ||||
|  | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| from __future__ import annotations | ||||
|  | ||||
| import tempfile | ||||
| from pathlib import Path | ||||
| from typing import TYPE_CHECKING | ||||
|   | ||||
| @@ -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. | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| from __future__ import annotations | ||||
|  | ||||
| from discord_rss_bot.filter.utils import is_word_in_text | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user