(Accountability): Add rooms cancel command.

This commit is contained in:
2021-09-19 12:12:10 +03:00
parent d39ec3153a
commit 0a0ac3c6cb
3 changed files with 104 additions and 16 deletions

View File

@@ -170,7 +170,7 @@ class TimeSlot:
"Attended": [], "Attended": [],
"Missing": [] "Missing": []
} }
for memid, mem in self.members.items(): for memid, mem in sorted(self.members.items(), key=lambda mem: mem.data.duration, reverse=True):
mention = '<@{}>'.format(memid) mention = '<@{}>'.format(memid)
if mem.has_attended: if mem.has_attended:
classifications["Attended"].append( classifications["Attended"].append(

View File

@@ -6,6 +6,7 @@ from cmdClient.checks import in_guild
from utils.lib import multiselect_regex, parse_ranges from utils.lib import multiselect_regex, parse_ranges
from data import NOTNULL from data import NOTNULL
from data.conditions import GEQ
from .module import module from .module import module
from .lib import utc_now from .lib import utc_now
@@ -25,7 +26,7 @@ async def cmd_rooms(ctx):
{prefix}rooms book {prefix}rooms book
{prefix}rooms cancel {prefix}rooms cancel
Description: Description:
... Book an accountability session timeslot.
""" """
lower = ctx.args.lower() lower = ctx.args.lower()
splits = lower.split() splits = lower.split()
@@ -34,7 +35,79 @@ async def cmd_rooms(ctx):
if not ctx.guild_settings.accountability_category.value: 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 accountability system isn't set up!")
if command == 'book': # First grab the sessions the member is booked in
joined_rows = accountability_member_info.select_where(
userid=ctx.author.id,
start_at=GEQ(utc_now()),
_extra="ORDER BY start_at ASC"
)
if command == 'cancel':
if not joined_rows:
return await ctx.error_reply("You have no bookings to cancel!")
# Show unbooking menu
lines = [
"`[{:>2}]` | <t:{}:d><t:{}:t> - <t:{}:t>".format(
i,
int(row['start_at'].timestamp()),
int(row['start_at'].timestamp()),
int(row['start_at'].timestamp()) + 3600
)
for i, row in enumerate(joined_rows)
]
out_msg = await ctx.reply(
embed=discord.Embed(
title="Please choose the bookings you want to cancel.",
description='\n'.join(lines),
colour=discord.Colour.orange()
).set_footer(
text=(
"Reply with the number(s) of the rooms you want to join.\n"
"E.g. 1, 3, 5 or 1-5, 7-8."
)
)
)
def check(msg):
valid = msg.channel == ctx.ch and msg.author == ctx.author
valid = valid and (re.search(multiselect_regex, msg.content) or msg.content.lower() == 'c')
return valid
try:
message = await ctx.client.wait_for('message', check=check, timeout=60)
except asyncio.TimeoutError:
await out_msg.delete()
await ctx.error_reply("Session timed out. No accountability bookings were cancelled.")
return
try:
await out_msg.delete()
await message.delete()
except discord.HTTPException:
pass
if message.content.lower() == 'c':
return
to_cancel = [
joined_rows[index]
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.")
cost = len(to_cancel) * ctx.guild_settings.accountability_price.value
accountability_members.delete_where(
userid=ctx.author.id,
slotid=[row['slotid'] for row in to_cancel]
)
ctx.alion.addCoins(-cost)
await ctx.embed_reply(
"Successfully canceled your bookings."
)
# elif command == 'book':
else:
# Show booking menu # Show booking menu
# Get attendee count # Get attendee count
@@ -52,8 +125,13 @@ async def cmd_rooms(ctx):
attendee_pad = max((len(str(num)) for num in attendees.values()), default=1) attendee_pad = max((len(str(num)) for num in attendees.values()), default=1)
# Build lines # Build lines
already_joined_times = set(row['start_at'] for row in joined_rows)
start_time = utc_now().replace(minute=0, second=0, microsecond=0) start_time = utc_now().replace(minute=0, second=0, microsecond=0)
times = list(start_time + datetime.timedelta(hours=n) for n in range(0, 25)) times = (
start_time + datetime.timedelta(hours=n)
for n in range(3, 28)
)
times = list(time for time in times if time not in already_joined_times)
lines = [ lines = [
"`[{:>2}]` | `{:>{}}` attending | <t:{}:d><t:{}:t> - <t:{}:t>".format( "`[{:>2}]` | `{:>{}}` attending | <t:{}:d><t:{}:t> - <t:{}:t>".format(
i, i,
@@ -63,12 +141,17 @@ async def cmd_rooms(ctx):
for i, time in enumerate(times) for i, time in enumerate(times)
] ]
# TODO: Nicer embed # TODO: Nicer embed
# TODO: Remove the slots that the member already booked # TODO: Don't allow multi bookings if the member has a bad attendence rate
out_msg = await ctx.reply( out_msg = await ctx.reply(
embed=discord.Embed( embed=discord.Embed(
title="Please choose the sessions you want to book.", title="Please choose the sessions you want to book.",
description='\n'.join(lines), description='\n'.join(lines),
colour=discord.Colour.orange() colour=discord.Colour.orange()
).set_footer(
text=(
"Reply with the number(s) of the rooms you want to join.\n"
"E.g. 1, 3, 5 or 1-5, 7-8."
)
) )
) )
@@ -109,7 +192,6 @@ async def cmd_rooms(ctx):
) )
) )
# TODO: Make sure we aren't double-booking
slot_rows = accountability_rooms.fetch_rows_where( slot_rows = accountability_rooms.fetch_rows_where(
start_at=to_book start_at=to_book
) )
@@ -125,15 +207,21 @@ async def cmd_rooms(ctx):
insert_keys=('slotid', 'userid', 'paid') insert_keys=('slotid', 'userid', 'paid')
) )
ctx.alion.addCoins(-cost) ctx.alion.addCoins(-cost)
await ctx.embed_reply("You have booked `{}` accountability sessions.".format(len(to_book))) await ctx.embed_reply(
elif command == 'cancel': "You have booked the following accountability sessions.\n{}".format(
# Show unbooking menu '\n'.join(
await ctx.reply("[Placeholder text for cancel menu]") "<t:{}:d><t:{}:t> - <t:{}:t>".format(
... int(time.timestamp()), int(time.timestamp()), int(time.timestamp() + 3600)
else: ) for time in to_book
# Show current booking information )
await ctx.reply("[Placeholder text for current booking information]") )
... )
# else:
# # Show current booking information
# embed = discord.Embed(
# title="Accountability Room Information"
# )
# ...
# TODO: roomadmin # TODO: roomadmin

View File

@@ -205,7 +205,7 @@ async def turnover():
# Update session data of all members in new channels # Update session data of all members in new channels
member_session_data = [ member_session_data = [
(0, slot.start_at, mem.slotid, mem.userid) (0, slot.start_time, mem.slotid, mem.userid)
for slot in current_slots for slot in current_slots
for mem in slot.members.values() for mem in slot.members.values()
if mem.member.voice and mem.member.voice.channel == slot.channel if mem.member.voice and mem.member.voice.channel == slot.channel