diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 78cface..b626dae 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -7,5 +7,6 @@
+
\ No newline at end of file
diff --git a/setup.cfg b/setup.cfg
index 0a7cf8f..1dcefd4 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -24,6 +24,7 @@ install_requires =
jishaku @ git+https://github.com/Gorialis/jishaku
psutil==5.7.2
pydig==0.3.0
+ ralgo @ git+https://github.com/Rom1-J/ralgo
rich==9.10.0
sentry_sdk>=0.20.2
structured_config==4.12
diff --git a/tuxbot/cogs/Crypto/__init__.py b/tuxbot/cogs/Crypto/__init__.py
new file mode 100644
index 0000000..0c2f110
--- /dev/null
+++ b/tuxbot/cogs/Crypto/__init__.py
@@ -0,0 +1,19 @@
+from collections import namedtuple
+
+from tuxbot.core.bot import Tux
+from .crypto import Crypto
+from .config import CryptoConfig, HAS_MODELS
+
+VersionInfo = namedtuple("VersionInfo", "major minor micro release_level")
+version_info = VersionInfo(major=1, minor=0, micro=0, release_level="alpha")
+
+__version__ = "v{}.{}.{}-{}".format(
+ version_info.major,
+ version_info.minor,
+ version_info.micro,
+ version_info.release_level,
+).replace("\n", "")
+
+
+def setup(bot: Tux):
+ bot.add_cog(Crypto(bot))
diff --git a/tuxbot/cogs/Crypto/config.py b/tuxbot/cogs/Crypto/config.py
new file mode 100644
index 0000000..1fdee5c
--- /dev/null
+++ b/tuxbot/cogs/Crypto/config.py
@@ -0,0 +1,10 @@
+from structured_config import Structure
+
+HAS_MODELS = False
+
+
+class CryptoConfig(Structure):
+ pass
+
+
+extra = {}
diff --git a/tuxbot/cogs/Crypto/crypto.py b/tuxbot/cogs/Crypto/crypto.py
new file mode 100644
index 0000000..74d7dc4
--- /dev/null
+++ b/tuxbot/cogs/Crypto/crypto.py
@@ -0,0 +1,79 @@
+import logging
+from io import BytesIO
+
+import discord
+from discord.ext import commands
+from ralgo.ralgo import Ralgo
+
+from tuxbot.cogs.Crypto.functions.extractor import extract
+from tuxbot.cogs.Crypto.functions.file import find_ext
+from tuxbot.core.bot import Tux
+from tuxbot.core.i18n import (
+ Translator,
+)
+from tuxbot.core.utils.functions.extra import group_extra, ContextPlus
+
+
+log = logging.getLogger("tuxbot.cogs.Crypto")
+_ = Translator("Crypto", __file__)
+
+
+class Crypto(commands.Cog, name="Crypto"):
+ def __init__(self, bot: Tux):
+ self.bot = bot
+
+ @group_extra(name="ralgo")
+ async def _ralgo(self, ctx: commands.Context):
+ if ctx.invoked_subcommand is None:
+ await ctx.send_help("ralgo")
+
+ @_ralgo.command(name="encode")
+ async def _ralgo_encode(self, ctx: ContextPlus, *, data: str = None):
+ try:
+ params = await extract(ctx.message.attachments, data, 100000)
+ except ValueError:
+ return await ctx.send("Invalid data provided")
+
+ statement = Ralgo(params["message"])
+ params = params["params"]
+ encoded = statement.encode(chars=params["chars"])
+
+ if params["compressed"]:
+ return await ctx.send(str(encoded.compress()))
+ if params["graphical"]:
+ output = encoded.graphical().encode()
+ file = discord.File(BytesIO(output.to_bytes()), "output.png")
+
+ return await ctx.send(file=file)
+
+ await ctx.send(str(encoded))
+
+ @_ralgo.command(name="decode")
+ async def _ralgo_decode(self, ctx: ContextPlus, *, data: str = None):
+ try:
+ params = await extract(ctx.message.attachments, data, 5000000)
+ except ValueError:
+ return await ctx.send("Invalid data provided")
+
+ statement = Ralgo(params["message"])
+ params = params["params"]
+
+ if params["graphical"]:
+ output = Ralgo(statement.graphical().decode()).decode()
+
+ output = discord.utils.escape_markdown(str(output))
+ output = discord.utils.escape_mentions(output)
+ elif params["compressed"]:
+ output = Ralgo(statement.decompress()).decode()
+ else:
+ output = statement.decode(chars=params["chars"])
+
+ if isinstance(output, bytes):
+ file = discord.File(BytesIO(output), f"output.{find_ext(output)}")
+
+ return await ctx.send(file=file)
+
+ output = discord.utils.escape_markdown(str(output))
+ output = discord.utils.escape_mentions(output)
+
+ await ctx.send(output if len(output) > 0 else "no content...")
diff --git a/tuxbot/cogs/Crypto/functions/extractor.py b/tuxbot/cogs/Crypto/functions/extractor.py
new file mode 100644
index 0000000..cef67f3
--- /dev/null
+++ b/tuxbot/cogs/Crypto/functions/extractor.py
@@ -0,0 +1,28 @@
+from typing import Optional, NoReturn, Union
+
+from discord import Attachment
+from tuxbot.cogs.Crypto.functions.parser import data_parser
+
+
+async def extract(
+ attachments: list[Optional[Attachment]], data: str, max_size: int
+) -> Union[dict, NoReturn]:
+ if not data and len(attachments) == 0:
+ raise ValueError
+
+ kwargs = data_parser(data)
+
+ if len(attachments) > 0:
+ file = attachments[0]
+ if file.size > max_size:
+ raise ValueError
+
+ kwargs["message"] = await file.read()
+
+ params = {
+ "compressed": "compressed" in kwargs.keys(),
+ "graphical": "graphical" in kwargs.keys(),
+ "chars": kwargs["chars"] if "chars" in kwargs.keys() else (".", ","),
+ }
+
+ return {"message": kwargs["message"], "params": params}
diff --git a/tuxbot/cogs/Crypto/functions/file.py b/tuxbot/cogs/Crypto/functions/file.py
new file mode 100644
index 0000000..3759262
--- /dev/null
+++ b/tuxbot/cogs/Crypto/functions/file.py
@@ -0,0 +1,10 @@
+# https://python-forum.io/Thread-read-a-binary-file-to-find-its-type
+def find_ext(content: bytes) -> str:
+ magic_numbers = {
+ 'png': bytes([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])
+ }
+
+ if content.startswith(magic_numbers["png"]):
+ return "png"
+
+ return "txt"
diff --git a/tuxbot/cogs/Crypto/functions/parser.py b/tuxbot/cogs/Crypto/functions/parser.py
new file mode 100644
index 0000000..5be0585
--- /dev/null
+++ b/tuxbot/cogs/Crypto/functions/parser.py
@@ -0,0 +1,32 @@
+import re
+
+
+def data_parser(data: str) -> dict:
+ output = {
+ "message": None,
+ }
+
+ if not data:
+ return output
+
+ if "--compressed" in data:
+ output["compressed"] = True
+ data = "".join(data.rsplit("--compressed", 1))
+
+ if "--graphical" in data:
+ output["graphical"] = True
+ data = "".join(data.rsplit("--graphical", 1))
+
+ if "compressed" in output.keys():
+ del output["compressed"]
+
+ if "--chars" in data:
+ regex = r"--chars=(\S\S)"
+ match = re.search(regex, data)
+
+ output["chars"] = tuple(match.group()[-2:])
+ data = "".join(data.rsplit(match.group(), 1))
+
+ output["message"] = data.strip()
+
+ return output
diff --git a/tuxbot/cogs/Crypto/locales/en-US.po b/tuxbot/cogs/Crypto/locales/en-US.po
new file mode 100644
index 0000000..dec6d18
--- /dev/null
+++ b/tuxbot/cogs/Crypto/locales/en-US.po
@@ -0,0 +1,57 @@
+# French translations for Tuxbot-bot package
+# Traductions françaises du paquet Tuxbot-bot.
+# Copyright (C) 2020 THE Tuxbot-bot'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the Tuxbot-bot package.
+# Automatically generated, 2020.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Tuxbot-bot\n"
+"Report-Msgid-Bugs-To: rick@gnous.eu\n"
+"POT-Creation-Date: 2020-10-21 01:15+0200\n"
+"PO-Revision-Date: 2020-10-21 01:15+0200\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: en_US\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: tuxbot/cogs/Polls/polls.py:55 tuxbot/cogs/Polls/polls.py:176
+msgid "**Preparation**"
+msgstr ""
+
+#: tuxbot/cogs/Polls/polls.py:204
+#, python-brace-format
+msgid "Proposed addition for poll #{id}"
+msgstr ""
+
+#: tuxbot/cogs/Polls/polls.py:209
+msgid "Poll"
+msgstr ""
+
+#: tuxbot/cogs/Polls/polls.py:211
+msgid "here"
+msgstr ""
+
+#: tuxbot/cogs/Polls/polls.py:215
+#, python-brace-format
+msgid "Requested by {author}"
+msgstr ""
+
+#: tuxbot/cogs/Polls/functions/converters.py:21
+#: tuxbot/cogs/Polls/functions/converters.py:49
+msgid "Please provide a message in this channel"
+msgstr ""
+
+#: tuxbot/cogs/Polls/functions/converters.py:30
+#: tuxbot/cogs/Polls/functions/converters.py:36
+#: tuxbot/cogs/Polls/functions/converters.py:41
+#: tuxbot/cogs/Polls/functions/converters.py:46
+msgid "Unable to find this poll"
+msgstr ""
+
+#: tuxbot/cogs/Polls/functions/converters.py:58
+msgid "Your proposal must be smaller than 30"
+msgstr ""
diff --git a/tuxbot/cogs/Crypto/locales/fr-FR.po b/tuxbot/cogs/Crypto/locales/fr-FR.po
new file mode 100644
index 0000000..a9be5d3
--- /dev/null
+++ b/tuxbot/cogs/Crypto/locales/fr-FR.po
@@ -0,0 +1,58 @@
+# French translations for Tuxbot-bot package
+# Traductions françaises du paquet Tuxbot-bot.
+# Copyright (C) 2020 THE Tuxbot-bot'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the Tuxbot-bot package.
+# Automatically generated, 2020.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Tuxbot-bot\n"
+"Report-Msgid-Bugs-To: rick@gnous.eu\n"
+"POT-Creation-Date: 2020-10-21 01:15+0200\n"
+"PO-Revision-Date: 2020-10-21 01:15+0200\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: tuxbot/cogs/Polls/polls.py:55 tuxbot/cogs/Polls/polls.py:176
+msgid "**Preparation**"
+msgstr "**Préparation**"
+
+#: tuxbot/cogs/Polls/polls.py:204
+#, python-brace-format
+msgid "Proposed addition for poll #{id}"
+msgstr "Proposition d'ajout pour le sondage #{id}"
+
+#: tuxbot/cogs/Polls/polls.py:209
+msgid "Poll"
+msgstr "Sondage"
+
+#: tuxbot/cogs/Polls/polls.py:211
+msgid "here"
+msgstr "ici"
+
+#: tuxbot/cogs/Polls/polls.py:215
+#, python-brace-format
+msgid "Requested by {author}"
+msgstr "Demandée par {author}"
+
+#: tuxbot/cogs/Polls/functions/converters.py:21
+#: tuxbot/cogs/Polls/functions/converters.py:49
+msgid "Please provide a message in this channel"
+msgstr "Veuillez fournir un message dans ce salon"
+
+#: tuxbot/cogs/Polls/functions/converters.py:30
+#: tuxbot/cogs/Polls/functions/converters.py:36
+#: tuxbot/cogs/Polls/functions/converters.py:41
+#: tuxbot/cogs/Polls/functions/converters.py:46
+msgid "Unable to find this poll"
+msgstr "Impossible de trouver ce sondage"
+
+#: tuxbot/cogs/Polls/functions/converters.py:58
+msgid "Your proposal must be smaller than 30"
+msgstr "Votre proposition doit être inférieure à 30"
+
diff --git a/tuxbot/cogs/Crypto/locales/messages.pot b/tuxbot/cogs/Crypto/locales/messages.pot
new file mode 100644
index 0000000..f6bd62b
--- /dev/null
+++ b/tuxbot/cogs/Crypto/locales/messages.pot
@@ -0,0 +1,56 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the Tuxbot-bot package.
+# FIRST AUTHOR , YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Tuxbot-bot\n"
+"Report-Msgid-Bugs-To: rick@gnous.eu\n"
+"POT-Creation-Date: 2021-01-26 16:12+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: tuxbot/cogs/Polls/polls.py:55 tuxbot/cogs/Polls/polls.py:176
+msgid "**Preparation**"
+msgstr ""
+
+#: tuxbot/cogs/Polls/polls.py:204
+#, python-brace-format
+msgid "Proposed addition for poll #{id}"
+msgstr ""
+
+#: tuxbot/cogs/Polls/polls.py:209
+msgid "Poll"
+msgstr ""
+
+#: tuxbot/cogs/Polls/polls.py:211
+msgid "here"
+msgstr ""
+
+#: tuxbot/cogs/Polls/polls.py:215
+#, python-brace-format
+msgid "Requested by {author}"
+msgstr ""
+
+#: tuxbot/cogs/Polls/functions/converters.py:21
+#: tuxbot/cogs/Polls/functions/converters.py:49
+msgid "Please provide a message in this channel"
+msgstr ""
+
+#: tuxbot/cogs/Polls/functions/converters.py:30
+#: tuxbot/cogs/Polls/functions/converters.py:36
+#: tuxbot/cogs/Polls/functions/converters.py:41
+#: tuxbot/cogs/Polls/functions/converters.py:46
+msgid "Unable to find this poll"
+msgstr ""
+
+#: tuxbot/cogs/Polls/functions/converters.py:58
+msgid "Your proposal must be smaller than 30"
+msgstr ""
diff --git a/tuxbot/cogs/Crypto/models/__init__.py b/tuxbot/cogs/Crypto/models/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tuxbot/cogs/Logs/logs.py b/tuxbot/cogs/Logs/logs.py
index b39da3f..1fa9a20 100644
--- a/tuxbot/cogs/Logs/logs.py
+++ b/tuxbot/cogs/Logs/logs.py
@@ -66,13 +66,14 @@ class Logs(commands.Cog, name="Logs"):
self.old_on_error = bot.on_error
bot.on_error = self.on_error
- sentry_sdk.init(
- dsn=self.__config.sentryKey,
- traces_sample_rate=1.0,
- environment=self.bot.instance_name,
- debug=False,
- attach_stacktrace=True,
- )
+ if self.bot.instance_name != "dev":
+ sentry_sdk.init(
+ dsn=self.__config.sentryKey,
+ traces_sample_rate=1.0,
+ environment=self.bot.instance_name,
+ debug=False,
+ attach_stacktrace=True,
+ )
def cog_unload(self):
self.bot.on_error = self.old_on_error
@@ -232,7 +233,8 @@ class Logs(commands.Cog, name="Logs"):
if isinstance(error, (discord.Forbidden, discord.NotFound)):
return
- sentry_sdk.capture_exception(error)
+ if self.bot.instance_name != "dev":
+ sentry_sdk.capture_exception(error)
self.bot.console.log(
"Command Error, check sentry or discord error channel"
)
@@ -273,7 +275,8 @@ class Logs(commands.Cog, name="Logs"):
e.remove_field(1)
e.remove_field(1)
- e.set_footer(text=sentry_sdk.last_event_id())
+ if self.bot.instance_name != "dev":
+ e.set_footer(text=sentry_sdk.last_event_id())
await ctx.send(embed=e)
diff --git a/tuxbot/core/bot.py b/tuxbot/core/bot.py
index f6fad32..a267849 100644
--- a/tuxbot/core/bot.py
+++ b/tuxbot/core/bot.py
@@ -42,6 +42,7 @@ packages: List[str] = [
"tuxbot.cogs.Polls",
"tuxbot.cogs.Custom",
"tuxbot.cogs.Network",
+ "tuxbot.cogs.Crypto",
]
diff --git a/tuxbot/core/utils/functions/extra.py b/tuxbot/core/utils/functions/extra.py
index c84254f..6f6bd56 100644
--- a/tuxbot/core/utils/functions/extra.py
+++ b/tuxbot/core/utils/functions/extra.py
@@ -1,5 +1,6 @@
import asyncio
import random
+from io import BytesIO
import aiohttp
import discord
@@ -23,7 +24,7 @@ class ContextPlus(commands.Context):
delete_after=None,
nonce=None,
allowed_mentions=None,
- deletable=True
+ deletable=True,
): # i know *args and **kwargs but, i prefer work with same values
from tuxbot.core.utils.functions.utils import (
replace_in_dict,
@@ -39,6 +40,10 @@ class ContextPlus(commands.Context):
)
.replace(self.bot.config.Core.ip, IP_REPLACEMENT)
)
+
+ if len(content) > 1800:
+ file = discord.File(BytesIO(content.encode()), "output.txt")
+ content = "output too long..."
if embed:
e = embed.to_dict()
for key, value in e.items():