diff --git a/help/help.md b/help/help.md index b92fc7b..72bbf64 100644 --- a/help/help.md +++ b/help/help.md @@ -8,3 +8,5 @@ Standard diceroller which works with the 1dX notation. See `!help roll` for more `# GIF embeds` For servers that want to disable embeds for any reason (triggers, unwanted imagery, etc), this function will make sure that (for specific channels configured in the config) gif URLs are picked up by the bot and embedded. This whole functionality is used for a problem that shouldn't be there in the first place, but because GIFs are linked to the Embed setting in Discord, for some servers this might pose a solution. +`# LARP Zomer Festival Babbelbingo` +For the LARP Zomer Festival babbelbingo, you can use the `!bingo` command anywhere on the LARP Platform Discord Server. You will get a Babbelbingo card in PM. You can use the `!bingo` command again for a new card if your old one is done or if you want a new one with other questions. diff --git a/jeeves.py b/jeeves.py index 7483dce..d8abdbe 100755 --- a/jeeves.py +++ b/jeeves.py @@ -1,12 +1,11 @@ #!/usr/bin/env python3 import discord -from discord.ext import commands, tasks +from discord.ext import commands +from discord.ext.commands import bot +from discord.utils import get import logging -from jeevesbot import bothelp, functions, env -import gspread -from oauth2client.service_account import ServiceAccountCredentials -import asyncio +from jeevesbot import bothelp, functions, env, babbelbingo # setup logging logging.basicConfig(level=logging.INFO) @@ -15,13 +14,23 @@ logger.setLevel(logging.INFO) handler = logging.FileHandler(filename='jeeves.log', encoding='utf-8', mode='a') handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s')) logger.addHandler(handler) -# setup discord.py -client = discord.Client() + +# setup discord.py bot +intents = discord.Intents().all() +client = commands.Bot(command_prefix='!', intents=intents) e = discord.Embed() -# setup gspread -scope = ['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive'] -creds = ServiceAccountCredentials.from_json_keyfile_name('jeevesbot/secret.json', scope) -gclient = gspread.authorize(creds) + +# listen for emojis (set message id and role id in env.py) +@client.event +async def on_raw_reaction_add(payload): + message = await client.get_channel(payload.channel_id).fetch_message(payload.message_id) + guild_id = payload.guild_id + guild = discord.utils.find(lambda g: g.id == guild_id, client.guilds) + member = discord.utils.get(guild.members, id=payload.user_id) + role = guild.get_role(env.EMOJIREACTROLE) + reaction = discord.utils.get(message.reactions, emoji="☎️") + if message.id in env.EMOJIREACTMSG and reaction is not None: + await member.add_roles(role) @client.event async def on_message(message): @@ -90,6 +99,17 @@ async def on_message(message): roll,result = functions.roll(param) msg = 'Rolling %s for {0.author.mention}: `%s`'.format(message) % (param,roll) await message.channel.send(msg) + if message.content.startswith('!bingo'): + name = message.author.name + bingocard = babbelbingo.bingo(name) + guild_id = message.guild.id + guild = discord.utils.find(lambda g: g.id == guild_id, client.guilds) + member = discord.utils.get(guild.members, id=message.author.id) + role = discord.utils.get(guild.roles , name='babbelbingo') + print(role) + await message.author.send(file=discord.File(bingocard)) + await member.add_roles(role) + @client.event async def on_ready(): @@ -99,3 +119,13 @@ async def on_ready(): if __name__ == '__main__': client.run(env.TOKEN) + + + # message = await client.get_channel(payload.channel_id).fetch_message(payload.message_id) + # guild_id = payload.guild_id + # guild = discord.utils.find(lambda g: g.id == guild_id, client.guilds) + # member = discord.utils.get(guild.members, id=payload.user_id) + # role = guild.get_role(env.EMOJIREACTROLE) + # reaction = discord.utils.get(message.reactions, emoji="☎️") + # if message.id in env.EMOJIREACTMSG and reaction is not None: + # await member.add_roles(role) \ No newline at end of file diff --git a/jeevesbot/babbelbingo.py b/jeevesbot/babbelbingo.py new file mode 100644 index 0000000..fa68430 --- /dev/null +++ b/jeevesbot/babbelbingo.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 + +import gspread +from oauth2client.service_account import ServiceAccountCredentials +import random +from PIL import Image, ImageFont, ImageDraw +import textwrap + +# setup gspread +scope = ['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive'] +creds = ServiceAccountCredentials.from_json_keyfile_name('jeevesbot/secret.json', scope) +gclient = gspread.authorize(creds) + +# load babbelbingofile +def babbelbingo_file(): + file = gclient.open_by_key("1zdWl17fhdT2P96ZgjSwB_2wsCHi_ZVA42JroX5d1ylc") + babbelbingo = file.get_worksheet(1) + values = babbelbingo.get_all_values() + list_values = [item for sublist in values for item in sublist] + questions = random.sample(list_values, k=24) + return questions + +def make_bingocard(name, questions): + image = Image.open('jeevesbot/files/bingokaart.png') + font_name = ImageFont.truetype('jeevesbot/files/Overpass-regular.ttf', 13) + draw = ImageDraw.Draw(image) + wrapper = textwrap.TextWrapper(width=20, break_on_hyphens=True) + box01 = '\n'.join(wrapper.wrap(questions[0])) + box02 = '\n'.join(wrapper.wrap(questions[1])) + box03 = '\n'.join(wrapper.wrap(questions[2])) + box04 = '\n'.join(wrapper.wrap(questions[3])) + box05 = '\n'.join(wrapper.wrap(questions[4])) + box06 = '\n'.join(wrapper.wrap(questions[5])) + box07 = '\n'.join(wrapper.wrap(questions[6])) + box08 = '\n'.join(wrapper.wrap(questions[7])) + box09 = '\n'.join(wrapper.wrap(questions[8])) + box10 = '\n'.join(wrapper.wrap(questions[9])) + box11 = '\n'.join(wrapper.wrap(questions[10])) + box12 = '\n'.join(wrapper.wrap(questions[11])) + box13 = '\n'.join(wrapper.wrap(questions[12])) + box14 = '\n'.join(wrapper.wrap(questions[13])) + box15 = '\n'.join(wrapper.wrap(questions[14])) + box16 = '\n'.join(wrapper.wrap(questions[15])) + box17 = '\n'.join(wrapper.wrap(questions[16])) + box18 = '\n'.join(wrapper.wrap(questions[17])) + box19 = '\n'.join(wrapper.wrap(questions[18])) + box20 = '\n'.join(wrapper.wrap(questions[19])) + box21 = '\n'.join(wrapper.wrap(questions[20])) + box22 = '\n'.join(wrapper.wrap(questions[21])) + box23 = '\n'.join(wrapper.wrap(questions[22])) + box24 = '\n'.join(wrapper.wrap(questions[23])) + draw.multiline_text((95, 280.5), box01, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((229, 280.5), box02, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((363, 280.5), box03, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((497, 280.5), box04, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((631, 280.5), box05, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((95, 399.5), box06, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((229, 399.5), box07, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((363, 399.5), box08, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((497, 399.5), box09, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((631, 399.5), box10, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((95, 518.5), box11, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((229, 518.5), box12, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((497, 518.5), box13, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((631, 518.5), box14, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((95, 637.5), box15, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((229, 637.5), box16, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((363, 637.5), box17, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((497, 637.5), box18, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((631, 637.5), box19, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((95, 756.5), box20, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((229, 756.5), box21, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((363, 756.5), box22, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((497, 756.5), box23, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + draw.multiline_text((631, 756.5), box24, (0, 0, 0), font=font_name, align='center', anchor='mm', spacing=8) + image.save('jeevesbot/files/generated_bingocards/' + name + '.png') + +def bingo(name): + questions = babbelbingo_file() + make_bingocard(name, questions) + bingoimage = ('jeevesbot/files/generated_bingocards/' + name + '.png') + return bingoimage diff --git a/jeevesbot/files/Overpass-Regular.ttf b/jeevesbot/files/Overpass-Regular.ttf new file mode 100644 index 0000000..0deeda5 Binary files /dev/null and b/jeevesbot/files/Overpass-Regular.ttf differ diff --git a/jeevesbot/files/bingokaart.png b/jeevesbot/files/bingokaart.png new file mode 100644 index 0000000..5ca3687 Binary files /dev/null and b/jeevesbot/files/bingokaart.png differ diff --git a/jeevesbot/files/generated_bingocards/Rowena Tilia.png b/jeevesbot/files/generated_bingocards/Rowena Tilia.png new file mode 100644 index 0000000..e6cd300 Binary files /dev/null and b/jeevesbot/files/generated_bingocards/Rowena Tilia.png differ diff --git a/jeevesbot/functions.py b/jeevesbot/functions.py index 1a2bec2..f1af938 100644 --- a/jeevesbot/functions.py +++ b/jeevesbot/functions.py @@ -1,14 +1,9 @@ #!/usr/bin/env python 3 from jeevesbot import env -# import urllib import aiohttp import dice -# This function is necessary for tenor, because they do not allow linking directly to the gif and need resolving. -#def resolve(url): -# return urllib.request.urlopen(url).url - # This function is necessary for tenor, because they do not allow linking directly to the gif and need resolving. ASYNC VERSION async def resolve(url): async with aiohttp.ClientSession() as session: @@ -33,4 +28,5 @@ def checkchannel(channelid): if channelid in env.GIFCHANNELS: return True else: - return False \ No newline at end of file + return False + diff --git a/requirements.txt b/requirements.txt index 9ad3911..559ae2f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,3 +13,6 @@ oauth2client # needs this version, otherwise TypeErrors will break stuff yarl==1.4.2 + +# babbelbingo +Pillow diff --git a/scripts/emojivvdd.py b/scripts/emojivvdd.py new file mode 100644 index 0000000..02dd51d --- /dev/null +++ b/scripts/emojivvdd.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 + +from collections import defaultdict +import time +import discord +from discord.ext import commands +import sys +import ast +import itertools +from discord.utils import get + +from pyasn1.type.constraint import PermittedAlphabetConstraint + +# general @ test = 749399756752814105 + +# setup discord.py bot +intents = discord.Intents().all() +client = commands.Bot(command_prefix='!', intents=intents) + +if len(sys.argv) >= 2: + params = sys.argv[1:] +else: + print("Missing parameter input.") + +async def score(question, score): + e = discord.Embed(title='Emoji-VVDD', color=discord.Color.green()) + e.set_author(name='Jeeves', icon_url='https://cdn.hippogrief.nl/jeevesbot/jeeves.jpg') + e.add_field(name=question, value='\u200b', inline=False) + e.add_field(name='Hoogste score:', value=score, inline=False) + e.set_thumbnail(url='https://cdn.hippogrief.nl/jeevesbot/logo.jpg') + return score + +async def run_script(params): + params = params + channel = client.get_channel(790908319005933598) # vvdd 729667183126511617 # tech 790908319005933598 # test 749399756752814105 + emoji_numbers = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣'] + question = params[0] # string + answers = ast.literal_eval(params[1]) # list + number_of_responses = len(answers) # int + e = discord.Embed(title='Emoji-VVDD', description='Klik de emoji beneden dit bericht om te stemmen op het antwoord wat bij de emoji hoort.', color=discord.Color.blue()) + e.set_author(name='Jeeves', icon_url='https://cdn.hippogrief.nl/jeevesbot/jeeves.jpg') + e.add_field(name=question, value='\u200b', inline=False) + for emoji, answer in zip(emoji_numbers, answers): + e.add_field(name=emoji, value=answer, inline=False) + e.set_thumbnail(url='https://cdn.hippogrief.nl/jeevesbot/logo.jpg') + message = await channel.send(embed=e) + for i in range(number_of_responses): + await message.add_reaction(emoji_numbers[i]) + for i in range(24, -1, -1): + time.sleep(60) + message = await channel.fetch_message(message.id) + + values = {} + for i in message.reactions: + itervalues = {str(i): int(i.count)} + values.update(itervalues) + max_key = max(values, key=values.get) + all_values = values.values() + max_value = max(all_values) + highest_keys = [key for key in values if values[key] == max_value] + + if len(highest_keys) == 1: + max_key = highest_keys[0] + hoogste_score = 'Hoogste score:' + elif len(highest_keys) != 1: + max_key = highest_keys + print(max_key) + hoogste_score = 'Gelijkspel tussen:' + + score = (str(max_key) + ' met ' + str(max_value) + ' stemmen.') + f = discord.Embed(title='Emoji-VVDD', color=discord.Color.green()) + f.set_author(name='Jeeves', icon_url='https://cdn.hippogrief.nl/jeevesbot/jeeves.jpg') + f.add_field(name=question, value='\u200b', inline=False) + f.add_field(name=hoogste_score, value=score, inline=False) + f.set_thumbnail(url='https://cdn.hippogrief.nl/jeevesbot/logo.jpg') + message = await channel.send(embed=f) + + await client.close() + +@client.event +async def on_ready(): + print('### Active with id %s as %s ###' % (client.user.id,client.user.name) ) + activity = discord.Activity(name='!help', type=discord.ActivityType.listening) + await client.change_presence(activity=activity) + await run_script(params) + +if __name__ == '__main__': + client.run('ODE5NjMyNDg1MjU5ODA0NzU0.YEpcPA.I-i1tDIV1vP7FW6-8cA7YLH5lN4') \ No newline at end of file diff --git a/scripts/jeeves.jpg b/scripts/jeeves.jpg new file mode 100644 index 0000000..ff800f8 Binary files /dev/null and b/scripts/jeeves.jpg differ diff --git a/scripts/logo.svg b/scripts/logo.svg new file mode 100644 index 0000000..eea1cf6 --- /dev/null +++ b/scripts/logo.svg @@ -0,0 +1,7 @@ + + + + + + +