Exemple #1
0
    async def remove_guild_currency(self, context, currency_name: str):
        guild = GuildModelInterface.get_or_none(guild_id=context.guild.id)
        if guild is None:
            return
        currency = GuildModelInterface.get_currency_for_guild_or_none(
            guild=guild,
            name=currency_name,
        )
        if currency is None:
            await context.channel.send(f'That currency does not exist in '
                                       f'this guild.')
            return
        await context.channel.send(f'Are you absolutely sure that you '
                                   f'want to remove that currency from '
                                   f'this guild? This action cannot be '
                                   f'undone, and users of this guild '
                                   f'will lose their holdings. Type '
                                   f'"Yes" to confirm, type anything '
                                   f'else to cancel.')

        def check(msg):
            return (msg.author == context.message.author
                    and msg.channel == context.channel)

        message = await self.bot.wait_for('message', check=check)
        if message.content == 'Yes':
            CurrencyModelInterface.delete_instance(currency)
            await context.channel.send(f'The currency {currency_name} '
                                       f'was removed from this guild.')
        else:
            await context.channel.send(f'Cancelled.')
Exemple #2
0
 async def list_guild_currencies(self, context):
     guild = GuildModelInterface.get_or_none(guild_id=context.guild.id)
     if guild is None:
         return
     embed = Embed(title=f'Currencies in {guild.guild_name}',
                   color=0x358022)
     for currency in GuildModelInterface.get_all_currencies_for_guild(
             guild):
         embed.add_field(name=currency.symbol,
                         value=currency.name,
                         inline=False)
     await context.channel.send(embed=embed)
 async def set_cooldown_type(self, context, type: str):
     valid_types = ['global', 'perpasta']
     if type not in valid_types:
         return
     guild = GuildModelInterface.get_or_none(guild_id=context.guild.id)
     if guild is None:
         return
     if type == 'global':
         guild.cooldown_type = guild.GLOBAL
     else:
         guild.cooldown_type = guild.PER_RESPONSE
     GuildModelInterface.save_instance(guild)
     await context.channel.send(f'Guild cooldown type changed to {type}')
     print(
         f'Guild {guild.guild_id} ({guild.guild_name}) triggered response '
         f'cooldown type updated to {type}')
 async def add_triggered_image(self, context, trigger: str, url: str):
     guild = GuildModelInterface.get_or_none(guild_id=context.guild.id)
     if guild is None:
         return
     image_headers = [
         'image/png',
         'image/jpg',
         'image/jpeg',
         'image/webp',
     ]
     async with aiohttp.ClientSession() as session:
         response, _ = \
             TriggeredResponseModelInterface.get_or_create(
                 guild=guild,
                 trigger=trigger,
                 defaults={
                     'type': TriggeredResponseModelInterface.IMAGE,
                     'image': None
                 }
             )
         async with session.get(url) as resp:
             if resp.headers.get('Content-Type', '') not in \
                     image_headers:
                 return await context.channel.send(
                     f'Only PNG, JPG images are supported.')
             if resp.status != 200:
                 return await context.message.channel.send(
                     f'Could not find image.')
             image_bytes = await resp.read()
             response.image = image_bytes
             TriggeredResponseModelInterface.save_instance(response)
             data = io.BytesIO(image_bytes)
             await context.message.channel.send(
                 file=discord.File(data, 'image.jpg'))
 async def _set_cooldown(context, cooldown_type: int, cooldown: int):
     guild = GuildModelInterface.get_or_none(guild_id=context.guild.id)
     if guild is None:
         return
     if cooldown_type == TriggeredResponseModelInterface.TEXT:
         old_cooldown = guild.triggered_text_cooldown
         guild.triggered_text_cooldown = cooldown
     else:
         old_cooldown = guild.triggered_image_cooldown
         guild.triggered_image_cooldown = cooldown
     GuildModelInterface.save_instance(guild)
     await context.channel.send(f'Guild cooldown changed from '
                                f'{old_cooldown} to {cooldown}')
     print(
         f'Guild {guild.guild_id} ({guild.guild_name}) triggered response '
         f'cooldown (type {cooldown_type}) updated from {old_cooldown} to '
         f'{cooldown}')
Exemple #6
0
 async def create_guild_currency(self,
                                 context,
                                 currency_name: str,
                                 symbol: str = None):
     guild = GuildModelInterface.get_or_none(guild_id=context.guild.id)
     if guild is None:
         return
     currency = GuildModelInterface.get_currency_for_guild_or_none(
         guild=guild,
         name=currency_name,
     )
     if currency is not None:
         await context.channel.send(f'That currency already exists in '
                                    f'this guild.')
         return
     GuildModelInterface.create_currency_for_guild(
         guild=guild,
         name=currency_name,
         symbol=symbol,
     )
     await context.channel.send(f'Currency "{currency_name}" created.')
 async def _remove_triggered_response(context, trigger: str, type: int):
     guild = GuildModelInterface.get_or_none(guild_id=context.guild.id)
     if guild is None:
         return
     triggered_response = TriggeredResponseModelInterface.get_or_none(
         type=type, guild=guild, trigger=trigger)
     if triggered_response is None:
         return
     TriggeredResponseModelInterface.delete_instance(triggered_response)
     await context.channel.send(f'Removed pasta "{trigger}" from the '
                                f'guild.')
     print(f'{context.message.author.id} removed a copy-pasta in '
           f'the guild: {guild.guild_id} ({guild.guild_name}). '
           f'Trigger: {trigger}')
Exemple #8
0
 async def change_guild_currency_name(self,
                                      context,
                                      currency_name: str,
                                      new_currency_name: str = None):
     if new_currency_name is None:
         await context.channel.send(
             f'Supply a new name for the currency if '
             f'you want to change its name.')
         return
     guild = GuildModelInterface.get_or_none(guild_id=context.guild.id)
     if guild is None:
         return
     currency = GuildModelInterface.get_currency_for_guild_or_none(
         guild=guild, name=currency_name)
     if currency is None:
         await context.channel.send(f'There is no currency by the '
                                    f'name "{currency_name}" in '
                                    f'this guild.')
         return
     currency.name = new_currency_name
     CurrencyModelInterface.save_instance(currency)
     await context.channel.send(f'Currency "{currency_name}" '
                                f'has been updated to '
                                f'"{new_currency_name}".')
 async def unban_word(self, context, word: str):
     guild = GuildModelInterface.get_or_none(guild_id=context.guild.id)
     if guild is None:
         return
     banned_word = BannedWordModelInterface.get_or_none(
         guild=guild,
         word=word
     )
     if banned_word is None:
         return
     BannedWordModelInterface.delete_instance(banned_word)
     await context.channel.send(f'That word is now un-banned '
                                f'in this guild.')
     print(f'{context.message.author.id} unbanned a word in '
           f'the guild: {guild.guild_id} ({guild.guild_name}). '
           f'word: {word}')
Exemple #10
0
 async def ban_word(self, context, word: str):
     guild = GuildModelInterface.get_or_none(guild_id=context.guild.id)
     if guild is None:
         return
     banned_word, created = BannedWordModelInterface.get_or_create(
         guild=guild,
         word=word.lower(),
     )
     if created:
         print(f'{context.message.author.id} banned a word in '
               f'the guild: {guild.guild_id} ({guild.guild_name}). '
               f'word: {word}')
     else:
         print(f'{context.message.author.id} tried to ban word in '
               f'the guild: {guild.guild_id} ({guild.guild_name}). '
               f'word: {word}, but it is already banned.')
     await context.channel.send(f'That word is now banned in this '
                                f'guild.')
 async def add_triggered_text(self, context, trigger: str, response: str):
     guild = GuildModelInterface.get_or_none(guild_id=context.guild.id)
     if guild is None:
         return
     triggered_response, created = \
         TriggeredResponseModelInterface.get_or_create(
             guild=guild,
             trigger=trigger,
             defaults={
                 'type': TriggeredResponseModelInterface.TEXT,
                 'response': response
             }
         )
     if created:
         print(f'{context.message.author.id} created a copy-pasta in '
               f'the guild: {guild.guild_id} ({guild.guild_name}). '
               f'Trigger: {trigger}, Response: {response}')
     else:
         triggered_response.response = response
         TriggeredResponseModelInterface.save_instance(triggered_response)
         print(f'{context.message.author.id} updated the copy-pasta in '
               f'the guild: {guild.guild_id} ({guild.guild_name}). '
               f'Trigger: {trigger}, New Response: {response}')
     await context.channel.send(response)
