add functionality for people to block other users they don't want to interact with
This commit is contained in:
parent
0c84b3cebd
commit
60a1f8b827
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
config.json
|
||||
blocks.json
|
||||
|
||||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
|
|
140
waggle-dance.py
140
waggle-dance.py
|
@ -4,20 +4,90 @@ import asyncio
|
|||
import discord
|
||||
import json
|
||||
import random
|
||||
import re
|
||||
import sys
|
||||
|
||||
BLOCKS_FILE = 'blocks.json'
|
||||
|
||||
def get_blocks():
|
||||
try:
|
||||
with open(BLOCKS_FILE) as f:
|
||||
return {int(k): v for (k, v) in json.load(f).items()}
|
||||
except FileNotFoundError:
|
||||
return {}
|
||||
|
||||
def add_block(requester, target):
|
||||
blocks = get_blocks()
|
||||
if requester not in blocks:
|
||||
blocks[requester] = []
|
||||
if target not in blocks[requester]:
|
||||
blocks[requester].append(target)
|
||||
with open(BLOCKS_FILE, 'w') as f:
|
||||
json.dump(blocks, f)
|
||||
|
||||
def remove_block(requester, target):
|
||||
blocks = get_blocks()
|
||||
if requester not in blocks:
|
||||
return
|
||||
while target in blocks[requester]:
|
||||
blocks[requester].remove(target)
|
||||
if len(blocks[requester]) == 0:
|
||||
del blocks[requester]
|
||||
with open(BLOCKS_FILE, 'w') as f:
|
||||
json.dump(blocks, f)
|
||||
|
||||
def matchings(l):
|
||||
if len(l) == 0:
|
||||
count = len(l)
|
||||
if count == 0:
|
||||
return []
|
||||
l = l.copy()
|
||||
random.shuffle(l)
|
||||
center = l.pop()
|
||||
ids = set(u.id for u in l)
|
||||
|
||||
blocks = get_blocks()
|
||||
block_pairs = set()
|
||||
for r in blocks:
|
||||
if r in ids:
|
||||
for t in blocks[r]:
|
||||
if t in ids:
|
||||
block_pairs.add((min(r,t), max(r,t)))
|
||||
disjoint_pairs = []
|
||||
while True:
|
||||
paired = set(u for pair in disjoint_pairs for u in pair)
|
||||
remaining = set(p for p in block_pairs if p[0] not in paired and p[1] not in paired)
|
||||
if len(remaining) == 0:
|
||||
break
|
||||
disjoint_pairs.append(remaining.pop())
|
||||
|
||||
circle = [None]*(count - 1)
|
||||
center = None
|
||||
for i in range(count // 2):
|
||||
if len(disjoint_pairs) != 0:
|
||||
p = disjoint_pairs.pop()
|
||||
l = [u for u in l if u.id not in p]
|
||||
u0 = p[0]
|
||||
u1 = p[1]
|
||||
else:
|
||||
u0 = l.pop()
|
||||
u1 = l.pop()
|
||||
|
||||
circle[i] = u0
|
||||
if i != count // 2 - 1:
|
||||
circle[-(i+1)] = u1
|
||||
else:
|
||||
center = u1
|
||||
|
||||
result = []
|
||||
for i in range(len(l)):
|
||||
matching = [(center, l[i])]
|
||||
for j in range(1, (len(l)-1)//2 + 1):
|
||||
matching.append((l[(i-j)%len(l)], l[(i+j)%len(l)]))
|
||||
for i in range(len(circle)):
|
||||
matching = [(center, circle[i])]
|
||||
for j in range(1, (len(circle)-1)//2 + 1):
|
||||
matching.append((circle[(i-j)%len(circle)], circle[(i+j)%len(circle)]))
|
||||
result.append(matching)
|
||||
|
||||
random.shuffle(result)
|
||||
for i in range(len(result)):
|
||||
random.shuffle(result[i])
|
||||
result = [matching for matching in result if all((min(match[0].id,match[1].id), max(match[0].id,match[1].id)) not in block_pairs for match in matching)]
|
||||
return result
|
||||
|
||||
async def delete_if_possible(channels):
|
||||
|
@ -39,15 +109,7 @@ with open('config.json') as f:
|
|||
|
||||
client = discord.Client()
|
||||
|
||||
@client.event
|
||||
async def on_ready():
|
||||
print('logged in as {0.user}'.format(client), file=sys.stderr)
|
||||
|
||||
@client.event
|
||||
async def on_message(message):
|
||||
if message.author == client.user:
|
||||
return
|
||||
|
||||
async def handle_guild_message(message):
|
||||
if not message.content.startswith('!waggle'):
|
||||
return
|
||||
|
||||
|
@ -81,10 +143,6 @@ async def on_message(message):
|
|||
participants.remove(message.author)
|
||||
await message.channel.send('leaving out {} so we have an even number of participants'.format(message.author.mention))
|
||||
|
||||
if len(participants) == 0:
|
||||
await message.channel.send('there are no participants! :(')
|
||||
return
|
||||
|
||||
mention_all = ' '.join(u.mention for u in participants)
|
||||
|
||||
schedule = matchings(participants)
|
||||
|
@ -92,6 +150,10 @@ async def on_message(message):
|
|||
if rounds:
|
||||
schedule = schedule[:rounds]
|
||||
|
||||
if len(schedule) == 0:
|
||||
await message.channel.send("there aren't enough people for pollination right now :(")
|
||||
return
|
||||
|
||||
pollination_channels = []
|
||||
channel_names = config['channel_names'].copy()
|
||||
exception_count = 0
|
||||
|
@ -147,4 +209,44 @@ async def on_message(message):
|
|||
|
||||
await delete_if_possible(pollination_channels)
|
||||
|
||||
async def handle_dm(message):
|
||||
requester = message.author.id
|
||||
match = re.search('@([^#]+)#([0-9a-f]+)', message.content)
|
||||
if match:
|
||||
handle = match.group(0)
|
||||
name = match.group(1)
|
||||
discriminator = match.group(2)
|
||||
matching_users = [u for u in client.users if u.name == name and u.discriminator == discriminator]
|
||||
if len(matching_users) == 0:
|
||||
await message.channel.send("sorry, I can't find user {}".format(handle))
|
||||
else:
|
||||
target = matching_users[0].id
|
||||
if target in get_blocks().get(requester, []):
|
||||
await message.channel.send("removing {} from your list of blocked users for pollination".format(handle))
|
||||
remove_block(requester, target)
|
||||
else:
|
||||
await message.channel.send("adding {} to your list of blocked users for pollination".format(handle))
|
||||
add_block(requester, target)
|
||||
|
||||
blocks = get_blocks().get(requester, [])
|
||||
if len(blocks) == 0:
|
||||
await message.channel.send("you currently don't have anyone blocked for pollination")
|
||||
else:
|
||||
await message.channel.send("your current list of blocked users for pollination is:\n{}".format('\n'.join('@{}#{}'.format(u.name, u.discriminator) for u in [client.get_user(uid) for uid in blocks] if u is not None)))
|
||||
await message.channel.send("to block or unblock a user, DM me their handle, like @creep#0000. to see this message and your list of blocked users, DM me something random. buzz buzz!")
|
||||
|
||||
@client.event
|
||||
async def on_ready():
|
||||
print('logged in as {0.user}'.format(client), file=sys.stderr)
|
||||
|
||||
@client.event
|
||||
async def on_message(message):
|
||||
if message.author == client.user:
|
||||
return
|
||||
|
||||
if isinstance(message.channel, discord.TextChannel):
|
||||
await handle_guild_message(message)
|
||||
elif isinstance(message.channel, discord.DMChannel):
|
||||
await handle_dm(message)
|
||||
|
||||
client.run(config['token'])
|
||||
|
|
Loading…
Reference in a new issue