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)
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)
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))
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)
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 )
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
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!")
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') }
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
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
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
def set_image(self, file: io.IOBase, filename: str): self.image_url = "attachment://%s" % filename self.file = File(file, filename=filename)
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)
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)