Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "after" command to Discord bot #1

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
133 changes: 97 additions & 36 deletions discord/role_commands.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from discord.utils import get
from asyncio import sleep

import discord
import time

import sys
assert sys.version_info >= (3, 10)

def get_delay(s):
if len(s) == 2:
return 4.0
Expand All @@ -16,44 +22,99 @@ async def command_out(message):
)
async def command_in(message):
# User wants to join @Seeking opponent
try:
hours = get_delay(message.content)
except ValueError:
# They said something that wasn't a number, so ignore it
return
if hours <= 0 or hours > 24:
await channel.send('Time parameter must be between 0 and 24 (hours)')
return
current_ts = int(time.time())
author = message.author
channel = message.channel
role = await member_role_set(author,'Seeking opponent',True)
seekers = [m for m in role.members if m != author]
if len(seekers) == 0:
seeker_note = 'No one else is currently looking.'
else:
seeker_note = 'All opponent seekers:\n{}'.format(
'\n'.join([m.mention for m in seekers])
)
await channel.send(
'For the next {} hours, {} is {}\n\n{}'.format(
hours,
author.mention,
role.mention,
seeker_note
)
)
await sleep(3600*hours)
# Check if they are still seeking opponent
r = get(author.roles,name='Seeking opponent')
if r is None:
# They no longer have the role and must have canceled early
return
role = await member_role_set(author,'Seeking opponent',False)
await channel.send(
'Time expired. {} is no longer seeking an opponent.'.format(
author.mention,
)
)

match message.content.split():
case ["in", "help"]:
help_message = """
#looking_for_opponent's commands

`in <available_hours> [delay <hours_before_available]`

Use this command to add your user to the "Looking for opponent" group,
enabling notifications (TODO: CONFIRM THAT) on this channel. The optional
delay parameter allows to announce a future availability.

Example usage:
Announce you are available to play for the next two hours:
`in 2`

Announce that in one hour you will be available two half an hour:
`in .05 delay 1`
"""
await channel.send(help_message)

case ["in", hours]:
try:
hours = get_delay(message.content)
except ValueError:
# They said something that wasn't a number, so ignore it
return
if hours <= 0 or hours > 24:
await message.channel.send('Time parameter must be between 0 and 24 (hours)')
return
role = await member_role_set(author,'Seeking opponent',True)
seekers = [m for m in role.members if m != author]
if len(seekers) == 0:
seeker_note = 'No one else is currently looking.'
else:
seeker_note = 'All opponent seekers:\n{}'.format(
'\n'.join([m.mention for m in seekers])
)
await channel.send(
'For the next {} hours, {} is {}\n\n{}'.format(
hours,
author.mention,
role.mention,
seeker_note
)
)
await sleep(3600*hours)
# Check if they are still seeking opponent
r = get(author.roles,name='Seeking opponent')
if r is None:
# They no longer have the role and must have canceled early
return
role = await member_role_set(author,'Seeking opponent',False)
await channel.send(
'Time expired. {} is no longer seeking an opponent.'.format(
author.mention,
)
)
case ["in", hours, "delay", delay_hours]:
wait_duration_seconds = int(float(delay_hours) * 3600)
available_duration_seconds = int(float(hours) * 3600)

if wait_duration_seconds > 24 * 7 * 3600 or wait_duration_seconds < 0:
await channel.send('The availability period must be scheduled between 0 and 168 hours (one week) from now.')
return

if available_duration_seconds > 24 * 3600 or available_duration_seconds < 0:
await channel.send('The availability period must be between 0 and 24 hours.')
return

start_time_ts = current_ts + wait_duration_seconds
end_time_ts = start_time_ts + available_duration_seconds

await channel.send(f'At <t:{start_time_ts}> {author.mention} will be seeking an opponent until <t:{end_time_ts}>')
await sleep(wait_duration_seconds)

role = await member_role_set(author,'Seeking opponent',True)
await channel.send(f'{author.mention} is now {role.mention} until <t:{end_time_ts}>')

await sleep(available_duration_seconds)

r = get(author.roles,name='Seeking opponent')
if r is None:
# They no longer have the role and must have canceled early
return
role = await member_role_set(author,'Seeking opponent',False)
await channel.send(f'Time expired. {author.mention} is no longer seeking an opponent.')

case _:
await channel.send("syntax: `in <nb_hours> [delay <nb_hours>]`")

async def member_role_set(member,role_name,value):
guild = member.guild
Expand Down