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`.
Loading this file via `commands.Bot.load_extension` will add `CommandCog` to the bot.
Extension for the `RssCog`.
Loading this file via `commands.Bot.load_extension` will add `RssCog` to the bot.
"""
import logging
import validators
from typing import Tuple
import aiohttp
import textwrap
import feedparser
from markdownify import markdownify
@ -16,6 +15,7 @@ from discord.ext import commands
from discord.app_commands import Choice, Group, autocomplete, choices
from sqlalchemy import insert, select, and_, delete
from utils import get_rss_data, followup, audit
from feed import get_source, Source
from db import DatabaseManager, SentArticleModel, RssSourceModel
@ -26,29 +26,6 @@ rss_list_sort_choices = [
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.
# Run a period task to check this.
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
class CommandCog(commands.Cog):
class RssCog(commands.Cog):
"""
Command cog.
"""
@ -318,6 +295,10 @@ class CommandCog(commands.Cog):
source = Source.from_parsed(feed)
articles = source.get_latest_articles(max)
if not articles:
await followup(inter, "Sorry, I couldn't find any articles from this feed.")
return
embeds = []
for article in articles:
md_description = markdownify(article.description, strip=("img",))
@ -330,8 +311,10 @@ class CommandCog(commands.Cog):
timestamp=article.published,
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_image(url=await article.get_thumbnail_url())
embed.set_image(url=thumbail_url)
embed.set_footer(text=article.author)
embed.set_author(
name=source.name,
@ -358,9 +341,9 @@ class CommandCog(commands.Cog):
async def setup(bot):
"""
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)
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)