Exemple #1
0
    async def answer_query(self,
                           ctx,
                           query,
                           assumptions=[],
                           small=False,
                           debug=False):
        safe.sprint('wolfram|alpha :', ctx.author.name, ':', query)
        channel = ctx.channel
        author = ctx.author
        api = get_api(ctx.bot)

        # Filter out bad words
        enable_filter = False
        if not is_private(channel):
            enable_filter = await ctx.bot.settings.resolve('f-wolf-filter',
                                                           channel,
                                                           channel.guild,
                                                           default='nsfw'
                                                           not in channel.name)
        if enable_filter and wordfilter.is_bad(query):
            await ctx.send(FILTER_FAILURE)
            return

        # Perform the query
        try:
            async with ctx.typing():
                units = await ctx.bot.keystore.get(f'p-wolf-units:{author.id}')
                result = await api.request(query,
                                           assumptions,
                                           imperial=(units == 'imperial'),
                                           debug=debug)
        except (wolfapi.WolframError, wolfapi.WolframDidntSucceed):
            await ctx.send(ERROR_MESSAGE_NO_RESULTS)
        except asyncio.TimeoutError:
            print('W|A timeout:', query)
            await ctx.send(ERROR_MESSAGE_TIMEOUT.format(query))
        except aiohttp.ClientError as error:
            print('Wolf: HTTP processing error:', error.message)
            await ctx.send('The server threw an error. Try again in a moment.')
        except xml.parsers.expat.ExpatError as error:
            print('Wolf: XML processing error:', error)
            await ctx.send(
                'The server returned some malformed data. Try again in a moment.'
            )
        else:

            if len(result.sections) == 0:
                await ctx.send(ERROR_MESSAGE_NO_RESULTS)
                return

            is_dark = (
                await
                ctx.bot.keystore.get(f'p-tex-colour:{author.id}')) == 'dark'

            sections_reduced = result.sections if not small else list(
                cleanup_section_list(
                    itertools.chain(
                        [find_first(section_is_input, result.sections, None)],
                        list(filter(section_is_important, result.sections))
                        or [
                            find_first(section_is_not_input, result.sections,
                                       None)
                        ])))

            # Post images
            messages = []
            for img in process_images(sections_reduced, is_dark):
                messages.append(
                    await
                    ctx.send(file=image_to_discord_file(img, 'result.png')))
                await asyncio.sleep(1.05)

            # Assuptions are currently disabled because of a 'bug'.
            # I think it's that discord sends emoji reaction updates
            # on a different shard to the one that handles the channel
            # that the message is in, which means that the shard
            # receiving the notif doesn't know what to do with the info
            # it receives.
            embed, show_assuptions = await self.format_adm(
                ctx, result.assumptions, small)

            posted = await ctx.send(embed=embed)

            try:
                await posted.add_reaction(DELETE_EMOJI)
                if not small and show_assuptions:
                    await self.add_reaction_emoji(posted, result.assumptions)
            except discord.errors.NotFound:
                pass
            payload = {
                'assumptions': result.assumptions.to_json(),
                'query': query,
                'used': False,
                'blame': author.id,
                'channel id': posted.channel.id,
                'message id': posted.id,
                'image ids': [i.id for i in messages],
                'no change warning': False
            }
            await ctx.bot.keystore.set_json('wolfram',
                                            'message',
                                            str(posted.id),
                                            payload,
                                            expire=60 * 60 * 24)

            print('Done.')
Exemple #2
0
def test_friendly():
    assert not is_bad('Hello, world!')
    assert not is_bad('THESE WORDS ARE FRIENDLY')
Exemple #3
0
def test_malicious():
    assert is_bad('CRAP')
    assert is_bad('oh f**k this')
    assert is_bad('This is shit.')
Exemple #4
0
# Interactive command for checkig if a word is bad
# This was written for testing purposes

from wordfilter import is_bad

line = input('> ')
while line:
	if is_bad(line):
		print('That\'s bad!')
	else:
		print('All good!')
	line = input('> ')
