<commit_before>"""
A rock, paper, scissors extension.
"""

import logging
import discord
from discord.ext import commands
from dog import Cog

log = logging.getLogger(__name__)


class RPS(Cog):
    async def rps_is_being_excluded(self, who: discord.Member) -> bool:
        """ Returns whether a person is being excluded from RPS. """
        return await self.bot.pg.fetchrow('SELECT * FROM rps_exclusions WHERE user_id = $1',
                                          who.id) is not None

    @commands.group(invoke_without_command=True)
    @commands.guild_only()
    @commands.cooldown(1, 2, commands.BucketType.user)
    async def rps(self, ctx, opponent: discord.Member):
        """ Fights someone in rock, paper, scissors! """
        if await self.rps_is_being_excluded(opponent):
            return await ctx.send('That person chose to be excluded from RPS.')

        progress_message = await ctx.send('Waiting for {} to choose...'.format(ctx.author))

        def rps_check(who: discord.Member):
            """ Returns a check that checks for a DM from a person. """

            def rps_predicate(reaction, adder):
                is_original_person = adder.id == who.id
                is_in_dm = isinstance(reaction.message.channel, discord.DMChannel)
                return is_original_person and is_in_dm

            return rps_predicate

        async def rps_get_choice(who: discord.Member) -> str:
            """ Sends someone the instructional message, then waits for a choice. """
            desc = ('React with what you want to play. If you don\'t wish to be challenged to RPS, '
                    'type `d?rps exclude` to exclude yourself from being challenged.')
            desc_prefix = ('You have been challenged by {}!\n\n'.format(ctx.author.mention) if who.id == opponent.id
                           else 'Because you initiated the game, you go first.\n\n')
            embed = discord.Embed(title='Rock, paper, scissors!',
                                  description=desc_prefix + desc)
            msg = await who.send(embed=embed)
            translate = {
                '\N{NEW MOON SYMBOL}': 'rock',
                '\N{NEWSPAPER}': 'paper',
                '\N{BLACK SCISSORS}': 'scissors'
            }
            for emoji in translate:
                await msg.add_reaction(emoji)
            while True:
                reaction, _ = await self.bot.wait_for('reaction_add', check=rps_check(who))
                if reaction.emoji in translate:
                    return translate[reaction.emoji]

        # get their choices
        initiator_choice = await rps_get_choice(ctx.author)
        await progress_message.edit(content='Waiting for the opponent ({}) to choose...'.format(
            opponent))
        opponent_choice = await rps_get_choice(opponent)

        # delete the original message, because edited mentions do not notify
        # the user
        await progress_message.delete()

        # check if it was a tie
        if initiator_choice == opponent_choice:
            fmt = '{}, {}: It was a tie! You both chose {}.'
            return await ctx.send(fmt.format(ctx.author.mention, opponent.mention,
                                             initiator_choice))

        async def inform_winner(who: discord.Member, beats_left: str, beats_right: str):
            fmt = '{}, {}: :first_place: {} was the winner! {} beats {}.'
            return await ctx.send(fmt.format(ctx.author.mention, opponent.mention, who.mention,
                                             beats_left.title(), beats_right))

        def beats(weapon: str, target: str) -> bool:
            """ Rock, paper, scissors defeat checker. """
            if weapon == 'paper':
                return target == 'rock'<commit_msg>handle rps message sending failure<commit_after>"""
A rock, paper, scissors extension.
"""

import logging
import discord
from discord.ext import commands
from dog import Cog

log = logging.getLogger(__name__)


class RPS(Cog):
    async def rps_is_being_excluded(self, who: discord.Member) -> bool:
        """ Returns whether a person is being excluded from RPS. """
        return await self.bot.pg.fetchrow('SELECT * FROM rps_exclusions WHERE user_id = $1',
                                          who.id) is not None

    @commands.group(invoke_without_command=True)
    @commands.guild_only()
    @commands.cooldown(1, 2, commands.BucketType.user)
    async def rps(self, ctx, opponent: discord.Member):
        """ Fights someone in rock, paper, scissors! """
        if await self.rps_is_being_excluded(opponent):
            return await ctx.send('That person chose to be excluded from RPS.')

        progress_message = await ctx.send('Waiting for {} to choose...'.format(ctx.author))

        def rps_check(who: discord.Member):
            """ Returns a check that checks for a DM from a person. """

            def rps_predicate(reaction, adder):
                is_original_person = adder.id == who.id
                is_in_dm = isinstance(reaction.message.channel, discord.DMChannel)
                return is_original_person and is_in_dm

            return rps_predicate

        async def rps_get_choice(who: discord.Member) -> str:
            """ Sends someone the instructional message, then waits for a choice. """
            desc = ('React with what you want to play. If you don\'t wish to be challenged to RPS, '
                    'type `d?rps exclude` to exclude yourself from being challenged.')
            desc_prefix = ('You have been challenged by {}!\n\n'.format(ctx.author.mention) if who.id == opponent.id
                           else 'Because you initiated the game, you go first.\n\n')
            embed = discord.Embed(title='Rock, paper, scissors!',
                                  description=desc_prefix + desc)
            msg = await who.send(embed=embed)
            translate = {
                '\N{NEW MOON SYMBOL}': 'rock',
                '\N{NEWSPAPER}': 'paper',
                '\N{BLACK SCISSORS}': 'scissors'
            }
            for emoji in translate:
                await msg.add_reaction(emoji)
            while True:
                reaction, _ = await self.bot.wait_for('reaction_add', check=rps_check(who))
                if reaction.emoji in translate:
                    return translate[reaction.emoji]

        # get their choices
        try:
            initiator_choice = await rps_get_choice(ctx.author)
            await progress_message.edit(content='Waiting for the opponent ({}) to choose...'.format(
                opponent))
            opponent_choice = await rps_get_choice(opponent)
        except discord.Forbidden:
            return await progress_message.edit(content='I failed to DM the initiator or the opponent.')

        # delete the original message, because edited mentions do not notify
        # the user
        await progress_message.delete()

        # check if it was a tie
        if initiator_choice == opponent_choice:
            fmt = '{}, {}: It was a tie! You both chose {}.'
            return await ctx.send(fmt.format(ctx.author.mention, opponent.mention,
                                             initiator_choice))

        async def inform_winner(who: discord.Member, beats_left: str, beats_right: str):
            fmt = '{}, {}: :first_place: {} was the winner! {} beats {}.'
            return await ctx.send(fmt.format(ctx.author.mention, opponent.mention, who.mention,
                                             beats_left.title(), beats_right))

        def beats(weapon: str, target: str) -> bool:
            """ Rock, paper, scissors defeat checker. """
            if weapon == 'paper':
                return target == 'rock'
{'fraction_non_alphanumeric': 0.10092927207021167, 'fraction_numerical': 0.0007743933918430562, 'mean_word_length': 2.0222308892355696, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1249137', 'n_tokens_mistral': 2138, 'n_tokens_neox': 2036, 'n_words': 621}