Compare commits

..

14 commits

Author SHA1 Message Date
5c999735f1
feat(issuecards): init
Some checks failed
Actions / Lint Code (Ruff & Pylint) (pull_request) Failing after 50s
Actions / Build Documentation (MkDocs) (pull_request) Successful in 1m2s
2025-03-28 10:23:05 -05:00
2505dd0980
fix(aurora): more ruff fixes
All checks were successful
Actions / Build Documentation (MkDocs) (push) Successful in 32s
Actions / Lint Code (Ruff & Pylint) (push) Successful in 36s
2025-03-28 10:22:08 -05:00
4407a99b8e
style(pterodactyl): ruff reformat
All checks were successful
Actions / Build Documentation (MkDocs) (push) Successful in 33s
Actions / Lint Code (Ruff & Pylint) (push) Successful in 39s
2025-03-28 10:17:43 -05:00
df22f73d2e
style(aurora): reformat with ruff 2025-03-28 10:17:35 -05:00
ab22b791d1
fix(hotreload): pylint fixes
All checks were successful
Actions / Build Documentation (MkDocs) (push) Successful in 33s
Actions / Lint Code (Ruff & Pylint) (push) Successful in 36s
2025-03-28 10:16:26 -05:00
c0c84358ef
fix(backup): pylint fix 2025-03-28 10:14:30 -05:00
336e01456c
fix(aurora): bandaid fixes so pylint passes
these are not good changes in the slightest and are only here because
pylint is failing otherwise, you should really be using aurora v3
instead of v2 even though it's in development
2025-03-28 10:13:48 -05:00
cc1745a9d2
Remove the dev container (#68)
Some checks failed
Actions / Build Documentation (MkDocs) (push) Successful in 36s
Actions / Lint Code (Ruff & Pylint) (push) Failing after 39s
I no longer need the dev container, as I use neovim where this isn't useful to me, and the nix flake is plenty good enough.

<!-- Create a new issue, if it doesn't exist yet -->

- [x] By submitting this pull request, I permit [cswimr](https://www.coastalcommits.com/cswimr) to license my work under
  the [Mozilla Public License Version 2.0](https://www.coastalcommits.com/cswimr/SeaCogs/src/branch/main/LICENSE).

Reviewed-on: #68
2025-03-28 11:05:00 -04:00
eefd5ece09
chore(deps): pin dependencies (#66)
Some checks failed
Actions / Build Documentation (MkDocs) (push) Successful in 35s
Actions / Lint Code (Ruff & Pylint) (push) Failing after 37s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/env](https://c.csw.im/actions/env) | action | pinDigest |  -> `1791216` |
| [actions/setup-uv](https://c.csw.im/actions/setup-uv) | action | pinDigest |  -> `2269511` |
| catthehacker/ubuntu | container | pinDigest |  -> `70d7485` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNjYuMCIsInVwZGF0ZWRJblZlciI6IjM5LjIxMS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: #66
Co-authored-by: Renovate <renovate@csw.im>
Co-committed-by: Renovate <renovate@csw.im>
2025-03-28 10:54:31 -04:00
0503f3b78d
feat(backup): update to most recent red version
Some checks failed
Actions / Build Documentation (MkDocs) (push) Successful in 30s
Actions / Lint Code (Ruff & Pylint) (push) Failing after 36s
2025-03-22 09:16:34 -04:00
4f01814896
fix(actions): switch back to local mirrored actions
Some checks failed
Actions / Build Documentation (MkDocs) (push) Successful in 33s
Actions / Lint Code (Ruff & Pylint) (push) Failing after 37s
2025-03-19 15:37:53 -04:00
4661555aa6
fix(actions): use full urls for actions
Some checks failed
Actions / Build Documentation (MkDocs) (push) Successful in 40s
Actions / Lint Code (Ruff & Pylint) (push) Failing after 43s
2025-03-19 13:57:15 -04:00
3e345cc3af
fix(actions): change actions urls
Some checks failed
Actions / Build Documentation (MkDocs) (push) Successful in 40s
Actions / Lint Code (Ruff & Pylint) (push) Failing after 46s
2025-03-19 08:19:05 -04:00
4844f5892c
fix(actions): change the meli url
Some checks failed
Actions / Build Documentation (MkDocs) (push) Successful in 29s
Actions / Lint Code (Ruff & Pylint) (push) Failing after 36s
2025-03-19 08:05:09 -04:00
18 changed files with 335 additions and 554 deletions

View file

@ -1,38 +0,0 @@
FROM ghcr.io/astral-sh/uv:0.5.30@sha256:bb74263127d6451222fe7f71b330edfb189ab1c98d7898df2401fbf4f272d9b9 AS uv
FROM python:3.11-slim@sha256:6ed5bff4d7d377e2a27d9285553b8c21cfccc4f00881de1b24c9bc8d90016e82 AS python
FROM code.forgejo.org/forgejo/runner:6.2.1@sha256:fecc96a111a15811a6887ce488e75718089f24599e613e93db8e54fe70b706e8 AS forgejo-runner
FROM mcr.microsoft.com/vscode/devcontainers/base:bookworm@sha256:6155a486f236fd5127b76af33086029d64f64cf49dd504accb6e5f949098eb7e
LABEL repository="www.coastalcommits.com/cswimr/SeaCogs"
LABEL maintainer="cswimr <seaswimmerthefsh@gmail.com>"
RUN apt-get update; \
apt-get install -y --no-install-recommends \
# Red-DiscordBot
build-essential \
git \
# PyNaCl
libsodium-dev \
# CFFI
libffi-dev \
# SSH repository support
openssh-client \
# Cog dependencies
# Audio
openjdk-17-jre-headless \
# PyLav
libaio1 \
libaio-dev \
# SeaUtils
dnsutils; \
apt-get clean; \
rm -rf /var/lib/apt/lists/*
COPY --from=uv --chown=vscode: /uv /uvx /bin/
COPY --from=python --chown=vscode: /usr/local /usr/local
COPY --from=forgejo-runner --chown=vscode: /bin/forgejo-runner /bin/forgejo-runner
COPY --chown=vscode: .devcontainer/home/* /home/vscode/
RUN ln -s /usr/local/bin/python3.11 /usr/local/bin/python; \
python --version; \
python -m ensurepip

View file

@ -1,52 +0,0 @@
{
"name": "Red-DiscordBot: SeaCogs",
"build": {
"context": "..",
"dockerfile": "Dockerfile"
},
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
},
"customizations": {
"vscode": {
"settings": {
"python.terminal.activateEnvInCurrentTerminal": true,
"python.terminal.activateEnvironment": true,
"terminal.integrated.defaultProfile.linux": "zsh",
"terminal.integrated.profiles.linux": {
"zsh": {
"path": "/bin/zsh"
}
}
},
"extensions": [
"charliermarsh.ruff",
"ms-azuretools.vscode-docker",
"ms-python.python",
"tekumara.typos-vscode",
"tamasfe.even-better-toml",
"redhat.vscode-yaml",
"DavidAnson.vscode-markdownlint",
"yy0931.vscode-sqlite3-editor",
"aaron-bond.better-comments",
"donjayamanne.githistory",
"eamodio.gitlens"
]
}
},
"containerEnv": {
"DISPLAY": "dummy",
"PYTHONUNBUFFERED": "True",
"UV_LINK_MODE": "copy",
"UV_PYTHON_PREFERENCE": "only-system",
"UV_PYTHON_DOWNLOADS": "never",
"PROJECT_DIR": "/workspaces/SeaCogs"
},
"mounts": [
"source=seacogs-persistent-data,target=/workspaces/SeaCogs/.data,type=volume"
],
"postCreateCommand": {
"Setup Virtual Environment": "uv sync --frozen && sudo chown -R vscode:vscode /workspaces/SeaCogs/.data && uv run redbot-setup --no-prompt --instance-name=local --data-path=/workspaces/SeaCogs/.data --backend=json"
},
"remoteUser": "vscode"
}

View file

@ -1,3 +0,0 @@
#!/usr/bin/env bash
alias runactions="forgejo-runner exec --default-actions-url=https://www.coastalcommits.com --gitea-instance=https://www.coastalcommits.com"

View file

@ -9,13 +9,13 @@ jobs:
lint:
name: Lint Code (Ruff & Pylint)
runs-on: docker
container: catthehacker/ubuntu:act-latest
container: catthehacker/ubuntu:act-latest@sha256:70d7485966a50a639ddab37445fd27c2f0b5086ad4959ec3bba228ed394c1928
steps:
- name: Checkout
uses: https://github.com/actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: "Setup uv"
uses: https://github.com/astral-sh/setup-uv@v5
uses: actions/setup-uv@22695119d769bdb6f7032ad67b9bca0ef8c4a174 # v5
with:
version: "latest"
enable-cache: true
@ -35,7 +35,7 @@ jobs:
docs:
name: Build Documentation (MkDocs)
runs-on: docker
container: catthehacker/ubuntu:act-latest
container: catthehacker/ubuntu:act-latest@sha256:70d7485966a50a639ddab37445fd27c2f0b5086ad4959ec3bba228ed394c1928
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
@ -43,7 +43,7 @@ jobs:
fetch-depth: 0
- name: "Setup uv"
uses: https://github.com/astral-sh/setup-uv@v5
uses: actions/setup-uv@22695119d769bdb6f7032ad67b9bca0ef8c4a174 # v5
with:
version: "latest"
enable-cache: true
@ -54,7 +54,7 @@ jobs:
run: uv sync --no-dev --group=documentation
- name: Set environment variables
uses: actions/env@v2
uses: actions/env@1791216cd180e6578dd1d67fb8d2852b883a5f53 # v2
- name: Build documentation
run: |
@ -74,7 +74,7 @@ jobs:
echo "${YELLOW}Deploying to ${BLUE}Meli ${YELLOW}on branch ${GREEN}$CI_ACTION_REF_NAME_SLUG${YELLOW}...\n"
npx -p "@getmeli/cli" meli upload ./site \
--url "https://pages.coastalcommits.com" \
--url "https://meli.csw.im" \
--site "${{ vars.MELI_SITE_ID }}" \
--token "${{ secrets.MELI_TOKEN }}" \
--release "$CI_ACTION_REF_NAME_SLUG/${{ env.GITHUB_SHA }}" \

View file

@ -40,7 +40,7 @@ class Aurora(commands.Cog):
This cog stores all of its data in an SQLite database."""
__author__ = ["cswimr"]
__version__ = "2.1.3"
__version__ = "2.1.5"
__documentation__ = "https://seacogs.coastalcommits.com/aurora/"
async def red_delete_data_for_user(self, *, requester, user_id: int):
@ -70,7 +70,8 @@ class Aurora(commands.Cog):
await config.user_from_id(user_id).clear()
else:
logger.warning(
"Invalid requester passed to red_delete_data_for_user: %s", requester
"Invalid requester passed to red_delete_data_for_user: %s",
requester,
)
def __init__(self, bot: Red):
@ -135,9 +136,8 @@ class Aurora(commands.Cog):
if await config.guild(entry.guild).ignore_other_bots() is True:
if entry.user.bot or entry.target.bot:
return
else:
if entry.user.id == self.bot.user.id:
return
elif entry.user.id == self.bot.user.id:
return
duration = "NULL"
@ -159,10 +159,10 @@ class Aurora(commands.Cog):
elif entry.action == discord.AuditLogAction.member_update:
if entry.after.timed_out_until is not None:
timed_out_until_aware = entry.after.timed_out_until.replace(
tzinfo=timezone.utc
tzinfo=timezone.utc,
)
duration_datetime = timed_out_until_aware - datetime.now(
tz=timezone.utc
tz=timezone.utc,
)
minutes = round(duration_datetime.total_seconds() / 60)
duration = timedelta(minutes=minutes)
@ -209,7 +209,7 @@ class Aurora(commands.Cog):
return
await interaction.response.send_message(
content=f"{target.mention} has recieved a note!\n**Reason** - `{reason}`"
content=f"{target.mention} has recieved a note!\n**Reason** - `{reason}`",
)
if silent is None:
@ -239,7 +239,7 @@ class Aurora(commands.Cog):
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has received a note! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
content=f"{target.mention} has received a note! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`",
)
await log(interaction, moderation_id)
@ -268,7 +268,7 @@ class Aurora(commands.Cog):
return
await interaction.response.send_message(
content=f"{target.mention} has been warned!\n**Reason** - `{reason}`"
content=f"{target.mention} has been warned!\n**Reason** - `{reason}`",
)
if silent is None:
@ -298,7 +298,7 @@ class Aurora(commands.Cog):
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been warned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
content=f"{target.mention} has been warned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`",
)
await log(interaction, moderation_id)
@ -342,7 +342,8 @@ class Aurora(commands.Cog):
parsed_time = parse_timedelta(duration)
if parsed_time is None:
await interaction.response.send_message(
content=error("Please provide a valid duration!"), ephemeral=True
content=error("Please provide a valid duration!"),
ephemeral=True,
)
return
else:
@ -350,12 +351,15 @@ class Aurora(commands.Cog):
if role.id not in addrole_whitelist:
await interaction.response.send_message(
content=error("That role isn't whitelisted!"), ephemeral=True
content=error("That role isn't whitelisted!"),
ephemeral=True,
)
return
if not await check_moddable(
target, interaction, ["moderate_members", "manage_roles"]
target,
interaction,
["moderate_members", "manage_roles"],
):
return
@ -390,7 +394,7 @@ class Aurora(commands.Cog):
reason=f"Role added by {interaction.user.id}{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''} for: {reason}",
)
response: discord.WebhookMessage = await interaction.followup.send(
content=f"{target.mention} has been given the {role.mention} role{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}!\n**Reason** - `{reason}`"
content=f"{target.mention} has been given the {role.mention} role{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}!\n**Reason** - `{reason}`",
)
moderation_id = await mysql_log(
@ -448,7 +452,8 @@ class Aurora(commands.Cog):
parsed_time = parse_timedelta(duration)
if parsed_time is None:
await interaction.response.send_message(
content=error("Please provide a valid duration!"), ephemeral=True
content=error("Please provide a valid duration!"),
ephemeral=True,
)
return
else:
@ -456,12 +461,15 @@ class Aurora(commands.Cog):
if role.id not in addrole_whitelist:
await interaction.response.send_message(
content=error("That role isn't whitelisted!"), ephemeral=True
content=error("That role isn't whitelisted!"),
ephemeral=True,
)
return
if not await check_moddable(
target, interaction, ["moderate_members", "manage_roles"]
target,
interaction,
["moderate_members", "manage_roles"],
):
return
@ -496,7 +504,7 @@ class Aurora(commands.Cog):
reason=f"Role removed by {interaction.user.id}{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''} for: {reason}",
)
response: discord.WebhookMessage = await interaction.followup.send(
content=f"{target.mention} has had the {role.mention} role removed{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}!\n**Reason** - `{reason}`"
content=f"{target.mention} has had the {role.mention} role removed{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}!\n**Reason** - `{reason}`",
)
moderation_id = await mysql_log(
@ -553,21 +561,24 @@ class Aurora(commands.Cog):
parsed_time = parse_timedelta(duration, maximum=timedelta(days=28))
if parsed_time is None:
await interaction.response.send_message(
error("Please provide a valid duration!"), ephemeral=True
error("Please provide a valid duration!"),
ephemeral=True,
)
return
except commands.BadArgument:
await interaction.response.send_message(
error("Please provide a duration that is less than 28 days."), ephemeral=True
error("Please provide a duration that is less than 28 days."),
ephemeral=True,
)
return
await target.timeout(
parsed_time, reason=f"Muted by {interaction.user.id} for: {reason}"
parsed_time,
reason=f"Muted by {interaction.user.id} for: {reason}",
)
await interaction.response.send_message(
content=f"{target.mention} has been muted for {humanize_timedelta(timedelta=parsed_time)}!\n**Reason** - `{reason}`"
content=f"{target.mention} has been muted for {humanize_timedelta(timedelta=parsed_time)}!\n**Reason** - `{reason}`",
)
if silent is None:
@ -598,7 +609,7 @@ class Aurora(commands.Cog):
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been muted for {humanize_timedelta(timedelta=parsed_time)}! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
content=f"{target.mention} has been muted for {humanize_timedelta(timedelta=parsed_time)}! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`",
)
await log(interaction, moderation_id)
@ -636,14 +647,15 @@ class Aurora(commands.Cog):
if reason:
await target.timeout(
None, reason=f"Unmuted by {interaction.user.id} for: {reason}"
None,
reason=f"Unmuted by {interaction.user.id} for: {reason}",
)
else:
await target.timeout(None, reason=f"Unbanned by {interaction.user.id}")
reason = "No reason given."
await interaction.response.send_message(
content=f"{target.mention} has been unmuted!\n**Reason** - `{reason}`"
content=f"{target.mention} has been unmuted!\n**Reason** - `{reason}`",
)
if silent is None:
@ -673,7 +685,7 @@ class Aurora(commands.Cog):
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been unmuted! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
content=f"{target.mention} has been unmuted! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`",
)
await log(interaction, moderation_id)
@ -702,7 +714,7 @@ class Aurora(commands.Cog):
return
await interaction.response.send_message(
content=f"{target.mention} has been kicked!\n**Reason** - `{reason}`"
content=f"{target.mention} has been kicked!\n**Reason** - `{reason}`",
)
if silent is None:
@ -734,7 +746,7 @@ class Aurora(commands.Cog):
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been kicked! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
content=f"{target.mention} has been kicked! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`",
)
await log(interaction, moderation_id)
@ -750,7 +762,7 @@ class Aurora(commands.Cog):
Choice(name="1 Day", value=86400),
Choice(name="3 Days", value=259200),
Choice(name="7 Days", value=604800),
]
],
)
async def ban(
self,
@ -786,7 +798,8 @@ class Aurora(commands.Cog):
try:
await interaction.guild.fetch_ban(target)
await interaction.response.send_message(
content=error(f"{target.mention} is already banned!"), ephemeral=True
content=error(f"{target.mention} is already banned!"),
ephemeral=True,
)
return
except discord.errors.NotFound:
@ -796,19 +809,21 @@ class Aurora(commands.Cog):
parsed_time = parse_relativedelta(duration)
if parsed_time is None:
await interaction.response.send_message(
content=error("Please provide a valid duration!"), ephemeral=True
content=error("Please provide a valid duration!"),
ephemeral=True,
)
return
try:
parsed_time = timedelta_from_relativedelta(parsed_time)
except ValueError:
await interaction.response.send_message(
content=error("Please provide a valid duration!"), ephemeral=True
content=error("Please provide a valid duration!"),
ephemeral=True,
)
return
await interaction.response.send_message(
content=f"{target.mention} has been banned for {humanize_timedelta(timedelta=parsed_time)}!\n**Reason** - `{reason}`"
content=f"{target.mention} has been banned for {humanize_timedelta(timedelta=parsed_time)}!\n**Reason** - `{reason}`",
)
try:
@ -842,7 +857,7 @@ class Aurora(commands.Cog):
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been banned for {humanize_timedelta(timedelta=parsed_time)}! (Case `#{moderation_id}`)\n**Reason** - `{reason}`"
content=f"{target.mention} has been banned for {humanize_timedelta(timedelta=parsed_time)}! (Case `#{moderation_id}`)\n**Reason** - `{reason}`",
)
await log(interaction, moderation_id)
@ -850,14 +865,14 @@ class Aurora(commands.Cog):
await send_evidenceformat(interaction, case)
else:
await interaction.response.send_message(
content=f"{target.mention} has been banned!\n**Reason** - `{reason}`"
content=f"{target.mention} has been banned!\n**Reason** - `{reason}`",
)
if silent is None:
silent = not await config.guild(interaction.guild).dm_users()
if silent is False:
try:
embed = embed = await message_factory(
embed = await message_factory(
await self.bot.get_embed_color(interaction.channel),
guild=interaction.guild,
moderator=interaction.user,
@ -886,7 +901,7 @@ class Aurora(commands.Cog):
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been banned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
content=f"{target.mention} has been banned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`",
)
await log(interaction, moderation_id)
@ -918,22 +933,25 @@ class Aurora(commands.Cog):
await interaction.guild.fetch_ban(target)
except discord.errors.NotFound:
await interaction.response.send_message(
content=error(f"{target.mention} is not banned!"), ephemeral=True
content=error(f"{target.mention} is not banned!"),
ephemeral=True,
)
return
if reason:
await interaction.guild.unban(
target, reason=f"Unbanned by {interaction.user.id} for: {reason}"
target,
reason=f"Unbanned by {interaction.user.id} for: {reason}",
)
else:
await interaction.guild.unban(
target, reason=f"Unbanned by {interaction.user.id}"
target,
reason=f"Unbanned by {interaction.user.id}",
)
reason = "No reason given."
await interaction.response.send_message(
content=f"{target.mention} has been unbanned!\n**Reason** - `{reason}`"
content=f"{target.mention} has been unbanned!\n**Reason** - `{reason}`",
)
if silent is None:
@ -963,7 +981,7 @@ class Aurora(commands.Cog):
reason,
)
await interaction.edit_original_response(
content=f"{target.mention} has been unbanned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`"
content=f"{target.mention} has been unbanned! (Case `#{moderation_id:,}`)\n**Reason** - `{reason}`",
)
await log(interaction, moderation_id)
@ -1001,42 +1019,28 @@ class Aurora(commands.Cog):
export: bool
Exports the server's entire moderation history to a JSON file"""
if ephemeral is None:
ephemeral = (
await config.user(interaction.user).history_ephemeral()
or await config.guild(interaction.guild).history_ephemeral()
or False
)
ephemeral = await config.user(interaction.user).history_ephemeral() or await config.guild(interaction.guild).history_ephemeral() or False
if inline is None:
inline = (
await config.user(interaction.user).history_inline()
or await config.guild(interaction.guild).history_inline()
or False
)
inline = await config.user(interaction.user).history_inline() or await config.guild(interaction.guild).history_inline() or False
if pagesize is None:
if inline is True:
pagesize = (
await config.user(interaction.user).history_inline_pagesize()
or await config.guild(interaction.guild).history_inline_pagesize()
or 6
)
pagesize = await config.user(interaction.user).history_inline_pagesize() or await config.guild(interaction.guild).history_inline_pagesize() or 6
else:
pagesize = (
await config.user(interaction.user).history_pagesize()
or await config.guild(interaction.guild).history_pagesize()
or 5
)
pagesize = await config.user(interaction.user).history_pagesize() or await config.guild(interaction.guild).history_pagesize() or 5
await interaction.response.defer(ephemeral=ephemeral)
permissions = check_permissions(
interaction.client.user, ["embed_links"], interaction
interaction.client.user,
["embed_links"],
interaction,
)
if permissions:
await interaction.followup.send(
error(
f"I do not have the `{permissions}` permission, required for this action."
f"I do not have the `{permissions}` permission, required for this action.",
),
ephemeral=True,
)
@ -1061,18 +1065,15 @@ class Aurora(commands.Cog):
cases.append(case)
try:
filename = (
str(data_manager.cog_data_path(cog_instance=self))
+ str(os.sep)
+ f"moderation_{interaction.guild.id}.json"
)
filename = str(data_manager.cog_data_path(cog_instance=self)) + str(os.sep) + f"moderation_{interaction.guild.id}.json"
with open(filename, "w", encoding="utf-8") as f:
json.dump(cases, f, indent=2)
await interaction.followup.send(
file=discord.File(
filename, f"moderation_{interaction.guild.id}.json"
filename,
f"moderation_{interaction.guild.id}.json",
),
ephemeral=ephemeral,
)
@ -1081,7 +1082,7 @@ class Aurora(commands.Cog):
except json.JSONDecodeError as e:
await interaction.followup.send(
content=error(
"An error occured while exporting the moderation history.\nError:\n"
"An error occured while exporting the moderation history.\nError:\n",
)
+ box(e, "py"),
ephemeral=ephemeral,
@ -1127,7 +1128,7 @@ class Aurora(commands.Cog):
embed = discord.Embed(color=await self.bot.get_embed_color(interaction.channel))
embed.set_author(icon_url=interaction.guild.icon.url, name="Infraction History")
embed.set_footer(
text=f"Page {page:,}/{page_quantity:,} | {case_quantity:,} Results"
text=f"Page {page:,}/{page_quantity:,} | {case_quantity:,} Results",
)
memory_dict = {}
@ -1136,33 +1137,30 @@ class Aurora(commands.Cog):
if case["target_id"] not in memory_dict:
if case["target_type"] == "USER":
memory_dict[str(case["target_id"])] = await fetch_user_dict(
interaction.client, case["target_id"]
interaction.client,
case["target_id"],
)
elif case["target_type"] == "CHANNEL":
memory_dict[str(case["target_id"])] = await fetch_channel_dict(
interaction.guild, case["target_id"]
interaction.guild,
case["target_id"],
)
target_user = memory_dict[str(case["target_id"])]
if case["target_type"] == "USER":
target_name = (
f"`{target_user['name']}`"
if target_user["discriminator"] == "0"
else f"`{target_user['name']}#{target_user['discriminator']}`"
)
target_name = f"`{target_user['name']}`" if target_user["discriminator"] == "0" else f"`{target_user['name']}#{target_user['discriminator']}`"
elif case["target_type"] == "CHANNEL":
target_name = f"`{target_user['mention']}`"
else:
target_name = ""
if case["moderator_id"] not in memory_dict:
memory_dict[str(case["moderator_id"])] = await fetch_user_dict(
interaction.client, case["moderator_id"]
interaction.client,
case["moderator_id"],
)
moderator_user = memory_dict[str(case["moderator_id"])]
moderator_name = (
f"`{moderator_user['name']}`"
if moderator_user["discriminator"] == "0"
else f"`{moderator_user['name']}#{moderator_user['discriminator']}`"
)
moderator_name = f"`{moderator_user['name']}`" if moderator_user["discriminator"] == "0" else f"`{moderator_user['name']}#{moderator_user['discriminator']}`"
field_name = f"Case #{case['moderation_id']:,} ({str.title(case['moderation_type'])})"
field_value = f"**Target:** {target_name} ({target_user['id']})\n**Moderator:** {moderator_name} ({moderator_user['id']})"
@ -1177,20 +1175,15 @@ class Aurora(commands.Cog):
**{
unit: int(val)
for unit, val in zip(
["hours", "minutes", "seconds"], case["duration"].split(":")
["hours", "minutes", "seconds"],
case["duration"].split(":"),
)
}
)
duration_embed = (
f"{humanize_timedelta(timedelta=td)} | <t:{case['end_timestamp']}:R>"
if bool(case["expired"]) is False
else f"{humanize_timedelta(timedelta=td)} | Expired"
},
)
duration_embed = f"{humanize_timedelta(timedelta=td)} | <t:{case['end_timestamp']}:R>" if bool(case["expired"]) is False else f"{humanize_timedelta(timedelta=td)} | Expired"
field_value += f"\n**Duration:** {duration_embed}"
field_value += (
f"\n**Timestamp:** <t:{case['timestamp']}> | <t:{case['timestamp']}:R>"
)
field_value += f"\n**Timestamp:** <t:{case['timestamp']}> | <t:{case['timestamp']}:R>"
if case["role_id"] != "0":
role = interaction.guild.get_role(int(case["role_id"]))
@ -1208,7 +1201,10 @@ class Aurora(commands.Cog):
@app_commands.command(name="resolve")
async def resolve(
self, interaction: discord.Interaction, case: int, reason: str = None
self,
interaction: discord.Interaction,
case: int,
reason: str = None,
):
"""Resolve a specific case.
@ -1226,7 +1222,7 @@ class Aurora(commands.Cog):
if permissions:
await interaction.response.send_message(
error(
f"I do not have the `{permissions}` permission, required for this action."
f"I do not have the `{permissions}` permission, required for this action.",
),
ephemeral=True,
)
@ -1235,9 +1231,7 @@ class Aurora(commands.Cog):
database = connect()
cursor = database.cursor()
query_1 = (
f"SELECT * FROM moderation_{interaction.guild.id} WHERE moderation_id = ?;"
)
query_1 = f"SELECT * FROM moderation_{interaction.guild.id} WHERE moderation_id = ?;"
cursor.execute(query_1, (case,))
result_1 = cursor.fetchone()
if result_1 is None or case == 0:
@ -1253,7 +1247,7 @@ class Aurora(commands.Cog):
if result_2 is None:
await interaction.response.send_message(
content=error(
f"This moderation has already been resolved!\nUse `/case {case}` for more information."
f"This moderation has already been resolved!\nUse `/case {case}` for more information.",
),
ephemeral=True,
)
@ -1267,7 +1261,7 @@ class Aurora(commands.Cog):
if len(changes) > 25:
await interaction.response.send_message(
content=error(
"Due to limitations with Discord's embed system, you cannot edit a case more than 25 times."
"Due to limitations with Discord's embed system, you cannot edit a case more than 25 times.",
),
ephemeral=True,
)
@ -1279,7 +1273,7 @@ class Aurora(commands.Cog):
"timestamp": case_dict["timestamp"],
"reason": case_dict["reason"],
"user_id": case_dict["moderator_id"],
}
},
)
changes.append(
{
@ -1287,7 +1281,7 @@ class Aurora(commands.Cog):
"timestamp": int(time.time()),
"reason": reason,
"user_id": interaction.user.id,
}
},
)
if case_dict["moderation_type"] in ["UNMUTE", "UNBAN"]:
@ -1301,11 +1295,12 @@ class Aurora(commands.Cog):
if case_dict["moderation_type"] == "MUTE":
try:
member = await interaction.guild.fetch_member(
case_dict["target_id"]
case_dict["target_id"],
)
await member.timeout(
None, reason=f"Case #{case:,} resolved by {interaction.user.id}"
None,
reason=f"Case #{case:,} resolved by {interaction.user.id}",
)
except discord.NotFound:
pass
@ -1315,7 +1310,8 @@ class Aurora(commands.Cog):
user = await interaction.client.fetch_user(case_dict["target_id"])
await interaction.guild.unban(
user, reason=f"Case #{case} resolved by {interaction.user.id}"
user,
reason=f"Case #{case} resolved by {interaction.user.id}",
)
except discord.NotFound:
pass
@ -1340,7 +1336,8 @@ class Aurora(commands.Cog):
case_dict=await fetch_case(case, interaction.guild.id),
)
await interaction.response.send_message(
content=f"✅ Moderation #{case:,} resolved!", embed=embed
content=f"✅ Moderation #{case:,} resolved!",
embed=embed,
)
await log(interaction, case, resolved=True)
@ -1352,7 +1349,7 @@ class Aurora(commands.Cog):
export=[
Choice(name="Export as File", value="file"),
Choice(name="Export as Codeblock", value="codeblock"),
]
],
)
async def case(
self,
@ -1376,41 +1373,35 @@ class Aurora(commands.Cog):
export: bool
Export the case to a JSON file or codeblock"""
permissions = check_permissions(
interaction.client.user, ["embed_links"], interaction
interaction.client.user,
["embed_links"],
interaction,
)
if permissions:
await interaction.response.send_message(
error(
f"I do not have the `{permissions}` permission, required for this action."
f"I do not have the `{permissions}` permission, required for this action.",
),
ephemeral=True,
)
return
if ephemeral is None:
ephemeral = (
await config.user(interaction.user).history_ephemeral()
or await config.guild(interaction.guild).history_ephemeral()
or False
)
ephemeral = await config.user(interaction.user).history_ephemeral() or await config.guild(interaction.guild).history_ephemeral() or False
if case != 0:
case_dict = await fetch_case(case, interaction.guild.id)
if case_dict:
if export:
if export.value == "file" or len(str(case_dict)) > 1800:
filename = (
str(data_manager.cog_data_path(cog_instance=self))
+ str(os.sep)
+ f"moderation_{interaction.guild.id}_case_{case}.json"
)
filename = str(data_manager.cog_data_path(cog_instance=self)) + str(os.sep) + f"moderation_{interaction.guild.id}_case_{case}.json"
with open(filename, "w", encoding="utf-8") as f:
json.dump(case_dict, f, indent=2)
if export.value == "codeblock":
content = f"Case #{case:,} exported.\n" + warning(
"Case was too large to export as codeblock, so it has been uploaded as a `.json` file."
"Case was too large to export as codeblock, so it has been uploaded as a `.json` file.",
)
else:
content = f"Case #{case:,} exported."
@ -1427,34 +1418,41 @@ class Aurora(commands.Cog):
os.remove(filename)
return
await interaction.response.send_message(
content=box(json.dumps(case_dict, indent=2), 'json'),
content=box(json.dumps(case_dict, indent=2), "json"),
ephemeral=ephemeral,
)
return
if changes:
embed = await changes_factory(
interaction=interaction, case_dict=case_dict
interaction=interaction,
case_dict=case_dict,
)
await interaction.response.send_message(
embed=embed, ephemeral=ephemeral
embed=embed,
ephemeral=ephemeral,
)
elif evidenceformat:
content = await evidenceformat_factory(
interaction=interaction, case_dict=case_dict
interaction=interaction,
case_dict=case_dict,
)
await interaction.response.send_message(
content=content, ephemeral=ephemeral
content=content,
ephemeral=ephemeral,
)
else:
embed = await case_factory(
interaction=interaction, case_dict=case_dict
interaction=interaction,
case_dict=case_dict,
)
await interaction.response.send_message(
embed=embed, ephemeral=ephemeral
embed=embed,
ephemeral=ephemeral,
)
return
await interaction.response.send_message(
content=f"No case with case number `{case}` found.", ephemeral=True
content=f"No case with case number `{case}` found.",
ephemeral=True,
)
@app_commands.command(name="edit")
@ -1476,13 +1474,16 @@ class Aurora(commands.Cog):
duration: str
What is the new duration? Does not reapply the moderation if it has already expired.
"""
end_timestamp = None
permissions = check_permissions(
interaction.client.user, ["embed_links"], interaction
interaction.client.user,
["embed_links"],
interaction,
)
if permissions:
await interaction.response.send_message(
error(
f"I do not have the `{permissions}` permission, required for this action."
f"I do not have the `{permissions}` permission, required for this action.",
),
ephemeral=True,
)
@ -1496,26 +1497,25 @@ class Aurora(commands.Cog):
parsed_time = parse_timedelta(duration)
if parsed_time is None:
await interaction.response.send_message(
error("Please provide a valid duration!"), ephemeral=True
error("Please provide a valid duration!"),
ephemeral=True,
)
return
end_timestamp = case_dict["timestamp"] + parsed_time.total_seconds()
if case_dict["moderation_type"] == "MUTE":
if (
time.time() - case_dict["timestamp"]
) + parsed_time.total_seconds() > 2419200:
if (time.time() - case_dict["timestamp"]) + parsed_time.total_seconds() > 2419200:
await interaction.response.send_message(
error(
"Please provide a duration that is less than 28 days from the initial moderation."
)
"Please provide a duration that is less than 28 days from the initial moderation.",
),
)
return
try:
member = await interaction.guild.fetch_member(
case_dict["target_id"]
case_dict["target_id"],
)
await member.timeout(
@ -1529,7 +1529,7 @@ class Aurora(commands.Cog):
if len(changes) > 25:
await interaction.response.send_message(
content=error(
"Due to limitations with Discord's embed system, you cannot edit a case more than 25 times."
"Due to limitations with Discord's embed system, you cannot edit a case more than 25 times.",
),
ephemeral=True,
)
@ -1543,9 +1543,10 @@ class Aurora(commands.Cog):
"user_id": case_dict["moderator_id"],
"duration": case_dict["duration"],
"end_timestamp": case_dict["end_timestamp"],
}
},
)
if parsed_time:
assert end_timestamp is not None
changes.append(
{
"type": "EDIT",
@ -1554,7 +1555,7 @@ class Aurora(commands.Cog):
"user_id": interaction.user.id,
"duration": convert_timedelta_to_str(parsed_time),
"end_timestamp": end_timestamp,
}
},
)
else:
changes.append(
@ -1565,7 +1566,7 @@ class Aurora(commands.Cog):
"user_id": interaction.user.id,
"duration": case_dict["duration"],
"end_timestamp": case_dict["end_timestamp"],
}
},
)
database = connect()
@ -1602,7 +1603,8 @@ class Aurora(commands.Cog):
database.close()
return
await interaction.response.send_message(
content=error(f"No case with case number `{case}` found."), ephemeral=True
content=error(f"No case with case number `{case}` found."),
ephemeral=True,
)
@tasks.loop(minutes=1)
@ -1634,14 +1636,11 @@ class Aurora(commands.Cog):
unban_num = 0
for target_id, moderation_id in zip(target_ids, moderation_ids):
user: discord.User = await self.bot.fetch_user(target_id)
name = (
f"{user.name}#{user.discriminator}"
if user.discriminator != "0"
else user.name
)
name = f"{user.name}#{user.discriminator}" if user.discriminator != "0" else user.name
try:
await guild.unban(
user, reason=f"Automatic unban from case #{moderation_id}"
user,
reason=f"Automatic unban from case #{moderation_id}",
)
embed = await message_factory(
@ -1690,13 +1689,16 @@ class Aurora(commands.Cog):
role_ids = [row[2] for row in result]
for target_id, moderation_id, role_id in zip(
target_ids, moderation_ids, role_ids
target_ids,
moderation_ids,
role_ids,
):
try:
member = await guild.fetch_member(target_id)
await member.remove_roles(
Object(role_id), reason=f"Automatic role removal from case #{moderation_id}"
Object(role_id),
reason=f"Automatic role removal from case #{moderation_id}",
)
removerole_num = removerole_num + 1
@ -1725,13 +1727,16 @@ class Aurora(commands.Cog):
role_ids = [row[2] for row in result]
for target_id, moderation_id, role_id in zip(
target_ids, moderation_ids, role_ids
target_ids,
moderation_ids,
role_ids,
):
try:
member = await guild.fetch_member(target_id)
await member.add_roles(
Object(role_id), reason=f"Automatic role addition from case #{moderation_id}"
Object(role_id),
reason=f"Automatic role addition from case #{moderation_id}",
)
addrole_num = addrole_num + 1
@ -1827,15 +1832,11 @@ class Aurora(commands.Cog):
@commands.admin()
async def aurora_import_aurora(self, ctx: commands.Context):
"""Import moderation history from another bot using Aurora."""
if (
ctx.message.attachments
and ctx.message.attachments[0].content_type
== "application/json; charset=utf-8"
):
if ctx.message.attachments and ctx.message.attachments[0].content_type == "application/json; charset=utf-8":
message = await ctx.send(
warning(
"Are you sure you want to import moderations from another bot?\n**This will overwrite any moderations that already exist in this guild's moderation table.**\n*The import process will block the rest of your bot until it is complete.*"
)
"Are you sure you want to import moderations from another bot?\n**This will overwrite any moderations that already exist in this guild's moderation table.**\n*The import process will block the rest of your bot until it is complete.*",
),
)
await message.edit(view=ImportAuroraView(60, ctx, message))
else:
@ -1845,20 +1846,16 @@ class Aurora(commands.Cog):
@commands.admin()
async def aurora_import_galacticbot(self, ctx: commands.Context):
"""Import moderation history from GalacticBot."""
if (
ctx.message.attachments
and ctx.message.attachments[0].content_type
== "application/json; charset=utf-8"
):
if ctx.message.attachments and ctx.message.attachments[0].content_type == "application/json; charset=utf-8":
message = await ctx.send(
warning(
"Are you sure you want to import GalacticBot moderations?\n**This will overwrite any moderations that already exist in this guild's moderation table.**\n*The import process will block the rest of your bot until it is complete.*"
)
"Are you sure you want to import GalacticBot moderations?\n**This will overwrite any moderations that already exist in this guild's moderation table.**\n*The import process will block the rest of your bot until it is complete.*",
),
)
await message.edit(view=ImportGalacticBotView(60, ctx, message))
else:
await ctx.send(
error("Please provide a valid GalacticBot moderation export file.")
error("Please provide a valid GalacticBot moderation export file."),
)
@aurora.command(aliases=["tdc", "td", "timedeltaconvert"])

View file

@ -17,13 +17,9 @@ class ImportAuroraView(ui.View):
self.message: Message = message
@ui.button(label="Yes", style=ButtonStyle.success)
async def import_button_y(
self, interaction: Interaction, button: ui.Button
): # pylint: disable=unused-argument
async def import_button_y(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
await self.message.delete()
await interaction.response.send_message(
"Deleting original table...", ephemeral=True
)
await interaction.response.send_message("Deleting original table...", ephemeral=True)
database = connect()
cursor = database.cursor()
@ -101,16 +97,10 @@ class ImportAuroraView(ui.View):
await interaction.edit_original_response(content="Import complete.")
if failed_cases:
await interaction.edit_original_response(
content="Import complete.\n"
+ warning("Failed to import the following cases:\n")
+ box(failed_cases)
)
await interaction.edit_original_response(content="Import complete.\n" + warning("Failed to import the following cases:\n") + box(failed_cases))
@ui.button(label="No", style=ButtonStyle.danger)
async def import_button_n(
self, interaction: Interaction, button: ui.Button
): # pylint: disable=unused-argument
async def import_button_n(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
await self.message.edit(content="Import cancelled.", view=None)
await self.message.delete(10)
await self.ctx.message.delete(10)

View file

@ -16,13 +16,9 @@ class ImportGalacticBotView(ui.View):
self.message: Message = message
@ui.button(label="Yes", style=ButtonStyle.success)
async def import_button_y(
self, interaction: Interaction, button: ui.Button
): # pylint: disable=unused-argument
async def import_button_y(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
await self.message.delete()
await interaction.response.send_message(
"Deleting original table...", ephemeral=True
)
await interaction.response.send_message("Deleting original table...", ephemeral=True)
database = connect()
cursor = database.cursor()
@ -92,9 +88,7 @@ class ImportGalacticBotView(ui.View):
if resolved_by is None:
resolved_by = "?"
if resolved_reason is None:
resolved_reason = (
"Could not get resolve reason during moderation import."
)
resolved_reason = "Could not get resolve reason during moderation import."
if resolved_timestamp is None:
resolved_timestamp = timestamp
changes = [
@ -142,16 +136,10 @@ class ImportGalacticBotView(ui.View):
await interaction.edit_original_response(content="Import complete.")
if failed_cases:
await interaction.edit_original_response(
content="Import complete.\n"
+ warning("Failed to import the following cases:\n")
+ box(failed_cases)
)
await interaction.edit_original_response(content="Import complete.\n" + warning("Failed to import the following cases:\n") + box(failed_cases))
@ui.button(label="No", style=ButtonStyle.danger)
async def import_button_n(
self, interaction: Interaction, button: ui.Button
): # pylint: disable=unused-argument
async def import_button_n(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
await self.message.edit(content="Import cancelled.", view=None)
await self.message.delete(10)
await self.ctx.message.delete(10)

View file

@ -23,7 +23,7 @@ class Addrole(ui.View):
return
await interaction.response.defer()
async with config.guild(self.ctx.guild).addrole_whitelist() as addrole_whitelist:
addrole_whitelist: list # type hint
addrole_whitelist: list # type hint
for value in select.values:
if value.id in addrole_whitelist:
addrole_whitelist.remove(value.id)
@ -32,7 +32,7 @@ class Addrole(ui.View):
await interaction.message.edit(embed=await addrole_embed(self.ctx))
@ui.button(label="Clear", style=ButtonStyle.red, row=1)
async def clear(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def clear(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message(error("You must have the manage guild permission to clear the guild's addrole whitelist."), ephemeral=True)
return
@ -41,7 +41,7 @@ class Addrole(ui.View):
await interaction.message.edit(embed=await addrole_embed(self.ctx))
@ui.button(label="Close", style=ButtonStyle.gray)
async def close(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def close(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message(error("You can't do that!"), ephemeral=True)
return

View file

@ -17,7 +17,7 @@ class Guild(ui.View):
await self.message.edit(view=None)
@ui.button(label="Show Moderator", style=ButtonStyle.green, row=0)
async def show_moderator(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def show_moderator(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
return
@ -27,7 +27,7 @@ class Guild(ui.View):
await interaction.message.edit(embed=await guild_embed(self.ctx))
@ui.button(label="Use Discord Permissions", style=ButtonStyle.green, row=0)
async def use_discord_permissions(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def use_discord_permissions(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
return
@ -37,7 +37,7 @@ class Guild(ui.View):
await interaction.message.edit(embed=await guild_embed(self.ctx))
@ui.button(label="Respect Hierarchy", style=ButtonStyle.green, row=0)
async def respect_heirarchy(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def respect_heirarchy(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
return
@ -47,7 +47,7 @@ class Guild(ui.View):
await interaction.message.edit(embed=await guild_embed(self.ctx))
@ui.button(label="Ignore Modlog", style=ButtonStyle.green, row=0)
async def ignore_modlog(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def ignore_modlog(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
return
@ -57,7 +57,7 @@ class Guild(ui.View):
await interaction.message.edit(embed=await guild_embed(self.ctx))
@ui.button(label="Ignore Other Bots", style=ButtonStyle.green, row=0)
async def ignore_other_bots(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def ignore_other_bots(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
return
@ -67,7 +67,7 @@ class Guild(ui.View):
await interaction.message.edit(embed=await guild_embed(self.ctx))
@ui.button(label="DM Users", style=ButtonStyle.green, row=1)
async def dm_users(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def dm_users(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
return
@ -77,7 +77,7 @@ class Guild(ui.View):
await interaction.message.edit(embed=await guild_embed(self.ctx))
@ui.button(label="Auto Evidence Format", style=ButtonStyle.green, row=1)
async def auto_evidenceformat(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def auto_evidenceformat(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
return
@ -87,7 +87,7 @@ class Guild(ui.View):
await interaction.message.edit(embed=await guild_embed(self.ctx))
@ui.button(label="Ephemeral", style=ButtonStyle.green, row=1)
async def ephemeral(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def ephemeral(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
return
@ -97,7 +97,7 @@ class Guild(ui.View):
await interaction.message.edit(embed=await guild_embed(self.ctx))
@ui.button(label="History Inline", style=ButtonStyle.green, row=1)
async def inline(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def inline(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
return
@ -107,7 +107,11 @@ class Guild(ui.View):
await interaction.message.edit(embed=await guild_embed(self.ctx))
@ui.select(placeholder="History Pagesize", options=create_pagesize_options(), row=2)
async def pagesize(self, interaction: Interaction, select: ui.Select,):
async def pagesize(
self,
interaction: Interaction,
select: ui.Select,
):
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
return
@ -119,7 +123,11 @@ class Guild(ui.View):
await interaction.message.edit(embed=await guild_embed(self.ctx))
@ui.select(placeholder="History Inline Pagesize", options=create_pagesize_options(), row=3)
async def inline_pagesize(self, interaction: Interaction, select: ui.Select,):
async def inline_pagesize(
self,
interaction: Interaction,
select: ui.Select,
):
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message("You must have the manage guild permission to change this setting.", ephemeral=True)
return

View file

@ -23,7 +23,7 @@ class Immune(ui.View):
return
await interaction.response.defer()
async with config.guild(self.ctx.guild).immune_roles() as immune_roles:
immune_roles: list # type hint
immune_roles: list # type hint
for value in select.values:
if value.id in immune_roles:
immune_roles.remove(value.id)
@ -32,7 +32,7 @@ class Immune(ui.View):
await interaction.message.edit(embed=await immune_embed(self.ctx))
@ui.button(label="Clear", style=ButtonStyle.red, row=1)
async def clear(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def clear(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message(error("You must have the manage guild permission to clear the guild's immune roles."), ephemeral=True)
return
@ -41,7 +41,7 @@ class Immune(ui.View):
await interaction.message.edit(embed=await immune_embed(self.ctx))
@ui.button(label="Close", style=ButtonStyle.gray)
async def close(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def close(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if not interaction.user.guild_permissions.manage_guild and not interaction.user.guild_permissions.administrator:
await interaction.response.send_message(error("You can't do that!"), ephemeral=True)
return

View file

@ -17,7 +17,7 @@ class Overrides(ui.View):
await self.message.edit(view=None)
@ui.button(label="Auto Evidence Format", style=ButtonStyle.green, row=0)
async def auto_evidenceformat(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def auto_evidenceformat(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if self.ctx.author != interaction.user:
await interaction.response.send_message("You cannot change this setting for other users.", ephemeral=True)
return
@ -32,7 +32,7 @@ class Overrides(ui.View):
await interaction.message.edit(embed=await overrides_embed(self.ctx))
@ui.button(label="Ephemeral", style=ButtonStyle.green, row=0)
async def ephemeral(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def ephemeral(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if self.ctx.author != interaction.user:
await interaction.response.send_message("You cannot change this setting for other users.", ephemeral=True)
return
@ -47,7 +47,7 @@ class Overrides(ui.View):
await interaction.message.edit(embed=await overrides_embed(self.ctx))
@ui.button(label="Inline", style=ButtonStyle.green, row=0)
async def inline(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
async def inline(self, interaction: Interaction, button: ui.Button): # pylint: disable=unused-argument
if self.ctx.author != interaction.user:
await interaction.response.send_message("You cannot change this setting for other users.", ephemeral=True)
return
@ -62,7 +62,11 @@ class Overrides(ui.View):
await interaction.message.edit(embed=await overrides_embed(self.ctx))
@ui.select(placeholder="Inline Pagesize", options=create_pagesize_options(), row=1)
async def inline_pagesize(self, interaction: Interaction, select: ui.Select,):
async def inline_pagesize(
self,
interaction: Interaction,
select: ui.Select,
):
if self.ctx.author != interaction.user:
await interaction.response.send_message("You cannot change this setting for other users.", ephemeral=True)
return
@ -74,7 +78,11 @@ class Overrides(ui.View):
await interaction.message.edit(embed=await overrides_embed(self.ctx))
@ui.select(placeholder="Pagesize", options=create_pagesize_options(), row=2)
async def pagesize(self, interaction: Interaction, select: ui.Select,):
async def pagesize(
self,
interaction: Interaction,
select: ui.Select,
):
if self.ctx.author != interaction.user:
await interaction.response.send_message("You cannot change this setting for other users.", ephemeral=True)
return

View file

@ -8,23 +8,18 @@ from discord import Guild
from redbot.core import data_manager
from .logger import logger
from .utils import (convert_timedelta_to_str, generate_dict,
get_next_case_number)
from .utils import convert_timedelta_to_str, generate_dict, get_next_case_number
def connect() -> sqlite3.Connection:
"""Connects to the SQLite database, and returns a connection object."""
try:
connection = sqlite3.connect(
database=data_manager.cog_data_path(raw_name="Aurora") / "aurora.db"
)
return connection
return sqlite3.connect(database=data_manager.cog_data_path(raw_name="Aurora") / "aurora.db")
except sqlite3.OperationalError as e:
logger.error("Unable to access the SQLite database!\nError:\n%s", e.msg)
raise ConnectionRefusedError(
f"Unable to access the SQLite Database!\n{e.msg}"
) from e
msg = f"Unable to access the SQLite Database!\n{e.msg}"
raise ConnectionRefusedError(msg) from e
async def create_guild_table(guild: Guild):

View file

@ -75,7 +75,9 @@ async def message_factory(
if await config.guild(guild).show_moderator() and moderator is not None:
embed.add_field(
name="Moderator", value=f"`{moderator.name} ({moderator.id})`", inline=False
name="Moderator",
value=f"`{moderator.name} ({moderator.id})`",
inline=False,
)
embed.add_field(name="Reason", value=f"`{reason}`", inline=False)
@ -94,7 +96,9 @@ async def message_factory(
async def log_factory(
interaction: Interaction, case_dict: dict, resolved: bool = False
interaction: Interaction,
case_dict: dict,
resolved: bool = False,
) -> Embed:
"""This function creates a log embed from set parameters, meant for moderation logging.
@ -103,14 +107,11 @@ async def log_factory(
case_dict (dict): The case dictionary.
resolved (bool, optional): Whether the case is resolved or not. Defaults to False.
"""
target_name = ""
if resolved:
if case_dict["target_type"] == "USER":
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
target_name = (
f"`{target_user['name']}`"
if target_user["discriminator"] == "0"
else f"`{target_user['name']}#{target_user['discriminator']}`"
)
target_name = f"`{target_user['name']}`" if target_user["discriminator"] == "0" else f"`{target_user['name']}#{target_user['discriminator']}`"
elif case_dict["target_type"] == "CHANNEL":
target_user = await fetch_channel_dict(interaction.guild, case_dict["target_id"])
if target_user["mention"]:
@ -119,11 +120,7 @@ async def log_factory(
target_name = f"`{target_user['name']}`"
moderator_user = await fetch_user_dict(interaction.client, case_dict["moderator_id"])
moderator_name = (
f"`{moderator_user['name']}`"
if moderator_user["discriminator"] == "0"
else f"`{moderator_user['name']}#{moderator_user['discriminator']}`"
)
moderator_name = f"`{moderator_user['name']}`" if moderator_user["discriminator"] == "0" else f"`{moderator_user['name']}#{moderator_user['discriminator']}`"
embed = Embed(
title=f"📕 Case #{case_dict['moderation_id']:,} Resolved",
@ -140,40 +137,24 @@ async def log_factory(
["hours", "minutes", "seconds"],
case_dict["duration"].split(":"),
)
}
)
duration_embed = (
f"{humanize_timedelta(timedelta=td)} | <t:{case_dict['end_timestamp']}:R>"
if case_dict["expired"] == "0"
else str(humanize_timedelta(timedelta=td))
)
embed.description = (
embed.description
+ f"\n**Duration:** {duration_embed}\n**Expired:** {bool(case_dict['expired'])}"
},
)
duration_embed = f"{humanize_timedelta(timedelta=td)} | <t:{case_dict['end_timestamp']}:R>" if case_dict["expired"] == "0" else str(humanize_timedelta(timedelta=td))
embed.description = embed.description + f"\n**Duration:** {duration_embed}\n**Expired:** {bool(case_dict['expired'])}"
embed.add_field(name="Reason", value=box(case_dict["reason"]), inline=False)
resolved_user = await fetch_user_dict(interaction.client, case_dict["resolved_by"])
resolved_name = (
resolved_user["name"]
if resolved_user["discriminator"] == "0"
else f"{resolved_user['name']}#{resolved_user['discriminator']}"
)
resolved_name = resolved_user["name"] if resolved_user["discriminator"] == "0" else f"{resolved_user['name']}#{resolved_user['discriminator']}"
embed.add_field(
name="Resolve Reason",
value=f"Resolved by `{resolved_name}` ({resolved_user['id']}) for:\n"
+ box(case_dict["resolve_reason"]),
value=f"Resolved by `{resolved_name}` ({resolved_user['id']}) for:\n" + box(case_dict["resolve_reason"]),
inline=False,
)
else:
if case_dict["target_type"] == "USER":
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
target_name = (
f"`{target_user['name']}`"
if target_user["discriminator"] == "0"
else f"`{target_user['name']}#{target_user['discriminator']}`"
)
target_name = f"`{target_user['name']}`" if target_user["discriminator"] == "0" else f"`{target_user['name']}#{target_user['discriminator']}`"
elif case_dict["target_type"] == "CHANNEL":
target_user = await fetch_channel_dict(interaction.guild, case_dict["target_id"])
if target_user["mention"]:
@ -182,11 +163,7 @@ async def log_factory(
target_name = f"`{target_user['name']}`"
moderator_user = await fetch_user_dict(interaction.client, case_dict["moderator_id"])
moderator_name = (
f"`{moderator_user['name']}`"
if moderator_user["discriminator"] == "0"
else f"`{moderator_user['name']}#{moderator_user['discriminator']}`"
)
moderator_name = f"`{moderator_user['name']}`" if moderator_user["discriminator"] == "0" else f"`{moderator_user['name']}#{moderator_user['discriminator']}`"
embed = Embed(
title=f"📕 Case #{case_dict['moderation_id']:,}",
@ -202,12 +179,9 @@ async def log_factory(
["hours", "minutes", "seconds"],
case_dict["duration"].split(":"),
)
}
)
embed.description = (
embed.description
+ f"\n**Duration:** {humanize_timedelta(timedelta=td)} | <t:{case_dict['end_timestamp']}:R>"
},
)
embed.description = embed.description + f"\n**Duration:** {humanize_timedelta(timedelta=td)} | <t:{case_dict['end_timestamp']}:R>"
embed.add_field(name="Reason", value=box(case_dict["reason"]), inline=False)
return embed
@ -220,13 +194,10 @@ async def case_factory(interaction: Interaction, case_dict: dict) -> Embed:
interaction (Interaction): The interaction object.
case_dict (dict): The case dictionary.
"""
target_name = ""
if case_dict["target_type"] == "USER":
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
target_name = (
f"`{target_user['name']}`"
if target_user["discriminator"] == "0"
else f"`{target_user['name']}#{target_user['discriminator']}`"
)
target_name = f"`{target_user['name']}`" if target_user["discriminator"] == "0" else f"`{target_user['name']}#{target_user['discriminator']}`"
elif case_dict["target_type"] == "CHANNEL":
target_user = await fetch_channel_dict(interaction.guild, case_dict["target_id"])
if target_user["mention"]:
@ -235,11 +206,7 @@ async def case_factory(interaction: Interaction, case_dict: dict) -> Embed:
target_name = f"`{target_user['name']}`"
moderator_user = await fetch_user_dict(interaction.client, case_dict["moderator_id"])
moderator_name = (
f"`{moderator_user['name']}`"
if moderator_user["discriminator"] == "0"
else f"`{moderator_user['name']}#{moderator_user['discriminator']}`"
)
moderator_name = f"`{moderator_user['name']}`" if moderator_user["discriminator"] == "0" else f"`{moderator_user['name']}#{moderator_user['discriminator']}`"
embed = Embed(
title=f"📕 Case #{case_dict['moderation_id']:,}",
@ -252,41 +219,28 @@ async def case_factory(interaction: Interaction, case_dict: dict) -> Embed:
**{
unit: int(val)
for unit, val in zip(
["hours", "minutes", "seconds"], case_dict["duration"].split(":")
["hours", "minutes", "seconds"],
case_dict["duration"].split(":"),
)
}
)
duration_embed = (
f"{humanize_timedelta(timedelta=td)} | <t:{case_dict['end_timestamp']}:R>"
if bool(case_dict["expired"]) is False
else str(humanize_timedelta(timedelta=td))
},
)
duration_embed = f"{humanize_timedelta(timedelta=td)} | <t:{case_dict['end_timestamp']}:R>" if bool(case_dict["expired"]) is False else str(humanize_timedelta(timedelta=td))
embed.description += f"\n**Duration:** {duration_embed}\n**Expired:** {bool(case_dict['expired'])}"
embed.description += (
f"\n**Changes:** {len(case_dict['changes']) - 1}"
if case_dict["changes"]
else "\n**Changes:** 0"
)
embed.description += f"\n**Changes:** {len(case_dict['changes']) - 1}" if case_dict["changes"] else "\n**Changes:** 0"
if case_dict["role_id"]:
embed.description += f"\n**Role:** <@&{case_dict['role_id']}>"
if case_dict["metadata"]:
if case_dict["metadata"]["imported_from"]:
embed.description += (
f"\n**Imported From:** {case_dict['metadata']['imported_from']}"
)
embed.description += f"\n**Imported From:** {case_dict['metadata']['imported_from']}"
embed.add_field(name="Reason", value=box(case_dict["reason"]), inline=False)
if case_dict["resolved"] == 1:
resolved_user = await fetch_user_dict(interaction.client, case_dict["resolved_by"])
resolved_name = (
f"`{resolved_user['name']}`"
if resolved_user["discriminator"] == "0"
else f"`{resolved_user['name']}#{resolved_user['discriminator']}`"
)
resolved_name = f"`{resolved_user['name']}`" if resolved_user["discriminator"] == "0" else f"`{resolved_user['name']}#{resolved_user['discriminator']}`"
embed.add_field(
name="Resolve Reason",
value=f"Resolved by {resolved_name} ({resolved_user['id']}) for:\n{box(case_dict['resolve_reason'])}",
@ -314,15 +268,12 @@ async def changes_factory(interaction: Interaction, case_dict: dict) -> Embed:
for change in case_dict["changes"]:
if change["user_id"] not in memory_dict:
memory_dict[str(change["user_id"])] = await fetch_user_dict(
interaction.client, change["user_id"]
interaction.client,
change["user_id"],
)
user = memory_dict[str(change["user_id"])]
name = (
user["name"]
if user["discriminator"] == "0"
else f"{user['name']}#{user['discriminator']}"
)
name = user["name"] if user["discriminator"] == "0" else f"{user['name']}#{user['discriminator']}"
timestamp = f"<t:{change['timestamp']}> | <t:{change['timestamp']}:R>"
@ -360,24 +311,17 @@ async def evidenceformat_factory(interaction: Interaction, case_dict: dict) -> s
interaction (Interaction): The interaction object.
case_dict (dict): The case dictionary.
"""
target_name = ""
if case_dict["target_type"] == "USER":
target_user = await fetch_user_dict(interaction.client, case_dict["target_id"])
target_name = (
target_user["name"]
if target_user["discriminator"] == "0"
else f"{target_user['name']}#{target_user['discriminator']}"
)
target_name = target_user["name"] if target_user["discriminator"] == "0" else f"{target_user['name']}#{target_user['discriminator']}"
elif case_dict["target_type"] == "CHANNEL":
target_user = await fetch_channel_dict(interaction.guild, case_dict["target_id"])
target_name = target_user["name"]
moderator_user = await fetch_user_dict(interaction.client, case_dict["moderator_id"])
moderator_name = (
moderator_user["name"]
if moderator_user["discriminator"] == "0"
else f"{moderator_user['name']}#{moderator_user['discriminator']}"
)
moderator_name = moderator_user["name"] if moderator_user["discriminator"] == "0" else f"{moderator_user['name']}#{moderator_user['discriminator']}"
content = f"Case: {case_dict['moderation_id']:,} ({str.title(case_dict['moderation_type'])})\nTarget: {target_name} ({target_user['id']})\nModerator: {moderator_name} ({moderator_user['id']})"
@ -419,17 +363,11 @@ async def overrides_embed(ctx: commands.Context) -> Embed:
}
override_str = [
"- "
+ bold("Auto Evidence Format: ")
+ get_bool_emoji(override_settings["auto_evidenceformat"]),
"- " + bold("Auto Evidence Format: ") + get_bool_emoji(override_settings["auto_evidenceformat"]),
"- " + bold("Ephemeral: ") + get_bool_emoji(override_settings["ephemeral"]),
"- " + bold("History Inline: ") + get_bool_emoji(override_settings["inline"]),
"- "
+ bold("History Inline Pagesize: ")
+ get_pagesize_str(override_settings["inline_pagesize"]),
"- "
+ bold("History Pagesize: ")
+ get_pagesize_str(override_settings["pagesize"]),
"- " + bold("History Inline Pagesize: ") + get_pagesize_str(override_settings["inline_pagesize"]),
"- " + bold("History Pagesize: ") + get_pagesize_str(override_settings["pagesize"]),
]
override_str = "\n".join(override_str)
@ -451,7 +389,7 @@ async def guild_embed(ctx: commands.Context) -> Embed:
guild_settings = {
"show_moderator": await config.guild(ctx.guild).show_moderator(),
"use_discord_permissions": await config.guild(
ctx.guild
ctx.guild,
).use_discord_permissions(),
"ignore_modlog": await config.guild(ctx.guild).ignore_modlog(),
"ignore_other_bots": await config.guild(ctx.guild).ignore_other_bots(),
@ -461,7 +399,7 @@ async def guild_embed(ctx: commands.Context) -> Embed:
"history_inline": await config.guild(ctx.guild).history_inline(),
"history_pagesize": await config.guild(ctx.guild).history_pagesize(),
"history_inline_pagesize": await config.guild(
ctx.guild
ctx.guild,
).history_inline_pagesize(),
"auto_evidenceformat": await config.guild(ctx.guild).auto_evidenceformat(),
"respect_hierarchy": await config.guild(ctx.guild).respect_hierarchy(),
@ -474,37 +412,17 @@ async def guild_embed(ctx: commands.Context) -> Embed:
channel = channel.mention
guild_str = [
"- "
+ bold("Show Moderator: ")
+ get_bool_emoji(guild_settings["show_moderator"]),
"- "
+ bold("Use Discord Permissions: ")
+ get_bool_emoji(guild_settings["use_discord_permissions"]),
"- "
+ bold("Respect Hierarchy: ")
+ get_bool_emoji(guild_settings["respect_hierarchy"]),
"- "
+ bold("Ignore Modlog: ")
+ get_bool_emoji(guild_settings["ignore_modlog"]),
"- "
+ bold("Ignore Other Bots: ")
+ get_bool_emoji(guild_settings["ignore_other_bots"]),
"- " + bold("Show Moderator: ") + get_bool_emoji(guild_settings["show_moderator"]),
"- " + bold("Use Discord Permissions: ") + get_bool_emoji(guild_settings["use_discord_permissions"]),
"- " + bold("Respect Hierarchy: ") + get_bool_emoji(guild_settings["respect_hierarchy"]),
"- " + bold("Ignore Modlog: ") + get_bool_emoji(guild_settings["ignore_modlog"]),
"- " + bold("Ignore Other Bots: ") + get_bool_emoji(guild_settings["ignore_other_bots"]),
"- " + bold("DM Users: ") + get_bool_emoji(guild_settings["dm_users"]),
"- "
+ bold("Auto Evidence Format: ")
+ get_bool_emoji(guild_settings["auto_evidenceformat"]),
"- "
+ bold("Ephemeral: ")
+ get_bool_emoji(guild_settings["history_ephemeral"]),
"- "
+ bold("History Inline: ")
+ get_bool_emoji(guild_settings["history_inline"]),
"- "
+ bold("History Pagesize: ")
+ get_pagesize_str(guild_settings["history_pagesize"]),
"- "
+ bold("History Inline Pagesize: ")
+ get_pagesize_str(guild_settings["history_inline_pagesize"]),
"- " + bold("Auto Evidence Format: ") + get_bool_emoji(guild_settings["auto_evidenceformat"]),
"- " + bold("Ephemeral: ") + get_bool_emoji(guild_settings["history_ephemeral"]),
"- " + bold("History Inline: ") + get_bool_emoji(guild_settings["history_inline"]),
"- " + bold("History Pagesize: ") + get_pagesize_str(guild_settings["history_pagesize"]),
"- " + bold("History Inline Pagesize: ") + get_pagesize_str(guild_settings["history_inline_pagesize"]),
"- " + bold("Log Channel: ") + channel,
]
guild_str = "\n".join(guild_str)
@ -528,17 +446,21 @@ async def addrole_embed(ctx: commands.Context) -> Embed:
for role in whitelist:
evalulated_role = ctx.guild.get_role(role) or error(f"`{role}` (Not Found)")
if isinstance(evalulated_role, Role):
roles.append({
"id": evalulated_role.id,
"mention": evalulated_role.mention,
"position": evalulated_role.position
})
roles.append(
{
"id": evalulated_role.id,
"mention": evalulated_role.mention,
"position": evalulated_role.position,
},
)
else:
roles.append({
"id": role,
"mention": error(f"`{role}` (Not Found)"),
"position": 0
})
roles.append(
{
"id": role,
"mention": error(f"`{role}` (Not Found)"),
"position": 0,
},
)
if roles:
roles = sorted(roles, key=lambda x: x["position"], reverse=True)
@ -549,9 +471,7 @@ async def addrole_embed(ctx: commands.Context) -> Embed:
e = await _config(ctx)
e.title += ": Addrole Whitelist"
e.description = (
"Use the select menu below to manage this guild's addrole whitelist."
)
e.description = "Use the select menu below to manage this guild's addrole whitelist."
if len(whitelist_str) > 4000 and len(whitelist_str) < 5000:
lines = whitelist_str.split("\n")
@ -581,17 +501,21 @@ async def immune_embed(ctx: commands.Context) -> Embed:
for role in immune_roles:
evalulated_role = ctx.guild.get_role(role) or error(f"`{role}` (Not Found)")
if isinstance(evalulated_role, Role):
roles.append({
"id": evalulated_role.id,
"mention": evalulated_role.mention,
"position": evalulated_role.position
})
roles.append(
{
"id": evalulated_role.id,
"mention": evalulated_role.mention,
"position": evalulated_role.position,
},
)
else:
roles.append({
"id": role,
"mention": error(f"`{role}` (Not Found)"),
"position": 0
})
roles.append(
{
"id": role,
"mention": error(f"`{role}` (Not Found)"),
"position": 0,
},
)
if roles:
roles = sorted(roles, key=lambda x: x["position"], reverse=True)

View file

@ -32,24 +32,17 @@ def check_permissions(
raise (KeyError)
for permission in permissions:
if (
not getattr(resolved_permissions, permission, False)
and resolved_permissions.administrator is not True
):
if not getattr(resolved_permissions, permission, False) and resolved_permissions.administrator is not True:
return permission
return False
async def check_moddable(
target: Union[User, Member], interaction: Interaction, permissions: list
) -> bool:
async def check_moddable(target: Union[User, Member], interaction: Interaction, permissions: list) -> bool:
"""Checks if a moderator can moderate a target."""
if check_permissions(interaction.client.user, permissions, guild=interaction.guild):
await interaction.response.send_message(
error(
f"I do not have the `{permissions}` permission, required for this action."
),
error(f"I do not have the `{permissions}` permission, required for this action."),
ephemeral=True,
)
return False
@ -57,43 +50,30 @@ async def check_moddable(
if await config.guild(interaction.guild).use_discord_permissions() is True:
if check_permissions(interaction.user, permissions, guild=interaction.guild):
await interaction.response.send_message(
error(
f"You do not have the `{permissions}` permission, required for this action."
),
error(f"You do not have the `{permissions}` permission, required for this action."),
ephemeral=True,
)
return False
if interaction.user.id == target.id:
await interaction.response.send_message(
content="You cannot moderate yourself!", ephemeral=True
)
await interaction.response.send_message(content="You cannot moderate yourself!", ephemeral=True)
return False
if target.bot:
await interaction.response.send_message(
content="You cannot moderate bots!", ephemeral=True
)
await interaction.response.send_message(content="You cannot moderate bots!", ephemeral=True)
return False
if isinstance(target, Member):
if interaction.user.top_role <= target.top_role and await config.guild(interaction.guild).respect_hierarchy() is True:
await interaction.response.send_message(
content=error(
"You cannot moderate members with a higher role than you!"
),
content=error("You cannot moderate members with a higher role than you!"),
ephemeral=True,
)
return False
if (
interaction.guild.get_member(interaction.client.user.id).top_role
<= target.top_role
):
if interaction.guild.get_member(interaction.client.user.id).top_role <= target.top_role:
await interaction.response.send_message(
content=error(
"You cannot moderate members with a role higher than the bot!"
),
content=error("You cannot moderate members with a role higher than the bot!"),
ephemeral=True,
)
return False
@ -118,15 +98,13 @@ async def get_next_case_number(guild_id: str, cursor=None) -> int:
if not cursor:
database = connect()
cursor = database.cursor()
cursor.execute(
f"SELECT moderation_id FROM `moderation_{guild_id}` ORDER BY moderation_id DESC LIMIT 1"
)
cursor.execute(f"SELECT moderation_id FROM `moderation_{guild_id}` ORDER BY moderation_id DESC LIMIT 1")
result = cursor.fetchone()
return (result[0] + 1) if result else 1
def generate_dict(result) -> dict:
case = {
return {
"moderation_id": result[0],
"timestamp": result[1],
"moderation_type": result[2],
@ -144,7 +122,6 @@ def generate_dict(result) -> dict:
"changes": json.loads(result[14]),
"metadata": json.loads(result[15]),
}
return case
async def fetch_user_dict(client: commands.Bot, user_id: str) -> dict:
@ -171,7 +148,6 @@ async def fetch_user_dict(client: commands.Bot, user_id: str) -> dict:
"discriminator": "0",
}
return user_dict
@ -198,11 +174,9 @@ async def fetch_role_dict(guild: Guild, role_id: int) -> dict:
"""This function returns a dictionary containing either role information or a standard deleted role template."""
role = guild.get_role(int(role_id))
if not role:
role_dict = {"id": role_id, "name": "Deleted Role"}
pass
role_dict = {"id": role.id, "name": role.name}
return role_dict
return {"id": role.id, "name": role.name}
async def log(interaction: Interaction, moderation_id: int, resolved: bool = False) -> None:
@ -216,9 +190,7 @@ async def log(interaction: Interaction, moderation_id: int, resolved: bool = Fal
case = await fetch_case(moderation_id, interaction.guild.id)
if case:
embed = await log_factory(
interaction=interaction, case_dict=case, resolved=resolved
)
embed = await log_factory(interaction=interaction, case_dict=case, resolved=resolved)
try:
await logging_channel.send(embed=embed)
except Forbidden:
@ -229,11 +201,7 @@ async def send_evidenceformat(interaction: Interaction, case_dict: dict) -> None
"""This function sends an ephemeral message to the moderator who took the moderation action, with a pre-made codeblock for use in the mod-evidence channel."""
from .factory import evidenceformat_factory
send_evidence_bool = (
await config.user(interaction.user).auto_evidenceformat()
or await config.guild(interaction.guild).auto_evidenceformat()
or False
)
send_evidence_bool = await config.user(interaction.user).auto_evidenceformat() or await config.guild(interaction.guild).auto_evidenceformat() or False
if send_evidence_bool is False:
return
@ -274,24 +242,19 @@ def create_pagesize_options() -> list[SelectOption]:
label="Default",
value="default",
description="Reset the pagesize to the default value.",
)
),
)
for i in range(1, 21):
options.append(
SelectOption(
label=str(i),
value=str(i),
description=f"Set the pagesize to {i}.",
)
)
options.extend(SelectOption(label=str(i), value=str(i), description=f"Set the pagesize to {i}") for i in range(1, 21))
return options
def timedelta_from_relativedelta(relativedelta: rd) -> td:
"""Converts a relativedelta object to a timedelta object."""
now = datetime.now()
then = now - relativedelta
return now - then
def get_footer_image(coginstance: commands.Cog) -> File:
"""Returns the footer image for the embeds."""
image_path = data_manager.bundled_data_path(coginstance) / "arrow.png"

View file

@ -26,7 +26,7 @@ class Backup(commands.Cog):
__author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"]
__git__ = "https://www.coastalcommits.com/cswimr/SeaCogs"
__version__ = "1.1.3"
__version__ = "1.1.4"
__documentation__ = "https://seacogs.coastalcommits.com/backup/"
def __init__(self, bot: Red):
@ -49,7 +49,6 @@ class Backup(commands.Cog):
@commands.is_owner()
async def backup(self, ctx: commands.Context) -> None:
"""Backup your installed cogs."""
pass
@backup.command(name="export")
@commands.is_owner()

View file

@ -11,7 +11,7 @@
"hidden": false,
"disabled": false,
"min_bot_version": "3.5.6",
"max_bot_version": "3.5.16",
"max_bot_version": "3.5.17",
"min_python_version": [
3,
9,

View file

@ -21,7 +21,7 @@ class HotReload(commands.Cog):
__author__ = ["[cswimr](https://www.coastalcommits.com/cswimr)"]
__git__ = "https://www.coastalcommits.com/cswimr/SeaCogs"
__version__ = "1.4.1"
__version__ = "1.4.2"
__documentation__ = "https://seacogs.coastalcommits.com/hotreload/"
def __init__(self, bot: Red) -> None:
@ -60,6 +60,7 @@ class HotReload(commands.Cog):
]
return "\n".join(text)
# pylint: disable=protected-access
async def get_paths(self) -> Generator[Path, None, None]:
"""Retrieve user defined paths."""
cog_manager = self.bot._cog_mgr # noqa: SLF001 # We have to use this private method because there is no public API to get user defined paths
@ -91,7 +92,6 @@ class HotReload(commands.Cog):
@commands.group(name="hotreload")
async def hotreload_group(self, ctx: commands.Context) -> None:
"""HotReload configuration commands."""
pass
@hotreload_group.command(name="notifychannel")
async def hotreload_notifychannel(self, ctx: commands.Context, channel: discord.TextChannel) -> None:
@ -155,6 +155,7 @@ class HotReloadHandler(RegexMatchingEventHandler):
loop=self.cog.bot.loop,
)
# pylint: disable=protected-access
async def reload_cogs(self, cog_names: Sequence[str], paths: Sequence[Path]) -> None:
"""Reload modified cogs."""
if not self.compile_modified_files(cog_names, paths):

View file

@ -2,28 +2,29 @@ from redbot.core import Config
config: Config = Config.get_conf(None, identifier=457581387213637448123567, cog_name="Pterodactyl", force_registration=True)
def register_config(config_obj: Config) -> None:
config_obj.register_global(
base_url=None,
server_id=None,
console_channel=None,
console_commands_enabled=False,
current_status='',
current_status="",
chat_regex=r"^\[\d{2}:\d{2}:\d{2}\sINFO\]: (?!\[(?:Server|Rcon)\])(?:<|\[)(\w+)(?:>|\]) (.*)",
server_regex=r"^\[\d{2}:\d{2}:\d{2} INFO\]:(?: \[Not Secure\])? \[(?:Server|Rcon)\] (.*)",
join_regex=r"^\[\d{2}:\d{2}:\d{2} INFO\]: ([^<\n]+) joined the game$",
leave_regex=r"^\[\d{2}:\d{2}:\d{2} INFO\]: ([^<\n]+) left the game$",
achievement_regex=r"^\[\d{2}:\d{2}:\d{2} INFO\]: (.*) has (made the advancement|completed the challenge) \[(.*)\]$",
chat_command='tellraw @a ["",{"text":".$N ","color":".$C","insertion":"<@.$I>","hoverEvent":{"action":"show_text","contents":"Shift click to mention this user inside Discord"}},{"text":"(DISCORD):","color":"blue","clickEvent":{"action":"open_url","value":".$V"},"hoverEvent":{"action":"show_text","contents":"Click to join the Discord Server"}},{"text":" .$M","color":"white"}]', # noqa: E501
topic='Server IP: .$H\nServer Players: .$P/.$M',
chat_command='tellraw @a ["",{"text":".$N ","color":".$C","insertion":"<@.$I>","hoverEvent":{"action":"show_text","contents":"Shift click to mention this user inside Discord"}},{"text":"(DISCORD):","color":"blue","clickEvent":{"action":"open_url","value":".$V"},"hoverEvent":{"action":"show_text","contents":"Click to join the Discord Server"}},{"text":" .$M","color":"white"}]', # noqa: E501
topic="Server IP: .$H\nServer Players: .$P/.$M",
topic_hostname=None,
topic_port=25565,
api_endpoint="minecraft",
chat_channel=None,
startup_msg='Server started!',
shutdown_msg='Server stopped!',
join_msg='Welcome to the server! 👋',
leave_msg='Goodbye! 👋',
startup_msg="Server started!",
shutdown_msg="Server stopped!",
join_msg="Welcome to the server! 👋",
leave_msg="Goodbye! 👋",
mask_ip=True,
invite=None,
regex_blacklist={},