Exemple #5
0
def test_esoteric():
    assert is_bad('\u200Bfuck')
    assert is_bad('sh\u200Bit')
Exemple #6
0
    async def answer_query(self,
                           query,
                           channel,
                           blame,
                           assumptions=[],
                           debug=False):
        safe.sprint('wolfram|alpha :', blame.name, ':', query)
        await self.client.send_typing(channel)
        images = []
        text = []
        error = 0
        error_message = 'No details'

        # Dummy message. This is a sign that I need to work on the settings module somewhat.
        class Dummy:
            def __init__(self, channel):
                self.channel = channel
                self.server = channel.server

        enable_filter = False
        if not channel.is_private:
            enable_filter = await core.settings.channel_get_setting(
                Dummy(channel), 'f-wolf-filter', 'nsfw' not in channel.name)
            # print(core.get_setting_context(Dummy(channel), 'f-wolf-filter', 'channel'))
            # print(core.get_setting_context(Dummy(channel), 'f-wolf-filter', 'server'))
            # print(enable_filter)
        if enable_filter and wordfilter.is_bad(query):
            await self.send_message(channel, FILTER_FAILURE, blame=blame)
            return
        try:
            print('Making request')
            result = await api.request(query, assumptions, debug=debug)
            print('Done?')
        except asyncio.TimeoutError:
            print('W|A timeout:', query)
            await self.send_message(channel,
                                    ERROR_MESSAGE_TIMEOUT.format(query),
                                    blame=blame)
        except aiohttp.ClientError as e:
            print('Wolf: HTTP processing error:', e.message)
            await self.send_message(
                channel,
                'The server threw an error. Try again in a moment.',
                blame=blame)
        except xml.parsers.expat.ExpatError as e:
            print('Wolf: XML processing error:', e.message)
            await self.send_message(
                channel,
                'The server returned some malformed data. Try again in a moment.',
                blame=blame)
        else:
            if len(result.sections) == 0:
                await self.send_message(channel,
                                        ERROR_MESSAGE_NO_RESULTS,
                                        blame=blame)
            elif result.did_fail:
                m = 'Something went wrong: {}'.format(result.error_text)
                await self.send_message(channel, m, blame=blame)
            else:
                # Get theme setting (TODO: Don't construct this myself)
                key = 'p-tex-colour:' + blame.id
                theme = await core.keystore.get(key)
                is_dark = (theme == 'dark')
                # print('The theme:', theme)
                # Send the image results
                background_colour = hex_to_tuple_a(
                    '36393EFF') if is_dark else hex_to_tuple_a('FFFFFFFF')
                if not debug:
                    strip = sections_to_image_strip(result.sections)
                    strip = retheme_images(
                        strip, image_recolour_to_dark_theme
                        if is_dark else lambda x: None)
                    for img in conjoin_image_results(strip, background_colour):
                        img = paste_to_background(img, background_colour)
                        # await self.send_image(channel, img, 'result.png', blame = blame)
                        # if theme == 'dark':
                        # 	image_recolour_to_dark_theme(img)
                        await self.send_image(channel,
                                              img,
                                              'result.png',
                                              blame=blame)
                        await asyncio.sleep(1.05)
                # Text section
                textitems = []
                # Assumptions
                assumption_text = self.get_assumption_text(result.assumptions)
                hidden_assumptions = assumption_text.count('\n') > 5
                if hidden_assumptions:
                    assumption_text = ASSUMPTIONS_MADE_MESSAGE
                textitems.append(assumption_text)
                # Tips
                if len(result.tips) > 0:
                    textitems += ['**Tips**\n', '\n'.join(result.tips), '\n\n']
                # Timeouts
                if len(result.timeouts) > 0:
                    textitems += [
                        '**Timeouts**\n', ', '.join(result.timeouts), '\n\n'
                    ]
                textout_joined = ''.join(textitems)
                url = urllib.parse.urlencode({'i': query})
                # Determine if the footer should be long or short
                adm = FOOTER_MESSAGE.format(mention=blame.mention, query=url)
                if len(textout_joined) + len(adm) > 1950:
                    adm = FOOTER_MESSAGE_SHORT.format(mention=blame.mention)
                # Send the result
                posted = await self.send_message(channel,
                                                 textout_joined + adm,
                                                 blame=blame)
                if result.assumptions.count - result.assumptions.count_unknown > 0:
                    try:
                        if hidden_assumptions:
                            await self.client.add_reaction(
                                posted, EXPAND_EMOJI)
                        else:
                            await self.add_reaction_emoji(
                                posted, result.assumptions)
                        payload = {
                            'assumptions': result.assumptions.to_json(),
                            'query': query,
                            'used': False,
                            'blame': blame.id,
                            'channel id': posted.channel.id,
                            'message id': posted.id,
                            'no change warning': False,
                            'hidden': hidden_assumptions
                        }
                        print(json.dumps(payload, indent=4))
                        # self.sent_footer_messages[str(posted.id)] = payload
                        await core.keystore.set_json('wolfram',
                                                     'message',
                                                     str(posted.id),
                                                     payload,
                                                     expire=60 * 60 * 24)
                        print(self.shard_id, 'Footer message id:', posted.id)
                    except discord.errors.Forbidden:
                        await self.send_message(channel,
                                                REACTION_PERM_FAILURE,
                                                blame=blame)
                # Complete!
                print('Done.')
