Skip to content

Commit 7a93b3c

Browse files
cmaureirmarcorichettaegeakman
authored
Adapt EuroPython bot to PyLadiesCon (#3)
* Adapt EuroPython bot to PyLadiesCon Closes #2 * run tests on PR and main branch (2025) * ci: run tests on PR and main branch (2025) * docs: add warning when testing registration form * adapt deployment --------- Co-authored-by: Marco Richetta <[email protected]> Co-authored-by: egeakman <[email protected]>
1 parent b3d9823 commit 7a93b3c

File tree

13 files changed

+74
-70
lines changed

13 files changed

+74
-70
lines changed

.github/workflows/ci.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ on:
77
push:
88
branches:
99
- main
10+
- "2025"
1011
pull_request:
12+
branches:
13+
- "2025"
1114

1215
jobs:
1316
lint:
@@ -32,3 +35,8 @@ jobs:
3235

3336
- name: Run code checks
3437
run: uv run --dev pre-commit run --all-files
38+
continue-on-error: true
39+
40+
- name: Run tests
41+
run: uv run pytest
42+
continue-on-error: true

.github/workflows/deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ jobs:
2929
ssh-private-key: ${{ secrets.DISCORD_BOT_DEPLOY_KEY }}
3030

3131
- name: Deploy Discord Bot with ansible
32-
run: ansible-playbook -i ${{ secrets.DISCORD_BOT_SERVER_HOST }}, ansible/deploy-playbook.yml --private-key="/home/runner/.ssh/id_rsa" --user=root
32+
run: ansible-playbook -i ${{ secrets.DISCORD_BOT_SERVER_HOST }}, ansible/deploy-playbook.yml --user=root
3333
env:
3434
ANSIBLE_HOST_KEY_CHECKING: "false"

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ to configure your existing Discord Server with the expected channels, roles and
103103

104104
Expected outcome: A Discord Server ready to be used for this bot.
105105

106+
107+
> ![WARNING]
108+
> You cannot test the Registration Cog as the owner user of the Discord Server.
109+
> You'll need to invite a new user to your server to test the registration flow. You can use the mock Pretix server from below.
110+
106111
### Pretix Integration
107112

108113
This bot connects to a Pretix instance to obtain a list of valid tickets.

ansible/deploy-playbook.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
- name: Deploy Discord Bot to the server
33
hosts: all
44
vars:
5-
repository_url: https://github.com/EuroPython/discord.git
5+
repository_url: https://github.com/pyladies/global-conference-discord.git
66

77
tasks:
88
- name: Enable persistent logging for journald
@@ -59,7 +59,7 @@
5959
force: yes
6060
accept_hostkey: yes
6161
single_branch: yes
62-
version: main
62+
version: "2025"
6363

6464
- name: Ensure 'bot' group exists
6565
group:

compose.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
services:
22
EuroPythonBot:
3-
image: europythonbot
3+
image: pyladiescon
44
build:
55
context: .
66
env_file:
@@ -32,7 +32,7 @@ services:
3232
read_only: false
3333

3434
# read all container only logs with
35-
# journalctl -u docker IMAGE_NAME=europythonbot -f
35+
# journalctl -u docker IMAGE_NAME=pyladiescon -f
3636
logging:
3737
driver: journald
3838
restart: unless-stopped

prod-config.toml

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,25 @@ registration_form_channel_name = "registration-form"
55
registration_help_channel_name = "registration-help"
66
registration_log_channel_name = "registration-log"
77

8-
pretix_base_url = "https://pretix.eu/api/v1/organizers/europython/events/ep2025"
8+
pretix_base_url = "https://pretix.eu/api/v1/organizers/pyladiescon/events/2025"
99

1010
registered_cache_file = "registered_log.txt"
1111
pretix_cache_file = "pretix_cache.json"
1212

1313
[registration.item_to_roles]
14-
# onsite participants
15-
"Business" = ["Participants", "Onsite Participants"]
16-
"Personal" = ["Participants", "Onsite Participants"]
17-
"Education" = ["Participants", "Onsite Participants"]
18-
"Community Contributors" = ["Participants", "Onsite Participants"]
19-
"Grant ticket" = ["Participants", "Onsite Participants"]
20-
# remote participants
21-
"Remote Participation Ticket" = ["Participants", "Remote Participants"]
22-
"Remote Grant ticket" = ["Participants", "Remote Participants"]
23-
"Remote Community Organiser" = ["Participants", "Remote Participants"]
24-
# sponsors
25-
"Sponsor Conference Pass" = ["Participants", "Onsite Participants", "Sponsors"]
26-
"Remote Sponsor" = ["Participants", "Remote Participants", "Sponsors"]
27-
# speakers
28-
"Presenter" = ["Participants", "Onsite Participants", "Speakers"]
29-
# onsite volunteers
30-
"On-site Volunteer" = ["Participants", "Onsite Participants", "Volunteers", "Onsite Volunteers"]
31-
# beginners' day
32-
"Beginners’ Day Unconference / Humble Data Access" = ["Beginners Day"]
14+
"Sponsors Ticket" = ["Participant", "Sponsor"]
15+
"Speaker Ticket" = ["Participant", "Speaker"]
16+
"General Ticket" = ["Participant"]
3317

3418
[registration.variation_to_roles]
35-
# organizers
36-
"Volunteer" = ["Organizers", "Volunteers", "Onsite Volunteers"]
19+
"Volunteer" = ["Organizer", "Volunteer"]
3720

3821
[program_notifications]
39-
# UTC offset in hours (e.g. 2 for CEST)
40-
api_url = "https://static.europython.eu/programme/ep2025/releases/current/schedule.json"
22+
# UTC offset in hours (e.g. 1 for CET)
23+
api_url = "https://programapi.conference.pyladies.com/schedule.json"
4124
schedule_cache_file = "schedule_cache.json"
4225
livestream_url_file = "livestreams.toml"
43-
main_notification_channel_name = "programme-notifications"
26+
main_notification_channel_name = "session-notifications"
4427

4528
# optional simulated start time for testing program notifications
4629
# simulated_start_time = "2024-07-10T07:30:00+02:00"
@@ -50,13 +33,8 @@ main_notification_channel_name = "programme-notifications"
5033
# fast_mode = true
5134

5235
[program_notifications.rooms_to_channel_names]
53-
"Forum Hall" = "forum-hall"
54-
"South Hall 2A" = "south-hall-2a"
55-
"South Hall 2B" = "south-hall-2b"
56-
"North Hall" = "north-hall"
57-
"Terrace 2A" = "terrace-2a"
58-
"Terrace 2B" = "terrace-2b"
59-
"Exhibit Hall" = "exhibit-hall"
36+
"Main Stream" = "main-stream"
37+
"Activities & Open Spaces" = "activities-open-spaces"
6038

6139
[guild_statistics]
62-
required_role = "Organizers"
40+
required_role = "Organizer"

src/europython_discord/bot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ async def run_bot(config: Config, auth_token: str) -> None:
5656

5757

5858
def main() -> None:
59-
parser = argparse.ArgumentParser(description="EuroPython Discord Bot")
59+
parser = argparse.ArgumentParser(description="PyLadiesCon Discord Bot")
6060
parser.add_argument("--config-file", type=Path, required=True, help="Configuration file")
6161
args = parser.parse_args()
6262

src/europython_discord/program_notifications/cog.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from europython_discord.program_notifications import session_to_embed
1010
from europython_discord.program_notifications.config import ProgramNotificationsConfig
11-
from europython_discord.program_notifications.livestream_connector import LivestreamConnector
11+
#from europython_discord.program_notifications.livestream_connector import LivestreamConnector
1212
from europython_discord.program_notifications.program_connector import ProgramConnector
1313

1414
_logger = logging.getLogger(__name__)
@@ -25,7 +25,7 @@ def __init__(self, bot: Client, config: ProgramNotificationsConfig) -> None:
2525
fast_mode=self.config.fast_mode,
2626
)
2727

