feat(bot): add support for recurring events
This commit is contained in:
parent
bf693dea0e
commit
c1be4e9a24
2 changed files with 71 additions and 22 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -176,3 +176,5 @@ pyvenv.cfg
|
||||||
.venv
|
.venv
|
||||||
pip-selfcheck.json
|
pip-selfcheck.json
|
||||||
|
|
||||||
|
#custom
|
||||||
|
vendor/
|
||||||
|
|
91
bot.py
91
bot.py
|
@ -1,10 +1,9 @@
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
# import sys
|
|
||||||
|
|
||||||
# needs the following version of discord.py for recurring events to work: https://github.com/DA-344/d.py/tree/recurrent_events
|
# needs the following version of discord.py for recurring events to work: https://github.com/DA-344/d.py/tree/recurrent_events
|
||||||
# sys.path.insert(1, path_to_discorpy_version)
|
# uncomment following lines
|
||||||
|
# import sys
|
||||||
|
# sys.path.insert(1, '/path/to/Posthorn/vendor/d.py')
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands, tasks
|
from discord.ext import commands, tasks
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
@ -27,20 +26,56 @@ bot = commands.Bot(command_prefix="!", intents=intents)
|
||||||
|
|
||||||
|
|
||||||
def getCommitMessage(event):
|
def getCommitMessage(event):
|
||||||
return f"{event.start_time.strftime("%Y-%m-%d")}_{event.name}"
|
return f"{event.start_time.strftime('%Y-%m-%d')}_{event.name}"
|
||||||
|
|
||||||
|
|
||||||
def getFilePath(event):
|
def getFilePath(event):
|
||||||
return f"_events/{event.start_time.strftime("%Y")}/discord-event-{event.id}.md"
|
return f"_events/{event.start_time.strftime('%Y')}/discord-event-{event.id}.md"
|
||||||
|
|
||||||
|
def getDay(day):
|
||||||
|
match day:
|
||||||
|
case 0:
|
||||||
|
return 'MO'
|
||||||
|
case 1:
|
||||||
|
return 'TU'
|
||||||
|
case 2:
|
||||||
|
return 'WE'
|
||||||
|
case 3:
|
||||||
|
return 'TH'
|
||||||
|
case 4:
|
||||||
|
return 'FR'
|
||||||
|
case 5:
|
||||||
|
return 'SA'
|
||||||
|
case 6:
|
||||||
|
return 'SU'
|
||||||
|
case _:
|
||||||
|
raise Exception(f'no matching day for int {day}')
|
||||||
|
|
||||||
|
def getRrule(event):
|
||||||
|
byDay = False
|
||||||
|
if hasattr(event.recurrence_rule, "n_weekdays"):
|
||||||
|
weekdays = event.recurrence_rule.n_weekdays
|
||||||
|
i = 0
|
||||||
|
for week, day in weekdays:
|
||||||
|
comma = ''
|
||||||
|
if i < len(weekdays) - 1:
|
||||||
|
comma = ','
|
||||||
|
byDay = f'{str(week)}{getDay(day)}{comma}'
|
||||||
|
i += 1
|
||||||
|
if byDay:
|
||||||
|
return f"FREQ={event.recurrence_rule.frequency.name.upper()};INTERVAL={event.recurrence_rule.interval};BYDAY={byDay}"
|
||||||
|
else:
|
||||||
|
return f"FREQ={event.recurrence_rule.frequency.name.upper()};INTERVAL={event.recurrence_rule.interval}"
|
||||||
|
|
||||||
def getEventYML(event):
|
def getEventYML(event):
|
||||||
if hasattr(event.recurrence_rule, "frequency") and hasattr(
|
location = "Leibnizstraße 32, 39104 Magdeburg"
|
||||||
event.recurrence_rule, "interval"
|
if hasattr(event, 'location'):
|
||||||
):
|
location = event.location
|
||||||
return f'---\nlayout: event\ntitle: "{event.name}"\nauthor: "Netz39 e.V." \nevent:\n start: {event.start_time.strftime("%Y-%m-%d %H:%M:%S")} \n end: {event.end_time.strftime("%Y-%m-%d %H:%M:%S")} \n organizer: "Netz39 Team <kontakt@netz39.de>" \n location: "Leibnizstr. 18, 39104 Magdeburg"\n frequency: "{event.recurrence_rule.frequency}"\n interval: {event.recurrence_rule.interval}\n---\n<!-- event imported from discord manual changes may be overwritten -->'
|
|
||||||
|
if hasattr(event, "recurrence_rule") and hasattr(event.recurrence_rule, "frequency") and hasattr(event.recurrence_rule, "interval"):
|
||||||
|
return f'---\nlayout: event\ntitle: "{event.name}"\nauthor: "Netz39 e.V." \nevent:\n start: {event.start_time.strftime("%Y-%m-%d %H:%M:%S")} \n end: {event.end_time.strftime("%Y-%m-%d %H:%M:%S")} \n organizer: "Netz39 Team <kontakt@netz39.de>" \n location: "{location}"\n rrule: "{getRrule(event)}"\n---\n<!-- event imported from discord manual changes may be overwritten -->\n{event.description}'
|
||||||
else:
|
else:
|
||||||
return f'---\nlayout: event\ntitle: "{event.name}"\nauthor: "Netz39 e.V." \nevent:\n start: {event.start_time.strftime("%Y-%m-%d %H:%M:%S")} \n end: {event.end_time.strftime("%Y-%m-%d %H:%M:%S")} \n organizer: "Netz39 Team <kontakt@netz39.de>" \n location: "Leibnizstr. 18, 39104 Magdeburg"\n---\n<!-- event imported from discord manual changes may be overwritten -->'
|
return f'---\nlayout: event\ntitle: "{event.name}"\nauthor: "Netz39 e.V." \nevent:\n start: {event.start_time.strftime("%Y-%m-%d %H:%M:%S")} \n end: {event.end_time.strftime("%Y-%m-%d %H:%M:%S")} \n organizer: "Netz39 Team <kontakt@netz39.de>" \n location: "{location}"\n---\n<!-- event imported from discord manual changes may be overwritten -->\n{event.description}'
|
||||||
|
|
||||||
|
|
||||||
def getAdmins(guild):
|
def getAdmins(guild):
|
||||||
|
@ -57,10 +92,10 @@ async def check_events():
|
||||||
for guild in bot.guilds:
|
for guild in bot.guilds:
|
||||||
scheduledEvents = await guild.fetch_scheduled_events()
|
scheduledEvents = await guild.fetch_scheduled_events()
|
||||||
for event in scheduledEvents:
|
for event in scheduledEvents:
|
||||||
await handleEvent(event)
|
await handleEvent(event, True)
|
||||||
|
|
||||||
|
|
||||||
async def handleEvent(event):
|
async def handleEvent(event, isUpdate = False):
|
||||||
guild = event.guild
|
guild = event.guild
|
||||||
channel = guild.system_channel
|
channel = guild.system_channel
|
||||||
admins = getAdmins(guild)
|
admins = getAdmins(guild)
|
||||||
|
@ -74,9 +109,21 @@ async def handleEvent(event):
|
||||||
eventYML,
|
eventYML,
|
||||||
f"new event: {commit_message}",
|
f"new event: {commit_message}",
|
||||||
)
|
)
|
||||||
await channel.send(
|
if not isUpdate:
|
||||||
f"📅 New event '{event.name}' on {event.start_time.strftime("%Y-%m-%d")}."
|
embed = discord.Embed(
|
||||||
)
|
title=f"📅 New event on {event.start_time.strftime('%Y-%m-%d')}",
|
||||||
|
description=f"### {event.name}\n\n{event.description}\n\n",
|
||||||
|
color=discord.Color.light_embed()
|
||||||
|
)
|
||||||
|
if hasattr(event, "cover_image") and event.cover_image:
|
||||||
|
embed.set_image(url=event.cover_image.url)
|
||||||
|
embed.add_field(name="📅 Time", value=event.start_time.strftime("%Y-%m-%d %HUhr"), inline=True)
|
||||||
|
if hasattr(event, 'location'):
|
||||||
|
embed.add_field(name="📍 Location", value=event.location, inline=True)
|
||||||
|
eventLink = f"[🔗 Netz39](https://www.netz39.de/events/2025/discord-event-{event.id})";
|
||||||
|
embed.add_field(value=eventLink, name="", inline=False)
|
||||||
|
embed.set_footer(text="Don’t miss it! ")
|
||||||
|
await channel.send(embed=embed)
|
||||||
else:
|
else:
|
||||||
eventJSON = json.dumps(
|
eventJSON = json.dumps(
|
||||||
{
|
{
|
||||||
|
@ -92,7 +139,7 @@ async def handleEvent(event):
|
||||||
user = await bot.fetch_user(event.creator_id)
|
user = await bot.fetch_user(event.creator_id)
|
||||||
await sendDm(
|
await sendDm(
|
||||||
admin,
|
admin,
|
||||||
f"{user.name} added a new Event on {event.start_time.strftime("%Y")}: {event.name}. Like this message to approve.\n\n\n```json\n{eventJSON}```",
|
f"{user.name} added a new Event on {event.start_time.strftime('%Y')}: {event.name}. Like this message to approve.\n\n\n```json\n{eventJSON}```",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,9 +168,9 @@ async def on_ready():
|
||||||
|
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_scheduled_event_update(event):
|
async def on_scheduled_event_update(before, after):
|
||||||
if event.status != "canceled":
|
if after.status != "canceled":
|
||||||
await handleEvent(event)
|
await handleEvent(after, True)
|
||||||
|
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
|
@ -160,10 +207,10 @@ async def on_reaction_add(reaction, user):
|
||||||
create_or_update_file(
|
create_or_update_file(
|
||||||
messageJSON["path"],
|
messageJSON["path"],
|
||||||
messageJSON["yml"],
|
messageJSON["yml"],
|
||||||
f"new event: {messageJSON["fileName"]}",
|
f"new event: {messageJSON['fileName']}",
|
||||||
)
|
)
|
||||||
await channel.send(
|
await channel.send(
|
||||||
f"📅 New event '{messageJSON["name"]}' on {messageJSON["date"]}."
|
f"📅 New event '{messageJSON['name']}' on {messageJSON['date']}."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue