diff --git a/README.md b/README.md index ea9fe2d..4a45049 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,8 @@ The modern all-in-one toolkit for LGBTQ+ folks Catherine-Chan is the all in one tookit for LGBTQ+ folks and allies. Catherine-Chan provides a wide varity of features, such as creating pride profiles, definitions for the LGBTQ+ community, and many others. > [!IMPORTANT] -> I would prefer if you do not run instances of Catherine-Chan. Just use the `>invite` command or use the Top.gg invite to have the bot on your server instead. The code provided is for educational use and for others to provide suggestions, catch issues, and feedback only. +> I would prefer if you do not run instances of Catherine-Chan. Just use the `/invite` command or use the Top.gg invite to have the bot on your server instead. The code provided is for educational use and for others to provide suggestions, catch issues, and feedback only. + ## Features - [x] Pronouns Tester @@ -24,12 +25,11 @@ Catherine-Chan is the all in one tookit for LGBTQ+ folks and allies. Catherine-C - [x] Resources for support - [x] ToneTags support -And so much more! If you want to suggest a feature, please open up an feature requests report on GitHub! +And so much more! If you want to suggest a feature, please open up a feature requests report on GitHub! ## Inviting the Bot -Currently Catherine-Chan is still in development, but generally should be stable enough to run. Catherine is not fully production ready so there may be bugs that need to be ironed out. - +Catherine-Chan is live! You can invite her into your server with the following link: [Invite Link](https://discord.com/oauth2/authorize?client_id=1142620675517984808&scope=bot+applications.commands) ## Support If you would like to support me as a developer, please consider supporting me on [KoFi](https://ko-fi.com/no767). The money will go towards to hosting Catherine-Chan and all other server-related costs so you can expect the bot to be up 24/7! diff --git a/bot/catherinebot.py b/bot/catherinebot.py index a71a621..0799151 100644 --- a/bot/catherinebot.py +++ b/bot/catherinebot.py @@ -26,13 +26,15 @@ TOKEN = os.environ["TOKEN"] DEV_MODE = os.getenv("DEV_MODE") in ("True", "TRUE") +ENABLE_MESSAGE_CONTENT = os.getenv("ENABLE_MESSAGE_CONTENT") in ("True", "TRUE") IPC_SECRET_KEY = os.environ["IPC_SECRET_KEY"] IPC_HOST = os.environ["IPC_HOST"] POSTGRES_URI = os.environ["POSTGRES_URI"] intents = discord.Intents.default() -intents.message_content = True +if DEV_MODE is True or ENABLE_MESSAGE_CONTENT is True: + intents.message_content = True async def main() -> None: diff --git a/bot/cogs/__init__.py b/bot/cogs/__init__.py index 030281a..ee8d1e5 100644 --- a/bot/cogs/__init__.py +++ b/bot/cogs/__init__.py @@ -13,4 +13,4 @@ def __str__(self) -> str: EXTENSIONS = [module.name for module in iter_modules(__path__, f"{__package__}.")] -VERSION: VersionInfo = VersionInfo(major=0, minor=2, micro=3, releaselevel="final") +VERSION: VersionInfo = VersionInfo(major=0, minor=2, micro=4, releaselevel="final") diff --git a/bot/cogs/meta.py b/bot/cogs/meta.py index a8da208..9b43a77 100644 --- a/bot/cogs/meta.py +++ b/bot/cogs/meta.py @@ -1,11 +1,15 @@ +import datetime +import itertools import platform import discord +import psutil +import pygit2 from catherinecore import Catherine from discord import app_commands from discord.ext import commands -from discord.utils import oauth_url -from libs.utils import human_timedelta +from discord.utils import format_dt, oauth_url +from libs.utils import Embed, human_timedelta class Meta(commands.Cog): @@ -13,12 +17,36 @@ class Meta(commands.Cog): def __init__(self, bot: Catherine) -> None: self.bot = bot + self.process = psutil.Process() def get_bot_uptime(self, *, brief: bool = False) -> str: return human_timedelta( self.bot.uptime, accuracy=None, brief=brief, suffix=False ) + def format_commit(self, commit: pygit2.Commit) -> str: + short, _, _ = commit.message.partition("\n") + short_sha2 = commit.hex[0:6] + commit_tz = datetime.timezone( + datetime.timedelta(minutes=commit.commit_time_offset) + ) + commit_time = datetime.datetime.fromtimestamp(commit.commit_time).astimezone( + commit_tz + ) + + # [`hash`](url) message (offset) + offset = format_dt(commit_time.astimezone(datetime.timezone.utc), "R") + return f"[`{short_sha2}`](https://github.com/No767/Catherine-Chan/commit/{commit.hex}) {short} ({offset})" + + def get_last_commits(self, count: int = 5): + repo = pygit2.Repository(".git") + commits = list( + itertools.islice( + repo.walk(repo.head.target, pygit2.GIT_SORT_TOPOLOGICAL), count + ) + ) + return "\n".join(self.format_commit(c) for c in commits) + @app_commands.command(name="uptime") async def uptime(self, interaction: discord.Interaction) -> None: """Displays the bot's uptime""" @@ -31,23 +59,40 @@ async def version(self, interaction: discord.Interaction) -> None: version_message = f"Version: {self.bot.version}" await interaction.response.send_message(version_message) - @app_commands.command(name="info") - async def info(self, interaction: discord.Interaction) -> None: + @app_commands.command(name="about") + async def about(self, interaction: discord.Interaction) -> None: """Shows some basic info about Catherine-Chan""" - embed = discord.Embed() - embed.title = f"{self.bot.user.name} Info" # type: ignore - embed.set_thumbnail(url=self.bot.user.display_avatar.url) # type: ignore - embed.add_field(name="Server Count", value=len(self.bot.guilds), inline=True) - embed.add_field(name="User Count", value=len(self.bot.users), inline=True) - embed.add_field( - name="Python Version", value=platform.python_version(), inline=True + total_members = 0 + total_unique = len(self.bot.users) + + for guild in self.bot.guilds: + total_members += guild.member_count or 0 + + # For Kumiko, it's done differently + # R. Danny's way of doing it is probably clos enough anyways + memory_usage = self.process.memory_full_info().uss / 1024**2 + cpu_usage = self.process.cpu_percent() / psutil.cpu_count() + + revisions = self.get_last_commits() + embed = Embed() + embed.set_author(name=self.bot.user.name, icon_url=self.bot.user.display_avatar.url) # type: ignore + embed.title = "Bot Invite" + embed.url = "https://discord.com/oauth2/authorize?client_id=1142620675517984808&scope=bot+applications.commands" + embed.description = f"Latest Changes (Stable):\n {revisions}" + embed.set_footer( + text=f"Made with discord.py v{discord.__version__}", + icon_url="https://cdn.discordapp.com/emojis/596577034537402378.png?size=128", ) + embed.add_field(name="Servers Count", value=len(self.bot.guilds)) embed.add_field( - name="Discord.py Version", value=discord.__version__, inline=True + name="User Count", value=f"{total_members} total\n{total_unique} unique" ) embed.add_field( - name="Catherine Build Version", value=str(self.bot.version), inline=True + name="Process", value=f"{memory_usage:.2f} MiB\n{cpu_usage:.2f}% CPU" ) + embed.add_field(name="Python verson", value=platform.python_version()) + embed.add_field(name="Catherine-Chan Version", value=str(self.bot.version)) + embed.add_field(name="Uptime", value=self.get_bot_uptime(brief=True)) await interaction.response.send_message(embed=embed) @app_commands.command(name="invite") diff --git a/bot/cogs/pronouns.py b/bot/cogs/pronouns.py index 986eb2c..ece38a0 100644 --- a/bot/cogs/pronouns.py +++ b/bot/cogs/pronouns.py @@ -16,7 +16,7 @@ from libs.utils import Embed from yarl import URL -APPROVAL_CHANNEL_ID = 1145189567331315803 +APPROVAL_CHANNEL_ID = 1150575176006782976 class Pronouns(commands.GroupCog, name="pronouns"): diff --git a/bot/cogs/support.py b/bot/cogs/support.py index 812cb5b..6a2f939 100644 --- a/bot/cogs/support.py +++ b/bot/cogs/support.py @@ -28,7 +28,7 @@ async def pride_servers(self, interaction: discord.Interaction) -> None: Enby_eautiful - https://discord.gg/j8MCnEC64S """ embed.set_footer( - text="If you are enjoying Catherine-Chan, please consider to tell your friends about this bot! If you can't, then you can still show your support by upvoting on Top.gg! [insert topgg link]", + text="If you are enjoying Catherine-Chan, please consider to tell your friends about this bot! If you can't, then you can still show your support by upvoting on Top.gg!", icon_url="https://cdn.discordapp.com/emojis/1096897624432443392.webp?size=128&quality=lossless", ) await interaction.response.send_message(embed=embed) diff --git a/changelog.md b/changelog.md index 449062c..8bab559 100644 --- a/changelog.md +++ b/changelog.md @@ -1,14 +1,16 @@ -# 🛠️ Catherine-Chan 0.2.3 🛠️ - -Apparently forgetting to update the prod.txt requirements... +# 🛠️ Catherine-Chan 0.2.4 🛠️ +Smaller bugfix update to fix any incosisentity ## ✨ TD;LR -- Updated prod.txt requirements +- Fixed small issues ## 🛠️ Changes -- Updated prod.txt requirements +- Renamed the `/info` command to `/about` and include more information +- Only allow `message_content` intents on development or if enabled +- Added invite links for the official bot +- Update docs as per usual ## ✨ Additions diff --git a/docs/source/index.rst b/docs/source/index.rst index 405f506..236ba2f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -42,6 +42,7 @@ Features * Pride Profile creator (create profiles to let others know about your pronouns and more) * Full pronouns.page integration * Resources for support +* ToneTags support If there is a feature that you would like to see, please either suggest it within the `Discord Server `_ or preferably make a `feature request ticket `_ on GitHub. diff --git a/docs/source/motivation.rst b/docs/source/motivation.rst index 57b418e..dad1fb9 100644 --- a/docs/source/motivation.rst +++ b/docs/source/motivation.rst @@ -3,9 +3,9 @@ Motivation This page details the motivation on why I decided to build this bot. -The main reason why I wanted to build this bot is seeing the lack of active LGBTQ+ focused bots. The biggest one I could find was Jade's PrideBot, which is currently down and has message contents issues. (gotta get that approved). And when looking up at pride bots, they all pretty much do exactly the same thing. I wanted a bot that would be useful just like Akari and Kumiko, and also be up with the latest Discord technologies and features (and general tech as well). Thus, Catherine-Chan was born. +One of the reasons why I wanted to build this bot is seeing the lack of active LGBTQ+ focused bots. The biggest one I could find was Jade's `PrideBot `_, which is currently down and has message contents issues. (gotta get that approved). And when looking up at pride bots, they all pretty much do exactly the same thing. I wanted a bot that would be useful just like Akari and Kumiko, and also be up with the latest Discord technologies and features (and general tech as well). Thus, Catherine-Chan was born. -The second bigger reason was to completely replaced Jade's `PrideBot `_ (don't think about inviting it bc it's down and has message content issues. pretty sure there are no plans to revive the bot). So, why try to replace PrideBot? I'll address my grievances in the next section. +The goal of Catherine-Chan is to completely replace Jade's `PrideBot `_ (don't think about inviting it bc it's down and has message content issues. pretty sure there are no plans to revive the bot). So, why try to replace PrideBot? I'll address my grievances in the next section. Grievances of PrideBot ^^^^^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ Grievances of PrideBot Upon reviewing the codebase of PrideBot, I found plenty of bad practices, poor programming techniques, and a very poorly maintained codebase. No documentation, just the source code. That's fine, and some libraries like ``asqlite`` don't have proper documentation. But with that bot in 100 servers, I felt like I needed to make one that would outshine PrideBot. -With PrideBot, there was multiple severe and problematic approaches to how the bot works.Here are the problematic reasoning for why PrideBot really is not the best choice for a bot: +With PrideBot, there was multiple severe and problematic approaches to how the bot works. Here are the problematic reasoning for why PrideBot really is not the best choice for a bot: 1. **PrideBot uses MongoDB** @@ -22,17 +22,17 @@ Fundamentally PrideBot uses MongoDB (with pymongo) for the database. To me, that "MongoDB is a NoSQL database that stores data as documents in BSON format. Not recommended in general as most of Discord data you are storing is relational (e.g. economy things) while mongodb is for non-relational data, hence there is no reason to use NoSQL over SQL to store relational data." - dauds -In this case, data **is** relational. One user can have one pride profile, and also have multiple suggestions for the pronouns tester. In fact, with Catherine-Chan, it's mapped out exactly like this. +In this case, data **is** relational. One user can have one pride profile, have multiple suggestions for the pronouns tester, and own multiple tonetags. In fact, with Catherine-Chan, it's mapped out exactly like this. 2. **PrideBot uses pymongo** -The major issue is that Jade, the creator of PrideBot, uses pymongo. Pymongo works fine for using Mongo for **regular synchronous** Python applications, but for async ones, this causes something called "blocking". Now, you may be wondering: What does blocking mean? For context, Python functions are ran one by one. If there is something that Function A is doing, Function B has to wait. In terms of async, when Function A just starting doing something, Function B already is working on something else. This is the basics of AsyncIO. In order to acheive asyncio, there needs to be something called the `event loop `_. When you run synchronous code, it blocks the event loop, which prevents your async functions from working. And when you spend time running queries for pymongo, **you block your whole entire bot from running**. Which essentially renders your bot useless. +The major issue is that Jade, the creator of PrideBot, uses PyMongo. Pymongo works fine for using Mongo for **regular synchronous** Python applications, but for async ones, this causes something called "blocking". Now, you may be wondering: What does blocking mean? For context, Python functions are ran one by one. If there is something that Function A is doing, Function B has to wait. In terms of async, when Function A just starting doing something, Function B already is working on something else. This is the basics of AsyncIO. In order to achieve asyncio, there needs to be something called the `event loop `_. When you run synchronous code, it blocks the event loop, which prevents your async functions from working. And when you spend time running queries for pymongo, **you block your whole entire bot from running**. Which essentially renders your bot useless. -Oh also PyMongo quite literally has `connection pooling set up on each client `_. So you are just constantly making connections and then closing them. Over and over again. And sometimes 2 or more times per command! +Oh also PyMongo quite literally has `connection pooling set up on each client `_. So you are just constantly making connections and then closing them rapidly, and sometimes multiple can be created from one command. Over and over again. And sometimes 2 or more times per command! 3. **Lack of PEP8 standards and poor code** -Jade is known to quite literally avoid PEP8 standards and do it her way because it's a "preference". In terms of a bot like this, where people aren't going to look through the source code, it's fine. But what happens is if you have other people looking through your work in order to learn (maybe bc the pridebot is their favorite or something), you end up setting a bad example for others. These people won't know what is good and bad within the Python community, so they will just copy it and when they now want to contribute to other projects, more than likely folks are going to make fun of them. +Jade is known to quite literally avoid PEP8 standards and do it her way because it's a "preference". In terms of a bot like this, where people aren't going to look through the source code, it's fine. But what happens is if you have other people looking through your work in order to learn (maybe bc the pridebot is their favorite or something), you end up setting a bad example for others. These people won't know what is good and bad within the Python community, so they will just copy it and when they now want to contribute to other projects, more than likely folk will go ahead and tell you to use PEP8 as the standard instead. This gets even worse if you are working as a team. Not only a lack of standards enables that, but the code is written extremely poorly. No standards, and full of bad practices. Let's take `this one `_ for example: @@ -65,7 +65,64 @@ Let's also take this `section of code bool: + bot: Catherine = interaction.client # type: ignore + if ( + bot.owner_id == interaction.user.id + or bot.application_id == interaction.user.id + ): + return True + + blacklisted_status = await get_or_fetch_blacklist( + bot, interaction.user.id, bot.pool + ) + if blacklisted_status is True: + await interaction.response.send_message( + f"My fellow user, {interaction.user.mention}, you are blacklisted." + ) + return False + return True + +``libs/utils/blacklist.py`` + +.. code-block:: python + + async def get_or_fetch_blacklist(bot, id: int, pool: asyncpg.Pool) -> bool: + """Gets or fetches a user's blacklist status + + Args: + bot (Catherine): The bot instance + id (int): The user's ID + pool (asyncpg.Pool): A global connection pool + + Returns: + bool: The user's blacklist status + """ + if id in bot.blacklist_cache: + return bot.blacklist_cache[id] + + query = """ + SELECT blacklist_status + FROM blacklist + WHERE id = $1; + """ + record = await pool.fetchrow(query, id) + if record is None: + return False + bot.blacklist_cache[id] = record["blacklist_status"] + return record["blacklist_status"] + +Catherine-Chan's blacklisting system takes a bit to explain, but it's fairly standard. Within the setup hook, the code queries the PostgreSQL database for the blacklisted users and guilds. This is then converted into a dict, which is assigned to a private attribute within ``Catherine``. The attribute can be only accessed through a property (which later may or may be cached for faster performance), and that essentially gives us a read-only 1:1 mapping of the data from the database. The data will always be guaranteed 1:1 as the cache is always updated. During the ``interaction_check`` in the subclassed ``CommandTree``, the code looks up the user on the blacklist cache, and if not found, pulls it from the database and updates the cache wth the data (in fact, most if not all of Kumiko's ``get_or_fetch*`` coroutines work like this). The code only reads from the cache, thus when checking if the user is blacklisted or not, the operation is extremely quick and has no performance impacts on the bot. + 4. **Catherine-Chan vs PrideBot** @@ -76,7 +133,9 @@ Now on to the last part: comparing the both of them. Here's a table comparing th +========================+================+==========+ | Discord Framework | discord.py | Pycord | +------------------------+----------------+----------+ -| Memory Usage | 57MB (v0.1.0) | Unknown | +| Framework Version | v2.3.2 (v0.2.x)| Unknown | ++------------------------+----------------+----------+ +| Memory Usage | 66MB (v0.2.x) | Unknown | +------------------------+----------------+----------+ | Database | PostgreSQL | MongoDB | +------------------------+----------------+----------+ diff --git a/envs/dev.env b/envs/dev.env index 7a6149b..31de43e 100644 --- a/envs/dev.env +++ b/envs/dev.env @@ -7,7 +7,7 @@ DEV_MODE=True # Target revision for the migrations # DO NOT CHANGE UNLESS IT IS TO UPGRADE -TARGET_REVISION=rev3 +TARGET_REVISION=rev4 # IPC configuration values. This is used to maintain a HTTP healthcheck, also could be used to get tonetags IPC_SECRET_KEY=key diff --git a/envs/prod.env b/envs/prod.env index 923e8e7..fcf50af 100644 --- a/envs/prod.env +++ b/envs/prod.env @@ -3,7 +3,7 @@ TOKEN=token # Target revision for the migrations # DO NOT CHANGE UNLESS IT IS TO UPGRADE -TARGET_REVISION=rev3 +TARGET_REVISION=rev4 # IPC configuration values. This is used to maintain a HTTP healthcheck, also could be used to get tonetags IPC_SECRET_KEY=key diff --git a/poetry.lock b/poetry.lock index f56b952..61a940d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2088,6 +2088,32 @@ nodeenv = ">=0.11.1" pyyaml = ">=5.1" virtualenv = ">=20.10.0" +[[package]] +name = "psutil" +version = "5.9.5" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, + {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5"}, + {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4"}, + {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"}, + {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4"}, + {file = "psutil-5.9.5-cp27-none-win32.whl", hash = "sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f"}, + {file = "psutil-5.9.5-cp27-none-win_amd64.whl", hash = "sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42"}, + {file = "psutil-5.9.5-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217"}, + {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da"}, + {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4"}, + {file = "psutil-5.9.5-cp36-abi3-win32.whl", hash = "sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d"}, + {file = "psutil-5.9.5-cp36-abi3-win_amd64.whl", hash = "sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9"}, + {file = "psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30"}, + {file = "psutil-5.9.5.tar.gz", hash = "sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c"}, +] + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + [[package]] name = "pycares" version = "4.3.0" @@ -2166,6 +2192,40 @@ files = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] +[[package]] +name = "pygit2" +version = "1.13.0" +description = "Python bindings for libgit2." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygit2-1.13.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1c9027b71a5d54b1de122c54f153b0b227ca270507d6308ed42b5a69fc740a2e"}, + {file = "pygit2-1.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0d7e31d9bfacc7e6670da65e77f441e9e21a7223f73c739dfd92d8c0c057009"}, + {file = "pygit2-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:713b38e69527ddc14b52408ba5e6e862903f838cfe426645839242801dcdc2b3"}, + {file = "pygit2-1.13.0-cp310-cp310-win32.whl", hash = "sha256:97d9a25a33354017f5bfdbdac1dd0133afee8b061a327b8e7c12d50d58c5b65d"}, + {file = "pygit2-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:8e8df423209869c148b23269d1b01f61c134a825e5e3e636736695e72cd7698b"}, + {file = "pygit2-1.13.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c03df33e4f09ffeb7fa5570edfbe96285276aeb6fec18c06f64ea2f8fc7de842"}, + {file = "pygit2-1.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb1a601b279d1e1a1e1ba8d9b6bf798103f4befc66bdc4d6c329a332eae6a7d7"}, + {file = "pygit2-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d5b650f3f1c304d07c884a0ac45b04169fc5e3ba27030015d96644b411df44c"}, + {file = "pygit2-1.13.0-cp311-cp311-win32.whl", hash = "sha256:d765610b087b81cb90d1a5eb266e243eda2a7c3f1b5458500c76bfd437fbe02c"}, + {file = "pygit2-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:b7686b82cd972b3be88e91e963dbcb35474814bb7127297cbc4b9ab874b7037b"}, + {file = "pygit2-1.13.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:947a774eb089f11fc79022c9e1c2ec20a9a0152e0b2390e6d733dfd25234530d"}, + {file = "pygit2-1.13.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79e8eda586f0b713911076db8e46a1f05882fca6911e1f63a028337fd442192"}, + {file = "pygit2-1.13.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e235506031a616339eb2d5be2d24a70295937b9c4cd58265da9ee3ac206aff8"}, + {file = "pygit2-1.13.0-cp38-cp38-win32.whl", hash = "sha256:431de0d476b77a855614afc1cf634ded78df44e20c77a2c35147ea980b69eb65"}, + {file = "pygit2-1.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:696a0c334b6e8e710f9b5666af6dffeab9305c7154a3779f0da36189a1e9ee82"}, + {file = "pygit2-1.13.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6f5daab6670d3b353e4694a0fbb652674dcc2a4bc77e20342575d24dc974a4a5"}, + {file = "pygit2-1.13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d646d975f3d33cedc947bfbf490bb26da2267ad57e3d25d88b8b0b675496d4a"}, + {file = "pygit2-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a21f09caf2ffdd5f94d7963622f1e0fad4a1160a68872d79b12a4326c32fa99"}, + {file = "pygit2-1.13.0-cp39-cp39-win32.whl", hash = "sha256:b48b113b2ff77bd5e2cd01c6cd29be2d06b057eb71be823e8083b435a41eda2a"}, + {file = "pygit2-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:faea44ade5254a836ed5fa525442d7174e4197ca20cdbf2704a3b91f77bf952f"}, + {file = "pygit2-1.13.0.tar.gz", hash = "sha256:6dde37436fab14264ad3d6cbc5aae3fd555eb9a9680a7bfdd6e564cd77b5e2b8"}, +] + +[package.dependencies] +cffi = ">=1.9.1" +setuptools = {version = "*", markers = "python_version >= \"3.12\""} + [[package]] name = "pygments" version = "2.16.1" @@ -3021,4 +3081,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0" -content-hash = "817009a9b29039bbbb00e62e40ac9f6d66a833c4b298b558789a03d2aead4d8f" +content-hash = "32f1ef0678a53ecdd1e0305e744bb6d051169869f8d107ee2e35dc3e5b0c1622" diff --git a/pyproject.toml b/pyproject.toml index 5e63115..6650f5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "catherine-chan" -version = "0.2.3" +version = "0.2.4" description = "An informational LGBTQ based discord bot" authors = ["No767 <73260931+No767@users.noreply.github.com>"] readme = "README.md" @@ -19,6 +19,8 @@ discord-ext-menus = {git = "https://github.com/Rapptz/discord-ext-menus.git", re msgspec = "^0.18.2" langcodes = {extras = ["data"], version = "^3.3.0"} discord-ext-ipcx = "^0.1.1" +pygit2 = "^1.13.0" +psutil = "^5.9.5" [tool.poetry.group.dev.dependencies] pre-commit = "^3.4.0" diff --git a/requirements/prod.txt b/requirements/prod.txt index b222787..199e537 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -22,8 +22,10 @@ marisa-trie==0.7.8 ; python_version >= "3.8" and python_version < "4.0" msgspec==0.18.2 ; python_version >= "3.8" and python_version < "4.0" multidict==6.0.4 ; python_version >= "3.8" and python_version < "4.0" orjson==3.9.5 ; python_version >= "3.8" and python_version < "4.0" +psutil==5.9.5 ; python_version >= "3.8" and python_version < "4.0" pycares==4.3.0 ; python_version >= "3.8" and python_version < "4.0" pycparser==2.21 ; python_version >= "3.8" and python_version < "4.0" +pygit2==1.13.0 ; python_version >= "3.8" and python_version < "4.0" python-dateutil==2.8.2 ; python_version >= "3.8" and python_version < "4.0" python-dotenv==1.0.0 ; python_version >= "3.8" and python_version < "4.0" setuptools==68.1.2 ; python_version >= "3.8" and python_version < "4.0"