text (rooms): Migrate to scheduled sessions.

This commit is contained in:
2022-01-20 10:31:44 +02:00
parent f2e4cfae8b
commit 0483233c25
4 changed files with 84 additions and 81 deletions

View File

@@ -99,7 +99,7 @@ class TimeSlot:
colour=discord.Colour.orange(),
timestamp=self.start_time
).set_footer(
text="About to start!\nJoin the session with {}rooms book".format(client.prefix)
text="About to start!\nJoin the session with {}schedule book".format(client.prefix)
)
if self.members:
@@ -111,7 +111,7 @@ class TimeSlot:
)
)
else:
embed.description = "No members booked for this session!"
embed.description = "No members scheduled this session!"
return embed
@@ -125,7 +125,7 @@ class TimeSlot:
description="Finishing <t:{}:R>.".format(timestamp + 3600),
colour=discord.Colour.orange(),
timestamp=self.start_time
).set_footer(text="Join the next session using {}rooms book".format(client.prefix))
).set_footer(text="Join the next session using {}schedule book".format(client.prefix))
if self.members:
classifications = {
@@ -158,7 +158,7 @@ class TimeSlot:
if value:
embed.add_field(name=field, value='\n'.join(value))
else:
embed.description = "No members booked for this session!"
embed.description = "No members scheduled this session!"
return embed
@@ -210,7 +210,7 @@ class TimeSlot:
if value:
embed.add_field(name=field, value='\n'.join(value))
else:
embed.description = "No members booked this session!"
embed.description = "No members scheduled this session!"
return embed
@@ -316,13 +316,13 @@ class TimeSlot:
if self.data and not self.channel:
try:
self.channel = await self.guild.create_voice_channel(
"Upcoming Accountability Study Room",
"Upcoming Scheduled Session",
overwrites=overwrites,
category=self.category
)
except discord.HTTPException:
GuildSettings(self.guild.id).event_log.log(
"Failed to create the accountability voice channel. Skipping this session.",
"Failed to create the scheduled session voice channel. Skipping this session.",
colour=discord.Colour.red()
)
return None
@@ -337,7 +337,7 @@ class TimeSlot:
)
except discord.HTTPException:
GuildSettings(self.guild.id).event_log.log(
"Failed to post the status message in the accountability lobby {}.\n"
"Failed to post the status message in the scheduled session lobby {}.\n"
"Skipping this session.".format(self.lobby.mention),
colour=discord.Colour.red()
)
@@ -351,7 +351,7 @@ class TimeSlot:
Ghost pings the session members in the lobby channel.
"""
if self.members:
content = content or "Your accountability session has opened! Please join!"
content = content or "Your scheduled session has started! Please join!"
out = "{}\n\n{}".format(
content,
' '.join('<@{}>'.format(memid) for memid, mem in self.members.items() if not mem.has_attended)
@@ -366,7 +366,7 @@ class TimeSlot:
"""
if self.channel:
try:
await self.channel.edit(name="Accountability Study Room")
await self.channel.edit(name="Scheduled Session Room")
await self.channel.set_permissions(self.guild.default_role, view_channel=True, connect=False)
except discord.HTTPException:
pass
@@ -388,7 +388,7 @@ class TimeSlot:
await asyncio.sleep(delay)
embed = discord.Embed(
title="Your accountability session has started!",
title="The scheduled session you booked has started!",
description="Please join {}.".format(self.channel.mention),
colour=discord.Colour.orange()
).set_footer(

View File

@@ -9,19 +9,19 @@ from .tracker import AccountabilityGuild as AG
@GuildSettings.attach_setting
class accountability_category(settings.Channel, settings.GuildSetting):
category = "Accountability Rooms"
category = "Scheduled Sessions"
attr_name = "accountability_category"
_data_column = "accountability_category"
display_name = "accountability_category"
desc = "Category in which to make the accountability rooms."
display_name = "session_category"
desc = "Category in which to make the scheduled session rooms."
_default = None
long_desc = (
"\"Accountability\" category channel.\n"
"The accountability voice channels will be created here."
"\"Schedule session\" category channel.\n"
"Scheduled sessions will be held in voice channels created under this category."
)
_accepts = "A category channel."
@@ -33,9 +33,9 @@ class accountability_category(settings.Channel, settings.GuildSetting):
# TODO Move this somewhere better
if self.id not in AG.cache:
AG(self.id)
return "The accountability category has been changed to **{}**.".format(self.value.name)
return "The session category has been changed to **{}**.".format(self.value.name)
else:
return "The accountability system has been started in **{}**.".format(self.value.name)
return "The scheduled session system has been started in **{}**.".format(self.value.name)
else:
if self.id in AG.cache:
aguild = AG.cache.pop(self.id)
@@ -43,26 +43,26 @@ class accountability_category(settings.Channel, settings.GuildSetting):
asyncio.create_task(aguild.current_slot.cancel())
if aguild.upcoming_slot:
asyncio.create_task(aguild.upcoming_slot.cancel())
return "The accountability system has been shut down."
return "The scheduled session system has been shut down."
else:
return "The accountability category has been unset."
return "The scheduled session category has been unset."
@GuildSettings.attach_setting
class accountability_lobby(settings.Channel, settings.GuildSetting):
category = "Accountability Rooms"
category = "Scheduled Sessions"
attr_name = "accountability_lobby"
_data_column = attr_name
display_name = attr_name
desc = "Category in which to post accountability session status updates."
display_name = "session_lobby"
desc = "Category in which to post scheduled session notifications updates."
_default = None
long_desc = (
"Accountability session updates will be posted here, and members will be notified in this channel.\n"
"The channel will be automatically created in the accountability category if it does not exist.\n"
"Scheduled session updates will be posted here, and members will be notified in this channel.\n"
"The channel will be automatically created in the configured `session_category` if it does not exist.\n"
"Members do not need to be able to write in the channel."
)
_accepts = "Any text channel."
@@ -76,65 +76,65 @@ class accountability_lobby(settings.Channel, settings.GuildSetting):
@GuildSettings.attach_setting
class accountability_price(settings.Integer, GuildSetting):
category = "Accountability Rooms"
category = "Scheduled Sessions"
attr_name = "accountability_price"
_data_column = attr_name
display_name = attr_name
desc = "Cost of booking an accountability time slot."
display_name = "session_price"
desc = "Cost of booking a scheduled session."
_default = 100
long_desc = (
"The price of booking each one hour accountability room slot."
"The price of booking each one hour scheduled session slot."
)
_accepts = "An integer number of coins."
@property
def success_response(self):
return "Accountability slots now cost `{}` coins.".format(self.value)
return "Scheduled session slots now cost `{}` coins.".format(self.value)
@GuildSettings.attach_setting
class accountability_bonus(settings.Integer, GuildSetting):
category = "Accountability Rooms"
category = "Scheduled Sessions"
attr_name = "accountability_bonus"
_data_column = attr_name
display_name = attr_name
desc = "Bonus given when all accountability members attend a time slot."
display_name = "session_bonus"
desc = "Bonus given when everyone attends a scheduled session slot."
_default = 1000
long_desc = (
"The extra bonus given when all the members who have booked an accountability time slot attend."
"The extra bonus given to each scheduled session member when everyone who booked attended the session."
)
_accepts = "An integer number of coins."
@property
def success_response(self):
return "Accountability members will now get `{}` coins if everyone joins.".format(self.value)
return "Scheduled session members will now get `{}` coins if everyone joins.".format(self.value)
@GuildSettings.attach_setting
class accountability_reward(settings.Integer, GuildSetting):
category = "Accountability Rooms"
category = "Scheduled Sessions"
attr_name = "accountability_reward"
_data_column = attr_name
display_name = attr_name
desc = "Reward given for attending a booked accountability slot."
display_name = "session_reward"
desc = "The individual reward given when a member attends their booked scheduled session."
_default = 200
long_desc = (
"Amount given to a member who books an accountability slot and attends it."
"Reward given to a member who attends a booked scheduled session."
)
_accepts = "An integer number of coins."
@property
def success_response(self):
return "Accountability members will now get `{}` coins at the end of their slot.".format(self.value)
return "Members will now get `{}` coins when they attend their scheduled session.".format(self.value)

View File

@@ -62,28 +62,29 @@ def ensure_exclusive(ctx):
@module.cmd(
name="rooms",
desc="Schedule an accountability study session.",
group="Productivity"
name="schedule",
desc="View your schedule, and get rewarded for attending scheduled sessions!",
group="Productivity",
aliases=('rooms', 'sessions')
)
@in_guild()
async def cmd_rooms(ctx):
"""
Usage``:
{prefix}rooms
{prefix}rooms book
{prefix}rooms cancel
{prefix}schedule
{prefix}schedule book
{prefix}schedule cancel
Description:
View your accountability profile with `{prefix}rooms`.
Use `{prefix}rooms book` to book an accountability session!
Use `{prefix}rooms cancel` to cancel a booked session.
View your schedule with `{prefix}schedule`.
Use `{prefix}schedule book` to schedule a session at a selected time..
Use `{prefix}schedule cancel` to cancel a scheduled session.
"""
lower = ctx.args.lower()
splits = lower.split()
command = splits[0] if splits else None
if not ctx.guild_settings.accountability_category.value:
return await ctx.error_reply("The accountability system isn't set up!")
return await ctx.error_reply("The scheduled session system isn't set up!")
# First grab the sessions the member is booked in
joined_rows = accountability_member_info.select_where(
@@ -94,7 +95,7 @@ async def cmd_rooms(ctx):
if command == 'cancel':
if not joined_rows:
return await ctx.error_reply("You have no bookings to cancel!")
return await ctx.error_reply("You have no scheduled sessions to cancel!")
# Show unbooking menu
lines = [
@@ -102,9 +103,9 @@ async def cmd_rooms(ctx):
for i, row in enumerate(joined_rows)
]
out_msg = await ctx.reply(
content="Please reply with the number(s) of the rooms you want to cancel. E.g. `1, 3, 5` or `1-3, 7-8`.",
content="Please reply with the number(s) of the sessions you want to cancel. E.g. `1, 3, 5` or `1-3, 7-8`.",
embed=discord.Embed(
title="Please choose the bookings you want to cancel.",
title="Please choose the sessions you want to cancel.",
description='\n'.join(lines),
colour=discord.Colour.orange()
).set_footer(
@@ -116,7 +117,7 @@ async def cmd_rooms(ctx):
await ctx.cancellable(
out_msg,
cancel_message="Cancel menu closed, no accountability sessions were cancelled.",
cancel_message="Cancel menu closed, no scheduled sessions were cancelled.",
timeout=70
)
@@ -133,7 +134,7 @@ async def cmd_rooms(ctx):
await out_msg.edit(
content=None,
embed=discord.Embed(
description="Cancel menu timed out, no accountability sessions were cancelled.",
description="Cancel menu timed out, no scheduled sessions were cancelled.",
colour=discord.Colour.red()
)
)
@@ -156,7 +157,7 @@ async def cmd_rooms(ctx):
for index in parse_ranges(message.content) if index < len(joined_rows)
]
if not to_cancel:
return await ctx.error_reply("No valid bookings selected for cancellation.")
return await ctx.error_reply("No valid sessions selected for cancellation.")
elif any(row['start_at'] < utc_now() for row in to_cancel):
return await ctx.error_reply("You can't cancel a running session!")
@@ -189,7 +190,7 @@ async def cmd_rooms(ctx):
remaining = [row for row in joined_rows if row['slotid'] not in slotids]
if not remaining:
await ctx.embed_reply("Cancelled all your upcoming accountability sessions!")
await ctx.embed_reply("Cancelled all your upcoming scheduled sessions!")
else:
next_booked_time = min(row['start_at'] for row in remaining)
if len(to_cancel) > 1:
@@ -245,9 +246,11 @@ async def cmd_rooms(ctx):
# TODO: Nicer embed
# TODO: Don't allow multi bookings if the member has a bad attendance rate
out_msg = await ctx.reply(
content="Please reply with the number(s) of the rooms you want to join. E.g. `1, 3, 5` or `1-3, 7-8`.",
content=(
"Please reply with the number(s) of the sessions you want to book. E.g. `1, 3, 5` or `1-3, 7-8`."
),
embed=discord.Embed(
title="Please choose the sessions you want to book.",
title="Please choose the sessions you want to schedule.",
description='\n'.join(lines),
colour=discord.Colour.orange()
).set_footer(
@@ -354,10 +357,10 @@ async def cmd_rooms(ctx):
# Ack purchase
embed = discord.Embed(
title="You have booked the following session{}!".format('s' if len(to_book) > 1 else ''),
title="You have scheduled the following session{}!".format('s' if len(to_book) > 1 else ''),
description=(
"*Please attend all your booked sessions!*\n"
"*If you can't attend, cancel with* `{}rooms cancel`\n\n{}"
"*Please attend all your scheduled sessions!*\n"
"*If you can't attend, cancel with* `{}schedule cancel`\n\n{}"
).format(
ctx.best_prefix,
'\n'.join(time_format(time) for time in to_book),
@@ -365,7 +368,7 @@ async def cmd_rooms(ctx):
colour=discord.Colour.orange()
).set_footer(
text=(
"Use {prefix}rooms to see your current bookings.\n"
"Use {prefix}schedule to see your current schedule.\n"
).format(prefix=ctx.best_prefix)
)
try:
@@ -400,10 +403,10 @@ async def cmd_rooms(ctx):
if not (history or joined_rows):
# First-timer information
about = (
"You haven't joined any accountability sessions yet!\n"
"Book a session by typing **`{}rooms book`** and selecting "
"You haven't scheduled any study sessions yet!\n"
"Schedule a session by typing **`{}schedule book`** and selecting "
"the hours you intend to study, "
"then attend by joining the accountability voice channel when the session starts!\n"
"then attend by joining the session voice channel when it starts!\n"
"Only if everyone attends will they get the bonus of `{}` LionCoins!\n"
"Let's all do our best and keep each other accountable 🔥"
).format(
@@ -492,7 +495,7 @@ async def cmd_rooms(ctx):
total_count,
(attended_count * 100) / total_count,
),
"Time": "**{:02}:{:02}** spent in accountability rooms.".format(
"Time": "**{:02}:{:02}** in scheduled sessions.".format(
total_duration // 3600,
(total_duration % 3600) // 60
),
@@ -558,16 +561,16 @@ async def cmd_rooms(ctx):
)
booked_field = (
"{}\n\n"
"*If you can't make your booking, please cancel using `{}rooms cancel`!*"
"*If you can't make your session, please cancel using `{}schedule cancel`!*"
).format(booked_list, ctx.best_prefix)
# Temporary footer for acclimatisation
# footer = "All times are displayed in your own timezone!"
footer = "Book another session using {}rooms book".format(ctx.best_prefix)
footer = "Book another session using {}schedule book".format(ctx.best_prefix)
else:
booked_field = (
"Your schedule is empty!\n"
"Book another session using `{}rooms book`."
"Book another session using `{}schedule book`."
).format(ctx.best_prefix)
footer = "Please keep your DMs open for notifications!"
@@ -576,7 +579,7 @@ async def cmd_rooms(ctx):
colour=discord.Colour.orange(),
description=desc,
).set_author(
name="Accountability profile for {}".format(ctx.author.name),
name="Schedule statistics for {}".format(ctx.author.name),
icon_url=ctx.author.avatar_url
).set_footer(
text=footer,

View File

@@ -94,9 +94,9 @@ async def open_next(start_time):
if not slot.category:
# Log and unload guild
aguild.guild_settings.event_log.log(
"The accountability category couldn't be found!\n"
"Shutting down the accountability system in this server.\n"
"To re-activate, please reconfigure `config accountability_category`."
"The scheduled session category couldn't be found!\n"
"Shutting down the scheduled session system in this server.\n"
"To re-activate, please reconfigure `config session_category`."
)
AccountabilityGuild.cache.pop(aguild.guildid, None)
await slot.cancel()
@@ -106,16 +106,16 @@ async def open_next(start_time):
# Create a new lobby
try:
channel = await guild.create_text_channel(
name="accountability-lobby",
name="session-lobby",
category=slot.category,
reason="Automatic creation of accountability lobby."
reason="Automatic creation of scheduled session lobby."
)
aguild.guild_settings.accountability_lobby.value = channel
slot.lobby = channel
except discord.HTTPException:
# Event log failure and skip session
aguild.guild_settings.event_log.log(
"Failed to create the accountability lobby text channel.\n"
"Failed to create the scheduled session lobby text channel.\n"
"Please set the lobby channel manually with `config`."
)
await slot.cancel()
@@ -123,7 +123,7 @@ async def open_next(start_time):
# Event log creation
aguild.guild_settings.event_log.log(
"Automatically created an accountability lobby channel {}.".format(channel.mention)
"Automatically created a scheduled session lobby channel {}.".format(channel.mention)
)
results = await slot.open()
@@ -221,7 +221,7 @@ async def turnover():
movement_tasks = (
mem.member.edit(
voice_channel=slot.channel,
reason="Moving to booked accountability session."
reason="Moving to scheduled session."
)
for slot in current_slots
for mem in slot.members.values()
@@ -317,7 +317,7 @@ async def _accountability_loop():
except Exception:
# Unknown exception. Catch it so the loop doesn't die.
client.log(
"Error while opening new accountability rooms! "
"Error while opening new scheduled sessions! "
"Exception traceback follows.\n{}".format(
traceback.format_exc()
),
@@ -332,7 +332,7 @@ async def _accountability_loop():
except Exception:
# Unknown exception. Catch it so the loop doesn't die.
client.log(
"Error while starting accountability rooms! "
"Error while starting scheduled sessions! "
"Exception traceback follows.\n{}".format(
traceback.format_exc()
),