Skip to content

Commit

Permalink
Merge branch 'master' into feature/rewrite-lastfm
Browse files Browse the repository at this point in the history
  • Loading branch information
joinemm committed Oct 13, 2023
2 parents c4c47bf + fe74b59 commit 39a8a65
Show file tree
Hide file tree
Showing 41 changed files with 2,026 additions and 821 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
- uses: actions/checkout@v3
- uses: psf/black@stable
with:
options: "--check --line-length=100 --verbose"
options: "--check --line-length=88 --verbose"
ruff:
runs-on: ubuntu-latest
steps:
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/reuse-complicance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: REUSE Compliance Check
on: [ push, pull_request ]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: REUSE Compliance Check
uses: fsfe/reuse-action@v2
11 changes: 8 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
repos:
- repo: https://github.com/ambv/black
rev: 23.3.0
rev: 23.7.0
hooks:
- id: black
args: [--line-length=100]
args: [--line-length=88]
language_version: python3

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.270
rev: v0.0.280
hooks:
- id: ruff
args: [--line-length=100, --ignore=E501]
Expand All @@ -17,3 +17,8 @@ repos:
hooks:
- id: isort
args: ["--profile", "black", "--filter-files"]

- repo: https://github.com/fsfe/reuse-tool
rev: v2.1.0
hooks:
- id: reuse
174 changes: 134 additions & 40 deletions cogs/configuration.py

Large diffs are not rendered by default.

134 changes: 110 additions & 24 deletions cogs/customcommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
# https://git.joinemm.dev/miso-bot

import asyncio
import io
import json

import arrow
import discord
from discord.ext import commands
from loguru import logger
from modules.misobot import MisoBot

from modules import emojis, exceptions, queries, util
from modules.misobot import MisoBot


class CustomCommands(commands.Cog, name="Commands"):
Expand Down Expand Up @@ -57,7 +58,9 @@ async def custom_command_list(self, guild_id, match=""):
"SELECT command_trigger FROM custom_command WHERE guild_id = %s", guild_id
)
return {
command_trigger for command_trigger in data if match == "" or match in command_trigger
command_trigger
for command_trigger in data
if match == "" or match in command_trigger
}

@commands.Cog.listener()
Expand Down Expand Up @@ -106,14 +109,19 @@ async def add(self, ctx: commands.Context, name, *, response):
if ctx.guild is None:
raise exceptions.CommandError("Unable to get current guild")

if not ctx.author.guild_permissions.manage_guild and await self.bot.db.fetch_value(
"SELECT restrict_custom_commands FROM guild_settings WHERE guild_id = %s",
ctx.guild.id,
if (
not ctx.author.guild_permissions.manage_guild
and await self.bot.db.fetch_value(
"SELECT restrict_custom_commands FROM guild_settings WHERE guild_id = %s",
ctx.guild.id,
)
):
raise commands.MissingPermissions(["manage_server"])

if name in self.bot_command_list():
raise exceptions.CommandWarning(f"`{ctx.prefix}{name}` is already a built in command!")
raise exceptions.CommandWarning(
f"`{ctx.prefix}{name}` is already a built in command!"
)
if await self.bot.db.fetch_value(
"SELECT content FROM custom_command WHERE guild_id = %s AND command_trigger = %s",
ctx.guild.id,
Expand Down Expand Up @@ -152,7 +160,9 @@ async def command_remove(self, ctx: commands.Context, name):
ctx.guild.id,
)
if not owner_id:
raise exceptions.CommandWarning(f"Custom command `{ctx.prefix}{name}` does not exist")
raise exceptions.CommandWarning(
f"Custom command `{ctx.prefix}{name}` does not exist"
)

owner = ctx.guild.get_member(owner_id)
if (
Expand All @@ -161,15 +171,20 @@ async def command_remove(self, ctx: commands.Context, name):
and not ctx.author.guild_permissions.manage_guild
):
raise exceptions.CommandWarning(
f"`{ctx.prefix}{name}` can only be removed by **{owner}** unless you have `manage_server` permission."
(
f"`{ctx.prefix}{name}` can only be removed by **{owner}** "
"unless you have `manage_server` permission."
)
)

await self.bot.db.execute(
"DELETE FROM custom_command WHERE guild_id = %s AND command_trigger = %s",
ctx.guild.id,
name,
)
await util.send_success(ctx, f"Custom command `{ctx.prefix}{name}` has been deleted")
await util.send_success(
ctx, f"Custom command `{ctx.prefix}{name}` has been deleted"
)

@command.command(name="search")
async def command_search(self, ctx: commands.Context, name):
Expand Down Expand Up @@ -203,25 +218,44 @@ async def command_list(self, ctx: commands.Context):
raise exceptions.CommandError("Unable to get current guild")

rows = [
f"{ctx.prefix}{command}" for command in await self.custom_command_list(ctx.guild.id)
f"{ctx.prefix}{command}"
for command in await self.custom_command_list(ctx.guild.id)
]
if rows:
content = discord.Embed(title=f"{ctx.guild.name} custom commands")
await util.send_as_pages(ctx, content, rows)
else:
raise exceptions.CommandInfo("No custom commands have been added on this server yet")
raise exceptions.CommandInfo(
"No custom commands have been added on this server yet"
)

@commands.is_owner()
@command.command(name="import")
@commands.has_permissions(manage_guild=True)
async def command_import(self, ctx: commands.Context):
"""Attach a json file in format {command: xxx, text: xxx}"""
"""Attach a json file with commands you want to import
The syntax for the json file:
```
[
{
"command": string,
"text": string,
"owner": user id (int, optional),
"added_on": UNIX timestamp (int, optional)
}
], [...]
```
"""
if not ctx.message.attachments:
raise exceptions.CommandWarning(
"Please attach a `.json` file to the message"
)

jsonfile = ctx.message.attachments[0]
imported = json.loads(await jsonfile.read())
tasks = []
for command in imported:
name = command["command"]
text = command["text"]
tasks.append(self.import_command(ctx, name, text))
tasks.append(self.import_command(ctx, command))

load = await ctx.send(emojis.LOADING)
results = await asyncio.gather(*tasks)
Expand All @@ -232,9 +266,49 @@ async def command_import(self, ctx: commands.Context):
failed_operations=[r[1] for r in filter(lambda x: not x[0], results)],
)

