Пример #1
0
 async def prepare_seed(default_seed=None):
     seed = default_seed if default_seed else random.randrange(
         10**6)  # 6 digits seed
     random.seed(seed)
     logger.debug(
         f"Picking winners using seed = {seed} ({utils.get_current_time()})"
     )
Пример #2
0
    async def celebrate_account_anniversaries(self):
        # Check if not running above frequency
        today = utils.bot_tz_now()
        last_anniversaries_celebration = zbot.db.get_metadata('last_anniversaries_celebration')
        if last_anniversaries_celebration:
            last_anniversaries_celebration_localized = converter.to_utc(last_anniversaries_celebration)
            if last_anniversaries_celebration_localized.date() == converter.to_utc(today).date():
                logger.debug(f"Prevented sending anniversaries celebration because running above defined frequency.")
                return

        # Get anniversary data
        self.record_account_creation_dates()
        account_anniversaries = zbot.db.get_anniversary_account_ids(
            today, self.MIN_ACCOUNT_CREATION_DATE
        )
        member_anniversaries = {}
        for years, account_ids in account_anniversaries.items():
            for account_id in account_ids:
                member = self.guild.get_member(account_id)
                if member and checker.has_role(member, Messaging.PLAYER_ROLE_NAME):
                    member_anniversaries.setdefault(years, []).append(member)

        # Remove celebration emojis in names from previous anniversaries
        for member in self.guild.members:
            if self.CELEBRATION_EMOJI in member.display_name:
                try:
                    await member.edit(
                        nick=member.display_name.replace(self.CELEBRATION_EMOJI, '').rstrip()
                    )
                except (discord.Forbidden, discord.HTTPException):
                    pass

        # Add celebration emojis for today's anniversaries
        for year, members in member_anniversaries.items():
            for member in members:
                try:
                    await member.edit(
                        nick=member.display_name + " " + self.CELEBRATION_EMOJI * year
                    )
                except (discord.Forbidden, discord.HTTPException):
                    pass

        # Announce anniversaries (after updating names to refresh the cache)
        celebration_channel = self.guild.get_channel(self.CELEBRATION_CHANNEL_ID)
        if member_anniversaries:
            await celebration_channel.send("**Voici les anniversaires du jour !** 🎂")
            for year in sorted(member_anniversaries.keys(), reverse=True):
                for member in member_anniversaries[year]:
                    await celebration_channel.send(
                        f"  • {member.mention} fête ses **{year}** ans sur World of Tanks ! 🥳"
                    )

        zbot.db.update_metadata('last_anniversaries_celebration', today)
Пример #3
0
    async def announce_results(
            results: dict, src_message: discord.Message, channel: discord.TextChannel, is_exclusive,
            required_role_name, organizer: discord.User = None, dest_message: discord.Message = None
    ):
        announcement_embed = discord.Embed(
            title="Résultats du sondage",
            description=f"[Cliquez ici pour accéder au sondage 🗳️]({src_message.jump_url})",
            color=Poll.EMBED_COLOR
        )
        # Compute ranking of votes count: {votes_count: position, votes_count: position, ...}
        votes_ranking = {k: v for v, k in enumerate(sorted(set(results.values()), reverse=True), start=1)}
        # Compute ranking of emojis: {emoji: position, emoji: position, ...}
        emoji_ranking = {emoji: votes_ranking[vote_count] for emoji, vote_count in results.items()}
        ranking_medals = {1: "🥇", 2: "🥈", 3: "🥉"}
        for emoji, vote_count in results.items():
            rank = emoji_ranking[emoji]
            medal_message = f" {ranking_medals.get(rank, '')}" if vote_count > 0 else ""
            announcement_embed.add_field(
                name=f"{emoji}\u2000**# {rank}**",
                value=f"Votes: **{vote_count}**{medal_message}"
            )
        if organizer:
            announcement_embed.set_author(
                name=f"Organisateur : @{organizer.display_name}", icon_url=organizer.avatar_url)
        if dest_message:  # Poll simulation
            await dest_message.edit(embed=announcement_embed)
        else:  # Assessment of a poll
            dest_message = await channel.send(embed=announcement_embed)

            embed = discord.Embed(
                title="Sondage clôturé",
                description=f"[Cliquez ici pour accéder aux résultats 📊]({dest_message.jump_url})"
                            + (f"\n\n{src_message.embeds[0].description}"
                               if src_message.embeds[0].description else ""),
                color=Poll.EMBED_COLOR
            )
            embed.add_field(name="Choix multiple", value="✅" if not is_exclusive else "❌")
            embed.add_field(
                name="Rôle requis",
                value=utils.try_get(
                    src_message.guild.roles,
                    error=exceptions.UnknownRole(required_role_name),
                    name=required_role_name
                ).mention if required_role_name else "Aucun"
            )
            if organizer:
                embed.set_author(
                    name=f"Organisateur : @{organizer.display_name}", icon_url=organizer.avatar_url)
            await src_message.edit(embed=embed)

        logger.debug(f"Poll results: {results}")
