Beispiel #1
0
    async def emoji(self, context: commands.Context, lottery_id: int,
                    emoji: typing.Union[discord.Emoji, str]):
        message, channel, previous_emoji, nb_winners, time, organizer = \
            await self.get_message_env(lottery_id, raise_if_not_found=True)

        if context.author != organizer:
            checker.has_any_mod_role(context, print_error=True)
        if isinstance(emoji, str) and emojis.emojis.count(emoji) != 1:
            raise exceptions.ForbiddenEmoji(emoji)

        previous_reaction = utils.try_get(
            message.reactions,
            error=exceptions.MissingEmoji(previous_emoji),
            emoji=previous_emoji)
        await previous_reaction.remove(zbot.bot.user)
        await message.add_reaction(emoji)
        embed = self.build_announce_embed(emoji, nb_winners, organizer, time,
                                          self.guild.roles)
        await message.edit(embed=embed)

        job_id = self.pending_lotteries[message.id]['_id']
        lottery_data = {
            'emoji_code': emoji if isinstance(emoji, str) else emoji.id
        }
        zbot.db.update_job_data(self.JOBSTORE, job_id, lottery_data)
        self.pending_lotteries[message.id].update(lottery_data)
        await context.send(
            f"Émoji du tirage au sort d'identifiant `{lottery_id}` remplacé par \"{emoji}\" : "
            f"<{message.jump_url}>")
Beispiel #2
0
    async def setup(self,
                    context: commands.Context,
                    announce: str,
                    dest_channel: discord.TextChannel,
                    emoji: typing.Union[discord.Emoji, str],
                    nb_winners: int,
                    time: converter.to_datetime,
                    *,
                    options=""):
        # Check arguments
        if not context.author.permissions_in(dest_channel).send_messages:
            raise exceptions.ForbiddenChannel(dest_channel)
        if isinstance(emoji, str) and emojis.emojis.count(emoji) != 1:
            raise exceptions.ForbiddenEmoji(emoji)
        if nb_winners < 1:
            raise exceptions.UndersizedArgument(nb_winners, 1)
        if (time - utils.get_current_time()).total_seconds() <= 0:
            argument_size = converter.humanize_datetime(time)
            min_argument_size = converter.humanize_datetime(
                utils.get_current_time())
            raise exceptions.UndersizedArgument(argument_size,
                                                min_argument_size)

        # Run command
        organizer = context.author
        do_announce = not utils.is_option_enabled(options, 'no-announce')
        prefixed_announce = utils.make_announce(
            context.guild, announce, do_announce and self.ANNOUNCE_ROLE_NAME)
        embed = self.build_announce_embed(emoji, nb_winners, organizer, time,
                                          self.guild.roles)
        message = await dest_channel.send(prefixed_announce, embed=embed)
        await message.add_reaction(emoji)

        # Register data
        job_id = scheduler.schedule_stored_job(self.JOBSTORE, time,
                                               self.run_lottery, message.id).id
        lottery_data = {
            'lottery_id': self.get_next_lottery_id(),
            'message_id': message.id,
            'channel_id': dest_channel.id,
            'emoji_code': emoji if isinstance(emoji, str) else emoji.id,
            'nb_winners': nb_winners,
            'organizer_id': organizer.id,
        }
        zbot.db.update_job_data(self.JOBSTORE, job_id, lottery_data)
        # Add data managed by scheduler later to avoid updating the database with them
        lottery_data.update({
            '_id': job_id,
            'next_run_time': converter.to_timestamp(time)
        })
        self.pending_lotteries[message.id] = lottery_data

        # Confirm command
        await context.send(
            f"Tirage au sort d'identifiant `{lottery_data['lottery_id']}` programmé : <{message.jump_url}>."
        )
