cmd.py to rss.py + utils

This commit is contained in:
Corban-Lee Jones 2023-12-18 01:06:45 +00:00
parent 994b940e0f
commit 428f459e98
2 changed files with 44 additions and 30 deletions

View File

@ -1,13 +1,12 @@
""" """
Extension for the `CommandCog`. Extension for the `RssCog`.
Loading this file via `commands.Bot.load_extension` will add `CommandCog` to the bot. Loading this file via `commands.Bot.load_extension` will add `RssCog` to the bot.
""" """
import logging import logging
import validators import validators
from typing import Tuple from typing import Tuple
import aiohttp
import textwrap import textwrap
import feedparser import feedparser
from markdownify import markdownify from markdownify import markdownify
@ -16,6 +15,7 @@ from discord.ext import commands
from discord.app_commands import Choice, Group, autocomplete, choices from discord.app_commands import Choice, Group, autocomplete, choices
from sqlalchemy import insert, select, and_, delete from sqlalchemy import insert, select, and_, delete
from utils import get_rss_data, followup, audit
from feed import get_source, Source from feed import get_source, Source
from db import DatabaseManager, SentArticleModel, RssSourceModel from db import DatabaseManager, SentArticleModel, RssSourceModel
@ -26,29 +26,6 @@ rss_list_sort_choices = [
Choice(name="Date Added", value=1) Choice(name="Date Added", value=1)
] ]
async def get_rss_data(url: str):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
items = await response.text(), response.status
return items
async def followup(inter: Interaction, *args, **kwargs):
"""Shorthand for following up on an interaction.
Parameters
----------
inter : Interaction
Represents an app command interaction.
"""
await inter.followup.send(*args, **kwargs)
async def audit(cog, *args, **kwargs):
"""Shorthand for auditing an interaction."""
await cog.bot.audit(*args, **kwargs)
# TODO SECURITY: a potential attack is that the user submits an rss feed then changes the target resource. # TODO SECURITY: a potential attack is that the user submits an rss feed then changes the target resource.
# Run a period task to check this. # Run a period task to check this.
async def validate_rss_source(nickname: str, url: str) -> Tuple[str | None, feedparser.FeedParserDict | None]: async def validate_rss_source(nickname: str, url: str) -> Tuple[str | None, feedparser.FeedParserDict | None]:
@ -93,7 +70,7 @@ async def validate_rss_source(nickname: str, url: str) -> Tuple[str | None, feed
return None, feed return None, feed
class CommandCog(commands.Cog): class RssCog(commands.Cog):
""" """
Command cog. Command cog.
""" """
@ -318,6 +295,10 @@ class CommandCog(commands.Cog):
source = Source.from_parsed(feed) source = Source.from_parsed(feed)
articles = source.get_latest_articles(max) articles = source.get_latest_articles(max)
if not articles:
await followup(inter, "Sorry, I couldn't find any articles from this feed.")
return
embeds = [] embeds = []
for article in articles: for article in articles:
md_description = markdownify(article.description, strip=("img",)) md_description = markdownify(article.description, strip=("img",))
@ -330,8 +311,10 @@ class CommandCog(commands.Cog):
timestamp=article.published, timestamp=article.published,
colour=Colour.brand_red() colour=Colour.brand_red()
) )
thumbail_url = await article.get_thumbnail_url()
thumbail_url = thumbail_url if validators.url(thumbail_url) else None
embed.set_thumbnail(url=source.icon_url) embed.set_thumbnail(url=source.icon_url)
embed.set_image(url=await article.get_thumbnail_url()) embed.set_image(url=thumbail_url)
embed.set_footer(text=article.author) embed.set_footer(text=article.author)
embed.set_author( embed.set_author(
name=source.name, name=source.name,
@ -358,9 +341,9 @@ class CommandCog(commands.Cog):
async def setup(bot): async def setup(bot):
""" """
Setup function for this extension. Setup function for this extension.
Adds `CommandCog` to the bot. Adds `RssCog` to the bot.
""" """
cog = CommandCog(bot) cog = RssCog(bot)
await bot.add_cog(cog) await bot.add_cog(cog)
log.info(f"Added {cog.__class__.__name__} cog") log.info(f"Added {cog.__class__.__name__} cog")

31
src/utils.py Normal file
View File

@ -0,0 +1,31 @@
"""A collection of utility functions that can be used in various places."""
import aiohttp
import logging
from discord import Interaction
log = logging.getLogger(__name__)
async def get_rss_data(url: str):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
items = await response.text(), response.status
return items
async def followup(inter: Interaction, *args, **kwargs):
"""Shorthand for following up on an interaction.
Parameters
----------
inter : Interaction
Represents an app command interaction.
"""
await inter.followup.send(*args, **kwargs)
async def audit(cog, *args, **kwargs):
"""Shorthand for auditing an interaction."""
await cog.bot.audit(*args, **kwargs)