Compare commits
83 commits
Author | SHA1 | Date | |
---|---|---|---|
7af8e02462 | |||
a40f78e88f | |||
216fa74a53 | |||
901c10a458 | |||
1150115171 | |||
8d4d61c017 | |||
23f2aaa2ee | |||
8b6d269e1a | |||
8c323e36a9 | |||
1392a9324a | |||
9cba1767e6 | |||
cbfff6d211 | |||
56d1e14454 | |||
571be4e245 | |||
6b2793e692 | |||
ad0bb7cf00 | |||
1244d5a941 | |||
1c0f12660b | |||
b4a54d214d | |||
260438f397 | |||
5bfb74de47 | |||
b7bde42672 | |||
0f36badbea | |||
f04b452396 | |||
7d4a6b9930 | |||
f6570dd072 | |||
ff68d6ea19 | |||
825a373a9b | |||
d173dd68a5 | |||
24239425c5 | |||
e3e96e5b84 | |||
28f814db56 | |||
7354769962 | |||
2ac1dacd19 | |||
66b933569b | |||
c06db07f08 | |||
46f189a297 | |||
545106d496 | |||
037a26deb0 | |||
f51329524c | |||
5b23f2f0fb | |||
8f492cd937 | |||
dfabac55f5 | |||
4f25e3d0f3 | |||
7207cd3747 | |||
069ea800db | |||
58245c621c | |||
b9f0dbf98a | |||
2d895d16c9 | |||
861a03719b | |||
ac5d4df36b | |||
ae8d0d5db4 | |||
0ea80075f6 | |||
8d3f5c1d5f | |||
42e209b547 | |||
0ed96babdb | |||
29b6a2141a | |||
c4ef2a7d4b | |||
99cd13ccf1 | |||
28246121a6 | |||
a641cae640 | |||
2886d5e80d | |||
50094b85fc | |||
7f46d6accc | |||
cb6ddabb4d | |||
8608e6a34e | |||
fb468ee63e | |||
b27a3ee778 | |||
54491cb9c9 | |||
29bb64b35c | |||
5ffc42480a | |||
7d51814a28 | |||
25fdf7b402 | |||
091f4fe36d | |||
d444242245 | |||
7a2ee0a655 | |||
8b68cb7530 | |||
028cae9e99 | |||
aa7e347a95 | |||
93f358cfad | |||
8867cc627f | |||
e2059eac77 | |||
e9c062afa9 |
43 changed files with 2600 additions and 2673 deletions
|
@ -10,7 +10,7 @@ Aurora is a fully-featured moderation system. It is heavily inspired by Galactic
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[p]repo add seacogs https://www.coastalcommits.com/SeaswimmerTheFsh/SeaCogs
|
[p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs
|
||||||
[p]cog install seacogs aurora
|
[p]cog install seacogs aurora
|
||||||
[p]cog load aurora
|
[p]cog load aurora
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
# Backup
|
# Backup
|
||||||
|
|
||||||
Backup allows you to export a JSON list of all of your installed repositories and cogs, then reimport them and automatically reinstall/reload the cogs.
|
Backup allows you to export a JSON list of all of your installed repositories and cogs, then reimport them and automatically reinstall the cogs.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[p]repo add seacogs https://www.coastalcommits.com/SeaswimmerTheFsh/SeaCogs
|
[p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs
|
||||||
[p]cog install seacogs backup
|
[p]cog install seacogs backup
|
||||||
[p]cog load backup
|
[p]cog load backup
|
||||||
```
|
```
|
||||||
|
|
||||||
## Version Compatibility
|
## Version Compatibility
|
||||||
|
|
||||||
As of commit [1edb08a](https://www.coastalcommits.com/SeaswimmerTheFsh/SeaCogs/commit/1edb08a1271f12098ca0bed11a735f7162cedd14), the Backup cog no longer supports Red versions older than 3.5.6. If you want to use the cog on an earlier version (3.5.0 - 3.5.5), install the cog pinned to this commit: `43464db6a7c51bc69282b1ae3dc507a4aae851de`.
|
As of commit [1edb08a](https://www.coastalcommits.com/cswimr/SeaCogs/commit/1edb08a1271f12098ca0bed11a735f7162cedd14), the Backup cog no longer supports Red versions older than 3.5.6. If you want to use the cog on an earlier version (3.5.0 - 3.5.5), install the cog pinned to this commit: `43464db6a7c51bc69282b1ae3dc507a4aae851de`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[p]cog installversion sea-cogs 43464db6a7c51bc69282b1ae3dc507a4aae851de backup
|
[p]cog installversion sea-cogs 43464db6a7c51bc69282b1ae3dc507a4aae851de backup
|
||||||
|
|
|
@ -6,7 +6,7 @@ This cog does require an api key to work.
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[p]repo add seacogs https://www.coastalcommits.com/SeaswimmerTheFsh/SeaCogs
|
[p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs
|
||||||
[p]cog install seacogs bible
|
[p]cog install seacogs bible
|
||||||
[p]cog load bible
|
[p]cog load bible
|
||||||
```
|
```
|
||||||
|
|
|
@ -5,7 +5,7 @@ EmojiInfo allows you to retrieve information about an emoji.
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[p]repo add seacogs https://www.coastalcommits.com/SeaswimmerTheFsh/SeaCogs
|
[p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs
|
||||||
[p]cog install seacogs emojiinfo
|
[p]cog install seacogs emojiinfo
|
||||||
[p]cog load emojiinfo
|
[p]cog load emojiinfo
|
||||||
```
|
```
|
||||||
|
|
|
@ -5,7 +5,7 @@ Nerdify allows you to nerdify other people's text.
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[p]repo add seacogs https://www.coastalcommits.com/SeaswimmerTheFsh/SeaCogs
|
[p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs
|
||||||
[p]cog install seacogs nerdify
|
[p]cog install seacogs nerdify
|
||||||
[p]cog load nerdify
|
[p]cog load nerdify
|
||||||
```
|
```
|
||||||
|
|
|
@ -69,10 +69,10 @@ Default value: `None`
|
||||||
|
|
||||||
/// admonition | This has no effect on the `[p]pterodactyl command` text command, or the matching slash command.
|
/// admonition | This has no effect on the `[p]pterodactyl command` text command, or the matching slash command.
|
||||||
type: danger
|
type: danger
|
||||||
If you want to disable the ability to execute commands on the server through Discord, use the following commands:
|
If you want to disable the ability to execute commands on the server through Discord, use the following commands:
|
||||||
`[p]pterodactyl config console commands False` - this command
|
`[p]pterodactyl config console commands False` - this command
|
||||||
`[p]command disable pterodactyl command` - disables the text command that lets you execute commands on the server
|
`[p]command disable pterodactyl command` - disables the text command that lets you execute commands on the server
|
||||||
`[p]slash disable pterodactyl` - due to how slash commands are laid out, this is the only way to disable the ability to execute commands on the server
|
`[p]slash disable pterodactyl` - due to how slash commands are laid out, this is the only way to disable the ability to execute commands on the server
|
||||||
`[p]slash sync` - apply above slash command change
|
`[p]slash sync` - apply above slash command change
|
||||||
///
|
///
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ The Downloader cog allows you to add Git repositories to your bot in order to do
|
||||||
Now, use Downloader to add my repository to your bot:
|
Now, use Downloader to add my repository to your bot:
|
||||||
|
|
||||||
```
|
```
|
||||||
[p]repo add sea-cogs https://www.coastalcommits.com/SeaswimmerTheFsh/SeaCogs
|
[p]repo add sea-cogs https://www.coastalcommits.com/cswimr/SeaCogs
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, install the Pterodactyl cog:
|
Now, install the Pterodactyl cog:
|
||||||
|
|
|
@ -10,7 +10,7 @@ Pterodactyl allows for connecting to a Pterodactyl server through websockets. It
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[p]repo add seacogs https://www.coastalcommits.com/SeaswimmerTheFsh/SeaCogs
|
[p]repo add seacogs https://www.coastalcommits.com/cswimr/SeaCogs
|
||||||
[p]cog install seacogs pterodactyl
|
[p]cog install seacogs pterodactyl
|
||||||
[p]cog load aurora
|
[p]cog load aurora
|
||||||
```
|
```
|
||||||
|
|
|
@ -10,7 +10,7 @@ There are a few caveats to running an instance of Red on Pterodactyl.
|
||||||
|
|
||||||
- You will not receive any support from the Red developers.
|
- You will not receive any support from the Red developers.
|
||||||
- The built-in Audio cog will not work.
|
- The built-in Audio cog will not work.
|
||||||
- Depending on your host, you might have to request a [`tmpfs` size increase](https://github.com/ign-gg/Pterodactyl-Eggs/tree/master/bots/discord/redbot#additional-requirements).
|
- Depending on your host, you might have to request a [`tmpfs` size increase](https://github.com/pelican-eggs/eggs/tree/master/bots/discord/redbot#additional-requirements).
|
||||||
|
|
||||||
If these are unacceptable to you, you should [install Red normally](https://docs.discord.red/en/stable/install_guides/index.html).
|
If these are unacceptable to you, you should [install Red normally](https://docs.discord.red/en/stable/install_guides/index.html).
|
||||||
///
|
///
|
||||||
|
@ -64,7 +64,7 @@ Red is quite a large bot, so I'll focus on the specifics of getting the bot work
|
||||||
```
|
```
|
||||||
2. Add my repository to the bot
|
2. Add my repository to the bot
|
||||||
```bash
|
```bash
|
||||||
[p]repo add sea-cogs https://www.coastalcommits.com/SeaswimmerTheFsh/SeaCogs
|
[p]repo add sea-cogs https://www.coastalcommits.com/cswimr/SeaCogs
|
||||||
```
|
```
|
||||||
3. Install and load the Pterodactyl cog
|
3. Install and load the Pterodactyl cog
|
||||||
```bash
|
```bash
|
||||||
|
|
10
.envrc
Normal file
10
.envrc
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
if ! has nix_direnv_version || ! nix_direnv_version 2.2.1; then
|
||||||
|
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.2.1/direnvrc" "sha256-zelF0vLbEl5uaqrfIzbgNzJWGmLzCmYAkInj/LNxvKs="
|
||||||
|
fi
|
||||||
|
|
||||||
|
watch_file flake.nix
|
||||||
|
watch_file flake.lock
|
||||||
|
if ! use flake . --no-pure-eval
|
||||||
|
then
|
||||||
|
echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2
|
||||||
|
fi
|
|
@ -1,8 +1,6 @@
|
||||||
name: Bug Report
|
name: Bug Report
|
||||||
about: File a bug report
|
about: File a bug report
|
||||||
title: "[Cog Name] "
|
|
||||||
labels: [bug]
|
labels: [bug]
|
||||||
ref: master
|
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
@ -13,7 +11,7 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: Please confirm that;
|
label: Please confirm that;
|
||||||
options:
|
options:
|
||||||
- label: I have checked that this bug does not already have an opened/closed [issue](https://www.coastalcommits.com/SeaswimmerTheFsh/SeaCogs/issues) or [pull request](https://www.coastalcommits.com/SeaswimmerTheFsh/SeaCogs/pulls) associated with it.
|
- label: I have checked that this bug does not already have an opened/closed [issue](https://www.coastalcommits.com/cswimr/SeaCogs/issues) or [pull request](https://www.coastalcommits.com/cswimr/SeaCogs/pulls) associated with it.
|
||||||
required: true
|
required: true
|
||||||
- label: I have checked that I am on the latest version of [Red-DiscordBot](https://github.com/CogCreators/Red-DiscordBot), and SeaCogs.
|
- label: I have checked that I am on the latest version of [Red-DiscordBot](https://github.com/CogCreators/Red-DiscordBot), and SeaCogs.
|
||||||
required: true
|
required: true
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
name: Suggestion
|
name: Suggestion
|
||||||
about: Trying to suggest something for SeaCogs? Use this.
|
about: Trying to suggest something for SeaCogs? Use this.
|
||||||
title: "[Cog Name] "
|
labels: [enhancement]
|
||||||
labels: enhancement
|
|
||||||
ref: master
|
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
@ -13,7 +11,7 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: What cog is your feature request for?
|
label: What cog is your feature request for?
|
||||||
description: Specify the cog within the repository.
|
description: Specify the cog within the repository.
|
||||||
placeholder: E.g., ModerationCog
|
placeholder: E.g., Pterodactyl
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
|
|
||||||
<!-- Create a new issue, if it doesn't exist yet -->
|
<!-- Create a new issue, if it doesn't exist yet -->
|
||||||
|
|
||||||
- [ ] By submitting this pull request, I permit SeaswimmerTheFsh to license my work under
|
- [ ] By submitting this pull request, I permit cswimr to license my work under
|
||||||
the [Mozilla Public License Version 2.0](https://www.coastalcommits.com/SeaswimmerTheFsh/SeaCogs/src/branch/main/LICENSE).
|
the [Mozilla Public License Version 2.0](https://www.coastalcommits.com/cswimr/SeaCogs/src/branch/main/LICENSE).
|
||||||
|
|
|
@ -18,4 +18,5 @@
|
||||||
import-self,
|
import-self,
|
||||||
relative-beyond-top-level,
|
relative-beyond-top-level,
|
||||||
too-many-instance-attributes,
|
too-many-instance-attributes,
|
||||||
duplicate-code
|
duplicate-code,
|
||||||
|
too-many-nested-blocks
|
||||||
|
|
|
@ -1,39 +1,46 @@
|
||||||
name: Actions
|
name: Actions
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
|
||||||
- 'main'
|
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Lint Code (Ruff & Pylint):
|
lint:
|
||||||
|
name: Lint Code (Ruff & Pylint)
|
||||||
runs-on: docker
|
runs-on: docker
|
||||||
container: www.coastalcommits.com/seaswimmerthefsh/actionscontainers-seacogs:latest
|
container: www.coastalcommits.com/cswimr/actions:uv
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install python
|
||||||
|
run: uv python install 3.11
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: poetry install --with dev --no-root
|
run: uv sync
|
||||||
|
|
||||||
- name: Analysing code with Ruff
|
- name: Analysing code with Ruff
|
||||||
run: ./.venv/bin/ruff check $(git ls-files '*.py')
|
run: uv run ruff check $(git ls-files '*.py')
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Analysing code with Pylint
|
- name: Analysing code with Pylint
|
||||||
run: ./.venv/bin/pylint --rcfile=.forgejo/workflows/config/.pylintrc $(git ls-files '*.py')
|
run: uv run pylint --rcfile=.forgejo/workflows/config/.pylintrc $(git ls-files '*.py')
|
||||||
|
|
||||||
Build Documentation (MkDocs):
|
docs:
|
||||||
|
name: Build Documentation (MkDocs)
|
||||||
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
runs-on: docker
|
runs-on: docker
|
||||||
container: www.coastalcommits.com/seaswimmerthefsh/actionscontainers-seacogs:latest
|
container: www.coastalcommits.com/cswimr/actions:docs
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Install python
|
||||||
|
run: uv python install 3.11
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: poetry install --with docs --no-root
|
run: uv sync --no-dev --extra=documentation
|
||||||
|
|
||||||
- name: Set environment variables
|
- name: Set environment variables
|
||||||
uses: actions/env@v2
|
uses: actions/env@v2
|
||||||
|
@ -42,7 +49,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
export SITE_URL="https://$CI_ACTION_REF_NAME_SLUG.seacogs.coastalcommits.com"
|
export SITE_URL="https://$CI_ACTION_REF_NAME_SLUG.seacogs.coastalcommits.com"
|
||||||
export EDIT_URI="src/branch/$CI_ACTION_REF_NAME/.docs"
|
export EDIT_URI="src/branch/$CI_ACTION_REF_NAME/.docs"
|
||||||
./.venv/bin/mkdocs build -v
|
uv run mkdocs build -v
|
||||||
|
|
||||||
- name: Deploy documentation
|
- name: Deploy documentation
|
||||||
run: |
|
run: |
|
||||||
|
@ -58,7 +65,7 @@ jobs:
|
||||||
npx -p "@getmeli/cli" meli upload ./site \
|
npx -p "@getmeli/cli" meli upload ./site \
|
||||||
--url "https://pages.coastalcommits.com" \
|
--url "https://pages.coastalcommits.com" \
|
||||||
--site "${{ vars.MELI_SITE_ID }}" \
|
--site "${{ vars.MELI_SITE_ID }}" \
|
||||||
--token "${{ secrets.MELI_SITE_SECRET }}" \
|
--token "${{ secrets.MELI_TOKEN }}" \
|
||||||
--release "$CI_ACTION_REF_NAME_SLUG/${{ env.GITHUB_SHA }}" \
|
--release "$CI_ACTION_REF_NAME_SLUG/${{ env.GITHUB_SHA }}" \
|
||||||
--branch "$CI_ACTION_REF_NAME_SLUG"
|
--branch "$CI_ACTION_REF_NAME_SLUG"
|
||||||
|
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,3 +2,6 @@
|
||||||
.vscode
|
.vscode
|
||||||
site
|
site
|
||||||
.venv
|
.venv
|
||||||
|
__pycache__
|
||||||
|
.direnv
|
||||||
|
.devenv
|
||||||
|
|
|
@ -11,7 +11,7 @@ My assorted cogs for Red-DiscordBot.
|
||||||
To get started with a development environment, first clone this repository.
|
To get started with a development environment, first clone this repository.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://coastalcommits.com/SeaswimmerTheFsh/SeaCogs.git
|
git clone https://coastalcommits.com/cswimr/SeaCogs.git
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, install Poetry.
|
Then, install Poetry.
|
||||||
|
|
|
@ -9,14 +9,15 @@ import discord
|
||||||
from red_commons.logging import getLogger
|
from red_commons.logging import getLogger
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
from redbot.core.bot import Config, Red
|
from redbot.core.bot import Config, Red
|
||||||
from redbot.core.utils.chat_formatting import humanize_list
|
from redbot.core.utils.chat_formatting import bold, humanize_list
|
||||||
|
|
||||||
|
|
||||||
class AntiPolls(commands.Cog):
|
class AntiPolls(commands.Cog):
|
||||||
"""AntiPolls deletes messages that contain polls, with a configurable per-guild role and channel whitelist and support for default Discord permissions (Manage Messages)."""
|
"""AntiPolls deletes messages that contain polls, with a configurable per-guild role and channel whitelist and support for default Discord permissions (Manage Messages)."""
|
||||||
|
|
||||||
__author__ = ["SeaswimmerTheFsh"]
|
__author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"]
|
||||||
__version__ = "1.0.0"
|
__git__ = "https://www.coastalcommits.com/cswimr/SeaCogs"
|
||||||
|
__version__ = "1.0.1"
|
||||||
__documentation__ = "https://seacogs.coastalcommits.com/antipolls/"
|
__documentation__ = "https://seacogs.coastalcommits.com/antipolls/"
|
||||||
|
|
||||||
def __init__(self, bot: Red):
|
def __init__(self, bot: Red):
|
||||||
|
@ -38,9 +39,9 @@ class AntiPolls(commands.Cog):
|
||||||
n = "\n" if "\n\n" not in pre_processed else ""
|
n = "\n" if "\n\n" not in pre_processed else ""
|
||||||
text = [
|
text = [
|
||||||
f"{pre_processed}{n}",
|
f"{pre_processed}{n}",
|
||||||
f"Cog Version: **{self.__version__}**",
|
f"{bold('Cog Version:')} [{self.__version__}]({self.__git__})",
|
||||||
f"Author: {humanize_list(self.__author__)}",
|
f"{bold('Author:')} {humanize_list(self.__author__)}",
|
||||||
f"Documentation: {self.__documentation__}",
|
f"{bold('Documentation:')} {self.__documentation__}",
|
||||||
]
|
]
|
||||||
return "\n".join(text)
|
return "\n".join(text)
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"author" : ["SeaswimmerTheFsh (seasw.)"],
|
"author" : ["cswimr"],
|
||||||
"install_msg" : "Thank you for installing AntiPolls!\nYou can find the source code of this cog [here](https://coastalcommits.com/SeaswimmerTheFsh/SeaCogs).",
|
"install_msg" : "Thank you for installing AntiPolls!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).",
|
||||||
"name" : "AntiPolls",
|
"name" : "AntiPolls",
|
||||||
"short" : "AntiPolls deletes messages that contain polls.",
|
"short" : "AntiPolls deletes messages that contain polls.",
|
||||||
"description" : "AntiPolls deletes messages that contain polls, with a configurable per-guild role and channel whitelist and support for default Discord permissions (Manage Messages).",
|
"description" : "AntiPolls deletes messages that contain polls, with a configurable per-guild role and channel whitelist and support for default Discord permissions (Manage Messages).",
|
||||||
"end_user_data_statement" : "This cog does not store any user data.",
|
"end_user_data_statement" : "This cog does not store any user data.",
|
||||||
"hidden": false,
|
"hidden": true,
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"min_bot_version": "3.5.0",
|
"min_bot_version": "3.5.0",
|
||||||
"min_python_version": [3, 10, 0],
|
"min_python_version": [3, 10, 0],
|
||||||
|
|
|
@ -39,7 +39,7 @@ class Aurora(commands.Cog):
|
||||||
It is heavily inspired by GalacticBot, and is designed to be a more user-friendly alternative to Red's core Mod cogs.
|
It is heavily inspired by GalacticBot, and is designed to be a more user-friendly alternative to Red's core Mod cogs.
|
||||||
This cog stores all of its data in an SQLite database."""
|
This cog stores all of its data in an SQLite database."""
|
||||||
|
|
||||||
__author__ = ["SeaswimmerTheFsh"]
|
__author__ = ["cswimr"]
|
||||||
__version__ = "2.1.3"
|
__version__ = "2.1.3"
|
||||||
__documentation__ = "https://seacogs.coastalcommits.com/aurora/"
|
__documentation__ = "https://seacogs.coastalcommits.com/aurora/"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"author" : ["SeaswimmerTheFsh (seasw.)"],
|
"author" : ["cswimr"],
|
||||||
"install_msg" : "Thank you for installing Aurora!\nMost of this cog's functionality requires enabling slash commands.\nYou can find the source code of this cog [here](https://coastalcommits.com/SeaswimmerTheFsh/SeaCogs).",
|
"install_msg" : "Thank you for installing Aurora!\nMost of this cog's functionality requires enabling slash commands.\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).",
|
||||||
"name" : "Aurora",
|
"name" : "Aurora",
|
||||||
"short" : "A full replacement for Red's core Mod cogs.",
|
"short" : "A full replacement for Red's core Mod cogs.",
|
||||||
"description" : "Aurora is a fully-featured moderation system. It is heavily inspired by GalacticBot, and is designed to be a more user-friendly alternative to Red's core Mod cogs. This cog stores all of its data in an SQLite database.",
|
"description" : "Aurora is a fully-featured moderation system. It is heavily inspired by GalacticBot, and is designed to be a more user-friendly alternative to Red's core Mod cogs. This cog stores all of its data in an SQLite database.",
|
||||||
|
|
|
@ -14,15 +14,16 @@ from redbot.cogs.downloader import errors
|
||||||
from redbot.cogs.downloader.converters import InstalledCog
|
from redbot.cogs.downloader.converters import InstalledCog
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
from redbot.core.bot import Red
|
from redbot.core.bot import Red
|
||||||
from redbot.core.utils.chat_formatting import error, humanize_list, text_to_file
|
from redbot.core.utils.chat_formatting import bold, error, humanize_list, text_to_file
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
class Backup(commands.Cog):
|
class Backup(commands.Cog):
|
||||||
"""A utility to make reinstalling repositories and cogs after migrating the bot far easier."""
|
"""A utility to make reinstalling repositories and cogs after migrating the bot far easier."""
|
||||||
|
|
||||||
__author__ = ["SeaswimmerTheFsh"]
|
__author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"]
|
||||||
__version__ = "1.1.0"
|
__git__ = "https://www.coastalcommits.com/cswimr/SeaCogs"
|
||||||
|
__version__ = "1.1.1"
|
||||||
__documentation__ = "https://seacogs.coastalcommits.com/backup/"
|
__documentation__ = "https://seacogs.coastalcommits.com/backup/"
|
||||||
|
|
||||||
def __init__(self, bot: Red):
|
def __init__(self, bot: Red):
|
||||||
|
@ -35,9 +36,9 @@ class Backup(commands.Cog):
|
||||||
n = "\n" if "\n\n" not in pre_processed else ""
|
n = "\n" if "\n\n" not in pre_processed else ""
|
||||||
text = [
|
text = [
|
||||||
f"{pre_processed}{n}",
|
f"{pre_processed}{n}",
|
||||||
f"Cog Version: **{self.__version__}**",
|
f"{bold('Cog Version:')} [{self.__version__}]({self.__git__})",
|
||||||
f"Author: {humanize_list(self.__author__)}",
|
f"{bold('Author:')} {humanize_list(self.__author__)}",
|
||||||
f"Documentation: {self.__documentation__}",
|
f"{bold('Documentation:')} {self.__documentation__}",
|
||||||
]
|
]
|
||||||
return "\n".join(text)
|
return "\n".join(text)
|
||||||
|
|
||||||
|
@ -100,7 +101,7 @@ class Backup(commands.Cog):
|
||||||
except (json.JSONDecodeError, IndexError):
|
except (json.JSONDecodeError, IndexError):
|
||||||
try:
|
try:
|
||||||
export = json.loads(await ctx.message.reference.resolved.attachments[0].read())
|
export = json.loads(await ctx.message.reference.resolved.attachments[0].read())
|
||||||
except (json.JSONDecodeError, IndexError):
|
except (json.JSONDecodeError, IndexError, AttributeError):
|
||||||
await ctx.send(error("Please provide a valid JSON export file."))
|
await ctx.send(error("Please provide a valid JSON export file."))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -196,7 +197,7 @@ class Backup(commands.Cog):
|
||||||
cog_modules = []
|
cog_modules = []
|
||||||
for cog in cogs:
|
for cog in cogs:
|
||||||
# If you're forking this cog, make sure to change these strings!
|
# If you're forking this cog, make sure to change these strings!
|
||||||
if cog["name"] == "backup" and "SeaswimmerTheFsh/SeaCogs" in url:
|
if cog["name"] == "backup" and "cswimr/SeaCogs" in url:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
cog_module = await InstalledCog.convert(ctx, cog["name"])
|
cog_module = await InstalledCog.convert(ctx, cog["name"])
|
||||||
|
@ -232,7 +233,7 @@ class Backup(commands.Cog):
|
||||||
commit = None
|
commit = None
|
||||||
|
|
||||||
# If you're forking this cog, make sure to change these strings!
|
# If you're forking this cog, make sure to change these strings!
|
||||||
if cog_name == "backup" and "SeaswimmerTheFsh/SeaCogs" in url:
|
if cog_name == "backup" and "cswimr/SeaCogs" in url:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
async with repository.checkout(
|
async with repository.checkout(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"author" : ["SeaswimmerTheFsh (seasw.)"],
|
"author" : ["cswimr"],
|
||||||
"install_msg" : "Thank you for installing Backup!\nYou can find the source code of this cog [here](https://coastalcommits.com/SeaswimmerTheFsh/SeaCogs).",
|
"install_msg" : "Thank you for installing Backup!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).",
|
||||||
"name" : "Backup",
|
"name" : "Backup",
|
||||||
"short" : "A utility to make reinstalling repositories and cogs after migrating the bot far easier.",
|
"short" : "A utility to make reinstalling repositories and cogs after migrating the bot far easier.",
|
||||||
"description" : "A utility to make reinstalling repositories and cogs after migrating the bot far easier.",
|
"description" : "A utility to make reinstalling repositories and cogs after migrating the bot far easier.",
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"min_bot_version": "3.5.6",
|
"min_bot_version": "3.5.6",
|
||||||
"max_bot_version": "3.5.9",
|
"max_bot_version": "3.5.13",
|
||||||
"min_python_version": [3, 9, 0],
|
"min_python_version": [3, 9, 0],
|
||||||
"tags": [
|
"tags": [
|
||||||
"utility",
|
"utility",
|
||||||
|
|
|
@ -15,7 +15,7 @@ from PIL import Image
|
||||||
from red_commons.logging import getLogger
|
from red_commons.logging import getLogger
|
||||||
from redbot.core import Config, commands, data_manager
|
from redbot.core import Config, commands, data_manager
|
||||||
from redbot.core.bot import Red
|
from redbot.core.bot import Red
|
||||||
from redbot.core.utils.chat_formatting import error, humanize_list
|
from redbot.core.utils.chat_formatting import bold, error, humanize_list
|
||||||
|
|
||||||
import bible.errors
|
import bible.errors
|
||||||
from bible.models import Version
|
from bible.models import Version
|
||||||
|
@ -24,9 +24,10 @@ from bible.models import Version
|
||||||
class Bible(commands.Cog):
|
class Bible(commands.Cog):
|
||||||
"""Retrieve Bible verses from the API.bible API."""
|
"""Retrieve Bible verses from the API.bible API."""
|
||||||
|
|
||||||
__author__ = ["SeaswimmerTheFsh"]
|
__author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"]
|
||||||
__version__ = "1.1.0"
|
__git__ = "https://www.coastalcommits.com/cswimr/SeaCogs"
|
||||||
__documentation__ = "https://seacogs.coastalcommits.com/bible/"
|
__version__ = "1.1.1"
|
||||||
|
__documentation__ = "https://seacogs.coastalcommits.com/pterodactyl/"
|
||||||
|
|
||||||
def __init__(self, bot: Red):
|
def __init__(self, bot: Red):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -44,12 +45,13 @@ class Bible(commands.Cog):
|
||||||
n = "\n" if "\n\n" not in pre_processed else ""
|
n = "\n" if "\n\n" not in pre_processed else ""
|
||||||
text = [
|
text = [
|
||||||
f"{pre_processed}{n}",
|
f"{pre_processed}{n}",
|
||||||
f"Cog Version: **{self.__version__}**",
|
f"{bold('Cog Version:')} [{self.__version__}]({self.__git__})",
|
||||||
f"Author: {humanize_list(self.__author__)}",
|
f"{bold('Author:')} {humanize_list(self.__author__)}",
|
||||||
f"Documentation: {self.__documentation__}",
|
f"{bold('Documentation:')} {self.__documentation__}",
|
||||||
]
|
]
|
||||||
return "\n".join(text)
|
return "\n".join(text)
|
||||||
|
|
||||||
|
|
||||||
def get_icon(self, color: Colour) -> File:
|
def get_icon(self, color: Colour) -> File:
|
||||||
"""Get the docs.api.bible favicon with a given color."""
|
"""Get the docs.api.bible favicon with a given color."""
|
||||||
image_path = data_manager.bundled_data_path(self) / "api.bible-logo.png"
|
image_path = data_manager.bundled_data_path(self) / "api.bible-logo.png"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"author" : ["SeaswimmerTheFsh (seasw.)"],
|
"author" : ["cswimr"],
|
||||||
"install_msg" : "Thank you for installing Bible!\nThis cog requires setting an API key for API.Bible. Please read the [documentation](https://seacogs.coastalcommits.com/bible/#setup) for more information.\nYou can find the source code of this cog [here](https://coastalcommits.com/SeaswimmerTheFsh/SeaCogs).",
|
"install_msg" : "Thank you for installing Bible!\nThis cog requires setting an API key for API.Bible. Please read the [documentation](https://seacogs.coastalcommits.com/bible/#setup) for more information.\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).",
|
||||||
"name" : "Bible",
|
"name" : "Bible",
|
||||||
"short" : "Retrieve Bible verses from API.Bible.",
|
"short" : "Retrieve Bible verses from API.Bible.",
|
||||||
"description" : "Retrieve Bible verses from the API.Bible API. This cog requires an API.Bible api key.",
|
"description" : "Retrieve Bible verses from the API.Bible API. This cog requires an API.Bible api key.",
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import io
|
import io
|
||||||
from typing import Any, Literal
|
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import discord
|
import discord
|
||||||
|
@ -15,9 +14,10 @@ from .model import PartialEmoji
|
||||||
class EmojiInfo(commands.Cog):
|
class EmojiInfo(commands.Cog):
|
||||||
"""Retrieve information about emojis."""
|
"""Retrieve information about emojis."""
|
||||||
|
|
||||||
__author__: list[str] = ["SeaswimmerTheFsh"]
|
__author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"]
|
||||||
__version__: str = "1.0.0"
|
__git__ = "https://www.coastalcommits.com/cswimr/SeaCogs"
|
||||||
__documentation__: str = "https://seacogs.coastalcommits.com/emojiinfo/"
|
__version__ = "1.0.1"
|
||||||
|
__documentation__ = "https://seacogs.coastalcommits.com/emojiinfo/"
|
||||||
|
|
||||||
def __init__(self, bot: Red) -> None:
|
def __init__(self, bot: Red) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -25,16 +25,17 @@ class EmojiInfo(commands.Cog):
|
||||||
self.logger: RedTraceLogger = getLogger(name="red.SeaCogs.Emoji")
|
self.logger: RedTraceLogger = getLogger(name="red.SeaCogs.Emoji")
|
||||||
|
|
||||||
def format_help_for_context(self, ctx: commands.Context) -> str:
|
def format_help_for_context(self, ctx: commands.Context) -> str:
|
||||||
pre_processed: Any | Literal[''] = super().format_help_for_context(ctx) or ""
|
pre_processed = super().format_help_for_context(ctx) or ""
|
||||||
n: Literal['\n'] | Literal[''] = "\n" if "\n\n" not in pre_processed else ""
|
n = "\n" if "\n\n" not in pre_processed else ""
|
||||||
text: list[str] = [
|
text = [
|
||||||
f"{pre_processed}{n}",
|
f"{pre_processed}{n}",
|
||||||
f"Cog Version: **{self.__version__}**",
|
f"{bold('Cog Version:')} [{self.__version__}]({self.__git__})",
|
||||||
f"Author: {humanize_list(items=self.__author__)}",
|
f"{bold('Author:')} {humanize_list(self.__author__)}",
|
||||||
f"Documentation: {self.__documentation__}",
|
f"{bold('Documentation:')} {self.__documentation__}",
|
||||||
]
|
]
|
||||||
return "\n".join(text)
|
return "\n".join(text)
|
||||||
|
|
||||||
|
|
||||||
async def fetch_twemoji(self, unicode_emoji) -> str:
|
async def fetch_twemoji(self, unicode_emoji) -> str:
|
||||||
base_url = "https://cdn.jsdelivr.net/gh/jdecked/twemoji@latest/assets/72x72/"
|
base_url = "https://cdn.jsdelivr.net/gh/jdecked/twemoji@latest/assets/72x72/"
|
||||||
emoji_codepoint = "-".join([hex(ord(char))[2:] for char in unicode_emoji])
|
emoji_codepoint = "-".join([hex(ord(char))[2:] for char in unicode_emoji])
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"author" : ["SeaswimmerTheFsh (seasw.)"],
|
"author" : ["cswimr"],
|
||||||
"install_msg" : "Thank you for installing Emoji!",
|
"install_msg" : "Thank you for installing Emoji!",
|
||||||
"name" : "Emoji",
|
"name" : "Emoji",
|
||||||
"short" : "Retrieve information about emojis.",
|
"short" : "Retrieve information about emojis.",
|
||||||
|
|
|
@ -81,6 +81,7 @@ class PartialEmoji(discord.PartialEmoji):
|
||||||
with open(path, "r", encoding="UTF-8") as file:
|
with open(path, "r", encoding="UTF-8") as file:
|
||||||
emojis: dict = json.load(file)
|
emojis: dict = json.load(file)
|
||||||
emoji_aliases = []
|
emoji_aliases = []
|
||||||
|
emoji_group = None
|
||||||
for dict_name, group in emojis.items():
|
for dict_name, group in emojis.items():
|
||||||
for k, v in group.items():
|
for k, v in group.items():
|
||||||
if v == value:
|
if v == value:
|
||||||
|
|
303
flake.lock
Normal file
303
flake.lock
Normal file
|
@ -0,0 +1,303 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"cachix": {
|
||||||
|
"inputs": {
|
||||||
|
"devenv": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"flake-compat": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"git-hooks": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1728672398,
|
||||||
|
"narHash": "sha256-KxuGSoVUFnQLB2ZcYODW7AVPAh9JqRlD5BrfsC/Q4qs=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "cachix",
|
||||||
|
"rev": "aac51f698309fd0f381149214b7eee213c66ef0a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"ref": "latest",
|
||||||
|
"repo": "cachix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"devenv": {
|
||||||
|
"inputs": {
|
||||||
|
"cachix": "cachix",
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"git-hooks": "git-hooks",
|
||||||
|
"nix": "nix",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1732121232,
|
||||||
|
"narHash": "sha256-CmJt7aeSCJnJYGtYpyslRI+pC28RPVD43PD/7kkIVuM=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv",
|
||||||
|
"rev": "6ff1e5f92c0d74bbb12f7454a239ca2f02e05ea1",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-compat": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1696426674,
|
||||||
|
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-compat_2": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1696426674,
|
||||||
|
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"devenv",
|
||||||
|
"nix",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1712014858,
|
||||||
|
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"git-hooks": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"gitignore": "gitignore",
|
||||||
|
"nixpkgs": [
|
||||||
|
"devenv",
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"nixpkgs-stable": [
|
||||||
|
"devenv"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1730302582,
|
||||||
|
"narHash": "sha256-W1MIJpADXQCgosJZT8qBYLRuZls2KSiKdpnTVdKBuvU=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"rev": "af8a16fe5c264f5e9e18bcee2859b40a656876cf",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gitignore": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"devenv",
|
||||||
|
"git-hooks",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1709087332,
|
||||||
|
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "gitignore.nix",
|
||||||
|
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "gitignore.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libgit2": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1697646580,
|
||||||
|
"narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=",
|
||||||
|
"owner": "libgit2",
|
||||||
|
"repo": "libgit2",
|
||||||
|
"rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "libgit2",
|
||||||
|
"repo": "libgit2",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nix": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"libgit2": "libgit2",
|
||||||
|
"nixpkgs": "nixpkgs_2",
|
||||||
|
"nixpkgs-23-11": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"nixpkgs-regression": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"pre-commit-hooks": [
|
||||||
|
"devenv"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1727438425,
|
||||||
|
"narHash": "sha256-X8ES7I1cfNhR9oKp06F6ir4Np70WGZU5sfCOuNBEwMg=",
|
||||||
|
"owner": "domenkozar",
|
||||||
|
"repo": "nix",
|
||||||
|
"rev": "f6c5ae4c1b2e411e6b1e6a8181cc84363d6a7546",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "domenkozar",
|
||||||
|
"ref": "devenv-2.24",
|
||||||
|
"repo": "nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1730531603,
|
||||||
|
"narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "7ffd9ae656aec493492b44d0ddfb28e79a1ea25d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-python": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat_2",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1730716553,
|
||||||
|
"narHash": "sha256-n4cibCp/ggDlSacCTnP8dVnywclQKYcHy6PRfe35Hk0=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "nixpkgs-python",
|
||||||
|
"rev": "8fcdb8ec34a1c2bae3f5326873a41b310e948ccc",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "nixpkgs-python",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1717432640,
|
||||||
|
"narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "88269ab3044128b7c2f4c7d68448b2fb50456870",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "release-24.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731676054,
|
||||||
|
"narHash": "sha256-OZiZ3m8SCMfh3B6bfGC/Bm4x3qc1m2SVEAlkV6iY7Yg=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "5e4fbfb6b3de1aa2872b76d49fafc942626e2add",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"devenv": "devenv",
|
||||||
|
"nixpkgs": "nixpkgs_3",
|
||||||
|
"nixpkgs-python": "nixpkgs-python",
|
||||||
|
"systems": "systems"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
46
flake.nix
Normal file
46
flake.nix
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
nixpkgs-python.url = "github:cachix/nixpkgs-python";
|
||||||
|
nixpkgs-python.inputs = { nixpkgs.follows = "nixpkgs"; };
|
||||||
|
systems.url = "github:nix-systems/default";
|
||||||
|
devenv.url = "github:cachix/devenv";
|
||||||
|
devenv.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
nixConfig = {
|
||||||
|
extra-trusted-public-keys =
|
||||||
|
"devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=";
|
||||||
|
extra-substituters = "https://devenv.cachix.org";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, devenv, systems, ... }@inputs:
|
||||||
|
let forEachSystem = nixpkgs.lib.genAttrs (import systems);
|
||||||
|
in {
|
||||||
|
packages = forEachSystem (system: {
|
||||||
|
devenv-up = self.devShells.${system}.default.config.procfileScript;
|
||||||
|
devenv-test = self.devShells.${system}.default.config.test;
|
||||||
|
});
|
||||||
|
|
||||||
|
devShells = forEachSystem (system:
|
||||||
|
let pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
in {
|
||||||
|
default = devenv.lib.mkShell {
|
||||||
|
inherit inputs pkgs;
|
||||||
|
modules = [{
|
||||||
|
languages.python = {
|
||||||
|
enable = true;
|
||||||
|
version = "3.11";
|
||||||
|
uv = {
|
||||||
|
enable = true;
|
||||||
|
sync = {
|
||||||
|
enable = true;
|
||||||
|
allExtras = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"author": [
|
"author": [
|
||||||
"SeaswimmerTheFsh (seasw.)"
|
"cswimr"
|
||||||
],
|
],
|
||||||
"install_msg": "Thanks for installing my repo!\n\nIf you have any issues with any of the cogs, please create an issue [here](https://coastalcommits.com/SeaswimmerTheFsh/SeaCogs/issues) or join my [Discord Server](https://discord.gg/eMUMe77Yb8 ).",
|
"install_msg": "Thanks for installing my repo!\n\nIf you have any issues with any of the cogs, please create an issue [here](https://coastalcommits.com/cswimr/SeaCogs/issues) or join my [Discord Server](https://discord.gg/eMUMe77Yb8 ).",
|
||||||
"index_name": "sea-cogs",
|
"index_name": "sea-cogs",
|
||||||
"short": "Various cogs for Red, by SeaswimmerTheFsh (seasw.)",
|
"short": "Various cogs for Red, by cswimr",
|
||||||
"description": "Various cogs for Red, by SeaswimmerTheFsh (seasw.)"
|
"description": "Various cogs for Red, by cswimr"
|
||||||
}
|
}
|
||||||
|
|
10
mkdocs.yml
10
mkdocs.yml
|
@ -1,12 +1,12 @@
|
||||||
site_name: SeaCogs Documentation
|
site_name: SeaCogs Documentation
|
||||||
site_url: !ENV [SITE_URL, 'https://seacogs.coastalcommits.com']
|
site_url: !ENV [SITE_URL, 'https://seacogs.coastalcommits.com']
|
||||||
repo_name: CoastalCommits
|
repo_name: CoastalCommits
|
||||||
repo_url: https://coastalcommits.com/SeaswimmerTheFsh/SeaCogs
|
repo_url: https://coastalcommits.com/cswimr/SeaCogs
|
||||||
edit_uri: !ENV [EDIT_URI, 'src/branch/main/.docs']
|
edit_uri: !ENV [EDIT_URI, 'src/branch/main/.docs']
|
||||||
copyright: Copyright © 2023-2024, SeaswimmerTheFsh
|
copyright: Copyright © 2023-2024, cswimr
|
||||||
docs_dir: .docs
|
docs_dir: .docs
|
||||||
|
|
||||||
site_author: SeaswimmerTheFsh
|
site_author: cswimr
|
||||||
site_description: Documentation for my Red-DiscordBot Cogs.
|
site_description: Documentation for my Red-DiscordBot Cogs.
|
||||||
|
|
||||||
nav:
|
nav:
|
||||||
|
@ -30,7 +30,7 @@ nav:
|
||||||
plugins:
|
plugins:
|
||||||
- git-authors
|
- git-authors
|
||||||
- search
|
- search
|
||||||
#- social
|
- social
|
||||||
- git-revision-date-localized:
|
- git-revision-date-localized:
|
||||||
enable_creation_date: true
|
enable_creation_date: true
|
||||||
type: timeago
|
type: timeago
|
||||||
|
@ -113,3 +113,5 @@ watch:
|
||||||
- ./bible
|
- ./bible
|
||||||
- ./nerdify
|
- ./nerdify
|
||||||
- ./pterodactyl
|
- ./pterodactyl
|
||||||
|
- ./emojiinfo
|
||||||
|
- ./antipolls
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"author" : ["SeaswimmerTheFsh (seasw.)"],
|
"author" : ["cswimr"],
|
||||||
"install_msg" : "Thank you for installing Nerdify!\nYou can find the source code of this cog [here](https://coastalcommits.com/SeaswimmerTheFsh/SeaCogs). Based off of PhasecoreX's [UwU](<https://github.com/PhasecoreX/PCXCogs/tree/master/uwu>) cog.",
|
"install_msg" : "Thank you for installing Nerdify!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs). Based off of PhasecoreX's [UwU](<https://github.com/PhasecoreX/PCXCogs/tree/master/uwu>) cog.",
|
||||||
"name" : "Nerdify",
|
"name" : "Nerdify",
|
||||||
"short" : "Nerdify your text!",
|
"short" : "Nerdify your text!",
|
||||||
"description" : "Nerdify your text!",
|
"description" : "Nerdify your text!",
|
||||||
|
|
|
@ -12,13 +12,15 @@ from typing import Any, Optional, Union
|
||||||
import discord
|
import discord
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
from redbot.core.utils import chat_formatting, common_filters
|
from redbot.core.utils import chat_formatting, common_filters
|
||||||
|
from redbot.core.utils.chat_formatting import bold, humanize_list
|
||||||
|
|
||||||
|
|
||||||
class Nerdify(commands.Cog):
|
class Nerdify(commands.Cog):
|
||||||
"""Nerdify your text."""
|
"""Nerdify your text."""
|
||||||
|
|
||||||
__author__ = ["SeaswimmerTheFsh"]
|
__author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"]
|
||||||
__version__ = "1.3.4"
|
__git__ = "https://www.coastalcommits.com/cswimr/SeaCogs"
|
||||||
|
__version__ = "1.3.5"
|
||||||
__documentation__ = "https://seacogs.coastalcommits.com/nerdify/"
|
__documentation__ = "https://seacogs.coastalcommits.com/nerdify/"
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
@ -29,12 +31,13 @@ class Nerdify(commands.Cog):
|
||||||
n = "\n" if "\n\n" not in pre_processed else ""
|
n = "\n" if "\n\n" not in pre_processed else ""
|
||||||
text = [
|
text = [
|
||||||
f"{pre_processed}{n}",
|
f"{pre_processed}{n}",
|
||||||
f"Cog Version: **{self.__version__}**",
|
f"{bold('Cog Version:')} [{self.__version__}]({self.__git__})",
|
||||||
f"Author: {chat_formatting.humanize_list(self.__author__)}",
|
f"{bold('Author:')} {humanize_list(self.__author__)}",
|
||||||
f"Documentation: {self.__documentation__}"
|
f"{bold('Documentation:')} {self.__documentation__}",
|
||||||
]
|
]
|
||||||
return "\n".join(text)
|
return "\n".join(text)
|
||||||
|
|
||||||
|
|
||||||
@commands.command(aliases=["nerd"])
|
@commands.command(aliases=["nerd"])
|
||||||
async def nerdify(
|
async def nerdify(
|
||||||
self, ctx: commands.Context, *, text: Optional[str] = None
|
self, ctx: commands.Context, *, text: Optional[str] = None
|
||||||
|
|
2454
poetry.lock
generated
2454
poetry.lock
generated
File diff suppressed because it is too large
Load diff
BIN
pterodactyl/data/unknown.png
Normal file
BIN
pterodactyl/data/unknown.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"author" : ["SeaswimmerTheFsh (seasw.)"],
|
"author" : ["cswimr"],
|
||||||
"install_msg" : "Thank you for installing Pterodactyl!\nYou can find the source code of this cog [here](https://coastalcommits.com/SeaswimmerTheFsh/SeaCogs).\nDocumentation can be found [here](https://seacogs.coastalcommits.com/pterodactyl ).",
|
"install_msg" : "Thank you for installing Pterodactyl!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).\nDocumentation can be found [here](https://seacogs.coastalcommits.com/pterodactyl ).",
|
||||||
"name" : "Pterodactyl",
|
"name" : "Pterodactyl",
|
||||||
"short" : "Interface with Pterodactyl through websockets.",
|
"short" : "Interface with Pterodactyl through websockets.",
|
||||||
"description" : "Interface with Pterodactyl through websockets.",
|
"description" : "Interface with Pterodactyl through websockets.",
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"min_bot_version": "3.5.0",
|
"min_bot_version": "3.5.0",
|
||||||
"min_python_version": [3, 8, 0],
|
"min_python_version": [3, 8, 0],
|
||||||
"requirements": ["git+https://github.com/SeaswimmerTheFsh/pydactyl", "websockets"],
|
"requirements": ["git+https://github.com/cswimr/pydactyl", "websockets"],
|
||||||
"tags": [
|
"tags": [
|
||||||
"pterodactyl",
|
"pterodactyl",
|
||||||
"minecraft",
|
"minecraft",
|
||||||
|
|
|
@ -9,7 +9,7 @@ from pydactyl import PterodactylClient
|
||||||
from redbot.core import app_commands, commands
|
from redbot.core import app_commands, commands
|
||||||
from redbot.core.app_commands import Choice
|
from redbot.core.app_commands import Choice
|
||||||
from redbot.core.bot import Red
|
from redbot.core.bot import Red
|
||||||
from redbot.core.utils.chat_formatting import box, error, humanize_list
|
from redbot.core.utils.chat_formatting import bold, box, error, humanize_list
|
||||||
from redbot.core.utils.views import ConfirmView
|
from redbot.core.utils.views import ConfirmView
|
||||||
|
|
||||||
from pterodactyl import mcsrvstatus
|
from pterodactyl import mcsrvstatus
|
||||||
|
@ -20,8 +20,9 @@ from pterodactyl.logger import logger
|
||||||
class Pterodactyl(commands.Cog):
|
class Pterodactyl(commands.Cog):
|
||||||
"""Pterodactyl allows you to manage your Pterodactyl Panel from Discord."""
|
"""Pterodactyl allows you to manage your Pterodactyl Panel from Discord."""
|
||||||
|
|
||||||
__author__ = ["SeaswimmerTheFsh"]
|
__author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"]
|
||||||
__version__ = "2.0.0"
|
__git__ = "https://www.coastalcommits.com/cswimr/SeaCogs"
|
||||||
|
__version__ = "2.0.4"
|
||||||
__documentation__ = "https://seacogs.coastalcommits.com/pterodactyl/"
|
__documentation__ = "https://seacogs.coastalcommits.com/pterodactyl/"
|
||||||
|
|
||||||
def __init__(self, bot: Red):
|
def __init__(self, bot: Red):
|
||||||
|
@ -39,12 +40,29 @@ class Pterodactyl(commands.Cog):
|
||||||
n = "\n" if "\n\n" not in pre_processed else ""
|
n = "\n" if "\n\n" not in pre_processed else ""
|
||||||
text = [
|
text = [
|
||||||
f"{pre_processed}{n}",
|
f"{pre_processed}{n}",
|
||||||
f"Cog Version: **{self.__version__}**",
|
f"{bold('Cog Version:')} [{self.__version__}]({self.__git__})",
|
||||||
f"Author: {humanize_list(self.__author__)}",
|
f"{bold('Author:')} {humanize_list(self.__author__)}",
|
||||||
f"Documentation: {self.__documentation__}",
|
f"{bold('Documentation:')} {self.__documentation__}",
|
||||||
]
|
]
|
||||||
return "\n".join(text)
|
return "\n".join(text)
|
||||||
|
|
||||||
|
async def cog_load(self) -> None:
|
||||||
|
pterodactyl_keys = await self.bot.get_shared_api_tokens("pterodactyl")
|
||||||
|
api_key = pterodactyl_keys.get("api_key")
|
||||||
|
if api_key is None:
|
||||||
|
self.task.cancel()
|
||||||
|
raise ValueError("Pterodactyl API key not set. Please set it using `[p]set api`.")
|
||||||
|
base_url = await config.base_url()
|
||||||
|
if base_url is None:
|
||||||
|
self.task.cancel()
|
||||||
|
raise ValueError("Pterodactyl base URL not set. Please set it using `[p]pterodactyl config url`.")
|
||||||
|
server_id = await config.server_id()
|
||||||
|
if server_id is None:
|
||||||
|
self.task.cancel()
|
||||||
|
raise ValueError("Pterodactyl server ID not set. Please set it using `[p]pterodactyl config serverid`.")
|
||||||
|
|
||||||
|
self.client = PterodactylClient(base_url, api_key).client
|
||||||
|
|
||||||
async def cog_unload(self) -> None:
|
async def cog_unload(self) -> None:
|
||||||
self.update_topic.cancel()
|
self.update_topic.cancel()
|
||||||
self.task.cancel()
|
self.task.cancel()
|
||||||
|
@ -175,76 +193,47 @@ class Pterodactyl(commands.Cog):
|
||||||
|
|
||||||
async def power(self, ctx: Union[discord.Interaction, commands.Context], action: str, action_ing: str, warning: str = '') -> None:
|
async def power(self, ctx: Union[discord.Interaction, commands.Context], action: str, action_ing: str, warning: str = '') -> None:
|
||||||
if isinstance(ctx, discord.Interaction):
|
if isinstance(ctx, discord.Interaction):
|
||||||
author = ctx.user
|
ctx = await self.bot.get_context(ctx)
|
||||||
else:
|
|
||||||
author = ctx.author
|
|
||||||
|
|
||||||
current_status = await config.current_status()
|
current_status = await config.current_status()
|
||||||
|
|
||||||
if current_status == action_ing:
|
if current_status == action_ing:
|
||||||
if isinstance(ctx, discord.Interaction):
|
return await ctx.send(f"Server is already {action_ing}.", ephemeral=True)
|
||||||
return await ctx.response.send_message(f"Server is already {action_ing}.", ephemeral=True)
|
|
||||||
return await ctx.send(f"Server is already {action_ing}.")
|
|
||||||
|
|
||||||
if current_status in ["starting", "stopping"] and action != "kill":
|
if current_status in ["starting", "stopping"] and action != "kill":
|
||||||
if isinstance(ctx, discord.Interaction):
|
return await ctx.send("Another power action is already in progress.", ephemeral=True)
|
||||||
return await ctx.response.send_message("Another power action is already in progress.", ephemeral=True)
|
|
||||||
return await ctx.send("Another power action is already in progress.")
|
|
||||||
|
|
||||||
view = ConfirmView(author, disable_buttons=True)
|
view = ConfirmView(ctx.author, disable_buttons=True)
|
||||||
|
|
||||||
if isinstance(ctx, discord.Interaction):
|
message = await ctx.send(f"{warning}Are you sure you want to {action} the server?", view=view)
|
||||||
await ctx.response.send_message(f"{warning}Are you sure you want to {action} the server?", view=view)
|
|
||||||
else:
|
|
||||||
message = await ctx.send(f"{warning}Are you sure you want to {action} the server?", view=view)
|
|
||||||
|
|
||||||
await view.wait()
|
await view.wait()
|
||||||
|
|
||||||
if view.result is True:
|
if view.result is True:
|
||||||
if isinstance(ctx, discord.Interaction):
|
await message.edit(content=f"Sending websocket command to {action} server...", view=None)
|
||||||
await ctx.edit_original_response(content=f"Sending websocket command to {action} server...", view=None)
|
|
||||||
else:
|
|
||||||
await message.edit(content=f"Sending websocket command to {action} server...", view=None)
|
|
||||||
|
|
||||||
await self.websocket.send(json.dumps({"event": "set state", "args": [action]}))
|
await self.websocket.send(json.dumps({"event": "set state", "args": [action]}))
|
||||||
|
|
||||||
if isinstance(ctx, discord.Interaction):
|
await message.edit(content=f"Server {action_ing}", view=None)
|
||||||
await ctx.edit_original_response(content=f"Server {action_ing}", view=None)
|
|
||||||
else:
|
|
||||||
await message.edit(content=f"Server {action_ing}", view=None)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if isinstance(ctx, discord.Interaction):
|
await message.edit(content="Cancelled.", view=None)
|
||||||
await ctx.edit_original_response(content="Cancelled.", view=None)
|
|
||||||
else:
|
|
||||||
await message.edit(content="Cancelled.", view=None)
|
|
||||||
|
|
||||||
async def send_command(self, ctx: Union[discord.Interaction, commands.Context], command: str):
|
async def send_command(self, ctx: Union[discord.Interaction, commands.Context], command: str):
|
||||||
channel = self.bot.get_channel(await config.console_channel())
|
channel = self.bot.get_channel(await config.console_channel())
|
||||||
if isinstance(ctx, discord.Interaction):
|
if isinstance(ctx, discord.Interaction):
|
||||||
if channel:
|
ctx = await self.bot.get_context(ctx)
|
||||||
await channel.send(f"Received console command from {ctx.user.id}: {command[:1900]}", allowed_mentions=discord.AllowedMentions.none())
|
if channel:
|
||||||
try:
|
await channel.send(f"Received console command from {ctx.author.id}: {command[:1900]}", allowed_mentions=discord.AllowedMentions.none())
|
||||||
await self.websocket.send(json.dumps({"event": "send command", "args": [command]}))
|
try:
|
||||||
await ctx.response.send_message(f"Command sent to server. {box(command, 'json')}", ephemeral=True)
|
await self.websocket.send(json.dumps({"event": "send command", "args": [command]}))
|
||||||
except websockets.exceptions.ConnectionClosed as e:
|
await ctx.send(f"Command sent to server. {box(command, 'json')}")
|
||||||
logger.error("WebSocket connection closed: %s", e)
|
except websockets.exceptions.ConnectionClosed as e:
|
||||||
await ctx.response.send_message(error("WebSocket connection closed."))
|
logger.error("WebSocket connection closed: %s", e)
|
||||||
self.task.cancel()
|
await ctx.send(error("WebSocket connection closed."))
|
||||||
self.retry_counter = 0
|
self.task.cancel()
|
||||||
self.task = self.get_task()
|
self.retry_counter = 0
|
||||||
else:
|
self.task = self.get_task()
|
||||||
if channel:
|
|
||||||
await channel.send(f"Received console command from {ctx.author.id}: {command[:1900]}", allowed_mentions=discord.AllowedMentions.none())
|
|
||||||
try:
|
|
||||||
await self.websocket.send(json.dumps({"event": "send command", "args": [command]}))
|
|
||||||
await ctx.send(f"Command sent to server. {box(command, 'json')}")
|
|
||||||
except websockets.exceptions.ConnectionClosed as e:
|
|
||||||
logger.error("WebSocket connection closed: %s", e)
|
|
||||||
await ctx.send(error("WebSocket connection closed."))
|
|
||||||
self.task.cancel()
|
|
||||||
self.retry_counter = 0
|
|
||||||
self.task = self.get_task()
|
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_red_api_tokens_update(self, service_name: str, api_tokens: Mapping[str,str]): # pylint: disable=unused-argument
|
async def on_red_api_tokens_update(self, service_name: str, api_tokens: Mapping[str,str]): # pylint: disable=unused-argument
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
# pylint: disable=cyclic-import
|
# pylint: disable=cyclic-import
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
from typing import Optional, Union
|
from pathlib import Path
|
||||||
|
from typing import Optional, Tuple, Union
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import discord
|
import discord
|
||||||
import websockets
|
import websockets
|
||||||
from pydactyl import PterodactylClient
|
from pydactyl import PterodactylClient
|
||||||
|
from redbot.core.data_manager import bundled_data_path
|
||||||
from redbot.core.utils.chat_formatting import bold, pagify
|
from redbot.core.utils.chat_formatting import bold, pagify
|
||||||
|
|
||||||
from pterodactyl.config import config
|
from pterodactyl.config import config
|
||||||
|
@ -78,7 +80,12 @@ async def establish_websocket_connection(coginstance: Pterodactyl) -> None:
|
||||||
if join_message:
|
if join_message:
|
||||||
if chat_channel is not None:
|
if chat_channel is not None:
|
||||||
if coginstance.bot.embed_requested(chat_channel):
|
if coginstance.bot.embed_requested(chat_channel):
|
||||||
await chat_channel.send(embed=await generate_join_leave_embed(join_message, True))
|
embed, img = await generate_join_leave_embed(coginstance=coginstance, username=join_message,join=True)
|
||||||
|
if img:
|
||||||
|
with open(img, 'rb') as file:
|
||||||
|
await chat_channel.send(embed=embed, file=file)
|
||||||
|
else:
|
||||||
|
await chat_channel.send(embed=embed)
|
||||||
else:
|
else:
|
||||||
await chat_channel.send(f"{join_message} joined the game", allowed_mentions=discord.AllowedMentions.none())
|
await chat_channel.send(f"{join_message} joined the game", allowed_mentions=discord.AllowedMentions.none())
|
||||||
|
|
||||||
|
@ -86,7 +93,12 @@ async def establish_websocket_connection(coginstance: Pterodactyl) -> None:
|
||||||
if leave_message:
|
if leave_message:
|
||||||
if chat_channel is not None:
|
if chat_channel is not None:
|
||||||
if coginstance.bot.embed_requested(chat_channel):
|
if coginstance.bot.embed_requested(chat_channel):
|
||||||
await chat_channel.send(embed=await generate_join_leave_embed(leave_message, False))
|
embed, img = await generate_join_leave_embed(coginstance=coginstance, username=leave_message,join=False)
|
||||||
|
if img:
|
||||||
|
with open(img, 'rb') as file:
|
||||||
|
await chat_channel.send(embed=embed, file=file)
|
||||||
|
else:
|
||||||
|
await chat_channel.send(embed=embed)
|
||||||
else:
|
else:
|
||||||
await chat_channel.send(f"{leave_message} left the game", allowed_mentions=discord.AllowedMentions.none())
|
await chat_channel.send(f"{leave_message} left the game", allowed_mentions=discord.AllowedMentions.none())
|
||||||
|
|
||||||
|
@ -94,7 +106,7 @@ async def establish_websocket_connection(coginstance: Pterodactyl) -> None:
|
||||||
if achievement_message:
|
if achievement_message:
|
||||||
if chat_channel is not None:
|
if chat_channel is not None:
|
||||||
if coginstance.bot.embed_requested(chat_channel):
|
if coginstance.bot.embed_requested(chat_channel):
|
||||||
await chat_channel.send(embed=await generate_achievement_embed(achievement_message['username'], achievement_message['achievement'], achievement_message['challenge']))
|
await chat_channel.send(embed=await generate_achievement_embed(coginstance, achievement_message['username'], achievement_message['achievement'], achievement_message['challenge']))
|
||||||
else:
|
else:
|
||||||
await chat_channel.send(f"{achievement_message['username']} has {'completed the challenge' if achievement_message['challenge'] else 'made the advancement'} {achievement_message['achievement']}")
|
await chat_channel.send(f"{achievement_message['username']} has {'completed the challenge' if achievement_message['challenge'] else 'made the advancement'} {achievement_message['achievement']}")
|
||||||
|
|
||||||
|
@ -153,7 +165,7 @@ async def check_if_server_message(text: str) -> Union[bool, str]:
|
||||||
regex = await config.server_regex()
|
regex = await config.server_regex()
|
||||||
match: Optional[re.Match[str]] = re.match(regex, text)
|
match: Optional[re.Match[str]] = re.match(regex, text)
|
||||||
if match:
|
if match:
|
||||||
logger.debug("Message is a server message")
|
logger.trace("Message is a server message")
|
||||||
return match.group(1)
|
return match.group(1)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -162,7 +174,7 @@ async def check_if_chat_message(text: str) -> Union[bool, dict]:
|
||||||
match: Optional[re.Match[str]] = re.match(regex, text)
|
match: Optional[re.Match[str]] = re.match(regex, text)
|
||||||
if match:
|
if match:
|
||||||
groups = {"username": match.group(1), "message": match.group(2)}
|
groups = {"username": match.group(1), "message": match.group(2)}
|
||||||
logger.debug("Message is a chat message\n%s", json.dumps(groups))
|
logger.trace("Message is a chat message\n%s", json.dumps(groups))
|
||||||
return groups
|
return groups
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -170,7 +182,7 @@ async def check_if_join_message(text: str) -> Union[bool, str]:
|
||||||
regex = await config.join_regex()
|
regex = await config.join_regex()
|
||||||
match: Optional[re.Match[str]] = re.match(regex, text)
|
match: Optional[re.Match[str]] = re.match(regex, text)
|
||||||
if match:
|
if match:
|
||||||
logger.debug("Message is a join message")
|
logger.trace("Message is a join message")
|
||||||
return match.group(1)
|
return match.group(1)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -178,7 +190,7 @@ async def check_if_leave_message(text: str) -> Union[bool, str]:
|
||||||
regex = await config.leave_regex()
|
regex = await config.leave_regex()
|
||||||
match: Optional[re.Match[str]] = re.match(regex, text)
|
match: Optional[re.Match[str]] = re.match(regex, text)
|
||||||
if match:
|
if match:
|
||||||
logger.debug("Message is a leave message")
|
logger.trace("Message is a leave message")
|
||||||
return match.group(1)
|
return match.group(1)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -191,23 +203,23 @@ async def check_if_achievement_message(text: str) -> Union[bool, dict]:
|
||||||
groups["challenge"] = True
|
groups["challenge"] = True
|
||||||
else:
|
else:
|
||||||
groups["challenge"] = False
|
groups["challenge"] = False
|
||||||
logger.debug("Message is an achievement message")
|
logger.trace("Message is an achievement message")
|
||||||
return groups
|
return groups
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def get_info(username: str) -> Optional[dict]:
|
async def get_info(username: str) -> Optional[dict]:
|
||||||
logger.debug("Retrieving player info for %s", username)
|
logger.verbose("Retrieving player info for %s", username)
|
||||||
endpoint = await config.api_endpoint()
|
endpoint = await config.api_endpoint()
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.get(f"https://playerdb.co/api/player/{endpoint}/{username}") as response:
|
async with session.get(f"https://playerdb.co/api/player/{endpoint}/{username}") as response:
|
||||||
if response.status == 200:
|
if response.status == 200:
|
||||||
logger.debug("Player info retrieved for %s", username)
|
logger.verbose("Player info retrieved for %s", username)
|
||||||
return await response.json()
|
return await response.json()
|
||||||
logger.error("Failed to retrieve player info for %s: %s", username, response.status)
|
logger.warning("Failed to retrieve player info for %s: %s", username, response.status)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def send_chat_discord(coginstance: Pterodactyl, username: str, message: str, avatar_url: str) -> None:
|
async def send_chat_discord(coginstance: Pterodactyl, username: str, message: str, avatar_url: str) -> None:
|
||||||
logger.debug("Sending chat message to Discord")
|
logger.trace("Sending chat message to Discord")
|
||||||
channel = coginstance.bot.get_channel(await config.chat_channel())
|
channel = coginstance.bot.get_channel(await config.chat_channel())
|
||||||
if channel is not None:
|
if channel is not None:
|
||||||
webhooks = await channel.webhooks()
|
webhooks = await channel.webhooks()
|
||||||
|
@ -215,33 +227,37 @@ async def send_chat_discord(coginstance: Pterodactyl, username: str, message: st
|
||||||
if webhook is None:
|
if webhook is None:
|
||||||
webhook = await channel.create_webhook(name="Pterodactyl Chat")
|
webhook = await channel.create_webhook(name="Pterodactyl Chat")
|
||||||
await webhook.send(content=message, username=username, avatar_url=avatar_url, allowed_mentions=discord.AllowedMentions(everyone=False, roles=False, users=True))
|
await webhook.send(content=message, username=username, avatar_url=avatar_url, allowed_mentions=discord.AllowedMentions(everyone=False, roles=False, users=True))
|
||||||
logger.debug("Chat message sent to Discord")
|
logger.trace("Chat message sent to Discord")
|
||||||
else:
|
else:
|
||||||
logger.warning("Chat channel not set. Skipping sending chat message to Discord")
|
logger.warning("Chat channel not set. Skipping sending chat message to Discord")
|
||||||
|
|
||||||
async def generate_join_leave_embed(username: str, join: bool) -> discord.Embed:
|
async def generate_join_leave_embed(coginstance: Pterodactyl, username: str, join: bool) -> Tuple[discord.Embed, Optional[Union[str, Path]]]:
|
||||||
embed = discord.Embed()
|
embed = discord.Embed()
|
||||||
embed.color = discord.Color.green() if join else discord.Color.red()
|
embed.color = discord.Color.green() if join else discord.Color.red()
|
||||||
embed.description = await config.join_msg() if join else await config.leave_msg()
|
embed.description = await config.join_msg() if join else await config.leave_msg()
|
||||||
info = await get_info(username)
|
info = await get_info(username)
|
||||||
if info:
|
if info:
|
||||||
|
img = None
|
||||||
embed.set_author(name=username, icon_url=info['data']['player']['avatar'])
|
embed.set_author(name=username, icon_url=info['data']['player']['avatar'])
|
||||||
else:
|
else:
|
||||||
embed.set_author(name=username, icon_url='https://seafsh.cc/u/j3AzqQ.png')
|
img = bundled_data_path(coginstance) / "unknown.png"
|
||||||
|
embed.set_author(name=username, icon_url='attachment://unknown.png')
|
||||||
embed.timestamp = discord.utils.utcnow()
|
embed.timestamp = discord.utils.utcnow()
|
||||||
return embed
|
return embed, img
|
||||||
|
|
||||||
async def generate_achievement_embed(username: str, achievement: str, challenge: bool) -> discord.Embed:
|
async def generate_achievement_embed(coginstance: Pterodactyl, username: str, achievement: str, challenge: bool) -> Tuple[discord.Embed, Optional[Union[str, Path]]]:
|
||||||
embed = discord.Embed()
|
embed = discord.Embed()
|
||||||
embed.color = discord.Color.from_str('#a800a7') if challenge else discord.Color.from_str('#54fb54')
|
embed.color = discord.Color.from_str('#a800a7') if challenge else discord.Color.from_str('#54fb54')
|
||||||
embed.description = f"{bold(username)} has {'completed the challenge' if challenge else 'made the advancement'} {bold(achievement)}"
|
embed.description = f"{bold(username)} has {'completed the challenge' if challenge else 'made the advancement'} {bold(achievement)}"
|
||||||
info = await get_info(username)
|
info = await get_info(username)
|
||||||
if info:
|
if info:
|
||||||
|
img = None
|
||||||
embed.set_author(name=username, icon_url=info['data']['player']['avatar'])
|
embed.set_author(name=username, icon_url=info['data']['player']['avatar'])
|
||||||
else:
|
else:
|
||||||
embed.set_author(name=username, icon_url='https://seafsh.cc/u/j3AzqQ.png')
|
img = bundled_data_path(coginstance) / "unknown.png"
|
||||||
|
embed.set_author(name=username, icon_url='attachment://unknown.png')
|
||||||
embed.timestamp = discord.utils.utcnow()
|
embed.timestamp = discord.utils.utcnow()
|
||||||
return embed
|
return embed, img
|
||||||
|
|
||||||
def mask_ip(string: str) -> str:
|
def mask_ip(string: str) -> str:
|
||||||
def check(match: re.Match[str]):
|
def check(match: re.Match[str]):
|
||||||
|
|
|
@ -1,42 +1,44 @@
|
||||||
[tool.poetry]
|
[project]
|
||||||
name = "seacogs"
|
name = "seacogs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "My assorted cogs for Red-DiscordBot."
|
description = "My assorted cogs for Red-DiscordBot."
|
||||||
authors = ["SeaswimmerTheFsh"]
|
authors = [{name = "cswimr", email = "seaswimmerthefsh@gmail.com"}]
|
||||||
license = "MPL 2"
|
license = {file="LICENSE"}
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
package-mode = false
|
requires-python = ">=3.11"
|
||||||
|
dependencies = [
|
||||||
|
"aiosqlite>=0.20.0",
|
||||||
|
"beautifulsoup4>=4.12.3",
|
||||||
|
"colorthief>=0.2.1",
|
||||||
|
"markdownify>=0.13.1",
|
||||||
|
"numpy>=2.1.2",
|
||||||
|
"phx-class-registry>=5.0.0",
|
||||||
|
"pillow>=10.4.0",
|
||||||
|
"py-dactyl",
|
||||||
|
"pydantic>=2.9.2",
|
||||||
|
"red-discordbot>=3.5.13",
|
||||||
|
"websockets>=13.1",
|
||||||
|
]
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[project.optional-dependencies]
|
||||||
python = ">=3.11,<3.12"
|
documentation = [
|
||||||
Red-DiscordBot = "^3.5.5"
|
"mkdocs>=1.6.1",
|
||||||
py-dactyl = "^2.0.4"
|
"mkdocs-git-authors-plugin>=0.9.0",
|
||||||
websockets = "^12.0"
|
"mkdocs-git-revision-date-localized-plugin>=1.2.9",
|
||||||
pillow = "^10.3.0"
|
"mkdocs-material[imaging]>=9.5.40",
|
||||||
numpy = "^1.26.4"
|
"mkdocstrings[python]>=0.26.1",
|
||||||
colorthief = "^0.2.1"
|
"mkdocs-redirects>=1.2.1",
|
||||||
|
]
|
||||||
|
|
||||||
[tool.poetry.group.dev]
|
[tool.uv]
|
||||||
optional = true
|
dev-dependencies = [
|
||||||
|
"pylint>=3.3.1",
|
||||||
|
"ruff>=0.6.9",
|
||||||
|
"sqlite-web>=0.6.4",
|
||||||
|
]
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.uv.sources]
|
||||||
ruff = "^0.3.1"
|
py-dactyl = { git = "https://github.com/cswimr/pydactyl" }
|
||||||
pylint = "^3.1.0"
|
|
||||||
|
|
||||||
[tool.poetry.group.docs]
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[tool.poetry.group.docs.dependencies]
|
|
||||||
mkdocs = "1.5.3"
|
|
||||||
mkdocstrings = {extras = ["python"], version = "0.24.0"}
|
|
||||||
mkdocs-git-authors-plugin = "0.7.2"
|
|
||||||
mkdocs-git-revision-date-localized-plugin = "1.2.2"
|
|
||||||
mkdocs-material = {extras = ["imaging"], version = "^9.5.2"}
|
|
||||||
mkdocs-redirects = "^1.2.1"
|
|
||||||
|
|
||||||
[build-system]
|
|
||||||
requires = ["poetry-core"]
|
|
||||||
build-backend = "poetry.core.masonry.api"
|
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
# Exclude a variety of commonly ignored directories.
|
# Exclude a variety of commonly ignored directories.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"author" : ["SeaswimmerTheFsh (seasw.)"],
|
"author" : ["cswimr"],
|
||||||
"install_msg" : "Thank you for installing SeaUtils!\nYou can find the source code of this cog [here](https://coastalcommits.com/SeaswimmerTheFsh/SeaCogs).",
|
"install_msg" : "Thank you for installing SeaUtils!\nYou can find the source code of this cog [here](https://coastalcommits.com/cswimr/SeaCogs).",
|
||||||
"name" : "SeaUtils",
|
"name" : "SeaUtils",
|
||||||
"short" : "A collection of useful utilities.",
|
"short" : "A collection of useful utilities.",
|
||||||
"description" : "A collection of useful utilities.",
|
"description" : "A collection of useful utilities.",
|
||||||
|
@ -8,5 +8,6 @@
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"min_bot_version": "3.5.0",
|
"min_bot_version": "3.5.0",
|
||||||
"min_python_version": [3, 8, 0]
|
"min_python_version": [3, 8, 0],
|
||||||
|
"requirements": ["beautifulsoup4", "markdownify"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,20 @@
|
||||||
# ____) | __/ (_| \__ \\ V V /| | | | | | | | | | | | __/ |
|
# ____) | __/ (_| \__ \\ V V /| | | | | | | | | | | | __/ |
|
||||||
# |_____/ \___|\__,_|___/ \_/\_/ |_|_| |_| |_|_| |_| |_|\___|_|
|
# |_____/ \___|\__,_|___/ \_/\_/ |_|_| |_| |_|_| |_| |_|\___|_|
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import inspect
|
import inspect
|
||||||
import operator
|
import operator
|
||||||
|
import re
|
||||||
|
from asyncio.subprocess import Process
|
||||||
from functools import partial, partialmethod
|
from functools import partial, partialmethod
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from discord import Embed, app_commands
|
import aiohttp
|
||||||
|
import yaml
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
from discord import Color, Embed, app_commands
|
||||||
from discord.utils import CachedSlotProperty, cached_property
|
from discord.utils import CachedSlotProperty, cached_property
|
||||||
|
from markdownify import MarkdownConverter
|
||||||
from redbot.core import commands
|
from redbot.core import commands
|
||||||
from redbot.core.bot import Red
|
from redbot.core.bot import Red
|
||||||
from redbot.core.dev_commands import cleanup_code
|
from redbot.core.dev_commands import cleanup_code
|
||||||
|
@ -19,13 +26,24 @@ from redbot.core.utils import chat_formatting as cf
|
||||||
from redbot.core.utils.views import SimpleMenu
|
from redbot.core.utils.views import SimpleMenu
|
||||||
|
|
||||||
|
|
||||||
|
def md(soup: BeautifulSoup, **options) -> Any | str:
|
||||||
|
return MarkdownConverter(**options).convert_soup(soup=soup)
|
||||||
|
|
||||||
|
def format_rfc_text(text: str, number: int) -> str:
|
||||||
|
one: str = re.sub(r"\(\.\/rfc(\d+)", r"(https://www.rfc-editor.org/rfc/rfc\1.html", text)
|
||||||
|
two: str = re.sub(r"\((#(?:section|page)-\d+(?:.\d+)?)\)", f"(https://www.rfc-editor.org/rfc/rfc{number}.html\1)", one)
|
||||||
|
three: str = re.sub(r"\n{3,}", "\n\n", two)
|
||||||
|
return three
|
||||||
|
|
||||||
class SeaUtils(commands.Cog):
|
class SeaUtils(commands.Cog):
|
||||||
"""A collection of random utilities."""
|
"""A collection of random utilities."""
|
||||||
|
|
||||||
__author__ = ["SeaswimmerTheFsh"]
|
__author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"]
|
||||||
__version__ = "1.0.0"
|
__git__ = "https://www.coastalcommits.com/cswimr/SeaCogs"
|
||||||
|
__version__ = "1.0.1"
|
||||||
|
__documentation__ = "https://seacogs.coastalcommits.com/seautils/"
|
||||||
|
|
||||||
def __init__(self, bot: Red):
|
def __init__(self, bot: Red) -> None:
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
def format_help_for_context(self, ctx: commands.Context) -> str:
|
def format_help_for_context(self, ctx: commands.Context) -> str:
|
||||||
|
@ -33,15 +51,17 @@ class SeaUtils(commands.Cog):
|
||||||
n = "\n" if "\n\n" not in pre_processed else ""
|
n = "\n" if "\n\n" not in pre_processed else ""
|
||||||
text = [
|
text = [
|
||||||
f"{pre_processed}{n}",
|
f"{pre_processed}{n}",
|
||||||
f"Cog Version: **{self.__version__}**",
|
f"{cf.bold('Cog Version:')} [{self.__version__}]({self.__git__})",
|
||||||
f"Author: {cf.humanize_list(self.__author__)}"
|
f"{cf.bold('Author:')} {cf.humanize_list(self.__author__)}",
|
||||||
|
f"{cf.bold('Documentation:')} {self.__documentation__}",
|
||||||
]
|
]
|
||||||
return "\n".join(text)
|
return "\n".join(text)
|
||||||
|
|
||||||
|
|
||||||
def format_src(self, obj: Any) -> str:
|
def format_src(self, obj: Any) -> str:
|
||||||
"""A large portion of this code is repurposed from Zephyrkul's RTFS cog.
|
"""A large portion of this code is repurposed from Zephyrkul's RTFS cog.
|
||||||
https://github.com/Zephyrkul/FluffyCogs/blob/master/rtfs/rtfs.py"""
|
https://github.com/Zephyrkul/FluffyCogs/blob/master/rtfs/rtfs.py"""
|
||||||
obj = inspect.unwrap(obj)
|
obj = inspect.unwrap(func=obj)
|
||||||
src: Any = getattr(obj, "__func__", obj)
|
src: Any = getattr(obj, "__func__", obj)
|
||||||
if isinstance(obj, (commands.Command, app_commands.Command)):
|
if isinstance(obj, (commands.Command, app_commands.Command)):
|
||||||
src = obj.callback
|
src = obj.callback
|
||||||
|
@ -51,11 +71,11 @@ class SeaUtils(commands.Cog):
|
||||||
src = obj.fget
|
src = obj.fget
|
||||||
elif isinstance(obj, (cached_property, CachedSlotProperty)):
|
elif isinstance(obj, (cached_property, CachedSlotProperty)):
|
||||||
src = obj.function
|
src = obj.function
|
||||||
return inspect.getsource(src)
|
return inspect.getsource(object=src)
|
||||||
|
|
||||||
@commands.command(aliases=["source", "src", "code", "showsource"])
|
@commands.command(aliases=["source", "src", "code", "showsource"])
|
||||||
@commands.is_owner()
|
@commands.is_owner()
|
||||||
async def showcode(self, ctx: commands.Context, *, object: str): # pylint: disable=redefined-builtin
|
async def showcode(self, ctx: commands.Context, *, object: str) -> None: # pylint: disable=redefined-builtin
|
||||||
"""Show the code for a particular object."""
|
"""Show the code for a particular object."""
|
||||||
try:
|
try:
|
||||||
if object.startswith("/") and (obj := ctx.bot.tree.get_command(object[1:])):
|
if object.startswith("/") and (obj := ctx.bot.tree.get_command(object[1:])):
|
||||||
|
@ -64,6 +84,8 @@ class SeaUtils(commands.Cog):
|
||||||
text = self.format_src(type(obj))
|
text = self.format_src(type(obj))
|
||||||
elif obj := ctx.bot.get_command(object):
|
elif obj := ctx.bot.get_command(object):
|
||||||
text = self.format_src(obj)
|
text = self.format_src(obj)
|
||||||
|
else:
|
||||||
|
raise AttributeError
|
||||||
temp_content = cf.pagify(
|
temp_content = cf.pagify(
|
||||||
text=cleanup_code(text),
|
text=cleanup_code(text),
|
||||||
escape_mass_mentions=True,
|
escape_mass_mentions=True,
|
||||||
|
@ -82,3 +104,151 @@ class SeaUtils(commands.Cog):
|
||||||
await ctx.send(embed=embed, reference=ctx.message.to_reference(fail_if_not_exists=False))
|
await ctx.send(embed=embed, reference=ctx.message.to_reference(fail_if_not_exists=False))
|
||||||
else:
|
else:
|
||||||
await ctx.send(content="Object not found!", reference=ctx.message.to_reference(fail_if_not_exists=False))
|
await ctx.send(content="Object not found!", reference=ctx.message.to_reference(fail_if_not_exists=False))
|
||||||
|
|
||||||
|
@commands.command(name='dig', aliases=['dnslookup', 'nslookup'])
|
||||||
|
@commands.is_owner()
|
||||||
|
async def dig(self, ctx: commands.Context, name: str, record_type: str | None = None, server: str | None = None, port: int = 53) -> None:
|
||||||
|
"""Retrieve DNS information for a domain.
|
||||||
|
|
||||||
|
Uses `dig` to perform a DNS query. Will fall back to `nslookup` if `dig` is not installed on the system.
|
||||||
|
`nslookup` does not provide as much information as `dig`, so only the `name` parameter will be used if `nslookup` is used.
|
||||||
|
Will return the A, AAAA, and CNAME records for a domain by default. You can specify a different record type with the `type` parameter."""
|
||||||
|
command_opts: list[str | int] = ['dig']
|
||||||
|
query_types: list[str] = [record_type] if record_type else ['A', 'AAAA', 'CNAME']
|
||||||
|
if server:
|
||||||
|
command_opts.extend(['@', server])
|
||||||
|
for query_type in query_types:
|
||||||
|
command_opts.extend([name, query_type])
|
||||||
|
command_opts.extend(['-p', str(port), '+yaml'])
|
||||||
|
|
||||||
|
try:
|
||||||
|
process: Process = await asyncio.create_subprocess_exec(*command_opts, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
|
||||||
|
stdout, stderr = await process.communicate()
|
||||||
|
if stderr:
|
||||||
|
await ctx.maybe_send_embed(message="An error was encountered!\n" + cf.box(text=stderr.decode()))
|
||||||
|
else:
|
||||||
|
data = yaml.safe_load(stdout.decode())
|
||||||
|
message_data: dict = data[0]['message']
|
||||||
|
response_data: dict = message_data['response_message_data']
|
||||||
|
if ctx.embed_requested():
|
||||||
|
embed = Embed(
|
||||||
|
title="DNS Query Result",
|
||||||
|
color=await ctx.embed_color(),
|
||||||
|
timestamp=message_data['response_time']
|
||||||
|
)
|
||||||
|
embed.add_field(name="Response Address", value=message_data['response_address'], inline=True)
|
||||||
|
embed.add_field(name="Response Port", value=message_data['response_port'], inline=True)
|
||||||
|
embed.add_field(name="Query Address", value=message_data['query_address'], inline=True)
|
||||||
|
embed.add_field(name="Query Port", value=message_data['query_port'], inline=True)
|
||||||
|
embed.add_field(name="Status", value=response_data['status'], inline=True)
|
||||||
|
embed.add_field(name="Flags", value=response_data['flags'], inline=True)
|
||||||
|
|
||||||
|
if response_data.get('status') != 'NOERROR':
|
||||||
|
embed.colour = Color.red()
|
||||||
|
embed.description = cf.error("Dig query did not return `NOERROR` status.")
|
||||||
|
|
||||||
|
questions = []
|
||||||
|
answers = []
|
||||||
|
authorities = []
|
||||||
|
for m in data:
|
||||||
|
response = m['message']['response_message_data']
|
||||||
|
if 'QUESTION_SECTION' in response:
|
||||||
|
for question in response['QUESTION_SECTION']:
|
||||||
|
if question not in questions:
|
||||||
|
questions.append(question)
|
||||||
|
|
||||||
|
if 'ANSWER_SECTION' in response:
|
||||||
|
for answer in response['ANSWER_SECTION']:
|
||||||
|
if answer not in answers:
|
||||||
|
answers.append(answer)
|
||||||
|
|
||||||
|
if 'AUTHORITY_SECTION' in response:
|
||||||
|
for authority in response['AUTHORITY_SECTION']:
|
||||||
|
if authority not in authorities:
|
||||||
|
authorities.append(authority)
|
||||||
|
|
||||||
|
if questions:
|
||||||
|
question_section = "\n".join(questions)
|
||||||
|
embed.add_field(name="Question Section", value=f"{cf.box(text=question_section, lang='prolog')}", inline=False)
|
||||||
|
|
||||||
|
if answers:
|
||||||
|
answer_section = "\n".join(answers)
|
||||||
|
if len(answer_section) > 1024:
|
||||||
|
embed.description = cf.warning("Answer section is too long to fit within embed field, falling back to description.") + cf.box(answer_section)
|
||||||
|
else:
|
||||||
|
embed.add_field(name="Answer Section", value=f"{cf.box(text=answer_section, lang='prolog')}", inline=False)
|
||||||
|
|
||||||
|
if authorities:
|
||||||
|
authority_section = "\n".join(authorities)
|
||||||
|
embed.add_field(name="Authority Section", value=f"{cf.box(text=authority_section, lang='prolog')}", inline=False)
|
||||||
|
await ctx.send(embed=embed)
|
||||||
|
else:
|
||||||
|
await ctx.send(content=cf.box(text=stdout, lang='yaml'))
|
||||||
|
except (FileNotFoundError):
|
||||||
|
try:
|
||||||
|
ns_process = await asyncio.create_subprocess_exec('nslookup', name, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
|
||||||
|
ns_stdout, ns_stderr = await ns_process.communicate()
|
||||||
|
if ns_stderr:
|
||||||
|
await ctx.maybe_send_embed(message="An error was encountered!\n" + cf.box(text=ns_stderr.decode()))
|
||||||
|
else:
|
||||||
|
warning = cf.warning("`dig` is not installed! Defaulting to `nslookup`.\nThis command provides more information when `dig` is installed on the system.\n")
|
||||||
|
if await ctx.embed_requested():
|
||||||
|
embed = Embed(
|
||||||
|
title="DNS Query Result",
|
||||||
|
color=await ctx.embed_color(),
|
||||||
|
timestamp=ctx.message.created_at
|
||||||
|
)
|
||||||
|
embed.description = warning + cf.box(text=ns_stdout.decode())
|
||||||
|
await ctx.send(embed=embed)
|
||||||
|
else:
|
||||||
|
await ctx.send(content = warning + cf.box(text=ns_stdout.decode()))
|
||||||
|
except (FileNotFoundError):
|
||||||
|
await ctx.maybe_send_embed(message=cf.error("Neither `dig` nor `nslookup` are installed on the system. Unable to resolve DNS query."))
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def rfc(self, ctx: commands.Context, number: int) -> None:
|
||||||
|
"""Retrieve the text of an RFC document.
|
||||||
|
|
||||||
|
This command uses the [RFC Editor website](https://www.rfc-editor.org/) to fetch the text of an RFC document.
|
||||||
|
A [Request for Comments (RFC)](https://en.wikipedia.org/wiki/Request_for_Comments) is a publication in a series from the principal technical development and standards-setting bodies for the [Internet](https://en.wikipedia.org/wiki/Internet), most prominently the [Internet Engineering Task Force](https://en.wikipedia.org/wiki/Internet_Engineering_Task_Force). An RFC is authored by individuals or groups of engineers and [computer scientists](https://en.wikipedia.org/wiki/Computer_scientist) in the form of a [memorandum](https://en.wikipedia.org/wiki/Memorandum) describing methods, behaviors, research, or innovations applicable to the working of the Internet and Internet-connected systems. It is submitted either for [peer review](https://en.wikipedia.org/wiki/Peer_review) or to convey new concepts, information, or, occasionally, engineering humor.""" # noqa: E501
|
||||||
|
url = f"https://www.rfc-editor.org/rfc/rfc{number}.html"
|
||||||
|
datatracker_url = f"https://datatracker.ietf.org/doc/rfc{number}"
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get(url=url) as response:
|
||||||
|
if response.status == 200:
|
||||||
|
html = await response.text()
|
||||||
|
soup = BeautifulSoup(html, 'html.parser')
|
||||||
|
pre_tags = soup.find_all('pre')
|
||||||
|
content: list[Embed | str] = []
|
||||||
|
for pre_tag in pre_tags:
|
||||||
|
text = format_rfc_text(md(pre_tag), number)
|
||||||
|
if len(text) > 4096:
|
||||||
|
pagified_text = cf.pagify(text, delims=["\n\n"], page_length=4096)
|
||||||
|
for page in pagified_text:
|
||||||
|
if await ctx.embed_requested():
|
||||||
|
embed = Embed(
|
||||||
|
title=f"RFC Document {number}",
|
||||||
|
url=datatracker_url,
|
||||||
|
description=page,
|
||||||
|
color=await ctx.embed_color()
|
||||||
|
)
|
||||||
|
content.append(embed)
|
||||||
|
else:
|
||||||
|
content.append(page)
|
||||||
|
else:
|
||||||
|
if await ctx.embed_requested():
|
||||||
|
embed = Embed(
|
||||||
|
title=f"RFC Document {number}",
|
||||||
|
url=datatracker_url,
|
||||||
|
description=text,
|
||||||
|
color=await ctx.embed_color()
|
||||||
|
)
|
||||||
|
content.append(embed)
|
||||||
|
else:
|
||||||
|
content.append(text)
|
||||||
|
if await ctx.embed_requested():
|
||||||
|
for embed in content:
|
||||||
|
embed.set_footer(text=f"Page {content.index(embed) + 1}/{len(content)}")
|
||||||
|
await SimpleMenu(pages=content, disable_after_timeout=True, timeout=300).start(ctx)
|
||||||
|
else:
|
||||||
|
await ctx.maybe_send_embed(message=cf.error(f"An error occurred while fetching RFC {number}. Status code: {response.status}."))
|
||||||
|
|
Loading…
Reference in a new issue