119 lines
3.0 KiB
Python
119 lines
3.0 KiB
Python
"""
|
|
The discord bot for the application.
|
|
"""
|
|
|
|
import os
|
|
import time
|
|
import logging
|
|
from datetime import datetime
|
|
|
|
import aiohttp
|
|
import discord
|
|
from bs4 import BeautifulSoup as bs4
|
|
from discord import Intents, Interaction, app_commands
|
|
from discord.ext import commands, tasks
|
|
from bbc_feeds import news
|
|
|
|
log = logging.getLogger(__name__)
|
|
EXTENSIONS_DIRECTORY = "src/extensions/"
|
|
|
|
|
|
class DiscordBot(commands.Bot):
|
|
|
|
def __init__(self):
|
|
super().__init__(command_prefix="-", intents=Intents.all())
|
|
|
|
async def sync_app_commands(self):
|
|
"""
|
|
Sync application commands.
|
|
"""
|
|
|
|
await self.wait_until_ready()
|
|
await self.tree.sync()
|
|
log.info("Application commands successfully synced")
|
|
|
|
async def on_ready(self):
|
|
"""
|
|
When the bot is ready.
|
|
"""
|
|
|
|
await self.sync_app_commands()
|
|
|
|
async def load_extensions(self):
|
|
"""
|
|
Load any extensions found in the extensions dictionary.
|
|
"""
|
|
|
|
for filename in os.listdir(EXTENSIONS_DIRECTORY):
|
|
if filename.endswith(".py"):
|
|
await self.load_extension(f"extensions.{filename[:-3]}")
|
|
|
|
|
|
class CommandsCog(commands.Cog):
|
|
|
|
def __init__(self, bot):
|
|
self.bot = bot
|
|
# self.news_task.start()
|
|
|
|
async def story_to_embed(self, story) -> discord.Embed:
|
|
"""
|
|
Returns a discord.Embed object representing the given story.
|
|
|
|
Parameters
|
|
----------
|
|
story : _type_
|
|
_description_
|
|
|
|
Returns
|
|
-------
|
|
discord.Embed
|
|
_description_
|
|
"""
|
|
async with aiohttp.ClientSession() as session:
|
|
async with session.get(story.link) as response:
|
|
html = await response.text()
|
|
|
|
soup = bs4(html, "html.parser")
|
|
image_src = soup.select_one("picture > img").get("src")
|
|
|
|
embed = discord.Embed(
|
|
colour=discord.Colour.from_rgb(255, 0, 0),
|
|
title=story.title,
|
|
description=story.summary,
|
|
url=story.link,
|
|
timestamp=datetime.fromtimestamp(time.mktime(story.published_parsed)),
|
|
)
|
|
embed.set_image(url=image_src)
|
|
return embed
|
|
|
|
group = app_commands.Group(
|
|
name="news",
|
|
description="BBC News"
|
|
)
|
|
|
|
checked_news = set()
|
|
|
|
@group.command(name="latest")
|
|
async def get_latest_news(self, inter: Interaction, limit: int = 1):
|
|
"""
|
|
Provides the latest developments from BBC News.
|
|
"""
|
|
|
|
await inter.response.defer()
|
|
stories = news().all(limit=limit)
|
|
for story in stories:
|
|
embed = await self.story_to_embed(story)
|
|
await inter.followup.send(embed=embed)
|
|
|
|
@tasks.loop(minutes=15)
|
|
async def news_task(self):
|
|
|
|
story = news().all(limit=1)[0]
|
|
if story.link in self.checked_news:
|
|
return
|
|
|
|
self.checked_news.add(story.link)
|
|
embed = await self.story_to_embed(story)
|
|
channel = self.bot.get_channel(1057004889458348042)
|
|
await channel.send(embed=embed)
|