Example #1
0
    async def googleimg(self, message, args):
        search = args[0]
        img_path = os.path.join(os.path.dirname(DB_PATH), "googleimg.png")
        response = search

        try:
            chrome_options = webdriver.ChromeOptions()
            chrome_options.add_argument("--headless")
            chrome_options.add_argument("--hide-scrollbars")
            chrome_options.add_argument("--log-level=3")
            driver = webdriver.Chrome(options=chrome_options)
            url = "https://www.google.com/search?tbm=isch&q={}".format(
                search.replace(" ", "+"))
            driver.get(url)
            # Scroll to the top edge of image results
            element = driver.find_element_by_id("center_col")
            actions = ActionChains(driver)
            actions.move_to_element(element).perform()
            driver.save_screenshot(img_path)
            driver.quit()
            await self.client.send_files(
                [File(img_path, filename=os.path.basename(img_path))],
                message.channel.id,
                content="Google Images results for **{}**".format(search))
        except Exception as exception:  # pylint: disable=W0703
            LOG.info("Cannot google image search with '%s'", search)
            LOG.exception(exception)
            response = NOT_FOUND
            await self.client.send_message(message.channel.id, response)
Example #2
0
    async def yagoo_group(self, ctx: commands.Context, text: str = "早安你好"):
        imagePath = YagooUtil.renderText(text)

        embedMsg = Embed()
        embedMsg.set_image(url='attachment://' + YagooUtil.getTempFileName())
        image = File(imagePath, filename=YagooUtil.getTempFileName())
        await ctx.message.delete()
        await ctx.send(file=image)
Example #3
0
    async def _sendfile(self, ctx, ticker):
        from discord.file import File

        path = ft.finance_plot(ticker,
                               start=datetime.date.today() -
                               datetime.timedelta(days=30),
                               end=datetime.date.today())
        with open(path, 'rb') as img:
            await ctx.send(file=File(img))
Example #4
0
    async def tex(self, ctx: Context, *message: clean_content):
        await ctx.trigger_typing()

        # Input filtering
        if not message:
            await ctx.send("Your message contained nothing to render")

        combined = " ".join([x.lstrip("@") for x in message])
        if combined[0] != "`" or combined[-1] != "`":
            await ctx.send("Please place your input in an inline code block")

        # Matplotlib preamble
        plt.clf()
        plt.rc("text", usetex=True)
        plt.rc("font", **{
            "family": "serif",
            "serif": ["Palatino"],
            "size": 16
        })
        plt.axis("off")

        # Generate the filename
        filename = (combined.lstrip("`").rstrip("`") + "-" +
                    str(hex(int(datetime.utcnow().timestamp()))).lstrip("0x") +
                    ".png").replace(" ", "")
        path_png = "{path}/{filename}".format(
            path=CONFIG["FIG_SAVE_PATH"].rstrip("/"), filename=filename)
        path_jpg = path_png.replace(".png", ".jpg")

        # Plot the latex and save it.
        plt.text(0, 1, combined.lstrip("`").rstrip("`"), color="white")
        plt.savefig(path_png, dpi=300, bbox_inches="tight", transparent=True)

        # Generate a mask of the transparent regions in the image
        img_arr = img_as_float(io.imread(path_png))
        transparent_mask = np.array([1, 1, 1, 0])
        img_mask = np.abs(img_arr - transparent_mask).sum(axis=2) < 1

        # Generate the bounding box for the mask
        mask_coords = np.array(np.nonzero(~img_mask))
        top_left = np.min(mask_coords, axis=1) - [15, 15]
        bottom_right = np.max(mask_coords, axis=1) + [15, 15]

        # Crop the image and add a background layer
        img_cropped = img_arr[top_left[0]:bottom_right[0],
                              top_left[1]:bottom_right[1]]
        img_cropped = color.rgba2rgb(img_cropped, background=IMAGE_BACKGROUND)

        # Save the image, delete the PNG and set the permissions for the JPEG
        io.imsave(path_jpg, img_cropped, quality=100)
        os.chmod(path_jpg, 0o644)
        os.remove(path_png)

        # Load the image as a file to be attached to an image
        img_file = File(path_jpg, filename="tex_output.jpg")
        display_name = get_name_string(ctx.message)
        await ctx.send(f"Here you go, {display_name}! :abacus:", file=img_file)
Example #5
0
 async def dev_create_captcha_image(self, ctx: Context):
     captcha_image, captcha_text = self.bot.captcha.create_captcha_image()
     embed: Embed = await embed_maker.message(
         ctx, title="Captcha Image.", description=f"Text: {captcha_text}"
     )
     embed.set_image(url="attachment://captcha.png")
     return await ctx.channel.send(
         file=File(fp=captcha_image, filename="captcha.png"), embed=embed
     )
