See merge request stark-industries/jarvis/jarvis-bot!73
This commit is contained in:
Zeva Rose 2022-08-16 01:20:51 +00:00
commit 1a1ffd0c57
5 changed files with 191 additions and 134 deletions

View file

@ -1,27 +1,28 @@
<div align="center"> <div align="center">
<img width=15% alt="J.A.R.V.I.S" src="https://git.zevaryx.com/stark-industries/j.a.r.v.i.s./-/raw/main/jarvis_small.png"> <img width=15% alt="JARVIS" src="https://git.zevaryx.com/stark-industries/jarvis/jarvis-bot/-/raw/main/jarvis_small.png">
# Just Another Rather Very Intelligent System # Just Another Rather Very Intelligent System
<br /> <br />
[![python 3.8+](https://img.shields.io/badge/python-3.8+-blue)]() [![python 3.10+](https://img.shields.io/badge/python-3.10+-blue)]()
[![tokei lines of code](https://tokei.rs/b1/git.zevaryx.com/stark-industries/j.a.r.v.i.s.?category=code)](https://git.zevaryx.com/stark-industries/j.a.r.v.i.s.) [![tokei lines of code](https://tokei.rs/b1/git.zevaryx.com/stark-industries/jarvis/jarvis-bot?category=code)](https://git.zevaryx.com/stark-industries/jarvis/jarvis-bot)
[![discord chat widget](https://img.shields.io/discord/862402786116763668?style=social&logo=discord)](https://discord.gg/VtgZntXcnZ) [![discord chat widget](https://img.shields.io/discord/862402786116763668?style=social&logo=discord)](https://discord.gg/VtgZntXcnZ)
</div> </div>
Welcome to the J.A.R.V.I.S. Initiative! While the main goal is to create the best discord bot there can be, a great achievement would be to present him to the Robots and have him integrated into the dbrand server. Feel free to suggest anything you may think to be useful… or cool. Welcome to the JARVIS Initiative! While the main goal is to create the best discord bot there can be, a great achievement would be to present him to the Robots and have him integrated into the dbrand server. Feel free to suggest anything you may think to be useful… or cool.
**Note:** Some commands have been custom made to be used in the dbrand server. **Note:** Some commands have been custom made to be used in the dbrand server.
## Features ## Features
JARVIS currently offers:
J.A.R.V.I.S. currently offers:
- 👩‍💼 **Administration**: `verify`, `ban/unban`, `kick`, `purge`, `mute/unmute` and more! - 👩‍💼 **Administration**: `verify`, `ban/unban`, `kick`, `purge`, `mute/unmute` and more!
- 🚓 **Moderation**: `lock/unlock`, `lockdown`, `warn`, `autoreact`, and also more! - 🚓 **Moderation**: `lock/unlock`, `lockdown`, `warn`, `autoreact`, and also more!
- 👻 **Fun**: `jokes`. Please proceed to laugh now. - 🔗 **Social Media**: `reddit` and `twitter` syncing!
- 🔧 **Utilities**: `remindme`, `rolegiver`, `temprole`, `image`, and so many more!
- 🏷️ **Tags**: Custom `tag`s! Useful for custom messages without the hassle!
- 👑 **dbrand**: `ctc2` and other dbrand-specific commands. [Join their server](https://discord.gg/dbrand) to see them in action! - 👑 **dbrand**: `ctc2` and other dbrand-specific commands. [Join their server](https://discord.gg/dbrand) to see them in action!
@ -31,7 +32,7 @@ Before **creating an issue**, please ensure that it hasn't already been reported
If you have a question, please join the community Discord before opening an issue. If you have a question, please join the community Discord before opening an issue.
If you wish to contribute to the J.A.R.V.I.S codebase or documentation, join the Discord! The recognized developers there will help you get started. If you wish to contribute to the JARVIS codebase or documentation, join the Discord! The recognized developers there will help you get started.
## Community ## Community
@ -41,45 +42,31 @@ Join the [Stark R&D Department Discord server](https://discord.gg/VtgZntXcnZ) to
- MongoDB 5.0 or higher - MongoDB 5.0 or higher
- Python 3.10 or higher - Python 3.10 or higher
- [tokei](https://github.com/XAMPPRocky/tokei) 12.1 or higher - [tokei](https://github.com/XAMPPRocky/tokei) 12.1 or higher
- Everything in `requirements.txt`
On top of the above requirements, the following pip packages are also required:
- `dis-snek>=5.0.0`
- `psutil>=5.8, <6`
- `GitPython>=3.1, <4`
- `PyYaml>=5.4, <6`
- `pymongo>=3.12.0, <4`
- `opencv-python>=4.5, <5`
- `Pillow>=8.2.0, <9`
- `python-gitlab>=2.9.0, <3`
- `ulid-py>=1.1.0, <2`
## J.A.R.V.I.S. Cogs ## JARVIS Cogs
Current cogs that are implemented: Current cogs that are implemented:
- `AdminCog` - `AdminCog`
- Handles all admin commands - Handles all admin commands
- `ModlogCog`
- Handles modlog events
- `AutoreactCog` - `AutoreactCog`
- Handles autoreaction configuration - Handles autoreaction configuration
- `BotutilCog`
- Handles internal bot utilities (private use only)
- `CTC2Cog` - `CTC2Cog`
- dbrand Complete the Code utilities - dbrand Complete the Code utilities
- `DbrandCog` - `DbrandCog`
- dbrand-specific functions and utilities - dbrand-specific functions and utilities
- `DevCog` - `DevCog`
- Developer utilities, such as hashing, encoding, and UUID generation - Developer utilities, such as hashing, encoding, and UUID generation
- `ErrorCog`
- Handles all bot errors
- `GitlabCog` - `GitlabCog`
- Shows Gitlab information about J.A.R.V.I.S. - Shows Gitlab information about J.A.R.V.I.S.
- `ImageCog` - `ImageCog`
- Image-processing cog. Only cog with no slash commands - Image-processing cog.
- `JokesCog` - `RedditCog`
- Get a joke, have a laugh - Reddit lookup and following commands
- `OwnerCog`
- For the bot owner. Bot management commands
- `RemindmeCog` - `RemindmeCog`
- Manage reminders - Manage reminders
- `RolegiverCog` - `RolegiverCog`
@ -88,6 +75,12 @@ Current cogs that are implemented:
- Manage Guild settings - Manage Guild settings
- `StarboardCog` - `StarboardCog`
- Configure and add starboards and stars - Configure and add starboards and stars
- `TagCog`
- For managing tags
- `TemproleCog`
- For managing and assigning temporary roles
- `TwitterCog`
- Twitter following commands
- `UtilCog` - `UtilCog`
- Generic utilities, like userinfo and roleinfo - Generic utilities, like userinfo and roleinfo
- `VerifyCog` - `VerifyCog`
@ -111,20 +104,12 @@ Contains all AdminCogs, including:
- `KickCog` - `KickCog`
- `LockCog` - `LockCog`
- `LockdownCog` - `LockdownCog`
- `ModcaseCog`
- `MuteCog` - `MuteCog`
- `PurgeCog` - `PurgeCog`
- `RolepingCog` - `RolepingCog`
- `WarningCog` - `WarningCog`
##### `jarvis.cogs.modlog`
Contains all ModlogCogs, including:
- `ModlogCommandCog`
- `ModlogMemberCog`
- `ModlogMessageCog`
`jarvis.cogs.modlog.utils` includes modlog-specific utilities
#### `jarvis.data` #### `jarvis.data`
Contains data relevant to J.A.R.V.I.S., such as emoji lookups and dbrand data Contains data relevant to J.A.R.V.I.S., such as emoji lookups and dbrand data
@ -133,20 +118,6 @@ Contains data relevant to J.A.R.V.I.S., such as emoji lookups and dbrand data
Any JSON files that are needed are stored here Any JSON files that are needed are stored here
#### `jarvis.db`
All database-related files.
`jarvis.db.types` handles almost all of the database conections
#### `jarvis.events`
Containers for `@on_` d.py events
#### `jarvis.tasks`
All background tasks run from this folder
#### `jarvis.utils` #### `jarvis.utils`
Generic utilities Generic utilities

View file

@ -110,12 +110,13 @@ class Jarvis(StatsClient):
async def _prerun(self, ctx: Context, *args, **kwargs) -> None: async def _prerun(self, ctx: Context, *args, **kwargs) -> None:
name = ctx.invoke_target name = ctx.invoke_target
cargs = ""
if isinstance(ctx, InteractionContext) and ctx.target_id: if isinstance(ctx, InteractionContext) and ctx.target_id:
kwargs["context target"] = ctx.target kwargs["context target"] = ctx.target
args = " ".join(f"{k}:{v}" for k, v in kwargs.items()) cargs = " ".join(f"{k}:{v}" for k, v in kwargs.items())
elif isinstance(ctx, PrefixedContext): elif isinstance(ctx, PrefixedContext):
args = " ".join(args) cargs = " ".join(args)
self.logger.debug(f"Running command `{name}` with args: {args or 'None'}") self.logger.debug(f"Running command `{name}` with args: {cargs or 'None'}")
async def _sync_domains(self) -> None: async def _sync_domains(self) -> None:
self.logger.debug("Loading phishing domains") self.logger.debug("Loading phishing domains")
@ -232,7 +233,8 @@ class Jarvis(StatsClient):
name = ctx.invoke_target name = ctx.invoke_target
if not isinstance(ctx.channel, DMChannel) and name not in ["pw"]: if not isinstance(ctx.channel, DMChannel) and name not in ["pw"]:
modlog = await Setting.find_one(q(guild=ctx.guild.id, setting="activitylog")) modlog = await Setting.find_one(q(guild=ctx.guild.id, setting="activitylog"))
if modlog: ignore = await Setting.find_one(q(guild=ctx.guild.id, setting="log_ignore"))
if modlog and (ignore and ctx.channel.id not in ignore.value):
channel = await ctx.guild.fetch_channel(modlog.value) channel = await ctx.guild.fetch_channel(modlog.value)
args = [] args = []
if isinstance(ctx, InteractionContext) and ctx.target_id: if isinstance(ctx, InteractionContext) and ctx.target_id:
@ -702,7 +704,8 @@ class Jarvis(StatsClient):
after = event.after after = event.after
if not after.author.bot: if not after.author.bot:
modlog = await Setting.find_one(q(guild=after.guild.id, setting="activitylog")) modlog = await Setting.find_one(q(guild=after.guild.id, setting="activitylog"))
if modlog: ignore = await Setting.find_one(q(guild=after.guild.id, setting="log_ignore"))
if modlog and (ignore and after.channel.id not in ignore.value):
if not before or before.content == after.content or before.content is None: if not before or before.content == after.content or before.content is None:
return return
try: try:
@ -754,7 +757,8 @@ class Jarvis(StatsClient):
"""Process on_message_delete events.""" """Process on_message_delete events."""
message = event.message message = event.message
modlog = await Setting.find_one(q(guild=message.guild.id, setting="activitylog")) modlog = await Setting.find_one(q(guild=message.guild.id, setting="activitylog"))
if modlog: ignore = await Setting.find_one(q(guild=message.guild.id, setting="log_ignore"))
if modlog and (ignore and message.channel.id not in ignore.value):
try: try:
content = message.content or "N/A" content = message.content or "N/A"
except AttributeError: except AttributeError:

View file

@ -5,7 +5,7 @@ from typing import Any
from jarvis_core.db import q from jarvis_core.db import q
from jarvis_core.db.models import Setting from jarvis_core.db.models import Setting
from naff import Client, Extension, InteractionContext from naff import AutocompleteContext, Client, Extension, InteractionContext
from naff.models.discord.channel import GuildText from naff.models.discord.channel import GuildText
from naff.models.discord.components import ActionRow, Button, ButtonStyles from naff.models.discord.components import ActionRow, Button, ButtonStyles
from naff.models.discord.embed import EmbedField from naff.models.discord.embed import EmbedField
@ -17,6 +17,7 @@ from naff.models.naff.application_commands import (
slash_option, slash_option,
) )
from naff.models.naff.command import check from naff.models.naff.command import check
from thefuzz import process
from jarvis.utils import build_embed from jarvis.utils import build_embed
from jarvis.utils.permissions import admin_or_permissions from jarvis.utils.permissions import admin_or_permissions
@ -152,6 +153,29 @@ class SettingsCog(Extension):
await self.update_settings("notify", active, ctx.guild.id) await self.update_settings("notify", active, ctx.guild.id)
await ctx.send(f"Settings applied. Notifications active: {active}") await ctx.send(f"Settings applied. Notifications active: {active}")
@set_.subcommand(
sub_cmd_name="log_ignore", sub_cmd_description="Ignore a channel for ActivityLog"
)
@slash_option(
name="channel", description="Channel to ignore", opt_type=OptionTypes.CHANNEL, required=True
)
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
async def _add_log_ignore(self, ctx: InteractionContext, channel: GuildText) -> None:
if not isinstance(channel, GuildText):
await ctx.send("Channel must be a GuildText", ephemeral=True)
return
setting = await Setting.find_one(q(guild=ctx.guild.id, setting="log_ignore"))
if not setting:
setting = Setting(guild=ctx.guild.id, setting="log_ignore", value=[])
if not setting.value:
setting.value = []
if channel in setting.value:
await ctx.send("Channel already ignored", ephemeral=True)
return
setting.value.append(channel.id)
await setting.commit(replace=True)
await ctx.send("Channel added to ActivityLog ignore list")
# Unset # Unset
@unset.subcommand( @unset.subcommand(
sub_cmd_name="modlog", sub_cmd_name="modlog",
@ -210,6 +234,37 @@ class SettingsCog(Extension):
await self.delete_settings("notify", ctx.guild.id) await self.delete_settings("notify", ctx.guild.id)
await ctx.send("Setting `notify` unset") await ctx.send("Setting `notify` unset")
@unset.subcommand(
sub_cmd_name="log_ignore", sub_cmd_description="Add a channel for ActivityLog"
)
@slash_option(
name="channel",
description="Channel to stop ignoring",
opt_type=OptionTypes.STRING,
required=True,
autocomplete=True,
)
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
async def _remove_log_ignore(self, ctx: InteractionContext, channel: str) -> None:
channel = int(channel)
setting = await Setting.find_one(q(guild=ctx.guild.id, setting="log_ignore"))
if not setting or channel not in setting.value:
await ctx.send("Channel not being ignored", ephemeral=True)
return
setting.value.remove(channel)
await setting.commit(replace=True)
await ctx.send("Channel no longer being ignored")
@_remove_log_ignore.autocomplete(option_name="channel")
async def _channel_search(self, ctx: AutocompleteContext, channel: str) -> None:
setting = await Setting.find_one(q(guild=ctx.guild.id, setting="log_ignore"))
if not setting:
return {}
channels = [ctx.guild.get_channel(x) for x in setting.value]
channels = {c.name: c.id for c in channels if c}
options = process.extract(channel, list(channels.keys()), limit=25)
await ctx.send(choices=[{"name": c[0], "value": str(channels[c[0]])} for c in options])
@settings.subcommand(sub_cmd_name="view", sub_cmd_description="View settings") @settings.subcommand(sub_cmd_name="view", sub_cmd_description="View settings")
@check(admin_or_permissions(Permissions.MANAGE_GUILD)) @check(admin_or_permissions(Permissions.MANAGE_GUILD))
async def _view(self, ctx: InteractionContext) -> None: async def _view(self, ctx: InteractionContext) -> None:
@ -242,6 +297,13 @@ class SettingsCog(Extension):
value += "\n" + nvalue.mention value += "\n" + nvalue.mention
else: else:
value += "\n||`[redacted]`||" value += "\n||`[redacted]`||"
elif setting.setting == "log_ignore":
names = []
for v in setting.value:
channel = ctx.guild.get_channel(v)
if channel:
names.append(channel.mention)
value = ", ".join(names) if names else "None"
fields.append(EmbedField(name=setting.setting, value=str(value) or "N/A", inline=False)) fields.append(EmbedField(name=setting.setting, value=str(value) or "N/A", inline=False))
embed = build_embed(title="Current Settings", description="", fields=fields) embed = build_embed(title="Current Settings", description="", fields=fields)

7
poetry.lock generated
View file

@ -514,7 +514,7 @@ python-versions = "*"
[[package]] [[package]]
name = "naff" name = "naff"
version = "1.7.1" version = "1.8.0"
description = "Not another freaking fork" description = "Not another freaking fork"
category = "main" category = "main"
optional = false optional = false
@ -1564,7 +1564,10 @@ mypy-extensions = [
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
] ]
naff = [] naff = [
{file = "naff-1.8.0-py3-none-any.whl", hash = "sha256:96284f17841a782bdf4cb1e0b767b75e93a0afb9c0cd852a448e9a475b38efb6"},
{file = "naff-1.8.0.tar.gz", hash = "sha256:0fada9174642d6daa5b76f2e52c992722ffc8219ba9067b101d018380df1ad24"},
]
nafftrack = [] nafftrack = []
nanoid = [ nanoid = [
{file = "nanoid-2.0.0-py3-none-any.whl", hash = "sha256:90aefa650e328cffb0893bbd4c236cfd44c48bc1f2d0b525ecc53c3187b653bb"}, {file = "nanoid-2.0.0-py3-none-any.whl", hash = "sha256:90aefa650e328cffb0893bbd4c236cfd44c48bc1f2d0b525ecc53c3187b653bb"},

View file

@ -1,76 +1,93 @@
aiofile==3.7.4 aiofile==3.7.4; python_version > "3.4" and python_version < "4"
aiofiles==0.6.0 ; python_version >= "3.6" aiofiles==0.6.0; python_version >= "3.6"
aiohttp==3.8.1 aiohttp==3.8.1; python_version >= "3.6"
aioredis==2.0.1 aioredis==2.0.1; python_version >= "3.6"
aiosignal==1.2.0 ; python_version >= "3.10" aiosignal==1.2.0; python_version >= "3.10" and python_version < "4.0"
aiosqlite==0.17.0 ; python_version >= "3.6" aiosqlite==0.17.0; python_version >= "3.6"
ansicon==1.89.0 ; python_version >= "3.8" and python_version < "4.0" and platform_system == "Windows" ansicon==1.89.0; python_version >= "3.8" and python_version < "4.0" and platform_system == "Windows"
async-generator==1.10 ; python_version >= "3.6" ansitoimg==2022.1; python_version >= "3.7" and python_version < "4.0"
async-timeout==4.0.2 ; python_version >= "3.6" appdirs==1.4.4; python_version >= "3.7" and python_version < "4.0"
asyncio-extras==1.3.2 ; python_version >= "3.6" async-generator==1.10; python_version >= "3.6"
asyncpraw==7.5.0 async-timeout==4.0.2; python_version >= "3.10" and python_version < "4.0"
asyncprawcore==2.3.0 ; python_version >= "3.6" asyncio-extras==1.3.2; python_version >= "3.6"
attrs==21.4.0 ; python_version >= "3.10" asyncpraw==7.5.0; python_version >= "3.6"
blessed==1.19.1 ; python_version >= "3.8" and python_version < "4.0" asyncprawcore==2.3.0; python_version >= "3.6"
caio==0.9.5 ; python_version >= "3.5" and python_version < "4" attrs==21.4.0; python_version >= "3.10" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.10" and python_version < "4.0" and python_full_version >= "3.5.0"
certifi==2021.10.8 blessed==1.19.1; python_version >= "3.8" and python_version < "4.0"
charset-normalizer==2.0.12 ; python_version >= "3.10" caio==0.9.5; python_version >= "3.5" and python_version < "4"
codefind==0.1.3 ; python_version >= "3.8" and python_version < "4.0" certifi==2021.10.8; python_full_version >= "3.7.0" and python_version >= "3.10" and (python_version >= "3.10" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.10") and python_version < "4.0"
commonmark==0.9.1 ; python_version >= "3.10" and python_full_version < "4.0.0" charset-normalizer==2.0.12; python_version >= "3.10" and python_version < "4.0" and python_full_version >= "3.7.0" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7") and (python_version >= "3.10" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.10")
dateparser==1.1.1 click==8.1.3; python_version >= "3.10" and python_version < "4.0"
discord-typings==0.4.0 ; python_version >= "3.10" codefind==0.1.3; python_version >= "3.8" and python_version < "4.0"
distro==1.7.0 ; python_version >= "3.6" colorama==0.4.4; python_version >= "3.10" and python_full_version < "3.0.0" and python_version < "4.0" and platform_system == "Windows" or python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows" and python_full_version >= "3.5.0"
frozenlist==1.3.0 ; python_version >= "3.10" commonmark==0.9.1; python_full_version >= "3.6.3" and python_full_version < "4.0.0" and python_version >= "3.10" and python_version < "4.0"
dateparser==1.1.1; python_version >= "3.5"
discord-typings==0.4.0; python_version >= "3.10" and python_version < "4.0"
distro==1.7.0; python_version >= "3.6"
frozenlist==1.3.0; python_version >= "3.10" and python_version < "4.0"
funcsigs==1.0.2 funcsigs==1.0.2
gitdb==4.0.9 ; python_version >= "3.7" gitdb==4.0.9; python_version >= "3.7"
gitpython==3.1.27 gitpython==3.1.27; python_version >= "3.7"
idna==3.3 ; python_version >= "3.10" h11==0.13.0; python_version >= "3.10" and python_version < "4.0"
jarvis-core @ git+https://git.zevaryx.com/stark-industries/jarvis/jarvis-core.git@main idna==3.3; python_full_version >= "3.7.0" and python_version >= "3.10" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7") and (python_version >= "3.10" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.10") and python_version < "4.0"
jinxed==1.2.0 ; python_version >= "3.8" and python_version < "4.0" and platform_system == "Windows" importlib-metadata==4.11.4; python_version >= "3.7" and python_version < "4.0"
jurigged==0.5.2 jarvis-core @ git+https://git.zevaryx.com/stark-industries/jarvis/jarvis-core.git@main ; python_version >= "3.10" and python_version < "4.0"
marshmallow==3.16.0 ; python_version >= "3.10" and python_version < "4.0" jinxed==1.2.0; python_version >= "3.8" and python_version < "4.0" and platform_system == "Windows"
mongoengine==0.23.1 jurigged==0.5.2; python_version >= "3.8" and python_version < "4.0"
motor==2.5.1 ; python_version >= "3.10" and python_version < "4.0" marshmallow==3.16.0; python_version >= "3.10" and python_version < "4.0"
multidict==6.0.2 ; python_version >= "3.10" mongoengine==0.23.1; python_version >= "3.6"
naff==1.2.0 motor==2.5.1; python_version >= "3.10" and python_version < "4.0" and python_full_version >= "3.5.2"
nanoid==2.0.0 ; python_version >= "3.10" and python_version < "4.0" multidict==6.0.2; python_version >= "3.10" and python_version < "4.0"
numpy==1.22.4 ; python_version >= "3.8" or python_version >= "3.8" and platform_system == "Darwin" and platform_machine == "arm64" or python_version >= "3.8" and platform_system == "Linux" and platform_machine == "aarch64" naff==1.7.1; python_version >= "3.10"
oauthlib==3.2.0 ; python_version >= "3.7" nafftrack @ git+https://github.com/artem30801/nafftrack.git@master ; python_version >= "3.10" and python_version < "4.0"
opencv-python==4.6.0.66 nanoid==2.0.0; python_version >= "3.10" and python_version < "4.0"
orjson==3.7.2 ; python_version >= "3.10" and python_version < "4.0" nest-asyncio==1.5.5; python_version >= "3.5"
ovld==0.3.2 ; python_version >= "3.8" and python_version < "4.0" numpy==1.22.4; python_version >= "3.10" and platform_system == "Linux" and platform_machine == "aarch64" or python_version >= "3.10" or python_version >= "3.9" and platform_system == "Darwin" and platform_machine == "arm64"
packaging==21.3 ; python_version >= "3.10" and python_version < "4.0" oauthlib==3.2.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
pastypy==1.0.2 opencv-python==4.6.0.66; python_version >= "3.6"
pillow==9.1.1 orjson==3.7.2; python_version >= "3.10" and python_version < "4.0"
protobuf==3.20.1 ; python_version >= "3.7" ovld==0.3.2; python_version >= "3.8" and python_version < "4.0"
psutil==5.9.1 packaging==21.3; python_version >= "3.10" and python_version < "4.0"
pycryptodome==3.14.1 ; python_version >= "3.10" pastypy==1.0.2; python_version >= "3.10"
pygments==2.12.0 ; python_version >= "3.10" and python_full_version < "4.0.0" pillow==9.1.1; python_version >= "3.7"
pymongo==3.12.3 ; python_version >= "3.10" and python_version < "4.0" or python_version >= "3.6" prometheus-client==0.14.1; python_version >= "3.10" and python_version < "4.0"
pyparsing==3.0.9 ; python_version >= "3.10" and python_version < "4.0" protobuf==3.20.1; python_version >= "3.7"
python-dateutil==2.8.2 ; python_version >= "3.5" psutil==5.9.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0")
python-gitlab==3.5.0 pycryptodome==3.14.1; python_version >= "3.10" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.10"
pytz==2022.1 ; python_version >= "3.10" and python_version < "4.0" or python_version >= "3.5" pyee==8.2.2; python_version >= "3.7" and python_version < "4.0"
pytz-deprecation-shim==0.1.0.post0 ; python_full_version >= "3.6.0" pygments==2.12.0; python_full_version >= "3.6.3" and python_full_version < "4.0.0" and python_version >= "3.10" and python_version < "4.0"
pyyaml==6.0 pymongo==3.12.3; python_version >= "3.10" and python_version < "4.0" and python_full_version >= "3.5.2"
regex==2022.3.2 ; python_version >= "3.6" pyparsing==3.0.9; python_version >= "3.10" and python_version < "4.0" and python_full_version >= "3.6.8"
requests==2.27.1 ; python_full_version >= "3.6.0" pyppeteer==1.0.2; python_version >= "3.7" and python_version < "4.0"
requests-oauthlib==1.3.1 ; python_version >= "3.7" python-dateutil==2.8.2; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.5"
requests-toolbelt==0.9.1 ; python_full_version >= "3.7.0" python-gitlab==3.5.0; python_full_version >= "3.7.0"
rich==12.4.4 python-levenshtein==0.12.2
pytz==2022.1; python_version >= "3.10" and python_version < "4.0"
pytz-deprecation-shim==0.1.0.post0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
pyyaml==6.0; python_version >= "3.6"
regex==2022.3.2; python_version >= "3.6"
requests==2.27.1; python_full_version >= "3.7.0" and python_version >= "3.7" and (python_version >= "3.10" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.10") and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7") and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6")
requests-oauthlib==1.3.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
requests-toolbelt==0.9.1; python_full_version >= "3.7.0"
rich==12.4.4; python_full_version >= "3.6.3" and python_full_version < "4.0.0"
rook==0.1.175 rook==0.1.175
six==1.16.0 ; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" or python_version >= "3.8" and python_version < "4.0" six==1.16.0; python_version >= "3.8" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.3.0" and python_version >= "3.8" and python_version < "4.0"
smmap==5.0.0 ; python_version >= "3.7" smmap==5.0.0; python_version >= "3.7"
tomli==2.0.1 ; python_version >= "3.10" thefuzz==0.19.0
tweepy==4.10.0 tomli==2.0.1; python_version >= "3.10" and python_version < "4.0"
typing-extensions==4.2.0 ; python_version >= "3.7" tqdm==4.64.0; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.4.0"
tzdata==2022.1 ; python_version >= "3.6" tweepy==4.10.0; python_version >= "3.7"
tzlocal==4.2 ; python_version >= "3.6" typing-extensions==4.2.0; python_version >= "3.10"
tzdata==2022.1; platform_system == "Windows" and python_version >= "3.6" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6")
tzlocal==4.2; python_version >= "3.6"
ulid-py==1.1.0 ulid-py==1.1.0
umongo==3.1.0 ; python_version >= "3.10" and python_version < "4.0" umongo==3.1.0; python_version >= "3.10" and python_version < "4.0"
update-checker==0.18.0 ; python_version >= "3.6" update-checker==0.18.0; python_version >= "3.6"
urllib3==1.26.8 ; python_version >= "3.10" and python_version < "4" urllib3==1.26.8; python_full_version >= "3.7.0" and python_version < "4" and python_version >= "3.10" and (python_version >= "3.10" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.10") and (python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.7")
watchdog==2.1.8 ; python_version >= "3.8" and python_version < "4.0" uvicorn==0.18.2; python_version >= "3.10" and python_version < "4.0"
wcwidth==0.2.5 ; python_version >= "3.8" and python_version < "4.0" watchdog==2.1.8; python_version >= "3.8" and python_version < "4.0"
websocket-client==1.3.2 ; python_version >= "3.7" wcwidth==0.2.5; python_version >= "3.8" and python_version < "4.0"
yarl==1.7.2 ; python_version >= "3.6" websocket-client==1.3.2; python_version >= "3.7"
websockets==10.3; python_version >= "3.7" and python_version < "4.0"
yarl==1.7.2; python_version >= "3.10" and python_version < "4.0"
zipp==3.8.0; python_version >= "3.7" and python_version < "4.0"