add functionality for people to block other users they don't want to interact with
This commit is contained in:
		
							parent
							
								
									0c84b3cebd
								
							
						
					
					
						commit
						60a1f8b827
					
				
					 2 changed files with 122 additions and 19 deletions
				
			
		
							
								
								
									
										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…
	
	Add table
		Add a link
		
	
		Reference in a new issue