Example #6
0
def upload_file(path, author=None) -> List[Tuple[Embed, File]]:
    file_name = os.path.basename(path)
    file_stat = os.stat(path)
    file_size = file_stat.st_size

    if file_size < DISCORD_MAX_FILE_SIZE:
        embeds = EmbedBuilder() \
            .set_author(author) \
            .set_title("Uploaded %s" % file_name) \
            .get_embeds()
        embeds.append((None, File(open(path, 'rb'), file_name)))
        return embeds

    else:
        with zipfile.ZipFile("temp.zip", 'w') as zip_file:
            zip_file.write(path, file_name)

        # Get the compressed file size
        file_stat = os.stat("temp.zip")
        file_size = file_stat.st_size
        num_parts = int(math.ceil(float(file_size) / DISCORD_MAX_FILE_SIZE))

        embedbuilder = EmbedBuilder() \
            .set_author(author) \
            .set_title("Uploaded %s in %i parts" % (file_name, num_parts))
        messages = embedbuilder.get_embeds()

        with open("temp.zip", 'rb') as zip_file:
            i = 1
            while True:
                part_name = "%s.zip.%.03i" % (file_name, i)
                part_file = io.BytesIO()
                data = zip_file.read(DISCORD_MAX_FILE_SIZE)
                if len(data) == 0:
                    break
                part_file.write(data)
                part_file.seek(0)
                messages.append((None, File(part_file, filename=part_name)))
                i += 1

        os.remove("temp.zip")
        return messages
Example #7
0
 async def get(self, ctx: commands.Context, *messages: Message):
   try:
     files = []
     for message in messages:
       for embed in message.embeds:
         edict = embed.to_dict()
         fb = BytesIO(bytes(json.dumps(edict, indent=2), 'utf-8'))
         files.append(File(fb, filename=f"{edict.get('title', 'embed')}.json"))
     await ctx.send(files=files)
   except:
     await ctx.send("Error in getting Embed!")
Example #8
0
    def playing_message(self) -> Dict[str, Union[Embed, File]]:
        self._cover.seek(0)

        em = Embed(
            colour=Colour.dark_green(),
            title=self._title,
            description=f'{self._album} - ({self._date})'
        )
        em.set_author(name=self._artist)
        em.set_thumbnail(url='attachment://cover.jpg')

        return {
            'embed': em,
            'file': File(self._cover, 'cover.jpg')
        }
Example #9
0
    async def get_minimap(self, awmap: AWMap) -> str:
        """Uses `AWMap`'s `minimap` parameter to generate a
        `PIL` image of a minimap representing the loaded map
        then returns a link to the file hosted on Discord
        using the `get_hosted_file` method

        :param awmap: `AWMap` instance of map

        :return: `str` URL of hosted minimap image"""

        if awmap.title:
            title = awmap.title
        else:
            title = "[Untitled]"

        attachment = File(fp=awmap.minimap, filename=f"{title}.gif")
        url = await self.get_hosted_file(attachment)

        return url
Example #10
0
    async def get_awbw(self, awmap: AWMap) -> str:
        """Uses `AWMap`'s `to_awbw` parameter to export a map
        to an AWBW CSV text file then returns a link to the file
        hosted on Discord using `get_hosted_file` method

        :param awmap: `AWMap` instance of map to export

        :return: `str` URL of hosted CSV file"""

        if awmap.title:
            title = awmap.title
        else:
            title = "Untitled"

        attachment = File(
            fp=BytesIO(awmap.to_awbw.encode("utf-8")),
            filename=f"{title}.csv"
        )
        url = await self.get_hosted_file(attachment)

        return url
Example #11
0
    async def get_aws(self, awmap: AWMap) -> str:
        """Uses `AWMap`'s `to_aws` parameter to export a map
        as AWS file then returns a link to the file hosted on
        Discord using `get_hosted_file` method

        :param awmap: `AWMap` instance of map to export

        :return: `str` URL of hosted AWS file"""

        if awmap.title:
            title = awmap.title
        else:
            title = "Untitled"

        attachment = File(
            fp=BytesIO(awmap.to_aws),
            filename=f"{title}.aws"
        )
        url = await self.get_hosted_file(attachment)

        return url
Example #12
0
 def set_image(self, file: io.IOBase, filename: str):
     self.image_url = "attachment://%s" % filename
     self.file = File(file, filename=filename)
