diff --git a/src/cogs/cs2_bingo.py b/src/cogs/cs2_bingo.py index a2b5766..a556055 100644 --- a/src/cogs/cs2_bingo.py +++ b/src/cogs/cs2_bingo.py @@ -3,6 +3,7 @@ import json import random from datetime import datetime from datetime import timedelta +from io import BytesIO from typing import override import cv2 @@ -121,13 +122,17 @@ class BingoGenerator: return player_cells @classmethod - async def generate_sheets(cls, players: list[discord.Member], bot: commands.Bot): + async def generate_sheets(cls, players: list[discord.Member], bot: commands.Bot) -> dict[str, bytes]: """ Generate bingo sheets for each player Parameters ---------- - players (list[str]): List of the player's discord IDs as strings + players (list[discord.Member]): The players to generate sheets for + + Returns + ---------- + (dict[str, bytes]): Each player's sheet as PNG data, keyed by their discord ID as a string """ players = [str(p.id) for p in players] @@ -141,8 +146,7 @@ class BingoGenerator: for player in players: player_sheets[player] = await cls.generate_sheet(sample_space[player], image) - for p, sheet in player_sheets.items(): - cv2.imwrite(f"./src/assets/temp/{p}_bingo.png", sheet) + return {p: cv2.imencode(".png", sheet)[1].tobytes() for p, sheet in player_sheets.items()} @classmethod async def generate_sheet(cls, sample_space: list, image: np.ndarray): @@ -192,16 +196,15 @@ class BingoView(LobbyView): ) await interaction.response.send_message(content=mention_players, embed=embed) - await BingoGenerator.generate_sheets(self.lobby.players, self.bot) + sheets = await BingoGenerator.generate_sheets(self.lobby.players, self.bot) for player in self.lobby.players: + sheet = sheets[str(player.id)] try: - await player.send(file=discord.File(f"./src/assets/temp/{player.id}_bingo.png")) + await player.send(file=discord.File(BytesIO(sheet), filename=f"{player.id}_bingo.png")) except discord.Forbidden: await interaction.followup.send( f"{player.mention} har ikke åpnet DM-ene sine :angry:\nSender den her i stedet", - file=discord.File( - f"./src/assets/temp/{player.id}_bingo.png", filename=f"SPOILER_{player.id}_bingo.png" - ), + file=discord.File(BytesIO(sheet), filename=f"SPOILER_{player.id}_bingo.png"), ) finally: await asyncio.sleep(1) diff --git a/src/cogs/info.py b/src/cogs/info.py index 1b7d894..5e103e1 100644 --- a/src/cogs/info.py +++ b/src/cogs/info.py @@ -260,9 +260,7 @@ class Info(commands.Cog): # IF roles list is longer than 2048, create text file and send it if len(roles) > 2048: - await discord_utils.send_as_txt_file( - interaction, roles, f"./src/assets/temp/{interaction.guild.id}_roles.txt" - ) + await discord_utils.send_as_txt_file(interaction, roles, f"{interaction.guild.id}_roles.txt") else: embed = discord.Embed(color=interaction.guild.me.color, description=roles) embed.set_author(name=f"Roller ({len(interaction.guild.roles)})", icon_url=interaction.guild.icon) @@ -748,7 +746,7 @@ class Info(commands.Cog): # If the list of roles is too long, send it as a file if len(roles) > 2048: await discord_utils.send_as_txt_file( - interaction, roles, f"./src/assets/temp/{interaction.guild.id}_{interaction.user.id}_roles.txt" + interaction, roles, f"{interaction.guild.id}_{interaction.user.id}_roles.txt" ) else: embed = discord.Embed(color=bruker.color, description=roles) @@ -779,7 +777,7 @@ class Info(commands.Cog): # If the list of roles is too long, send it as a file if len(roles) > 2048: await discord_utils.send_as_txt_file( - interaction, roles, f"./src/assets/temp/{interaction.guild.id}_{interaction.user.id}_missing_roles.txt" + interaction, roles, f"{interaction.guild.id}_{interaction.user.id}_missing_roles.txt" ) else: embed = discord.Embed(color=bruker.color, description=roles) diff --git a/src/cogs/user_facts.py b/src/cogs/user_facts.py index 93c2c99..2568088 100644 --- a/src/cogs/user_facts.py +++ b/src/cogs/user_facts.py @@ -1,3 +1,5 @@ +from io import BytesIO + import discord import graphviz import numpy as np @@ -240,10 +242,8 @@ class UserFacts(commands.Cog): if user: others.append((user, mbti)) - self.create_mbti_graph((bruker, user_mbti), others) - - with open(f"src/assets/temp/{bruker.id}_mbti.png", "rb") as f: - image = discord.File(f, filename=f"{bruker.id}_mbti.png") + graph_png = self.create_mbti_graph((bruker, user_mbti), others) + image = discord.File(BytesIO(graph_png), filename=f"{bruker.id}_mbti.png") embed.set_image(url=f"attachment://{bruker.id}_mbti.png") await interaction.followup.send(embed=embed, file=image) @@ -359,7 +359,9 @@ class UserFacts(commands.Cog): return similarity_matrix - def create_mbti_graph(self, user_mbti: tuple[discord.Member, str], others: list[tuple[discord.Member, str]]): + def create_mbti_graph( + self, user_mbti: tuple[discord.Member, str], others: list[tuple[discord.Member, str]] + ) -> bytes: user, mbti = user_mbti # Create a Graphviz graph @@ -382,7 +384,7 @@ class UserFacts(commands.Cog): graph.node(str(other_user.id), f"{other_user.display_name}\n{other_mbti}") graph.edge(str(user.id), str(other_user.id), len=str(edge_length)) - graph.render(f"{user.id}_mbti", directory="./src/assets/temp", view=False, overwrite_source=True) + return graph.pipe(format="png") async def setup(bot: commands.Bot): diff --git a/src/cogs/utils/discord_utils.py b/src/cogs/utils/discord_utils.py index 8c22046..8da3050 100644 --- a/src/cogs/utils/discord_utils.py +++ b/src/cogs/utils/discord_utils.py @@ -1,4 +1,3 @@ -import os from dataclasses import dataclass from datetime import datetime from io import BytesIO @@ -12,31 +11,20 @@ from .misc_utils import Paginator from .misc_utils import log_errors -async def send_as_txt_file(interaction: discord.Interaction, content: str, file_path: str): +async def send_as_txt_file(interaction: discord.Interaction, content: str, filename: str): """ - Sends a string as a txt file and deletes the file afterwards + Sends a string as a txt file Parameters ---------- interaction (discord.Interaction): Slash command context object content (str): String that's too long to send - file_path (str): Path to file + filename (str): Name of the file as shown in Discord """ - # Create file - with open(file_path, "w", encoding="utf-8") as file: - file.write(content) - - # Send file - txt_file = discord.File(file_path) + txt_file = discord.File(BytesIO(content.encode("utf-8")), filename=filename) await interaction.response.send_message(file=txt_file) - # Delete file - try: - os.remove(file_path) - except OSError: - pass - async def get_file_bytesio(file: discord.Attachment | discord.Asset) -> BytesIO: """