28-
self.livestream_connector = LivestreamConnector(self.config.livestream_url_file)
28+
#self.livestream_connector = LivestreamConnector(self.config.livestream_url_file)
2929

3030
self.notified_sessions = set()
3131
_logger.info("Cog 'Program Notifications' has been initialized")
@@ -48,7 +48,7 @@ async def cog_load(self) -> None:
4848
"Starting the schedule updater and setting the interval for the session notifier..."
4949
)
5050
self.fetch_schedule.start()
51-
self.fetch_livestreams.start()
51+
#self.fetch_livestreams.start()
5252
self.notify_sessions.change_interval(
5353
seconds=2 if self.config.fast_mode and self.config.simulated_start_time else 60
5454
)
@@ -66,11 +66,11 @@ async def fetch_schedule(self) -> None:
6666
_logger.info("Starting the periodic schedule update...")
6767
await self.program_connector.fetch_schedule()
6868

69-
@tasks.loop(minutes=5)
70-
async def fetch_livestreams(self) -> None:
71-
_logger.info("Starting the periodic livestream update...")
72-
await self.livestream_connector.fetch_livestreams()
73-
_logger.info("Finished the periodic livestream update.")
69+
#@tasks.loop(minutes=5)
70+
#async def fetch_livestreams(self) -> None:
71+
# _logger.info("Starting the periodic livestream update...")
72+
# await self.livestream_connector.fetch_livestreams()
73+
# _logger.info("Finished the periodic livestream update.")
7474

