| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
 | import asyncio
import logging
import random
from json import load
from pathlib import Path
import discord
from discord.ext import commands
from bot.constants import Colours
log = logging.getLogger(__name__)
with open(Path("bot/resources/easter/egghead_questions.json"), "r", encoding="utf8") as f:
    EGGHEAD_QUESTIONS = load(f)
EMOJIS = [
    '\U0001f1e6', '\U0001f1e7', '\U0001f1e8', '\U0001f1e9', '\U0001f1ea',
    '\U0001f1eb', '\U0001f1ec', '\U0001f1ed', '\U0001f1ee', '\U0001f1ef',
    '\U0001f1f0', '\U0001f1f1', '\U0001f1f2', '\U0001f1f3', '\U0001f1f4',
    '\U0001f1f5', '\U0001f1f6', '\U0001f1f7', '\U0001f1f8', '\U0001f1f9',
    '\U0001f1fa', '\U0001f1fb', '\U0001f1fc', '\U0001f1fd', '\U0001f1fe',
    '\U0001f1ff'
]  # Regional Indicators A-Z (used for voting)
TIMELIMIT = 30
class EggheadQuiz(commands.Cog):
    """This cog contains the command for the Easter quiz!"""
    def __init__(self, bot):
        self.bot = bot
        self.quiz_messages = {}
    @commands.command(aliases=["eggheadquiz", "easterquiz"])
    async def eggquiz(self, ctx):
        """
        Gives a random quiz question, waits 30 seconds and then outputs the answer
        Also informs of the percentages and votes of each option
        """
        random_question = random.choice(EGGHEAD_QUESTIONS)
        question, answers = random_question["question"], random_question["answers"]
        answers = [(EMOJIS[i], a) for i, a in enumerate(answers)]
        correct = EMOJIS[random_question["correct_answer"]]
        valid_emojis = [emoji for emoji, _ in answers]
        description = f"You have {TIMELIMIT} seconds to vote.\n\n"
        description += "\n".join([f"{emoji} -> **{answer}**" for emoji, answer in answers])
        q_embed = discord.Embed(title=question, description=description, colour=Colours.pink)
        msg = await ctx.send(embed=q_embed)
        for emoji in valid_emojis:
            await msg.add_reaction(emoji)
        self.quiz_messages[msg.id] = valid_emojis
        await asyncio.sleep(TIMELIMIT)
        del self.quiz_messages[msg.id]
        msg = await ctx.channel.fetch_message(msg.id)  # Refreshes message
        total_no = sum([len(await r.users().flatten()) for r in msg.reactions]) - len(valid_emojis)  # - bot's reactions
        if total_no == 0:
            return await msg.delete()  # To avoid ZeroDivisionError if nobody reacts
        results = ["**VOTES:**"]
        for emoji, _ in answers:
            num = [len(await r.users().flatten()) for r in msg.reactions if str(r.emoji) == emoji][0] - 1
            percent = round(100 * num / total_no)
            s = "" if num == 1 else "s"
            string = f"{emoji} - {num} vote{s} ({percent}%)"
            results.append(string)
        mentions = " ".join([
            u.mention for u in [
                await r.users().flatten() for r in msg.reactions if str(r.emoji) == correct
            ][0] if not u.bot
        ])
        content = f"Well done {mentions} for getting it correct!" if mentions else "Nobody got it right..."
        a_embed = discord.Embed(
            title=f"The correct answer was {correct}!",
            description="\n".join(results),
            colour=Colours.pink
        )
        await ctx.send(content, embed=a_embed)
    @staticmethod
    async def already_reacted(message, user):
        """Returns whether a given user has reacted more than once to a given message"""
        users = [u.id for reaction in [await r.users().flatten() for r in message.reactions] for u in reaction]
        return users.count(user.id) > 1  # Old reaction plus new reaction
    @commands.Cog.listener()
    async def on_reaction_add(self, reaction, user):
        """Listener to listen specifically for reactions of quiz messages"""
        if user.bot:
            return
        if reaction.message.id not in self.quiz_messages:
            return
        if str(reaction.emoji) not in self.quiz_messages[reaction.message.id]:
            return await reaction.message.remove_reaction(reaction, user)
        if await self.already_reacted(reaction.message, user):
            return await reaction.message.remove_reaction(reaction, user)
def setup(bot):
    """Egghead Quiz Cog load."""
    bot.add_cog(EggheadQuiz(bot))
    log.info("EggheadQuiz bot loaded")
 |