async def import_command(self, ctx: commands.Context, name, text):
@command.command(name="export")
@commands.has_permissions(manage_guild=True)
async def command_export(self, ctx: commands.Context):
"""Exports all custom commands in json format"""
if ctx.guild is None:
raise exceptions.CommandError("Unable to get current guild")
data = await self.bot.db.fetch(
"""
SELECT command_trigger, content, added_by, added_on
FROM custom_command WHERE guild_id = %s
""",
ctx.guild.id,
)
if not data:
raise exceptions.CommandInfo(
"No custom commands have been added on this server yet"
)

jsondata = [
{
"command": trigger,
"text": content,
"owner": added_by,
"timestamp": int(added_on.timestamp()),
}
for (trigger, content, added_by, added_on) in data
]
buffer = json.dumps(jsondata, indent=4).encode("utf-8")
await ctx.send(
file=discord.File(
fp=io.BytesIO(buffer),
filename=f"{ctx.guild} commands.json",
)
)

async def import_command(self, ctx: commands.Context, command: dict):
if ctx.guild is None:
raise exceptions.CommandError("Unable to get current guild")

name = command["command"]
text = command["text"]
owner_id = command.get("owner", ctx.author.id)
added_on = command.get("added_on", arrow.utcnow().int_timestamp)

if name in self.bot_command_list():
return False, f"`{ctx.prefix}{name}` is already a built in command!"
Expand All @@ -243,23 +317,28 @@ async def import_command(self, ctx: commands.Context, name, text):
ctx.guild.id,
name,
):
return False, f"Custom command `{ctx.prefix}{name}` already exists on this server!"
return (
False,
f"Custom command `{ctx.prefix}{name}` already exists on this server!",
)

await self.bot.db.execute(
"INSERT INTO custom_command VALUES(%s, %s, %s, %s, %s)",
ctx.guild.id,
name,
text,
arrow.utcnow().datetime,
ctx.author.id,
arrow.get(added_on).datetime,
owner_id,
)
return True, name

@command.command(name="restrict")
@commands.has_permissions(manage_guild=True)
async def command_restrict(self, ctx: commands.Context, value: bool):
"""Restrict command management to only people with manage_server permission"""
await queries.update_setting(ctx, "guild_settings", "restrict_custom_commands", value)
await queries.update_setting(
ctx, "guild_settings", "restrict_custom_commands", value
)
if value:
await util.send_success(
ctx, "Adding custom commands is now restricted to server managers."
Expand Down Expand Up @@ -289,8 +368,13 @@ async def command_clear(self, ctx: commands.Context):
if count < 1:
raise exceptions.CommandWarning("This server has no custom commands yet!")

content = discord.Embed(title=":warning: Are you sure?", color=int("ffcc4d", 16))
content.description = f"This action will delete all **{count}** custom commands on this server and is **irreversible**."
content = discord.Embed(
title=":warning: Are you sure?", color=int("ffcc4d", 16)
)
content.description = (
f"This action will delete all **{count}** custom commands on "
"this server and is **irreversible**."
)
msg = await ctx.send(embed=content)

async def confirm():
Expand All @@ -311,7 +395,9 @@ async def cancel():

functions = {"✅": confirm, "❌": cancel}
asyncio.ensure_future(
util.reaction_buttons(ctx, msg, functions, only_author=True, single_use=True)
util.reaction_buttons(
ctx, msg, functions, only_author=True, single_use=True
)
)


Expand Down
Loading

0 comments on commit 39a8a65

Please sign in to comment.