Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The scripts work standalone and only require an Auth token. Please find more doc
The bot has the following extensions ("Cogs"):

* Ping: To check if the bot is running, write `$ping` in any channel. The bot will respond with `Pong!`.
* Guild Statistics: As an organizer, write `$participants` in an organizer-only channel. The bot will respond with a list of roles, and the number of members per role.
* Guild Statistics: As an organiser, write `$participants` in an organiser-only channel. The bot will respond with a list of roles, and the number of members per role.
* Registration: On startup, the bot posts a registration form. New users must register using their Pretix ticket data. On success, the bot assigns the appropriate roles.
* Programme Notifications: Before each session, the bot posts a session summary and updates the livestream URLs.

Expand Down Expand Up @@ -193,4 +193,4 @@ Related files:
* `/root/livestreams.toml`: Livestream URL configuration
* `/home/bot/registered_log.txt`: Registration log
* `/home/bot/pretix_cache.json`: Pretix cache
* `/home/bot/schedule_cache.json`: Program cache
* `/home/bot/schedule_cache.json`: Programme cache
14 changes: 7 additions & 7 deletions prod-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,23 @@ pretix_cache_file = "pretix_cache.json"
"Beginners’ Day Unconference / Humble Data Access" = ["Beginners Day"]

[registration.variation_to_roles]
# organizers
"Volunteer" = ["Organizers", "Volunteers", "Onsite Volunteers"]
# organisers
"Volunteer" = ["Organisers", "Volunteers", "Onsite Volunteers"]

[program_notifications]
[programme_notifications]
api_url = "https://static.europython.eu/programme/ep2026/releases/current/schedule.json"
schedule_cache_file = "schedule_cache.json"
livestream_url_file = "livestreams.toml"
main_notification_channel_name = "programme-notifications"

# optional simulated start time for testing program notifications
# optional simulated start time for testing programme notifications
# simulated_start_time = "2026-07-15T08:50:00+02:00"

# optional fast mode for faster testing of program notifications
# optional fast mode for faster testing of programme notifications
# will only take effect if simulated_start_time is set
# fast_mode = true

[program_notifications.rooms_to_channel_names]
[programme_notifications.rooms_to_channel_names]
"S1" = "s1"
"S2" = "s2"
"S3A" = "s3a"
Expand All @@ -62,7 +62,7 @@ main_notification_channel_name = "programme-notifications"
"Exhibit Hall" = "exhibit-hall"

[guild_statistics]
required_role = "Organizers"
required_role = "Organisers"

[dog]
channel_name = "animal-appreciation"
Expand Down
24 changes: 12 additions & 12 deletions scripts/configure-guild.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ def verify_permission_roles(self) -> Self:

ROLE_COC = "Code of Conduct Committee"
ROLE_MODERATORS = "Moderators"
ROLE_ORGANIZERS = "Organizers"
ROLE_ORGANISERS = "Organisers"
ROLE_VOLUNTEERS = "Volunteers"
ROLE_SPEAKERS = "Speakers"
ROLE_SPONSORS = "Sponsors"
Expand All @@ -248,10 +248,10 @@ def verify_permission_roles(self) -> Self:

ROLES_COC = [ROLE_COC]
ROLES_MODERATORS = [ROLE_MODERATORS, *ROLES_COC]
ROLES_ORGANIZERS = [ROLE_ORGANIZERS, *ROLES_MODERATORS]
ROLES_VOLUNTEERS = [ROLE_VOLUNTEERS, *ROLES_ORGANIZERS]
ROLES_SPEAKERS = [ROLE_SPEAKERS, *ROLES_ORGANIZERS]
ROLES_SPONSORS = [ROLE_SPONSORS, *ROLES_ORGANIZERS]
ROLES_ORGANISERS = [ROLE_ORGANISERS, *ROLES_MODERATORS]
ROLES_VOLUNTEERS = [ROLE_VOLUNTEERS, *ROLES_ORGANISERS]
ROLES_SPEAKERS = [ROLE_SPEAKERS, *ROLES_ORGANISERS]
ROLES_SPONSORS = [ROLE_SPONSORS, *ROLES_ORGANISERS]
ROLES_REGISTERED = [
ROLE_PARTICIPANTS,
ROLE_SPONSORS,
Expand Down Expand Up @@ -291,7 +291,7 @@ def verify_permission_roles(self) -> Self:
],
),
Role(
name=ROLE_ORGANIZERS,
name=ROLE_ORGANISERS,
color=COLOR_DARK_YELLOW,
permissions=["mention_everyone", "use_external_apps", "manage_roles"],
),
Expand Down Expand Up @@ -474,7 +474,7 @@ def verify_permission_roles(self) -> Self:
PermissionOverwrite(
roles=[ROLE_EVERYONE], deny=["send_messages", "create_public_threads"]
),
PermissionOverwrite(roles=[ROLE_ORGANIZERS], allow=["send_messages"]),
PermissionOverwrite(roles=[ROLE_ORGANISERS], allow=["send_messages"]),
],
),
TextChannel(
Expand All @@ -487,9 +487,9 @@ def verify_permission_roles(self) -> Self:
ForumChannel(
name="support",
topic="""
Use this forum channel to create support tickets if you **need support from the conference organization**. Please don't open forum threads related to other topics, as that makes it difficult for the organizers to keep track of support tickets that need their attention.
Use this forum channel to create support tickets if you **need support from the conference organization**. Please don't open forum threads related to other topics, as that makes it difficult for the organisers to keep track of support tickets that need their attention.

If you to make a report to the Code of Conduct Committee, please use coc@europython.eu or contact an organizer at the conference.
If you to make a report to the Code of Conduct Committee, please use coc@europython.eu or contact an organiser at the conference.
""", # noqa: E501 (line too long)
tags=["Remote Support", "On-Site Support"],
require_tag=True,
Expand Down Expand Up @@ -756,7 +756,7 @@ def verify_permission_roles(self) -> Self:
roles=[ROLE_EVERYONE], deny=["send_messages", "create_public_threads"]
),
PermissionOverwrite(roles=ROLES_REGISTERED, deny=["view_channel"]),
PermissionOverwrite(roles=ROLES_ORGANIZERS, allow=["view_channel"]),
PermissionOverwrite(roles=ROLES_ORGANISERS, allow=["view_channel"]),
],
),
TextChannel(
Expand All @@ -767,7 +767,7 @@ def verify_permission_roles(self) -> Self:
roles=[ROLE_EVERYONE], deny=["send_messages", "create_public_threads"]
),
PermissionOverwrite(roles=ROLES_REGISTERED, deny=["view_channel"]),
PermissionOverwrite(roles=ROLES_ORGANIZERS, allow=["view_channel"]),
PermissionOverwrite(roles=ROLES_ORGANISERS, allow=["view_channel"]),
],
),
ForumChannel(
Expand All @@ -779,7 +779,7 @@ def verify_permission_roles(self) -> Self:
""", # noqa: E501 (line too long)
permission_overwrites=[
PermissionOverwrite(roles=ROLES_REGISTERED, deny=["view_channel"]),
PermissionOverwrite(roles=ROLES_ORGANIZERS, allow=["view_channel"]),
PermissionOverwrite(roles=ROLES_ORGANISERS, allow=["view_channel"]),
],
),
TextChannel(
Expand Down
8 changes: 4 additions & 4 deletions src/europython_discord/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
from europython_discord.cogs.ping import PingCog
from europython_discord.dog.cog import DogCog
from europython_discord.dog.config import DogConfig
from europython_discord.program_notifications.cog import ProgramNotificationsCog
from europython_discord.program_notifications.config import ProgramNotificationsConfig
from europython_discord.programme_notifications.cog import ProgrammeNotificationsCog
from europython_discord.programme_notifications.config import ProgrammeNotificationsConfig
from europython_discord.registration.cog import RegistrationCog
from europython_discord.registration.config import RegistrationConfig

Expand All @@ -32,7 +32,7 @@
class Config(BaseModel):
log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
registration: RegistrationConfig
program_notifications: ProgramNotificationsConfig
programme_notifications: ProgrammeNotificationsConfig
guild_statistics: GuildStatisticsConfig
dog: DogConfig

Expand All @@ -49,7 +49,7 @@ async def run_bot(config: Config, auth_token: str) -> None:
await bot.add_cog(PingCog(bot))
await bot.add_cog(DogCog(bot, config.dog))
await bot.add_cog(RegistrationCog(bot, config.registration))
await bot.add_cog(ProgramNotificationsCog(bot, config.program_notifications))
await bot.add_cog(ProgrammeNotificationsCog(bot, config.programme_notifications))
await bot.add_cog(GuildStatisticsCog(bot, config.guild_statistics))

await bot.start(auth_token)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
from discord.ext import commands, tasks
from discord.utils import get as discord_get

from europython_discord.program_notifications import session_to_embed
from europython_discord.program_notifications.config import ProgramNotificationsConfig
from europython_discord.program_notifications.livestream_connector import LivestreamConnector
from europython_discord.program_notifications.models import Session
from europython_discord.program_notifications.program_connector import ProgramConnector
from europython_discord.programme_notifications import session_to_embed
from europython_discord.programme_notifications.config import ProgrammeNotificationsConfig
from europython_discord.programme_notifications.livestream_connector import LivestreamConnector
from europython_discord.programme_notifications.models import Session
from europython_discord.programme_notifications.programme_connector import ProgrammeConnector

_logger = logging.getLogger(__name__)


class ProgramNotificationsCog(commands.Cog):
def __init__(self, bot: Client, config: ProgramNotificationsConfig) -> None:
class ProgrammeNotificationsCog(commands.Cog):
def __init__(self, bot: Client, config: ProgrammeNotificationsConfig) -> None:
self.bot = bot
self.config = config
self.program_connector = ProgramConnector(
self.programme_connector = ProgrammeConnector(
api_url=self.config.api_url,
cache_file=self.config.schedule_cache_file,
simulated_start_time=self.config.simulated_start_time,
Expand All @@ -30,7 +30,7 @@ def __init__(self, bot: Client, config: ProgramNotificationsConfig) -> None:
self.livestream_connector = LivestreamConnector(self.config.livestream_url_file)

self.notified_sessions: set[tuple[str, datetime]] = set()
_logger.info("Cog 'Program Notifications' has been initialized")
_logger.info("Cog 'Programme Notifications' has been initialized")

@commands.Cog.listener()
async def on_ready(self) -> None:
Expand All @@ -42,7 +42,7 @@ async def on_ready(self) -> None:
_logger.debug(f"Fast mode: {self.config.fast_mode}")
_logger.info("Starting the session notifier...")
self.notify_sessions.start()
_logger.info("Cog 'Program Notifications' is ready")
_logger.info("Cog 'Programme Notifications' is ready")

async def cog_load(self) -> None:
"""Start schedule updater task."""
Expand All @@ -66,7 +66,7 @@ async def cog_unload(self) -> None:
@tasks.loop(minutes=5)
async def fetch_schedule(self) -> None:
_logger.info("Starting the periodic schedule update...")
await self.program_connector.fetch_schedule()
await self.programme_connector.fetch_schedule()

@tasks.loop(minutes=5)
async def fetch_livestreams(self) -> None:
Expand All @@ -78,7 +78,7 @@ async def fetch_livestreams(self) -> None:
async def notify_sessions(self) -> None:
# determine sessions to send notifications for
sessions_to_notify = []
for session in await self.program_connector.get_upcoming_sessions():
for session in await self.programme_connector.get_upcoming_sessions():
if _get_session_key(session) in self.notified_sessions:
continue # already notified
if len(session.rooms) > 1:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pydantic import AwareDatetime, BaseModel


class ProgramNotificationsConfig(BaseModel):
class ProgrammeNotificationsConfig(BaseModel):
api_url: str
schedule_cache_file: Path
livestream_url_file: Path
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
import aiofiles
import aiohttp

from europython_discord.program_notifications.models import Break, Schedule, Session
from europython_discord.programme_notifications.models import Break, Schedule, Session

_logger = logging.getLogger(__name__)


class ProgramConnector:
class ProgrammeConnector:
def __init__(
self,
api_url: str,
Expand Down Expand Up @@ -51,7 +51,7 @@ async def parse_schedule(self, schedule: dict) -> dict[date, list[Session]]:
return sessions_by_day

async def fetch_schedule(self) -> None:
"""Fetch schedule data from the Program API and write it to a file as backup."""
"""Fetch schedule data from the Programme API and write it to a file as backup."""
async with self._fetch_lock:
try:
async with (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from discord import Embed
from discord.utils import escape_markdown, format_dt

from europython_discord.program_notifications.models import Session, Speaker
from europython_discord.programme_notifications.models import Session, Speaker

_AUTHOR_WIDTH: Final = 128
_TWEET_WIDTH: Final = 200
Expand Down
2 changes: 1 addition & 1 deletion src/europython_discord/registration/cog.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ async def cog_unload(self) -> None:
await reg_channel.send(
f"{WELCOME_MESSAGE_TITLE}\n"
"The registration bot is currently offline. "
"We apologize for the inconvenience and are working hard to fix the issue."
"We apologise for the inconvenience and are working hard to fix the issue."
)

@tasks.loop(minutes=5)
Expand Down
14 changes: 7 additions & 7 deletions test-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,24 @@ pretix_cache_file = "pretix_cache.json"
"Beginners’ Day Unconference / Humble Data Access" = ["Beginners Day"]

[registration.variation_to_roles]
# organizers
"Volunteer" = ["Organizers", "Volunteers", "Onsite Volunteers"]
# organisers
"Volunteer" = ["Organisers", "Volunteers", "Onsite Volunteers"]

[program_notifications]
[programme_notifications]
# UTC offset in hours (e.g. 2 for CEST)
api_url = "https://static.europython.eu/programme/ep2026/releases/current/schedule.json"
schedule_cache_file = "schedule_cache.json"
livestream_url_file = "test-livestreams.toml"
main_notification_channel_name = "programme-notifications"

# optional simulated start time for testing program notifications
# optional simulated start time for testing programme notifications
simulated_start_time = "2026-07-15T08:50:00+02:00"

# optional fast mode for faster testing of program notifications
# optional fast mode for faster testing of programme notifications
# will only take effect if simulated_start_time is set
fast_mode = true

[program_notifications.rooms_to_channel_names]
[programme_notifications.rooms_to_channel_names]
"S1" = "s1"
"S2" = "s2"
"S3A" = "s3a"
Expand All @@ -63,7 +63,7 @@ fast_mode = true
"Exhibit Hall" = "exhibit-hall"

[guild_statistics]
required_role = "Organizers"
required_role = "Organisers"

[dog]
channel_name = "animal-appreciation"
Expand Down
Loading