Bot pro KSP Discord
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
3.4 KiB

11 months ago
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, KSP_URL
11 months ago
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=f"{KSP_URL}/img/hippo_head.png")
11 months ago
date = datetime.fromisoformat(entry.published)
embed.set_footer(text=date.strftime("%-d. %-m. %Y"))
return embed
async def post_news(bot, guild, entry_id):
11 months ago
news_json = data.load_guild_data(guild.id, NEWS_JSON)
if "news_channel" not in news_json:
return "News channel not set."
11 months ago
channel = get(guild.channels, id=news_json["news_channel"])
feed = await ksp_feed()
entries_with_id = list(filter(lambda e: e.id == f"{KSP_URL}/{entry_id}", feed.entries))
if len(entries_with_id) == 0:
return f"Entry with id ``{entry_id}`` not found."
await channel.send(embed=format_entry(entries_with_id[0], author=feed.feed.author))
return None
11 months ago
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_id", str, description="Id of the channel for sending news.")
async def set_channel(self, ctx, channel_id: str):
try:
channel_id = int(channel_id)
except ValueError:
return await ctx.respond(f"Channel id must be int.", ephemeral=True)
if not (channel := get(ctx.guild.channels, id=channel_id)):
return await ctx.respond(f"No channel with id ``{channel_id}``.", ephemeral=True)
11 months ago
news_json = data.load_guild_data(ctx.guild.id, NEWS_JSON)
news_json["news_channel"] = channel_id
11 months ago
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("id", str, description="Id of entry to send.")
async def post_news(self, ctx, id: int):
err = await post_news(self.bot, ctx.guild, id)
if err:
return await ctx.respond(err, ephemeral=True)
11 months ago
return await ctx.respond(f"News posted.", ephemeral=True)
def setup(bot):
bot.add_cog(News(bot))