Пример #4
0
    async def send_automessage(self):
        # Check if not running above frequency
        now = utils.bot_tz_now()
        last_automessage_date = zbot.db.get_metadata('last_automessage_date')
        if last_automessage_date:
            last_automessage_date_localized = converter.to_utc(last_automessage_date)
            if not utils.is_time_almost_elapsed(last_automessage_date_localized, now, self.AUTOMESSAGE_FREQUENCY):
                logger.debug(f"Prevented sending automessage because running above defined frequency.")
                return

        # Get automessages data
        automessages_data = zbot.db.load_automessages(
            {'automessage_id': {
                '$ne': zbot.db.get_metadata('last_automessage_id')  # Don't post the same message twice in a row
            }},
            ['automessage_id', 'channel_id', 'message']
        )
        if not automessages_data:  # At most a single automessage exists
            automessages_data = zbot.db.load_automessages(  # Load it anyway
                {}, ['automessage_id', 'channel_id', 'message']
            )
        if not automessages_data:  # Not automessage exists
            return  # Abort
        automessage_data = random.choice(automessages_data)
        automessage_id = automessage_data['automessage_id']
        message = automessage_data['message']
        channel = self.guild.get_channel(automessage_data['channel_id'])
        last_channel_message = (await channel.history(limit=1).flatten())[0]

        # Run halt checks on target channel
        if last_channel_message.author == self.user:  # Avoid spamming an channel
            # Check if the cooldown between two bot messages has expired
            last_channel_message_date_localized = converter.to_utc(last_channel_message.created_at)
            cooldown_expired = last_channel_message_date_localized < now - self.AUTOMESSAGE_COOLDOWN
            if not cooldown_expired:
                logger.debug(f"Skipped automessage of id {automessage_id} as cooldown has not expired yet.")
                return
        else:  # Avoid interrupting conversations
            is_channel_quiet, attempt_count = False, 0
            while not is_channel_quiet:  # Wait for the channel to be quiet to send the message
                now = utils.bot_tz_now()
                last_channel_message_date_localized = converter.to_utc(last_channel_message.created_at)
                is_channel_quiet = last_channel_message_date_localized < now - self.AUTOMESSAGE_WAIT
                if not is_channel_quiet:
                    attempt_count += 1
                    if attempt_count < 3:
                        logger.debug(
                            f"Pausing automessage of id {automessage_id} for {self.AUTOMESSAGE_WAIT.seconds} "
                            f"seconds while waiting for quietness in target channel."
                        )
                        await asyncio.sleep(self.AUTOMESSAGE_WAIT.seconds)  # Sleep for the duration of the delay
                    else:  # After 3 failed attempts, skip
                        logger.debug(f"Skipped automessage of id {automessage_id} after 3 waits for quietness.")
                        return

        # All checks passed, send the automessage
        zbot.db.update_metadata('last_automessage_id', automessage_id)
        zbot.db.update_metadata('last_automessage_date', now)
        await channel.send(message)
Пример #5
0
 def __init__(self, bot):
     super().__init__(bot)
     today = converter.get_tz_aware_datetime_now()
     anniversary_celebration_time = self.TIMEZONE.localize(
         datetime.datetime.combine(today, datetime.time(9, 0, 0)))
     last_anniversaries_celebration = zbot.db.get_metadata(
         'last_anniversaries_celebration')
     if not last_anniversaries_celebration \
             or last_anniversaries_celebration.date() != anniversary_celebration_time.date():
         scheduler.schedule_volatile_job(
             anniversary_celebration_time,
             self.celebrate_account_anniversaries,
             interval=datetime.timedelta(days=1))
     else:
         logger.debug(
             f"Prevented sending anniversaries celebration because running above defined frequency."
         )
     self.send_automessage.start()
Пример #6
0
    async def announce_winners(winners: [discord.User],
                               players: [discord.User],
                               message,
                               organizer: discord.User = None):
        embed = discord.Embed(
            title="Résultats du tirage au sort 🎉",
            description=f"Gagnant(s) parmi {len(players)} participant(s):\n" +
            utils.make_user_list(winners, "\n"),
            color=Lottery.EMBED_COLOR)
        if organizer:
            embed.set_author(name=f"Organisateur : @{organizer.display_name}",
                             icon_url=organizer.avatar_url)
        await message.edit(embed=embed)

        if organizer:
            # DM winners
            unreachable_winners = []
            for winner in winners:
                if not await utils.try_dm(
                        winner,
                        f"Félicitations ! Tu as été tiré au sort lors de la loterie organisée "
                        f"par {organizer.display_name} ({organizer.mention}) !\n"
                        f"Contacte cette personne par MP pour obtenir ta récompense :wink:"
                        + f"\nLien : {message.jump_url}"):
                    unreachable_winners.append(winner)
            # DM organizer
            winner_list = utils.make_user_list(winners)
            await utils.try_dm(
                organizer, f"Les gagnants de la loterie sont: {winner_list}\n"
                f"Lien : {message.jump_url}")
            if unreachable_winners:
                unreachable_winner_list = utils.make_user_list(
                    unreachable_winners)
                await utils.try_dm(
                    organizer,
                    f"Les gagnants suivants ont bloqué les MPs et n'ont "
                    f"pas pu être contactés: {unreachable_winner_list}")
            # Log players and winners
            player_list = utils.make_user_list(players, mention=False)
            winner_list = utils.make_user_list(winners, mention=False)
            logger.debug(f"Players: {player_list}")
            logger.debug(f"Winners: {winner_list}")
Пример #7
0
    async def record_server_stats(self):
        now = utils.bot_tz_now()
        last_server_stats_record_date = zbot.db.get_metadata(
            'last_server_stats_record')
        if last_server_stats_record_date:
            last_server_stats_record_date_localized = converter.to_utc(
                last_server_stats_record_date)
            if not utils.is_time_almost_elapsed(
                    last_server_stats_record_date_localized,
                    now,
                    self.SERVER_STATS_RECORD_FREQUENCY,
                    tolerance=datetime.timedelta(minutes=5)):
                logger.debug(
                    f"Prevented recording server stats because running above define frequency."
                )
                return

        await self.record_member_count(now)
        await self.record_message_count(now)
        zbot.db.update_metadata('last_server_stats_record', now)