From 534b4076743fe4ea1c81ab17bab8c2f7a3ccc36d Mon Sep 17 00:00:00 2001 From: "airo.pi_" <47398145+AiroPi@users.noreply.github.com> Date: Sun, 7 Aug 2022 18:33:54 +0200 Subject: [PATCH] refactor: cleanup code event.py and clash_of_code.py are excepted. - remove i18n - create a sub-module in utils for API scrappers - remove some useless functions... - fix annotations - reformat files using bandit --- src/cogs/doc.py | 78 ++- src/cogs/googleit.py | 30 +- src/cogs/lines.py | 43 +- src/cogs/miscellaneous.py | 2 +- src/main.py | 4 +- .../locale/en_EN/LC_MESSAGES/help_center.mo | Bin 386 -> 0 bytes .../locale/en_EN/LC_MESSAGES/help_center.po | 19 - .../locale/fr_FR/LC_MESSAGES/help_center.mo | Bin 12540 -> 0 bytes .../locale/fr_FR/LC_MESSAGES/help_center.po | 563 ------------------ src/utils/__init__.py | 10 + src/utils/api/__init__.py | 0 src/utils/{ => api}/codingame.py | 0 src/utils/{ => api}/gist.py | 0 src/utils/api/piston.py | 23 + src/utils/checkers.py | 49 -- src/utils/custom_command_tree.py | 40 +- src/utils/i18n.py | 53 -- src/utils/misc.py | 109 ---- src/utils/piston.py | 23 - src/utils/types.py | 6 +- 20 files changed, 128 insertions(+), 924 deletions(-) delete mode 100644 src/resources/locale/en_EN/LC_MESSAGES/help_center.mo delete mode 100644 src/resources/locale/en_EN/LC_MESSAGES/help_center.po delete mode 100644 src/resources/locale/fr_FR/LC_MESSAGES/help_center.mo delete mode 100644 src/resources/locale/fr_FR/LC_MESSAGES/help_center.po create mode 100644 src/utils/api/__init__.py rename src/utils/{ => api}/codingame.py (100%) rename src/utils/{ => api}/gist.py (100%) create mode 100644 src/utils/api/piston.py delete mode 100644 src/utils/checkers.py delete mode 100644 src/utils/i18n.py delete mode 100644 src/utils/misc.py delete mode 100644 src/utils/piston.py diff --git a/src/cogs/doc.py b/src/cogs/doc.py index 36264bd..1e6b684 100644 --- a/src/cogs/doc.py +++ b/src/cogs/doc.py @@ -1,90 +1,88 @@ +from __future__ import annotations + from typing import TYPE_CHECKING from urllib import parse import discord -from discord import app_commands -from discord.ext import commands from aiohttp import ClientSession from bs4 import BeautifulSoup +from discord import app_commands +from discord.ext import commands from utils.constants import BUG_CENTER_ID -from utils.i18n import _ -# from .utils import checkers -# from .utils.misc import delete_with_emote if TYPE_CHECKING: from main import HelpCenterBot class Doc(commands.Cog): - def __init__(self, bot: 'HelpCenterBot'): - self.bot = bot + def __init__(self, bot: HelpCenterBot) -> None: + self.bot: HelpCenterBot = bot self.bot.tree.add_command(self.doc, guild=discord.Object(id=BUG_CENTER_ID)) @app_commands.command( - name='doc', - description='Shows 4 or fewer links referring to a documentation on readthedocs.io :D', - ) - @app_commands.describe( - doc="The documentation you want to search for.", - query="The search query." + name="doc", + description="Shows 4 or fewer links referring to a documentation on readthedocs.io :D", ) + @app_commands.describe(doc="The documentation you want to search for.", query="The search query.") # @checkers.authorized_channels() - async def doc(self, - inter: discord.Interaction, - doc: str, - query: str): - - url = 'https://readthedocs.org/api/v2/search/' + async def doc(self, inter: discord.Interaction, doc: str, query: str) -> None: + url = "https://readthedocs.org/api/v2/search/" params = { - 'q': query, - 'project': doc, - 'version': 'master', + "q": query, + "project": doc, + "version": "master", } async with ClientSession() as session: async with session.get(url, params=params) as r: json = await r.json() print(json) - if not json.get('count'): - return await inter.response.send_message(_('Nothing found.', inter)) + if not json.get("count"): + return await inter.response.send_message("Nothing found.") - embed = discord.Embed(title=_("{} Results (click here for a complete search)".format(json['count'])), - url="{}/en/stable/search.html?q={}".format(json['results'][0]['domain'], query)) + embed = discord.Embed( + title=f"{json['count']} Results (click here for a complete search)", + url=f"{json['results'][0]['domain']}/en/stable/search.html?q={query}", + ) description = "" - for result in json['results'][:4]: + for result in json["results"][:4]: try: - for block in result['blocks'][:2]: - description += f"\n[{block['title']}]({result['domain']}{result['path']}?highlight={query}#{block['id']})" + for block in result["blocks"][:2]: + description += ( + f"\n[{block['title']}]({result['domain']}{result['path']}?highlight={query}#{block['id']})" + ) except KeyError: - # embed.description += f"\n[{result['title']}]({result['domain']}{result['path']}?highlight={query}#{block['id']})" pass embed.description = description - embed.set_footer(text=_('Documentations provided by https://readthedocs.org')) - await inter.response.send_message(_("Results for query **{0}** and documentation **{1}**".format(query, doc)), embed=embed) - # await delete_with_emote(self.bot, inter.author, await inter.original_message()) + embed.set_footer(text="Documentations provided by https://readthedocs.org") + await inter.response.send_message("Results for query **{query}** and documentation **{doc}**", embed=embed) - @doc.autocomplete('doc') + @doc.autocomplete("doc") async def doc_autocomplete(self, interaction: discord.Interaction, current: str) -> list[app_commands.Choice[str]]: if len(current) < 4: - return [app_commands.Choice(name='discord.py', value='discord.py')] + return [app_commands.Choice(name="discord.py", value="discord.py")] async with ClientSession() as session: - async with session.get("https://readthedocs.org/search/?type=project&version=latest&q=" + parse.quote_plus(current)) as r: + async with session.get( + "https://readthedocs.org/search/?type=project&version=latest&q=" + parse.quote_plus(current) + ) as r: result = await r.text() - soup = BeautifulSoup(result, 'html.parser') + soup = BeautifulSoup(result, "html.parser") return [ app_commands.Choice(name=value, value=value) - for tag in soup.select('#content > div > div > div > div.module > div > div.module-list > div > ul > li > p.module-item-title > a') - if (value := tag.get_text().split(' (')[0].strip()) or True + for tag in soup.select( + "#content > div > div > div > div.module > div > div.module-list > div > ul > li > p.module-item-title > a" + ) + if (value := tag.get_text().split(" (")[0].strip()) or True ][:25] -async def setup(bot: 'HelpCenterBot'): +async def setup(bot: HelpCenterBot) -> None: await bot.add_cog(Doc(bot)) bot.logger.info("Extension [doc] loaded successfully.") diff --git a/src/cogs/googleit.py b/src/cogs/googleit.py index 26316be..8217d3d 100644 --- a/src/cogs/googleit.py +++ b/src/cogs/googleit.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import TYPE_CHECKING from urllib import parse @@ -5,9 +7,6 @@ from discord import app_commands from discord.ext import commands -# from .utils import checkers -# from .utils.misc import delete_with_emote -from utils.i18n import _ from utils.constants import BUG_CENTER_ID if TYPE_CHECKING: @@ -15,27 +14,30 @@ class GoogleIt(commands.Cog): - def __init__(self, bot: 'HelpCenterBot') -> None: + def __init__(self, bot: HelpCenterBot) -> None: """Allow you to transform a query to a google research using https://letmegooglethat.com.""" - self.bot = bot + self.bot: HelpCenterBot = bot self.bot.tree.add_command(self.google_it, guild=discord.Object(id=BUG_CENTER_ID)) @app_commands.command( - name='googleit', - description='Show how to do a google search :D', + name="googleit", + description="Show how to do a google search :D", ) - # @checkers.authorized_channels() - async def google_it(self, inter: discord.Interaction, search: str) -> None: # Using string (with *, arg) instead of array (*arg) to prevent argument missing. + async def google_it( + self, inter: discord.Interaction, search: str + ) -> None: # Using string (with *, arg) instead of array (*arg) to prevent argument missing. """Return an url link that animate a google research.""" - stringed_array = " ".join(word[:50] for word in search.split(' ')[:32]) # Maximum of 32 words, and a word has 50 chars max. + stringed_array = " ".join( + word[:50] for word in search.split(" ")[:32] + ) # Maximum of 32 words, and a word has 50 chars max. query = parse.quote_plus(stringed_array) - await inter.response.send_message(_("The google tool is very powerful, see how it works!\n", inter) + - f"") - # await delete_with_emote(self.bot, inter.user, await inter.original_message()) + await inter.response.send_message( + f"The google tool is very powerful, see how it works!\n" + ) -async def setup(bot: 'HelpCenterBot') -> None: +async def setup(bot: HelpCenterBot) -> None: await bot.add_cog(GoogleIt(bot)) bot.logger.info("Extension [google_it] loaded successfully.") diff --git a/src/cogs/lines.py b/src/cogs/lines.py index 7faf83b..bfbeee1 100644 --- a/src/cogs/lines.py +++ b/src/cogs/lines.py @@ -1,53 +1,38 @@ from typing import TYPE_CHECKING import discord +from discord import app_commands, ui from discord.ext import commands -from discord import ui -from discord import app_commands +from typing_extensions import Self from utils.constants import BUG_CENTER_ID -# from .utils.misc import delete_with_emote -from utils.i18n import _ - if TYPE_CHECKING: from main import HelpCenterBot -# LANGUAGES = ["python", "javascript", "typescript", "java", "rust", "lisp", "elixir"] - - -# async def lines_autocomplete(inter: discord.ApplicationCommandInteraction, user_input: str) -> list[str]: -# return [lang for lang in LANGUAGES + [user_input] if user_input.lower() in lang] - -class LinesModal(ui.Modal, title='Add lines to your code'): - language = ui.TextInput(label='Language') - code = ui.TextInput(label='Code', style=discord.TextStyle.paragraph, min_length=5, max_length=1950) - - async def on_submit(self, inter: discord.Interaction): +class LinesModal(ui.Modal, title="Add lines to your code"): + language = ui.TextInput[Self](label="Language") + code = ui.TextInput[Self](label="Code", style=discord.TextStyle.paragraph, min_length=5, max_length=1950) - numbered_code = '\n'.join(f'{i+1:>3} | {line}' for i, line in enumerate(str(self.code).splitlines())) + async def on_submit(self, interaction: discord.Interaction) -> None: + numbered_code: str = "\n".join(f"{i+1:>3} | {line}" for i, line in enumerate(str(self.code).splitlines())) - await inter.response.send_message(_('Numbered code of {0} :\n').format(inter.user) + - '```' + (str(self.language) or '') + '\n' + - numbered_code + - '\n```') - # await delete_with_emote(inter.client, ctx.author, await ctx.original_message()) + await interaction.response.send_message( + f"Numbered code of {interaction.user} :\n```{str(self.language) or ''}\n{numbered_code}\n```" + ) class Lines(commands.Cog): - def __init__(self, bot: 'HelpCenterBot') -> None: - self.bot = bot + def __init__(self, bot: HelpCenterBot) -> None: + self.bot: HelpCenterBot = bot self.bot.tree.add_command(self.lines, guild=discord.Object(id=BUG_CENTER_ID)) - @app_commands.command( - name='lines', - description='Ajouter le numéro des lignes à votre code.' - ) + @app_commands.command(name="lines", description="Ajouter le numéro des lignes à votre code.") async def lines(self, inter: discord.Interaction) -> None: await inter.response.send_modal(LinesModal()) -async def setup(bot: 'HelpCenterBot') -> None: +async def setup(bot: HelpCenterBot) -> None: await bot.add_cog(Lines(bot)) bot.logger.info("Extension [lines] loaded successfully.") diff --git a/src/cogs/miscellaneous.py b/src/cogs/miscellaneous.py index 6356bcc..2514bd9 100644 --- a/src/cogs/miscellaneous.py +++ b/src/cogs/miscellaneous.py @@ -12,9 +12,9 @@ from discord.ext import commands from typing_extensions import Self # TODO: remove on 3.11 release +from utils.api.gist import create_new_gist, delete_gist from utils.constants import BUG_CENTER_ID from utils.custom_errors import CustomError -from utils.gist import create_new_gist, delete_gist if TYPE_CHECKING: from re import Pattern diff --git a/src/main.py b/src/main.py index 6100eae..13002e4 100644 --- a/src/main.py +++ b/src/main.py @@ -47,7 +47,7 @@ def __init__(self) -> None: # self.before_invoke(self.set_command_language) self.add_check(self.is_on_bug_center) - async def setup_hook(self): + async def setup_hook(self) -> None: for ext in self.initial_extensions: try: await self.load_extension(ext) @@ -65,7 +65,7 @@ async def on_ready(self) -> None: logger.info(f"Logged in as : {bot_user.name}") logger.info(f"ID : {bot_user.id}") - def is_on_bug_center(self, ctx: "Context[HelpCenterBot]") -> bool: + def is_on_bug_center(self, ctx: commands.Context[HelpCenterBot]) -> bool: if ctx.guild and ctx.guild.id != BUG_CENTER_ID: raise custom_errors.NotInBugCenter() return True diff --git a/src/resources/locale/en_EN/LC_MESSAGES/help_center.mo b/src/resources/locale/en_EN/LC_MESSAGES/help_center.mo deleted file mode 100644 index 64ae4dcc0fa2017580a822f2408641dfb0d3981f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 386 zcmYk0!Ab)$5QZyy%F(lj2p$xjZL$ciDSJ^{Ews336|duV+^%esB}qje#Mkp#oVCz8 z=C!n=1WBaG+pOg_}k8YzlY$}5Jj`{*ucp7WiZmVe=_9hK(3$pv6Y9p)F*?j Q-6Nqd7X=%FVoTBc1zG}XzyJUM diff --git a/src/resources/locale/en_EN/LC_MESSAGES/help_center.po b/src/resources/locale/en_EN/LC_MESSAGES/help_center.po deleted file mode 100644 index 76f62f0..0000000 --- a/src/resources/locale/en_EN/LC_MESSAGES/help_center.po +++ /dev/null @@ -1,19 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: \n" -"POT-Creation-Date: 2021-02-10 18:07+0100\n" -"PO-Revision-Date: 2021-02-10 18:07+0100\n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: en\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.4.1\n" -"X-Poedit-Basepath: ../../../../cogs\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Poedit-SearchPath-0: .\n" - -#: test.py:16 -msgid "hello" -msgstr "" diff --git a/src/resources/locale/fr_FR/LC_MESSAGES/help_center.mo b/src/resources/locale/fr_FR/LC_MESSAGES/help_center.mo deleted file mode 100644 index c09b25f43313951cbc1aa913fb0c106d668583f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12540 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�>ya(bcQOVu zmsdI-?lMwrq{9~!)d%r&{5ipsZDkW^iH&h9< z%&Jte5}WO%|Cd8P65TG_B!^0smb=^DZYU> zAkHf`>7a!wThO$0(o10@?5i!q(Yj?tlij31v({uDPmrPoElZa{z)r+gMj_0r9;J*z zKVLmdl0((3JTu%iin8M*@2p{oP>^BC-{|=MBpGyvyJ}eucj;Ne?i9ATVLI3n!Nc1* z2YRKMtQY&p$_IF>7W~3nX`>E zwq(h11M~DcPsdf_U_)wTaxm17I=-GuvAcAlGzXP%lMa8>4aDsNn1*+mG{xoJdK57qSsS}cg|5{qtCuIHaRU-8Wqb7`hDtf zCez|(El@w;#N6OlH1YuwAwMucSqpkCa{ z`OjFQvQIdr&Sp6sP0}v3L+_3AD9sTyNhOo`2pY4(Zco=%G5Ldi(ub|Qy1_8&m7dVy zns(_lCm`6#XM!^FZ{9jxfej~xt{x=?Q=;(0j?b^sPN{oVnaC8QCTjKIo;6|i6Vnr( zVt!9co^$GO7pi2^6t2S0PfU|ZAnj6ViVt7b_6PjZg??sn4^?rM#u>W-6^IIxh$bsp zE}7;B8QXY!&!V0we37wd(a|%Z2;Fo1xclIJY}|O&=qJWYsH|@J&StBWs>N1rc*^0l z>SKyL0*eM zf@8RQ5pVOBvevAbz`H`_>x2-*H~fN*DbeNOF6~)%qU<+{9EgsLk~4L85YMT?rueW2 z@RqIgsex?F>4+aFAW?Q|hZ?A-H~a#9Lj8asTBeE!dF$FTn*Qwnvvq5E)Awf)tZd;bzRXo&>+--P#-uoyXy?+!C9Bca;|r0r zKev^t5;a(4jn%0d>!wZJQTDJZ%nnW1N*)sO!a z&$`8aR?<)@e3dlJ9qdc{$|#C^khs{(TE0~i*p~$`u1|HQjY#J&Rcxg*m^&6fFp`pi z3~zN41TaxJS5)F_Nbfb0xoiTT)lrVw%kt0rOFkWL;;%YxRwX8ihz9&(z~*!Sh6S(+ zdno(D6AR|k;+rtb5SV>hMKhkKQOZ_n$9qdvXZz-`Lc<;_OWo0iZvIfI(OW!Ixg0ym z{UO}Q+#<^#Bukc=WVuSps_kpxYX^VTRcxE)F!UflwrYbO@0n;b%yd3mv)|Hg+Di6X zda;wvm=1^5P-uv({v$xE{BX-KfXR@7V(mG2^dl0aJ}CT&l)s)M`E(tNd1TInWPC zN>_p9n;;#;zSXSy9yVKv;LyZ;Q3m$~XQg_GL@hT$Jmh+UwG?O*mkJNXDA}=E3MEm*HZD&({**LlWkxyAn_z1P*lWTL+pKIt$ zk`&7xiu%49PQ*SnNMpAQ^H(<%wER>HsjzL%WdgB?%K8|>$TCy09nrTQx2V;pQ6k+V60T?m zzllaQ)xPY`A0ju8ATK3=aKQidDaBSdgQ9f0Ua#8JRYP1`X-9+0BwLt{6OtX+?q7P) zI@c@~_J+?QMAf_=6?9JhYl0(ls;{hmDeK{?+Ae)B_kHXY$_RK#Wv{kSvDJ;OY}*E1 i)loBh;<-)V*M6Z#MjdS=Bekk~RCcvhle>+$8~h)hdT7A_ diff --git a/src/resources/locale/fr_FR/LC_MESSAGES/help_center.po b/src/resources/locale/fr_FR/LC_MESSAGES/help_center.po deleted file mode 100644 index fc59387..0000000 --- a/src/resources/locale/fr_FR/LC_MESSAGES/help_center.po +++ /dev/null @@ -1,563 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: \n" -"POT-Creation-Date: 2021-10-03 10:26+0200\n" -"PO-Revision-Date: 2021-10-03 10:29+0200\n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: fr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.0\n" -"X-Poedit-Basepath: ../../../..\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Poedit-SearchPath-0: cogs\n" -"X-Poedit-SearchPath-1: main.py\n" - -#: cogs/auto_help_system.py:104 -msgid "" -"**Give a title to your request.** \n" -"*Do not send your whole problem, just a very concise description with " -"maximum context. (Language, OS, library used...) *\n" -"\n" -"> Example: \"[Python - Discord.py] Is it possible to kick any one of a " -"server with its id?\"" -msgstr "" -"**Donnez un titre à votre demande.**\n" -"*N'envoyez pas tout votre problème, juste une description très concise avec " -"un maximum de contexte. (langage, OS, librairie utilisée...)*\n" -"\n" -"> Exemple : \\\"[python - discord.py] Est-il possible d'expulser quelqu'un " -"d'un serveur avec son ID ?\\\"" - -#: cogs/auto_help_system.py:119 -#, python-brace-format -msgid "" -"{0}\n" -"\n" -"⚠ **This is not your full message of the request, the title must be short " -"(less than 100 characters)**.\n" -"\n" -"Your current request:```\n" -"{1}\n" -"```" -msgstr "" -"{0}\n" -"\n" -"\\⚠ **Ceci n'est pas votre message complet de la demande, le titre doit être " -"court (moins de 100 caractères)**.\n" -"\n" -"Votre demande actuelle : ```\n" -"{1}\n" -"```" - -#: cogs/auto_help_system.py:145 -msgid "Archive" -msgstr "" - -#: cogs/auto_help_system.py:146 -msgid "Delete" -msgstr "" - -#: cogs/auto_help_system.py:155 -msgid "Ask your question." -msgstr "Posez votre question." - -#: cogs/auto_help_system.py:156 -msgid "" -"Be as clear as possible, remember to send code if there is, or screens " -"highlighting the problem! \n" -"\n" -"**\\⚠️ Do not share passwords, bot tokens... if anyone in demand, warn a " -"staff member** \\⚠️" -msgstr "" -"Soyez le plus claire possible, pensez à envoyer du code s'il y en a, ou des " -"screens mettant bien en évidence le problème !\n" -"\n" -"**\\⚠️ Ne partagez en aucun cas des mots de passe, des tokens de bots... si " -"quelqu'un vous en demande, prévenez un membre du staff.**\\⚠️" - -#: cogs/auto_help_system.py:161 -msgid "⬇ click to archive the thread" -msgstr "⬇ cliquez pour archiver le fil" - -#: cogs/auto_help_system.py:167 -msgid "How to ask a question ?" -msgstr "Comment poser une question ?" - -#: cogs/auto_help_system.py:168 -#, python-brace-format -msgid "" -":ballot_box_with_check: have you searched on Google ? [Search](https://" -"google.com/search?q={0})\n" -":ballot_box_with_check: have you read the doc ?\n" -":ballot_box_with_check: don't ask to ask, just ask. https://dontasktoask." -"com/\n" -":ballot_box_with_check: asking about your attempted solution rather than " -"your actual problem. https://xyproblem.info/" -msgstr "" -":ballot_box_with_check: avez vous cherché sur Google ? [Rechercher](https://" -"google.com/search?q={0})\n" -":ballot_box_with_check: avez vous lu la documentation ?\n" -":ballot_box_with_check: ne demandez pas pour demander, demandez simplement. " -"https://dontasktoask.com/\n" -":ballot_box_with_check: posez des questions sur votre tentative de solution " -"plutôt que sur votre problème réel. https://xyproblem.info/" - -#: cogs/clash_of_code.py:73 -msgid "30 minutes" -msgstr "30 minutes" - -#: cogs/clash_of_code.py:74 -msgid "1 hour" -msgstr "1 heure" - -#: cogs/clash_of_code.py:75 -msgid "3 hours" -msgstr "3 heures" - -#: cogs/clash_of_code.py:76 -msgid "12 hours" -msgstr "12 heures" - -#: cogs/clash_of_code.py:77 -msgid "1 day" -msgstr "1 journée" - -#: cogs/clash_of_code.py:102 -msgid "Publish a clash of code !" -msgstr "Publiez un clash of code !" - -#: cogs/clash_of_code.py:121 cogs/clash_of_code.py:138 -msgid "Published !" -msgstr "Publié !" - -#: cogs/clash_of_code.py:143 -msgid "no" -msgstr "non" - -#: cogs/clash_of_code.py:143 -msgid "yes" -msgstr "oui" - -#: cogs/clash_of_code.py:145 -msgid "New clash of code !" -msgstr "Nouveau clash of code !" - -#: cogs/clash_of_code.py:147 -#, python-brace-format -msgid "" -"> `public` : {0}\n" -"> `mode` : {1}\n" -"> `started` : {2}\n" -"> `finished` : {3}" -msgstr "" -"> `publique` : {0}\n" -"> `mode` : {1}\n" -"> `commandé` : {2}\n" -"> `finis` : {3}" - -#: cogs/clash_of_code.py:157 -msgid "**Created :**" -msgstr "**Créé :**" - -#: cogs/clash_of_code.py:162 -msgid "**Start planned :**" -msgstr "**Début prévu :**" - -#: cogs/clash_of_code.py:169 -msgid "**End :**" -msgstr "**Fin :**" - -#: cogs/clash_of_code.py:190 -msgid "none" -msgstr "aucun" - -#: cogs/command_error.py:34 -#, python-brace-format -msgid "{ctx.bot.user.name}#{ctx.bot.user.discriminator} open-source project" -msgstr "{ctx.bot.user.name}#{ctx.bot.user.discriminator} projet open-source" - -#: cogs/command_error.py:51 -#, python-brace-format -msgid "" -"You can't execute this command in <#{ctx.channel.id}>. Try in one of these " -"channels :\n" -"\n" -msgstr "" -"Vous ne pouvez pas exécuter cette commande dans <#{ctx.channel.id}>. Essayez " -"dans l'un de ces salons :\n" -"\n" - -#: cogs/command_error.py:55 -msgid "" -"You can't execute this command, you need one of these roles :\n" -"\n" -msgstr "" -"Vous ne pouvez pas exécuter cette commande, vous devez avoir l'un de ces " -"rôles :\n" -"\n" - -#: cogs/command_error.py:59 -msgid "" -"You send an invalid link/code, or the game cannot be joined anymore, or the " -"game doesn't exist !" -msgstr "" -"Vous avez envoyé un lien/code invalide, ou la partie ne peut plus être " -"rejointe, ou la partie n'existe pas !" - -#: cogs/command_error.py:61 -msgid "This clash is already published !" -msgstr "Ce clash a déjà été publié !" - -#: cogs/command_error.py:66 -msgid "A required argument is missing in the command !\n" -msgstr "Il manque un argument obligatoire dans la commande !\n" - -#: cogs/command_error.py:70 -msgid "This command must be executed in Private Messages" -msgstr "Cette commande doit être exécutée en messages privés" - -#: cogs/command_error.py:75 -msgid "That query didn't provide enough results." -msgstr "Cette recherche n'a pas donné assez de résultats." - -#: cogs/command_error.py:82 -msgid "" -"There is no public coc started at the moment. Try again in a few seconds or " -"go to https://www.codingame.com/multiplayer/clashofcode and click \"Join a " -"clash\"." -msgstr "" -"Il n\\'y a pas de coc public commencé pour le moment. Réessayez dans " -"quelques secondes ou rendez-vous sur https://www.codingame.com/multiplayer/" -"clashofcode et cliquez \"Rejoindre un clash\"." - -#: cogs/doc.py:19 -msgid "" -"Shows 4 or fewer links referring to a documentation on readthedocs.io :D" -msgstr "" -"Affiche 4 liens ou moins renvoyant à une documentation sur readthedocs.io :D" - -#: cogs/doc.py:35 -msgid "{} Results (click here for a complete search)" -msgstr "{} Résultats (cliquer ici pour des résultats complets)" - -#: cogs/doc.py:47 -#, python-brace-format -msgid "Results for query **{0}** and documentation **{1}**" -msgstr "Résultats pour la recherche **{0}** et la documentation **{1}**" - -#: cogs/event.py:57 -msgid "There is no event right now, sorry !" -msgstr "Il n'y a pas d'évènement actuellement, désolé !" - -#: cogs/event.py:72 -msgid "The event is ended, sorry !" -msgstr "L'évènement est terminé, désolé !" - -#: cogs/event.py:88 -msgid "Participate or get informations about an event." -msgstr "Participer ou obtenir des informations sur un évènement." - -#: cogs/event.py:97 -msgid "Use of /event" -msgstr "Utilisation de /event" - -#: cogs/event.py:174 -msgid "Participate to the contest !" -msgstr "Participez au concours !" - -#: cogs/event.py:187 -msgid "" -"Your message must contains a block of code (with code language) ! *look `/" -"tag discord markdown`*" -msgstr "" -"Votre message doit contenir un bloque de code (avec le code du langage) ! " -"*Regardez `/tag discord code block`*" - -#: cogs/event.py:191 -msgid "" -"Looks like your code is too long! Try to remove the useless parts, the goal " -"is to have a short and optimized code!" -msgstr "" -"On dirait que votre code est trop long ! Essayez de supprimer les parties " -"inutiles, le but est d'avoir un code court et optimisé !" - -#: cogs/event.py:195 -msgid "Your language seems not be valid for the event." -msgstr "Votre langage ne semple pas être valide pour l'évènement." - -#: cogs/event.py:205 -msgid "" -"**This is your participation :**\n" -"\n" -msgstr "" -"**Voici votre participation :**\n" -"\n" - -#: cogs/event.py:206 -#, python-brace-format -msgid "`Language` -> `{0}` ({1})\n" -msgstr "`Langage` -> `{0}` ({1})\n" - -#: cogs/event.py:207 -#, python-brace-format -msgid "`Length` -> `{0}`\n" -msgstr "`Longueur` -> `{0}`\n" - -#: cogs/event.py:209 -msgid "Do you want ot post it ? ✅ ❌" -msgstr "Voulez-vous l'envoyer ? ✅ ❌" - -#: cogs/event.py:220 -msgid " Your code is passing some tests..." -msgstr "" -" Votre code est en train de faire quelques " -"tests…" - -#: cogs/event.py:231 cogs/help.py:22 cogs/miscellaneous.py:116 -msgid "An error occurred." -msgstr "Une erreur est survenue." - -#: cogs/event.py:234 -msgid "Your code excited with an error." -msgstr "Votre code s'est arrêté avec une erreur." - -#: cogs/event.py:243 -msgid "" -"Your code didn't pass all the tests. If you think it's an error, please " -"contact a staff." -msgstr "" -"Votre code n'a pas passé tout les tests. Si vous pensez qu'il s'agit d'une " -"erreur, veuillez contacter un staff." - -#: cogs/event.py:259 -msgid "All tests passed successfully." -msgstr "Tout les tests ont été passés avec succès." - -#: cogs/event.py:277 -msgid "Your entry has been successfully modified !" -msgstr "Votre participation a été modifiée avec succès !" - -#: cogs/event.py:280 -msgid "Your entry has been successfully sent !" -msgstr "Votre participation a été envoyée avec succès !" - -#: cogs/event.py:285 -msgid "Cancelled" -msgstr "Annulé" - -#: cogs/event.py:290 -msgid "Remove your participation from the contest" -msgstr "Retirer votre participation du concours" - -#: cogs/event.py:301 -msgid "You didn't participate !" -msgstr "Vous n'avez pas participé !" - -#: cogs/event.py:310 -msgid "__Choose which participation you want to cancel :__\n" -msgstr "__Choisissez quel participation vous souhaitez annuler :__\n" - -#: cogs/event.py:327 -msgid "Your participation has been successfully deleted" -msgstr "Votre participation a été supprimée avec succès" - -#: cogs/event.py:331 -msgid "Get some stats about the current contest" -msgstr "Obtenir quelques statistiques a propos du concours actuel" - -#: cogs/event.py:342 -msgid "There is no participation at the moment." -msgstr "Il n'y a aucune participation pour le moment." - -#: cogs/event.py:345 -msgid "Some informations..." -msgstr "Quelques informations..." - -#: cogs/event.py:347 -msgid "**Number of participations :** {}\n" -msgstr "**Nombre de participations :**{}\n" - -#: cogs/event.py:348 -msgid "" -"**Number of unique participations :** {}\n" -"\\u200b" -msgstr "" -"**Nombre de participatants uniques :**{}\n" -"\\u200b" - -#: cogs/event.py:355 -msgid "• Global ranking : **{}** *({} > you > {})*\n" -msgstr "• Classement global : **{}** *({} > vous > {})*\n" - -#: cogs/event.py:357 cogs/event.py:358 cogs/event.py:363 cogs/event.py:364 -msgid "nobody" -msgstr "personne" - -#: cogs/event.py:361 -msgid "• By language ranking : **{}** *({} > you > {})*" -msgstr "• Classement par langage : **{}** *({} > vous > {})*" - -#: cogs/event.py:367 -msgid "**Your participation with {} :**" -msgstr "**Votre participation avec {} :**" - -#: cogs/event.py:374 -msgid "Breakdown by languages used." -msgstr "Répartition par langages utilisés." - -#: cogs/event.py:375 -msgid "Number of participations" -msgstr "Nombre de participations" - -#: cogs/event.py:376 -msgid "Number of characters" -msgstr "Nombre de caractères" - -#: cogs/google_it.py:20 -msgid "Show how to do a google search :D" -msgstr "Montrer comment faire une recherche google ! :D" - -#: cogs/google_it.py:28 -msgid "The google tool is very powerful, see how it works!\n" -msgstr "L'outil google est très puissant, voici comment il fonctionne!\n" - -#: cogs/help.py:13 -msgid "Show bot commands." -msgstr "Afficher les commandes du bot." - -#: cogs/help.py:32 -msgid "Here are my commands:" -msgstr "Voice mes commandes :" - -#: cogs/help.py:56 -#, python-brace-format -msgid "The command {string} way not found." -msgstr "La commande {string} n'a pas été trouvée." - -#: cogs/lines.py:18 -msgid "Add the lines number to your code." -msgstr "Ajoute le numéro des lignes au code." - -#: cogs/lines.py:26 -msgid "" -"Your message must contains a block of code ! *look `/tag discord code block`*" -msgstr "" -"Votre message doit contenir un bloque de code ! *Regardez `/tag discord code " -"block`*" - -#: cogs/lines.py:32 -#, python-brace-format -msgid "Numbered code of {ctx.author} :\n" -msgstr "Code numéroté de {ctx.author} : \n" - -#: cogs/miscellaneous.py:86 -msgid "What's the programmation language ?\n" -msgstr "Quel est le langage de programmation ?\n" - -#: cogs/miscellaneous.py:87 -msgid "" -"Click on the correspondant reaction, or send a message with the extension (`." -"js`, `.py`...)\n" -"\n" -msgstr "" -"Cliquez sur la réaction correspondante, ou envoyez un message avec " -"l'extension (`.js`, `.py`...)\n" -"\n" - -#: cogs/miscellaneous.py:120 cogs/miscellaneous.py:122 -msgid "A gist has been created :\n" -msgstr "Un gist a été créé :\n" - -#: cogs/miscellaneous.py:156 -#, python-brace-format -msgid "**{message.author.mention} you just sent a valid bot token.**\n" -msgstr "" -"**{message.author.mention} vous venez d'envoyer un token de bot valide.**\n" - -#: cogs/miscellaneous.py:157 -msgid "" -"This one will be revoked, but be careful and check that it has been " -"successfully reset on the **dev portal** (https://discord.com/developers/" -"applications/{}).\n" -msgstr "" -"Celui-ci va être révoqué, mais faites tout de même attention et vérifiez " -"qu'il ai bien été réinitialisé sur le **portail dev** (https://discord.com/" -"developers/applications/{}).\n" - -#: cogs/miscellaneous.py:176 -#, python-brace-format -msgid "" -"{message.author.mention} you just sent a valid **user token**.\n" -"**What is it? ** This is a kind of password that allows access to a " -"contentious account without a username, password or IP address " -"verification.\n" -"**Change your password as a precaution**.\n" -"We also recommend that you enable**two-factor authentication, or 2FA.** " -"(settings)\n" -msgstr "" -"{message.author.mention} vous venez d’envoyer un token d’utilisateur " -"valide.\n" -"**C’est quoi ?** C’est une sorte de mot de passe qui permet d’accéder à un " -"compte discord sans identifiant ni mot de passe ou encore vérification " -"d’adresse IP.\n" -"**Changez votre mot de passe par précaution**.\n" -"Nous vous conseillons aussi d’activer l'**authentification à deux facteurs, " -"ou A2F.** (paramètres)\n" - -#: cogs/tag.py:64 -msgid "Send redundant help messages." -msgstr "Envoyer les messages d'aides répétitifs." - -#: cogs/tag.py:83 -msgid "Category not found. Try among :" -msgstr "Catégorie non trouvée. Essayez parmi :" - -#: cogs/tag.py:99 -#, python-brace-format -msgid "Here are the tags from the `{0}` category :" -msgstr "Voice les tags de la catégorie `{0}` :" - -#: cogs/tag.py:116 -#, python-brace-format -msgid "do you mean `{0}` ? Otherwise " -msgstr "voulez-vous dire `{0}` ? Sinon " - -#: cogs/tag.py:117 -#, python-brace-format -msgid "Tag not found, {0}look `/tag list`" -msgstr "Le tag n'a pas été trouvé, {0}look `/tag list`" - -#: cogs/tag.py:127 -msgid "__Choose the target :__\n" -msgstr "__Choisissez la cible :__\n" - -#~ msgid "Shows a documentation for discord.js or discord.py :D" -#~ msgstr "Affiche une documentation pour discord.js ou discord.py :D" - -#~ msgid "{}/en/stable/search.html?q={query}" -#~ msgstr "{}/en/stable/search.html?q={query}" - -#~ msgid "This is the api reference for {}!\n" -#~ msgstr "Ceci est la référence de l'API pour {}!\n" - -#~ msgid "Your global position :" -#~ msgstr "Votre position globale :" - -#~ msgid "Shortest participation (not tested) :" -#~ msgstr "La participation la plus courte (non testée) :" - -#~ msgid "An error occurred" -#~ msgstr "Une erreur est survenue." - -#, python-brace-format -#~ msgid "Hum, it looks like you're english {ctx.author}" -#~ msgstr "Hum, on dirait que tu es français {ctx.author}" - -#~ msgid "hello" -#~ msgstr "bonjour" - -#~ msgid "bonjour" -#~ msgstr "bonjour" diff --git a/src/utils/__init__.py b/src/utils/__init__.py index e69de29..534b644 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -0,0 +1,10 @@ +from discord import Color + + +class ExtendedColor(Color): + @classmethod + def grey_embed(cls): + return cls(0x2F3136) + + def to_matplotlib(self, a: float = 1) -> tuple[float, float, float, float]: + return self.r / 255, self.g / 255, self.b / 255, a diff --git a/src/utils/api/__init__.py b/src/utils/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/codingame.py b/src/utils/api/codingame.py similarity index 100% rename from src/utils/codingame.py rename to src/utils/api/codingame.py diff --git a/src/utils/gist.py b/src/utils/api/gist.py similarity index 100% rename from src/utils/gist.py rename to src/utils/api/gist.py diff --git a/src/utils/api/piston.py b/src/utils/api/piston.py new file mode 100644 index 0000000..17c8331 --- /dev/null +++ b/src/utils/api/piston.py @@ -0,0 +1,23 @@ +from typing import Optional + +import aiohttp + +# TODO : fix annotations + + +async def execute_piston_code( + language: str, version: str, files: list, *, stdin: Optional[list] = None, args: Optional[list] = None +) -> dict: + url = "https://emkc.org/api/v2/piston/execute" + payload = {"language": language, "version": version, "files": files} + if stdin: + payload["stdin"] = stdin + if args: + payload["args"] = args + + async with aiohttp.ClientSession() as session: + async with session.post(url=url, json=payload) as response: + json_response: dict = await response.json() + if response.status == 200: + return json_response["run"] + raise Exception(json_response.get("message", "unknown error")) diff --git a/src/utils/checkers.py b/src/utils/checkers.py deleted file mode 100644 index 24a2d83..0000000 --- a/src/utils/checkers.py +++ /dev/null @@ -1,49 +0,0 @@ -from typing import Union - -import discord -from discord.ext import commands -from discord.ext.commands import check - -from . import custom_errors -from .constants import BUG_CENTER_ID, STAFF_ROLES, AUTHORIZED_CHANNELS_IDS -from main import HelpCenterBot - - -def authorized_channels_check(ctx: Union[discord.ApplicationCommandInteraction, commands.Context]) -> bool: - target = ctx.channel.id - if isinstance(ctx.channel, discord.Thread): - target = ctx.channel.parent_id - - if target in AUTHORIZED_CHANNELS_IDS: - return True - - raise custom_errors.NotAuthorizedChannels(AUTHORIZED_CHANNELS_IDS) - - -def authorized_channels(): - return check(authorized_channels_check) - - -def is_high_staff_check(bot: HelpCenterBot, user: Union[discord.Member, discord.User]) -> tuple[bool, list[int]]: - assert (tmp := bot.get_guild(BUG_CENTER_ID)) - bug_center: discord.Guild = tmp - - if isinstance(user, discord.User): - assert (tmp := bug_center.get_member(user.id)) - member: discord.Member = tmp - else: - member = user - - allowed_roles_ids: list[int] = [value for (key, value) in STAFF_ROLES.items() if key in ('administrator', 'assistant', 'screening')] - - return bool(discord.utils.find(lambda r: r.id in allowed_roles_ids, member.roles)) or member.guild_permissions.administrator, allowed_roles_ids - - -def is_high_staff(): - async def inner(ctx: Union[discord.ApplicationCommandInteraction, commands.Context]): - result, list_ids = is_high_staff_check(ctx.bot, ctx.author) # type: ignore - if result: - return True - raise custom_errors.NotAuthorizedRoles(list_ids) - - return check(inner) diff --git a/src/utils/custom_command_tree.py b/src/utils/custom_command_tree.py index d64967b..5474276 100644 --- a/src/utils/custom_command_tree.py +++ b/src/utils/custom_command_tree.py @@ -1,30 +1,28 @@ -from typing import Optional, TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Optional import discord + # from discord.ext import commands from discord.app_commands import ( - ContextMenu, - Command, AppCommandError, - CommandTree, - CommandInvokeError, CheckFailure, - CommandNotFound + Command, + CommandInvokeError, + CommandNotFound, + CommandTree, + ContextMenu, ) from utils import custom_errors as custom -# from .utils.codingame import NoPendingCOC -# from .utils.misc import Color -from utils.i18n import _ if TYPE_CHECKING: from main import HelpCenterBot # , Context -class CustomCommandTree(CommandTree): - def __init__(self, bot: 'HelpCenterBot') -> None: +class CustomCommandTree(CommandTree[HelpCenterBot]): + def __init__(self, bot: HelpCenterBot) -> None: """Handle error for the bot commands.""" - self.bot = bot + self.bot: HelpCenterBot = bot super().__init__(bot) @staticmethod @@ -49,7 +47,9 @@ async def send_error(inter: discord.Interaction, error_message: str): # return await ctx.send(embed=embed, delete_after=10) - async def on_error(self, inter: discord.Interaction, command: ContextMenu | Command[Any, (...), Any], error: AppCommandError) -> Optional[discord.Message]: + async def on_error( + self, interaction: discord.Interaction, command: ContextMenu | Command[Any, (...), Any], error: AppCommandError + ) -> Optional[discord.Message]: """Function called when a command raise an error.""" if isinstance(error, CommandNotFound): @@ -58,12 +58,18 @@ async def on_error(self, inter: discord.Interaction, command: ContextMenu | Comm # Custom errors : if isinstance(error, custom.NotAuthorizedChannels): - formatted_text = (_("You can't execute this command in <#{inter.channel.id}>. Try in one of these channels :\n\n", inter).format(**locals()) + - f"<#{'>, <#'.join(str(channel_id) for channel_id in error.list_channels_id)}>") + formatted_text = ( + _( + "You can't execute this command in <#{inter.channel.id}>. Try in one of these channels :\n\n", inter + ).format(**locals()) + + f"<#{'>, <#'.join(str(channel_id) for channel_id in error.list_channels_id)}>" + ) return await self.send_error(inter, formatted_text) if isinstance(error, custom.NotAuthorizedRoles): - formatted_text = (_("You can't execute this command, you need one of these roles :\n\n", inter).format(**locals()) + - f"<@&{'>, <@&'.join(str(role_id) for role_id in error.list_roles_id)}>") + formatted_text = ( + _("You can't execute this command, you need one of these roles :\n\n", inter).format(**locals()) + + f"<@&{'>, <@&'.join(str(role_id) for role_id in error.list_roles_id)}>" + ) return await self.send_error(inter, formatted_text) # if isinstance(error, custom.COCLinkNotValid): # return await self.send_error(inter, _("You send an invalid link/code, or the game cannot be joined anymore, or the game doesn't exist !")) diff --git a/src/utils/i18n.py b/src/utils/i18n.py deleted file mode 100644 index 1272617..0000000 --- a/src/utils/i18n.py +++ /dev/null @@ -1,53 +0,0 @@ -# i18n for discord bot, source here : -# https://github.com/XuaTheGrate/i18n/blob/master/i18n.py - -import gettext -import os.path -from glob import glob -from typing import Optional - -import discord - -BASE_DIR = "ressources/" # change this if you store your files under `src/` or similar -LOCALE_DEFAULT = 'en-US' -LOCALE_DIR = "locale" -locales = frozenset(map(os.path.basename, filter(os.path.isdir, glob(os.path.join(BASE_DIR, LOCALE_DIR, '*'))))) - - -gettext_translations = { - locale: gettext.translation( - 'help_center', - languages=(locale,), - localedir=os.path.join(BASE_DIR, LOCALE_DIR)) - for locale in locales} - -gettext_translations['en-US'] = gettext.NullTranslations() -locales |= {'en-US'} - -cached_users_locals = {} - - -def get_translation(message: str, target: Optional[discord.User | discord.Member | discord.Interaction] = None): - if not target: - locale = LOCALE_DEFAULT - elif isinstance(target, discord.User) or isinstance(target, discord.Member): - if cached_users_locals.get(target.id): - locale = cached_users_locals[target.id] - else: - locale = LOCALE_DEFAULT - else: - locale = target.locale.value - cached_users_locals[target.user.id] = locale - - if not gettext_translations: - return gettext.gettext(message) - - return ( - gettext_translations.get( - locale, - gettext_translations[LOCALE_DEFAULT] - ).gettext(message) - ) - - -_ = get_translation diff --git a/src/utils/misc.py b/src/utils/misc.py deleted file mode 100644 index 764d76f..0000000 --- a/src/utils/misc.py +++ /dev/null @@ -1,109 +0,0 @@ -import asyncio -from typing import Union, Iterable, TYPE_CHECKING - -from schema import Schema, Or, And, Use, Optional, Regex -import discord - -if TYPE_CHECKING: - from main import HelpCenterBot - from .types import Person - -text_or_list = Schema(Or(str, And(list, Use('\n'.join)))) - -embed_schema = Schema({ - 'title': str, - 'description': text_or_list, - Optional('image'): { - 'url': str - }, - Optional('fields'): [ - { - 'name': str, - 'value': text_or_list, - Optional('inline'): bool - } - ] -}) - -inner_tag_schema = Schema({ - Optional('lang'): Regex(r'[a-z]{2}_[A-Z]{2}'), - 'name': str, - Optional('aliases'): list, - 'description': str, - 'response': Or({'embed': embed_schema}, { - 'choices': [ - { - "choice_name": str, - "embed": embed_schema - } - ] - }) -}) - -tag_schema = Schema(Or([inner_tag_schema], inner_tag_schema)) - - -async def add_reactions(message: discord.Message, reactions: Iterable[Union[discord.Emoji, discord.PartialEmoji, str]]) -> None: - for react in reactions: - await message.add_reaction(react) - - -async def delete_with_emote(bot: 'HelpCenterBot', author: 'Person', message: discord.Message) -> None: - assert bot.user is not None, "Bot must be logged out to use this function." - - await message.add_reaction("🗑️") - - try: - await bot.wait_for("reaction_add", timeout=120, - check=lambda react, usr: str(react.emoji) == "🗑️" and react.message.id == message.id and usr.id == author.id) - except asyncio.TimeoutError: - try: - await message.remove_reaction("🗑️", bot.user) - except discord.HTTPException: - pass - return - try: - await message.delete() - except discord.HTTPException: - pass - - -class Color: - def __init__(self, r: int, g: int, b: int, a: int = 1) -> None: - """Represent a Color object with pre-done colors that can be used as discord.Color etc...""" - self.r = r - self.g = g - self.b = b - self.a = a - - @classmethod - def black(cls): - return cls(0, 0, 0) - - @classmethod - def grey_embed(cls): - return cls(47, 49, 54) - - @classmethod - def green(cls): - return cls(87, 242, 135) - - @classmethod - def red(cls): - return cls(237, 66, 69) - - @classmethod - def yellow(cls): - return cls(254, 231, 92) - - @property - def mpl(self): # matplotlib - return self.r / 255, self.g / 255, self.b / 255, self.a - - @property - def discord(self): - return discord.Color.from_rgb(self.r, self.g, self.b) - - @property - def rgb(self): - return self.r, self.g, self.b diff --git a/src/utils/piston.py b/src/utils/piston.py deleted file mode 100644 index d515be4..0000000 --- a/src/utils/piston.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Optional - -import aiohttp - - -async def execute_piston_code(language: str, version: str, files: list, *, stdin: Optional[list] = None, args: Optional[list] = None) -> dict: - url = "https://emkc.org/api/v2/piston/execute" - payload = { - 'language': language, - 'version': version, - 'files': files - } - if stdin: - payload['stdin'] = stdin - if args: - payload['args'] = args - - async with aiohttp.ClientSession() as session: - async with session.post(url=url, json=payload) as response: - json_response: dict = await response.json() - if response.status == 200: - return json_response['run'] - raise Exception(json_response.get('message', 'unknown error')) diff --git a/src/utils/types.py b/src/utils/types.py index 16de190..c1c8c6f 100644 --- a/src/utils/types.py +++ b/src/utils/types.py @@ -1,10 +1,6 @@ from typing import Union -from discord import User, Member -from discord.ext.commands import Context as Ctx - -from main import HelpCenterBot +from discord import Member, User Person = Union[User, Member] Snowflake = int -Context = Ctx[HelpCenterBot]