Exemple #7
0
    async def answer_query_short(self, query, channel, blame):
        safe.sprint('wolfram|alpha :', blame.name, ':', query)
        await self.client.send_typing(channel)
        images = []
        text = []
        error = 0
        error_message = 'No details'

        # Dummy message. This is a sign that I need to work on the settings module somewhat.
        class Dummy:
            def __init__(self, channel):
                self.channel = channel
                self.server = channel.server

        enable_filter = False
        if not channel.is_private:
            enable_filter = await core.settings.channel_get_setting(
                Dummy(channel), 'f-wolf-filter', 'nsfw' not in channel.name)
        if enable_filter and wordfilter.is_bad(query):
            await self.send_message(channel, FILTER_FAILURE, blame=blame)
            return
        try:
            print('Making request')
            result = await api.request(query, [], debug=False)
            print('Done?')
        except asyncio.TimeoutError:
            print('W|A timeout:', query)
            await self.send_message(channel,
                                    ERROR_MESSAGE_TIMEOUT.format(query),
                                    blame=blame)
        except aiohttp.ClientError as e:
            print('Wolf: HTTP processing error:', e.message)
            await self.send_message(
                channel,
                'The server threw an error. Try again in a moment.',
                blame=blame)
        except xml.parsers.expat.ExpatError as e:
            print('Wolf: XML processing error:', e.message)
            await self.send_message(
                channel,
                'The server returned some malformed data. Try again in a moment.',
                blame=blame)
        else:
            # print(json.dumps(result.sections, indent = 4))
            if len(result.sections) == 0:
                await self.send_message(channel,
                                        ERROR_MESSAGE_NO_RESULTS,
                                        blame=blame)
            elif result.did_fail:
                m = 'Something went wrong: {}'.format(result.error_text)
                await self.send_message(channel, m, blame=blame)
            else:
                # for i in result.sections:
                # 	print(' -', i.title)
                sections_reduced = list(
                    cleanup_section_list(
                        itertools.chain(
                            [
                                find_first(section_is_input, result.sections,
                                           None)
                            ],
                            list(filter(section_is_important, result.sections))
                            or [
                                find_first(section_is_not_input,
                                           result.sections, None)
                            ])))
                is_dark = ((await core.keystore.get('p-tex-colour',
                                                    blame.id)) == 'dark')
                # Send the image results
                background_colour = hex_to_tuple_a(
                    '36393EFF' if is_dark else 'FFFFFFFF')
                strip = sections_to_image_strip(sections_reduced)
                if is_dark:
                    strip = retheme_images(strip, image_recolour_to_dark_theme)
                else:
                    strip = (i for i, _, _ in strip)
                for img in conjoin_image_results(strip, background_colour):
                    img = paste_to_background(img, background_colour)
                    await self.send_image(channel,
                                          img,
                                          'result.png',
                                          blame=blame)
                    await asyncio.sleep(1.05)
                # Text section
                url = urllib.parse.urlencode({'i': query})
                adm = FOOTER_MESSAGE.format(mention=blame.mention, query=url)
                adm += '\n**This command is in development.** Suggest improvements on the MathBot server (type `=about` for the link).'
                posted = await self.send_message(channel, adm, blame=blame)
                print('Done.')