7575
@tasks.loop()
7676
async def notify_sessions(self) -> None:
@@ -96,16 +96,18 @@ async def notify_sessions(self) -> None:
9696
room_channel = self._get_room_channel(room_name)
9797

9898
# update room's livestream URL
99-
livestream_url = await self.livestream_connector.get_livestream_url(
100-
room_name, session.start.date()
101-
)
102-
embed = session_to_embed.create_session_embed(session, livestream_url)
99+
#livestream_url = await self.livestream_connector.get_livestream_url(
100+
# room_name, session.start.date()
101+
#)
102+
#embed = session_to_embed.create_session_embed(session, livestream_url)
103+
embed = session_to_embed.create_session_embed(session, None)
104+
103105

104106
await main_notification_channel.send(embed=embed)
105107
if room_channel is not None:
106-
await room_channel.edit(
107-
topic=f"Livestream: [YouTube]({livestream_url})" if livestream_url else ""
108-
)
108+
#await room_channel.edit(
109+
# topic=f"Livestream: [YouTube]({livestream_url})" if livestream_url else ""
110+
#)
109111
await room_channel.send(
110112
content=f"# Starting in 5 minutes @ {session.rooms[0]}",
111113
embed=embed,

src/europython_discord/program_notifications/models.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@
66

77

88
class DaySchedule(BaseModel):
9-
"""Schedule of a single day of EuroPython."""
9+
"""Schedule of a single day of PyLadiesCon."""
1010

1111
rooms: list[str]
1212
events: list[Session | Break]
1313

1414

1515
class Schedule(BaseModel):
16-
"""Complete schedule of EuroPython."""
16+
"""Complete schedule of PyLadiesCon."""
1717

1818
days: dict[date, DaySchedule]
1919

2020

2121
class Break(BaseModel):
22-
"""Break in the EuroPython schedule."""
22+
"""Break in the PyLadiesCon schedule."""
2323

2424
event_type: str
2525
title: str
@@ -29,7 +29,7 @@ class Break(BaseModel):
2929

3030

3131
class Session(BaseModel):
32-
"""Session in the EuroPython schedule."""
32+
"""Session in the PyLadiesCon schedule."""
3333

3434
event_type: str
3535
code: str
@@ -40,6 +40,7 @@ class Session(BaseModel):
4040
tweet: str
4141
level: str
4242
track: str | None
43+
youtube_url: str | None = None # Add PyLadiesCon
4344
rooms: list[str]
4445
start: AwareDatetime
4546
website_url: str

src/europython_discord/program_notifications/program_connector.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ async def fetch_schedule(self) -> None:
8181
await f.write(json.dumps(schedule, indent=2))
8282
_logger.info("Schedule written to cache file.")
8383

84+
# TODO PyLadiesCon: Here we need to modify the fetched schedule file
85+
# and add the new field of each session 'youtube_url' from a local
86+
# configuration file that needs to be provided once the videos are scheduled
87+
# The file needs to have a map with 'Session Code' and the 'Youtube URL',
88+
# for example:
89+
# {
90+
# 'XSRQD': 'https://youtube.com/adasdsdsad',
91+
# }
92+
# so later we can go to the schedule.json and find the 'code'
93+
# field in each item inside 'events', and add it.
94+
8495
self.sessions_by_day = await self.parse_schedule(schedule)
8596
_logger.info("Schedule parsed and loaded.")
8697

0 commit comments

Comments
 (0)