Exemple #12
0
async def on_message(message):
    # We don't want the bot replying to itself.
    if message.author == bot.user:
        return
    print(f'Message received, author: {message.author}, '
          f'content: {message.content}, '
          f'cleaned content: {message.clean_content}')
    profile, profile_created = DiscordProfileModelInterface.get_or_create(
        id=message.author.id, defaults={'display_name': message.author.name})
    guild, guild_created = GuildModelInterface.get_or_create(
        guild_id=message.guild.id, defaults={'guild_name': message.guild.name})
    if not guild_created and guild.guild_name != message.guild.name:
        print(f'Guild {guild.guild_id} has had its name updated and is being '
              f'updated in the database.')
        guild.guild_name = message.guild.name
        GuildModelInterface.save_instance(guild)
    if profile_created:
        print(f'Discord profile {message.author.id} has been added '
              f'to the database.')
    elif profile.display_name != message.author.name:
        print(f'User {message.author.id} updated their username and is being'
              f'updated in the database.')
        profile.display_name = message.author.name
        DiscordProfileModelInterface.save_instance(profile)
    words_in_message = message.content.lower().split(' ')
    first_word = words_in_message[0]
    punctuation_removal_translation = str.maketrans('', '', string.punctuation)
    if not (first_word.startswith('$')
            and first_word[1:] in Environment.instance().BOT_COMMANDS):
        # Local cache of words so we don't have to hit the database for
        # repeated words, like if a message is "bot bot bot bot bot dead"
        # it won't do a query for "bot" 5 times.
        checked_words = []
        for word in words_in_message:
            # Remove all punctuation and symbols.
            word = word.translate(punctuation_removal_translation)
            if word in checked_words:
                continue
            # Delete messages if they contain banned words.
            banned_word = BannedWordModelInterface.get_or_none(guild=guild,
                                                               word=word)
            if banned_word is not None:
                await message.delete()
                # Send a warning DM to the sender.
                await message.author.send(f'Don\'t be saying that stuff.')
                break
            checked_words.append(word)
            response = TriggeredResponseModelInterface.get_allowed_or_none(
                user=profile.user,
                guild=guild,
                trigger=word,
            )
            if response is not None:
                print(f'{message.author.id} triggered the "{word}" '
                      f'triggered response (type {response.type}).')
                if response.type == TriggeredResponseModelInterface.TEXT:
                    await message.channel.send(response.response)
                else:
                    data = io.BytesIO(response.image)
                    await message.channel.send(
                        file=discord.File(data, 'image.jpg'))
                # Only 1 triggered response per message.
                break
    await bot.process_commands(message)
Exemple #13
0
 async def give_currency(self, context, recipient: str, currency: str,
                         amount: int):
     if not recipient.startswith('<@'):
         await context.channel.send(f'You need to mention a user in order '
                                    f'to give to them.')
         return
     if not isinstance(amount, int):
         await context.channel.send(f'You can only send whole number '
                                    f'amounts.')
         return
     guild = GuildModelInterface.get_or_none(guild_id=context.guild.id)
     if guild is None:
         return
     # Mentions work like: <@!150816670493966336> so ignore extra characters.
     recipient_id = recipient[2:-1]
     if recipient.startswith('<@!'):
         recipient_id = recipient_id[1:]
     sender_profile = DiscordProfileModelInterface.get_or_none(
         id=context.message.author.id)
     if sender_profile is not None:
         sender = sender_profile.user
     else:
         print(f'Something went wrong and the sender DiscordProfile has '
               f'no user.')
         return
     receiver = DiscordProfileModelInterface.get_or_none(id=recipient_id)
     if receiver is not None:
         receiver = receiver.user
     else:
         print(f'Something went wrong and the receiver DiscordProfile has '
               f'no user.')
         return
     if receiver is None:
         await context.channel.send(f'Looks like that user is not an '
                                    f'active member of the guild. You '
                                    f'can only give to active members.')
         return
     guild_currency = \
         GuildModelInterface.get_currency_for_guild_or_none(
             guild=guild,
             name=currency
         )
     if guild_currency is None:
         await context.channel.send(f'That is not a currency.')
         return
     sender_has_infinite_money = context.channel \
         .permissions_for(context.message.author) \
         .manage_messages
     receiver_has_infinite_money = context.channel \
         .permissions_for(context.guild.get_member(int(recipient_id))) \
         .manage_messages
     if not sender_has_infinite_money:
         try:
             UserModelInterface.pay(
                 user=sender,
                 currency=guild_currency,
                 amount=amount,
             )
         except InsufficientFundsError as exc:
             await context.channel.send(exc.detail)
             return
     if not receiver_has_infinite_money:
         UserModelInterface.receive(
             user=receiver,
             currency=guild_currency,
             amount=amount,
         )
     await context.channel.send(f'Gave {amount} {currency} to '
                                f'{receiver.display_name}.')