Beispiel #3
0
    async def emojis(
            self, context: commands.Context,
            poll_id: int,
            emoji_list: converter.to_emoji_list,
            *, options=""
    ):
        message, channel, previous_emoji_list, is_exclusive, required_role_name, time, organizer = \
            await self.get_message_env(poll_id, raise_if_not_found=True)

        if context.author != organizer:
            checker.has_any_mod_role(context, print_error=True)
        if not context.author.permissions_in(channel).send_messages:
            raise exceptions.ForbiddenChannel(channel)
        if not emoji_list:
            raise commands.MissingRequiredArgument(context.command.params['emoji_list'])
        for emoji in emoji_list:
            if isinstance(emoji, str) and emojis.emojis.count(emoji) != 1:
                raise exceptions.ForbiddenEmoji(emoji)
        required_role_name = utils.get_option_value(options, 'role')
        if required_role_name:
            utils.try_get(  # Raise if role does not exist
                self.guild.roles, error=exceptions.UnknownRole(required_role_name),
                name=required_role_name
            )

        is_exclusive = utils.is_option_enabled(options, 'exclusive')
        previous_reactions = [
            utils.try_get(
                message.reactions,
                error=exceptions.MissingEmoji(previous_emoji),
                emoji=previous_emoji
            )
            for previous_emoji in previous_emoji_list
        ]
        for previous_reaction in previous_reactions:
            await previous_reaction.remove(zbot.bot.user)
        for emoji in emoji_list:
            await message.add_reaction(emoji)
        embed = self.build_announce_embed(
            message.embeds[0].description, is_exclusive, required_role_name, organizer, time,
            self.guild.roles
        )
        await message.edit(embed=embed)

        job_id = self.pending_polls[message.id]['_id']
        poll_data = {
            'emoji_codes': list(map(lambda e: e if isinstance(e, str) else e.id, emoji_list)),
            'is_exclusive': is_exclusive,
            'required_role_name': required_role_name
        }
        zbot.db.update_job_data(self.JOBSTORE, job_id, poll_data)
        self.pending_polls[message.id].update(poll_data)
        await context.send(
            f"Émojis du sondage d'identifiant `{poll_id}` mis à jour : <{message.jump_url}>"
        )
Beispiel #4
0
    async def simulate(
            self, context: commands.Context,
            src_channel: discord.TextChannel,
            message_id: int,
            emoji_list: converter.to_emoji_list = (),
            dest_channel: discord.TextChannel = None,
            *, options=""
    ):
        for emoji in emoji_list:
            if isinstance(emoji, str) and emojis.emojis.count(emoji) != 1:
                raise exceptions.ForbiddenEmoji(emoji)
        if dest_channel and not context.author.permissions_in(dest_channel).send_messages:
            raise exceptions.ForbiddenChannel(dest_channel)
        is_exclusive = utils.is_option_enabled(options, 'exclusive')
        required_role_name = utils.get_option_value(options, 'role')
        if required_role_name:
            utils.try_get(  # Raise if role does not exist
                self.guild.roles, error=exceptions.UnknownRole(required_role_name),
                name=required_role_name
            )

        message = await utils.try_get_message(
            src_channel, message_id, error=exceptions.MissingMessage(message_id)
        )
        if not emoji_list:
            if len(message.reactions) == 0:
                raise exceptions.MissingConditionalArgument(
                    "Une liste d'émojis doit être fournie si le message ciblé n'a pas de réaction."
                )
            else:
                emoji_list = [reaction.emoji for reaction in message.reactions]

        reactions, results = await Poll.count_votes(
            message, emoji_list, is_exclusive, required_role_name
        )
        announcement = await (dest_channel or context).send(
            "Évaluation des votes sur base des réactions."
        )
        await Poll.announce_results(
            results, message, announcement.channel, is_exclusive, required_role_name,
            dest_message=announcement
        )