Exemple #8
0
def test():
    assert (not is_bad('Hello, world!'))
    assert (not is_bad('THESE WORDS ARE FRIENDLY'))
    assert (is_bad('CRAP'))
    assert (is_bad('oh f**k this'))
    assert (is_bad('This is shit.'))
Exemple #9
0
    async def answer_query(self,
                           query,
                           channel,
                           blame,
                           assumptions=[],
                           small=False,
                           debug=False):
        safe.sprint('wolfram|alpha :', blame.name, ':', query)
        await self.send_typing(channel)
        enable_filter = False
        if not channel.is_private:
            enable_filter = await core.settings.resolve('f-wolf-filter',
                                                        channel,
                                                        channel.server,
                                                        default='nsfw'
                                                        not in channel.name)
        if enable_filter and wordfilter.is_bad(query):
            await self.send_message(channel, FILTER_FAILURE, blame=blame)
            return
        try:
            print('Making request')
            units = await core.keystore.get('p-wolf-units:' + str(blame.id))
            result = await api.request(query,
                                       assumptions,
                                       imperial=(units == 'imperial'),
                                       debug=debug)
        except (wolfapi.WolframError, wolfapi.WolframDidntSucceed):
            await self.send_message(channel,
                                    ERROR_MESSAGE_NO_RESULTS,
                                    blame=blame)
        except asyncio.TimeoutError:
            print('W|A timeout:', query)
            await self.send_message(channel,
                                    ERROR_MESSAGE_TIMEOUT.format(query),
                                    blame=blame)
        except aiohttp.ClientError as error:
            print('Wolf: HTTP processing error:', error.message)
            await self.send_message(
                channel,
                'The server threw an error. Try again in a moment.',
                blame=blame)
        except xml.parsers.expat.ExpatError as error:
            print('Wolf: XML processing error:', error)
            await self.send_message(
                channel,
                'The server returned some malformed data. Try again in a moment.',
                blame=blame)
        else:

            if len(result.sections) == 0:
                await self.send_message(channel,
                                        ERROR_MESSAGE_NO_RESULTS,
                                        blame=blame)
                return

            is_dark = (await
                       core.keystore.get('p-tex-colour:' + blame.id)) == 'dark'

            sections_reduced = result.sections if not small else list(
                cleanup_section_list(
                    itertools.chain(
                        [find_first(section_is_input, result.sections, None)],
                        list(filter(section_is_important, result.sections))
                        or [
                            find_first(section_is_not_input, result.sections,
                                       None)
                        ])))

            # Post images
            for img in process_images(sections_reduced, is_dark):
                await self.send_image(channel, img, 'result.png', blame=blame)
                await asyncio.sleep(1.05)

            embed, show_assuptions = await self.format_adm(
                channel, blame, query, result.assumptions, small)

            posted = await self.send_message(channel, embed=embed, blame=blame)

            if not small and show_assuptions:
                try:
                    await self.add_reaction_emoji(posted, result.assumptions)
                    payload = {
                        'assumptions': result.assumptions.to_json(),
                        'query': query,
                        'used': False,
                        'blame': blame.id,
                        'channel id': posted.channel.id,
                        'message id': posted.id,
                        'no change warning': False
                    }
                    await core.keystore.set_json('wolfram',
                                                 'message',
                                                 str(posted.id),
                                                 payload,
                                                 expire=60 * 60 * 24)
                except discord.errors.Forbidden:
                    await self.send_message(channel,
                                            REACTION_PERM_FAILURE,
                                            blame=blame)

            print('Done.')
