diff --git a/client.py b/client.py new file mode 100644 index 0000000..defd55b --- /dev/null +++ b/client.py @@ -0,0 +1,19 @@ +import discord +from discord import app_commands + +from modules import FourasModule, RhymesModule +from dotenv import load_dotenv + +load_dotenv() + +MODULES = FourasModule, RhymesModule + +intents = discord.Intents.default() +intents.members = True +intents.presences = True +intents.guilds = True +intents.messages = True +intents.message_content = True +client = discord.Client(intents=intents) + +tree = app_commands.CommandTree(client) diff --git a/main.py b/main.py index 1eb6d49..a6d324a 100644 --- a/main.py +++ b/main.py @@ -1,19 +1,10 @@ -from dotenv import load_dotenv import discord import os from modules.base import BaseModule -from modules import FourasModule, RhymesModule -MODULES = FourasModule, RhymesModule +from client import client, MODULES, tree +from modules import gitea -intents = discord.Intents.default() -intents.members = True -intents.presences = True -intents.guilds = True -intents.messages = True -intents.message_content = True -client = discord.Client(intents=intents) -load_dotenv() token = os.getenv("DISCORD_TOKEN", "NO_TOKEN") client.riddles = [] @@ -28,6 +19,7 @@ client.modules: list[BaseModule] = [] @client.event async def on_ready(): client.modules = [m(client) for m in MODULES] + await tree.sync(guild=discord.Object(id=gitea.GUILD_ID)) for m in client.modules: await m.load() print(f"Logged in as {client.user}") diff --git a/modules/base.py b/modules/base.py index c3a4428..6206fca 100644 --- a/modules/base.py +++ b/modules/base.py @@ -16,11 +16,18 @@ class BaseModule: async def save(self, save_to_file=True): raise NotImplementedError - async def handle_message(self, message)-> bool: + async def handle_message(self, message) -> bool: raise NotImplementedError async def load_history(self, channel): - messages = [{"id": message.id, "content": message.content, "date": message.created_at.strftime("%d/%m %H:%M:%S")} async for message in channel.history(limit=10)] + messages = [ + { + "id": message.id, + "content": message.content, + "date": message.created_at.strftime("%d/%m %H:%M:%S"), + } + async for message in channel.history(limit=10) + ] return json.dumps(messages, ensure_ascii=False) async def get_guild_name(self, guildId) -> str: diff --git a/modules/fouras.py b/modules/fouras.py index ee4e8df..123b05e 100644 --- a/modules/fouras.py +++ b/modules/fouras.py @@ -45,13 +45,14 @@ RIDDLES_FILE = "riddles.txt" ANSWERS_FILE = "answers.txt" SAVE_FILE = appdirs.user_data_dir() + "/PereFouras/fouras_riddles.json" + class FourasModule(BaseModule): async def load(self): with open(RIDDLES_FILE, "r", encoding=ENCODING) as r_file: self._client.riddles = r_file.read().split("\n\n") with open(ANSWERS_FILE, "r", encoding=ENCODING) as a_file: self._client.answers = [line.strip() for line in a_file.readlines()] - str=f"Loaded {len(self._client.riddles)} riddles" + str = f"Loaded {len(self._client.riddles)} riddles" try: with open(SAVE_FILE, "r") as file: @@ -60,7 +61,9 @@ class FourasModule(BaseModule): for k, v in config.items(): channel = await self._client.fetch_channel(int(k)) channel_info = v - channel_info["message"] = await channel.fetch_message(channel_info["message"]) + channel_info["message"] = await channel.fetch_message( + channel_info["message"] + ) ongoing_riddles[channel] = channel_info self._client.ongoing_riddles = ongoing_riddles str = str + 'Loaded fouras save file "{0}"'.format(SAVE_FILE) @@ -184,10 +187,12 @@ class FourasModule(BaseModule): channel_id=message.channel.id, message=message_content, history=messages_json, - state=self.save(False) + state=self.save(False), ) ) - await message.channel.send(f'Rapport de bug envoyé à {author_user.mention}\nMerci de ton feedback !') + await message.channel.send( + f"Rapport de bug envoyé à {author_user.mention}\nMerci de ton feedback !" + ) return True broadcast_match = re.match(r"^broadcast\s+(\d+) (.*)", message.content) @@ -198,7 +203,7 @@ class FourasModule(BaseModule): if channel: await channel.send(broadcast_message) else: - await message.channel.send(f'Invalid channel id : {index}') + await message.channel.send(f"Invalid channel id : {index}") return True if message_content == "about fouras": @@ -209,13 +214,15 @@ class FourasModule(BaseModule): return True if message_content == "save fouras": - if(message.author.id == 151626081458192384): - json_str = "```json\n{0}```".format(json.dumps(self.save(), ensure_ascii=False, indent=2)) + if message.author.id == 151626081458192384: + json_str = "```json\n{0}```".format( + json.dumps(self.save(), ensure_ascii=False, indent=2) + ) await message.author.send(json_str) return True if message_content == "load fouras": - if(message.author.id == 151626081458192384): + if message.author.id == 151626081458192384: await self.load() await message.author.send( "Loaded {0} riddles".format(len(self._client.riddles)) @@ -223,7 +230,7 @@ class FourasModule(BaseModule): return True if message_content == "debug fouras": - if(message.author.id == 151626081458192384): + if message.author.id == 151626081458192384: dump = {} for key, value in self._client.ongoing_riddles.items(): dump_channel = dict(value) @@ -232,7 +239,9 @@ class FourasModule(BaseModule): channel_name = await self.get_channel_name(key) dump[channel_name] = dump_channel await message.author.send( - "```json\n{0}```".format(json.dumps(dump, ensure_ascii=False, indent=4)) + "```json\n{0}```".format( + json.dumps(dump, ensure_ascii=False, indent=4) + ) ) return True diff --git a/modules/gitea.py b/modules/gitea.py new file mode 100644 index 0000000..f717c03 --- /dev/null +++ b/modules/gitea.py @@ -0,0 +1,70 @@ +import os + +import discord +from discord import app_commands + +import httpx +from client import tree + + +GUILD_ID = os.getenv("GUILD_ID") +GITEA_API_KEY = os.getenv("GITEA_API_KEY") + +gitea_url = "https://git.epicsparrow.com/api/v1" + +GITEA_PROJECTS = {} + +auth_headers = {"Authorization": f"token {GITEA_API_KEY}"} + + +def init_gitea_projects(): + res = httpx.get(gitea_url + "/repos/search", headers=auth_headers) + if res.status_code == 200: + GITEA_PROJECTS.update( + { + str(project["id"]): { + "name": project["name"], + "owner": project["owner"]["login"], + } + for project in res.json()["data"] + } + ) + return [(project["name"], project["id"]) for project in res.json()["data"]] + else: + return [] + + +init_gitea_projects() + + +@tree.command( + name="gitea-issue", + description="Create issues to gitea", + guild=discord.Object(id=GUILD_ID), +) +@app_commands.describe( + title="Issue title", project="The project where the issue is created" +) +@app_commands.choices( + project=[ + app_commands.Choice(name=project["name"], value=id_) + for id_, project in GITEA_PROJECTS.items() + ] +) +async def gitea(interaction: discord.Interaction, project: str, title: str): + embed = discord.Embed(title="Gitea issue") + embed.add_field(name="Project", value=GITEA_PROJECTS[project]["name"]) + embed.add_field(name="Title", value=title) + embed.add_field(name="Created by", value=interaction.user.mention) + + creation_url = f"{gitea_url}/repos/{GITEA_PROJECTS[project]['owner']}/{GITEA_PROJECTS[project]['name']}/issues" + creation_data = { + "title": title, + "body": f"Created by {interaction.user.nick or interaction.user.name} from Discord.", + } + res = httpx.post(creation_url, headers=auth_headers, data=creation_data) + if res.status_code == 201: + embed.add_field(name="Issue created", value=res.json()["html_url"]) + else: + embed.add_field(name="Error", value=res.text) + await interaction.response.send_message(embed=embed) diff --git a/modules/rhymes.py b/modules/rhymes.py index 9c00e5f..49a02b6 100644 --- a/modules/rhymes.py +++ b/modules/rhymes.py @@ -14,6 +14,7 @@ SAVE_FILE = appdirs.user_data_dir() + "/PereFouras/poilau_save.json" # Ajouter ce bot à votre serveur : {url} # """ + class RhymesModule(BaseModule): rhymes: list = [] guild_config: dict = {} @@ -48,7 +49,7 @@ class RhymesModule(BaseModule): if truncated[-1].isalpha() and truncated[-2].isalpha(): break truncated = truncated[:-1] - truncated = truncated.split(' ')[-1] + truncated = truncated.split(" ")[-1] if truncated.isalpha(): return truncated else: @@ -66,33 +67,47 @@ class RhymesModule(BaseModule): message_content = message.content.lower() if message_content == "debug poilau": - if(message.author.id == 151626081458192384): + if message.author.id == 151626081458192384: dump = {} for key, value in self.guild_config.items(): channel_name = await self.get_guild_name(key) - sleeping_time = "{:.2f} s".format(max(0, value["cooldown"] - time.time())) - dump[channel_name] = {"cooldown": sleeping_time, "self-control": value["self-control"]} + sleeping_time = "{:.2f} s".format( + max(0, value["cooldown"] - time.time()) + ) + dump[channel_name] = { + "cooldown": sleeping_time, + "self-control": value["self-control"], + } await message.author.send( - "```json\n{0}```".format(json.dumps(dump, ensure_ascii=False, indent=2)) + "```json\n{0}```".format( + json.dumps(dump, ensure_ascii=False, indent=2) + ) ) return True if message_content == "save poilau": - if(message.author.id == 151626081458192384): + if message.author.id == 151626081458192384: self.save() - json_str = "```json\n{0}```".format(json.dumps(self.guild_config, ensure_ascii=False, indent=2)) + json_str = "```json\n{0}```".format( + json.dumps(self.guild_config, ensure_ascii=False, indent=2) + ) await message.author.send(json_str) return True if message_content == "load poilau": - if(message.author.id == 151626081458192384): + if message.author.id == 151626081458192384: await message.author.send(await self.load()) - json_str = "```json\n{0}```".format(json.dumps(self.guild_config, ensure_ascii=False, indent=2)) + json_str = "```json\n{0}```".format( + json.dumps(self.guild_config, ensure_ascii=False, indent=2) + ) await message.author.send(json_str) return True if message_content == "tg fouras" and message.guild: - self.guild_config[str(message.guild.id)] = {"cooldown": time.time() + 40000, "self-control": 2.0} + self.guild_config[str(message.guild.id)] = { + "cooldown": time.time() + 40000, + "self-control": 2.0, + } await message.channel.send("ok :'(") return True @@ -100,7 +115,9 @@ class RhymesModule(BaseModule): if message.author != self._client.user and message.guild and last_word: poil = self.poil_auquel(last_word) guildId = str(message.guild.id) - guild_config = self.guild_config.get(guildId, {"cooldown": 0, "self-control": 1.0}) + guild_config = self.guild_config.get( + guildId, {"cooldown": 0, "self-control": 1.0} + ) if poil and time.time() - guild_config["cooldown"] > 0: self_control = guild_config["self-control"] if random.random() < self_control: @@ -110,7 +127,10 @@ class RhymesModule(BaseModule): wait_time = random.randint(0, 900) if bool(random.getrandbits(1)): wait_time = random.randint(900, 10800) - self.guild_config[guildId] = {"cooldown": time.time() + wait_time, "self-control": self_control + 1.0} + self.guild_config[guildId] = { + "cooldown": time.time() + wait_time, + "self-control": self_control + 1.0, + } await message.channel.send(poil) return True return False