Beispiel #5
0
    async def simulate(self,
                       context: commands.Context,
                       src_channel: discord.TextChannel,
                       message_id: int,
                       emoji: typing.Union[discord.Emoji, str] = None,
                       nb_winners: int = 1,
                       dest_channel: discord.TextChannel = None,
                       organizer: discord.User = None,
                       seed: int = None):
        if emoji and isinstance(emoji,
                                str) and emojis.emojis.count(emoji) != 1:
            raise exceptions.ForbiddenEmoji(emoji)
        if nb_winners < 1:
            raise exceptions.UndersizedArgument(nb_winners, 1)
        if dest_channel and not context.author.permissions_in(
                dest_channel).send_messages:
            raise exceptions.ForbiddenChannel(dest_channel)

        message = await utils.try_get_message(
            src_channel,
            message_id,
            error=exceptions.MissingMessage(message_id))
        if not emoji:
            if len(message.reactions) != 1:
                raise exceptions.MissingConditionalArgument(
                    "Un émoji doit être fourni si le message ciblé n'a pas exactement une réaction."
                )
            else:
                emoji = message.reactions[0].emoji
        players, reaction, winners = await Lottery.draw(message,
                                                        emoji,
                                                        nb_winners,
                                                        seed=seed)
        announce = f"Tirage au sort sur base de la réaction {emoji}" \
                   f"{f' et du seed `{seed}`' if seed else ''} au message {message.jump_url}"
        announcement = await (dest_channel or context).send(announce)
        await Lottery.announce_winners(winners,
                                       players,
                                       announcement,
                                       organizer=organizer)
Beispiel #6
0
    async def start(
            self, context: commands.Context,
            announce: str,
            description: str,
            dest_channel: discord.TextChannel,
            emoji_list: converter.to_emoji_list,
            time: converter.to_datetime,
            *, options=""
    ):
        # Check arguments
        if not context.author.permissions_in(dest_channel).send_messages:
            raise exceptions.ForbiddenChannel(dest_channel)
        if not emoji_list:
            raise commands.MissingRequiredArgument(context.command.params['emoji_list'])
        for emoji in emoji_list:
            if isinstance(emoji, str) and emojis.emojis.count(emoji) != 1:
                raise exceptions.ForbiddenEmoji(emoji)
        if (time - utils.get_current_time()).total_seconds() <= 0:
            argument_size = converter.humanize_datetime(time)
            min_argument_size = converter.humanize_datetime(utils.get_current_time())
            raise exceptions.UndersizedArgument(argument_size, min_argument_size)
        do_announce = utils.is_option_enabled(options, 'do-announce')
        do_pin = utils.is_option_enabled(options, 'pin')
        if do_announce or do_pin:
            checker.has_any_mod_role(context, print_error=True)
        required_role_name = utils.get_option_value(options, 'role')
        if required_role_name:
            utils.try_get(  # Raise if role does not exist
                self.guild.roles, error=exceptions.UnknownRole(required_role_name),
                name=required_role_name
            )

        # Run command
        is_exclusive = utils.is_option_enabled(options, 'exclusive')
        organizer = context.author
        prefixed_announce = utils.make_announce(
            context.guild, announce, do_announce and self.ANNOUNCE_ROLE_NAME)
        embed = self.build_announce_embed(
            description, is_exclusive, required_role_name, organizer, time, self.guild.roles)
        message = await dest_channel.send(prefixed_announce, embed=embed)
        for emoji in emoji_list:
            await message.add_reaction(emoji)
        if do_pin:
            await message.pin()

        # Register data
        job_id = scheduler.schedule_stored_job(self.JOBSTORE, time, self.close_poll, message.id).id
        poll_data = {
            'poll_id': self.get_next_poll_id(),
            'message_id': message.id,
            'channel_id': dest_channel.id,
            'emoji_codes': list(map(lambda e: e if isinstance(e, str) else e.id, emoji_list)),
            'organizer_id': organizer.id,
            'is_exclusive': is_exclusive,
            'required_role_name': required_role_name,
        }
        zbot.db.update_job_data(self.JOBSTORE, job_id, poll_data)
        # Add data managed by scheduler later to avoid updating the database with them
        poll_data.update({'_id': job_id, 'next_run_time': converter.to_timestamp(time)})
        self.pending_polls[message.id] = poll_data

        # Confirm command
        await context.send(f"Sondage d'identifiant `{poll_data['poll_id']}` programmé : <{message.jump_url}>.")
        await context.send(f"Sondage démarré.")