Exemple #10
0
    async def answer_query(self,
                           query,
                           channel,
                           blame,
                           assumptions=[],
                           small=False,
                           debug=False):
        safe.sprint('wolfram|alpha :', blame.name, ':', query)
        await self.send_typing(channel)
        enable_filter = False
        if not channel.is_private:
            enable_filter = await core.settings.resolve('f-wolf-filter',
                                                        channel,
                                                        channel.server,
                                                        default='nsfw'
                                                        not in channel.name)
        if enable_filter and wordfilter.is_bad(query):
            await self.send_message(channel, FILTER_FAILURE, blame=blame)
            return
        try:
            print('Making request')
            result = await api.request(query, assumptions, debug=debug)
        except (wolfapi.WolframError, wolfapi.WolframDidntSucceed):
            await self.send_message(channel,
                                    ERROR_MESSAGE_NO_RESULTS,
                                    blame=blame)
        except asyncio.TimeoutError:
            print('W|A timeout:', query)
            await self.send_message(channel,
                                    ERROR_MESSAGE_TIMEOUT.format(query),
                                    blame=blame)
        except aiohttp.ClientError as error:
            print('Wolf: HTTP processing error:', error.message)
            await self.send_message(
                channel,
                'The server threw an error. Try again in a moment.',
                blame=blame)
        except xml.parsers.expat.ExpatError as error:
            print('Wolf: XML processing error:', error)
            await self.send_message(
                channel,
                'The server returned some malformed data. Try again in a moment.',
                blame=blame)
        else:

            if len(result.sections) == 0:
                await self.send_message(channel,
                                        ERROR_MESSAGE_NO_RESULTS,
                                        blame=blame)
                return

            is_dark = (await
                       core.keystore.get('p-tex-colour:' + blame.id)) == 'dark'

            sections_reduced = result.sections if not small else list(
                cleanup_section_list(
                    itertools.chain(
                        [find_first(section_is_input, result.sections, None)],
                        list(filter(section_is_important, result.sections))
                        or [
                            find_first(section_is_not_input, result.sections,
                                       None)
                        ])))

            # Post images
            for img in process_images(sections_reduced, is_dark):
                await self.send_image(channel, img, 'result.png', blame=blame)
                await asyncio.sleep(1.05)

            # Assumptions
            assumption_text = ''
            if not small:
                assumption_text = self.get_assumption_text(result.assumptions)
                hidden_assumptions = assumption_text.count('\n') > 5
                if hidden_assumptions:
                    assumption_text = ASSUMPTIONS_MADE_MESSAGE

            url = urllib.parse.urlencode({'i': query})

            # Determine if the footer should be long or short
            adm = await self.format_adm(channel, blame, query, small)
            output = assumption_text + adm
            too_long = False
            if len(output) >= 2000:
                too_long = True
                output = adm

            # Send the result
            posted = await self.send_message(channel, output, blame=blame)
            if not small and result.assumptions.count_known > 0 and not too_long:
                try:
                    if hidden_assumptions:
                        await self.client.add_reaction(posted, EXPAND_EMOJI)
                    else:
                        await self.add_reaction_emoji(posted,
                                                      result.assumptions)
                    payload = {
                        'assumptions': result.assumptions.to_json(),
                        'query': query,
                        'used': False,
                        'blame': blame.id,
                        'channel id': posted.channel.id,
                        'message id': posted.id,
                        'no change warning': False,
                        'hidden': hidden_assumptions
                    }
                    # print(json.dumps(payload, indent=4))
                    # self.sent_footer_messages[str(posted.id)] = payload
                    await core.keystore.set_json('wolfram',
                                                 'message',
                                                 str(posted.id),
                                                 payload,
                                                 expire=60 * 60 * 24)
                    # print(self.shard_id, 'Footer message id:', posted.id)
                except discord.errors.Forbidden:
                    await self.send_message(channel,
                                            REACTION_PERM_FAILURE,
                                            blame=blame)

            print('Done.')