diff --git a/bin/hrochobot b/bin/hrochobot index ae6ba5f..729e853 100755 --- a/bin/hrochobot +++ b/bin/hrochobot @@ -23,6 +23,7 @@ cogs_list = [ 'roles', 'messages', 'ksp', + 'news', ] for cog in cogs_list: diff --git a/hrochobot/cogs/news.py b/hrochobot/cogs/news.py new file mode 100644 index 0000000..8778fbb --- /dev/null +++ b/hrochobot/cogs/news.py @@ -0,0 +1,89 @@ +from datetime import datetime +import discord +from discord.ext import commands +from discord.utils import get +from markdownify import markdownify +import re +from bs4 import BeautifulSoup + +from hrochobot.utils.ksp_utils import ksp_feed +import hrochobot.utils.data as data + +NEWS_JSON = "news" + +def guess_color(title): + """ + Automagically guess color of given post. + Not always reliable as all things automagic. + """ + def contains(*regexes): + return any(re.search(regex, title) for regex in regexes) + + if contains(r"(\d+)-Z(\d+)", "začátečnic", "KSP-Z"): + return discord.Color.green() + elif contains(r"(\d+)-(\d+)", "seriál", "série", "KSP-H"): + return discord.Color.blue() + else: + return discord.Color.dark_purple() + +def format_entry(entry, author=None): + content = "\n\n".join(map(lambda x: x.replace('\n', ' '), entry.summary.split("\n\n"))) + embed = discord.Embed( + title=entry.title, + url=entry.link, + description=markdownify(content, strip=["img"]), + color=guess_color(entry.title), + ) + + soup = BeautifulSoup(content, 'html.parser') + img = soup.find('img') + if img: + embed.set_image(url=img['src']) + + if author: + embed.set_author(name=author) + + embed.set_thumbnail(url="https://ksp.mff.cuni.cz/img/hippo_head.png") + + date = datetime.fromisoformat(entry.published) + embed.set_footer(text=date.strftime("%-d. %-m. %Y")) + + return embed + +async def post_news(bot, guild, index): + news_json = data.load_guild_data(guild.id, NEWS_JSON) + if "news_channel" not in news_json: + return + + channel = get(guild.channels, id=news_json["news_channel"]) + feed = await ksp_feed() + return await channel.send(embed=format_entry(feed.entries[index], author=feed.feed.author)) + + +class News(commands.Cog): + def __init__(self, bot): + self.bot = bot + news = discord.SlashCommandGroup( + "news", + "Commands for management of ksp news.", + guild_only=True, + checks=[commands.has_permissions(manage_guild=True)] + ) + + @news.command(description="Adds a new secret role.") + @discord.option("channel", discord.TextChannel, description="Channel for sending news.") + async def set_channel(self, ctx, channel: discord.TextChannel): + news_json = data.load_guild_data(ctx.guild.id, NEWS_JSON) + news_json["news_channel"] = channel.id + data.dump_guild_data(ctx.guild.id, NEWS_JSON, news_json) + return await ctx.respond(f"News channel set to {channel.mention}.", ephemeral=True) + + @news.command(description="Synchronize news feed.") + @discord.option("index", int, description="Send index-th most recent entry. (indexed from 0)") + async def post_news(self, ctx, index: int): + await post_news(self.bot, ctx.guild, index) + return await ctx.respond(f"News posted.", ephemeral=True) + + +def setup(bot): + bot.add_cog(News(bot))