Example #13
0
    async def on_message_delete(self, msg: Message):
        """Event called when a message is deleted"""

        if not self._is_tracked(msg.guild, EventPriority.delete):
            return

        modlog_channels = [
            int(channel_id)
            for channel_id in self.get_guild_config(msg.guild).values()
        ]

        # If message deleted from modlog, record event with header only
        if msg.channel.id in modlog_channels:

            description = f"\n\n{msg.embeds[0].description}" if msg.embeds else ""
            description = escape_markdown(
                description.replace("Modlog message deleted\n\n", ""))

            em = self.em_base(msg.author,
                              f"Modlog message deleted{description}",
                              EventColors.delete.value)

            return await self.log_event(em, msg.guild, EventPriority.delete)

        # Otherwise, ignore bot's deleted embed-only (help pages, et.) messages
        elif msg.author.id == self.bot.user.id and not msg.content:
            return

        em = self.em_base(
            msg.author,
            f"Message by {msg.author.mention} ({msg.author.name}) deleted",
            EventColors.delete.value)

        em.description = f"{em.description}\n\nChannel: {msg.channel.mention} ({msg.channel.name})"

        if msg.content:
            chunks = [
                msg.content[i:i + 1024]
                for i in range(0, len(msg.content), 1024)
            ]
            for i, chunk in enumerate(chunks):
                em.add_field(name=f"🗑 Content [{i + 1}/{len(chunks)}]",
                             value=chunk)

        else:
            em.add_field(name="🗑 Content [0/0]",
                         value="Message had no content")

        # Try to re-download attached images if possible. The proxy url doesn't 404 immediately unlike the
        # regular URL, so it may be possible to download from it before it goes down as well.
        reupload = None

        if msg.attachments:
            temp_image = BytesIO()
            attachment = msg.attachments[0]
            if attachment.size > 5000000:
                # caching is important and all, but this will just cause more harm than good
                return

            try:
                await download_image(msg.attachments[0].proxy_url, temp_image)
                reupload = File(temp_image,
                                filename="reupload.{}".format(
                                    attachment.filename))

                em.description = f"{em.description}\n\n**Attachment Included Above**"

            except Exception as error:
                await self.errorlog.send(error)
                reupload = None

                em.description = f"{em.description}\n\n**Attachment Reupload Failed (See Error Log)**"

        await self.log_event(em,
                             msg.guild,
                             priority=EventPriority.delete,
                             file=reupload)
Example #14
0
    async def tex(self, ctx: Context, *message: clean_content):
        await ctx.trigger_typing()
        print(message)
        # Input filtering
        if not message:
            await ctx.send("Your message contained nothing to render")

        if message[0] == "```tex":
            message = ("```", *message[1:])
        combined = " ".join([x.lstrip("@") for x in message])
        if combined[0] != "`" or combined[-1] != "`":
            await ctx.send("Please place your input in an inline code block")
            return

        tex_code = combined.lstrip("`").rstrip("`")
        # May want to consider enforcing the $message$ requirement here
        # May also want to disallow/convert $$message$$ environments here

        # Matplotlib preamble
        plt.clf()
        plt.rc("text", usetex=True)
        plt.rc("text.latex", preamble=r"\usepackage{amsmath}")
        plt.rc("font", **{
            "family": "serif",
            "serif": ["Palatino"],
            "size": 16
        })
        plt.axis("off")

        # Generate the filename
        filename = (tex_code + "-" +
                    str(hex(int(datetime.utcnow().timestamp()))).lstrip("0x") +
                    ".png").replace(" ", "")
        path_png = CONFIG.FIG_SAVE_PATH / filename
        path_jpg = path_png.with_suffix(".jpg")
        try:
            # Plot the latex and save it.
            plt.text(0, 1, tex_code, color="white")
            plt.savefig(path_png,
                        dpi=300,
                        bbox_inches="tight",
                        transparent=True)
        except RuntimeError as r:
            # Failed to render latex. Report error
            logging.error(r)
            await ctx.send(
                "Unable to render LaTeX. Please check that it's correct")
        else:
            # Generate a mask of the transparent regions in the image
            img_arr = img_as_float(io.imread(path_png))
            transparent_mask = np.array([1, 1, 1, 0])
            img_mask = np.abs(img_arr - transparent_mask).sum(axis=2) < 1

            # Generate the bounding box for the mask
            mask_coords = np.array(np.nonzero(~img_mask))
            top_left = np.min(mask_coords, axis=1) - [15, 15]
            bottom_right = np.max(mask_coords, axis=1) + [15, 15]

            # Crop the image and add a background layer
            img_cropped = img_arr[top_left[0]:bottom_right[0],
                                  top_left[1]:bottom_right[1]]
            img_cropped = color.rgba2rgb(img_cropped,
                                         background=IMAGE_BACKGROUND)

            # Save the image, delete the PNG and set the permissions for the JPEG
            io.imsave(path_jpg, img_cropped, quality=100)
            os.chmod(path_jpg, 0o644)
            os.remove(path_png)

            # Load the image as a file to be attached to an image
            img_file = File(path_jpg, filename="tex_output.jpg")
            display_name = get_name_string(ctx.message)
            await ctx.send(f"Here you go, {display_name}! :abacus:",
                           file=img_file)