Skip to content

Commit 89f50eb

Browse files
authored
Merge branch 'development' into alias-add-improvements
2 parents 69ba146 + 6e75c44 commit 89f50eb

File tree

4 files changed

+155
-18
lines changed

4 files changed

+155
-18
lines changed

bot.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,33 @@ def check_manual_blocked(self, author: discord.Member) -> bool:
794794
logger.debug("User blocked, user %s.", author.name)
795795
return False
796796

797+
def check_local_git(self) -> bool:
798+
"""
799+
Checks if the bot is installed via git.
800+
"""
801+
valid_local_git = False
802+
git_folder_path = os.path.join(".git")
803+
804+
# Check if the .git folder exists and is a directory
805+
if os.path.exists(git_folder_path) and os.path.isdir(git_folder_path):
806+
required_files = ["config", "HEAD"]
807+
required_dirs = ["refs", "objects"]
808+
809+
# Verify required files exist
810+
for file in required_files:
811+
if not os.path.isfile(os.path.join(git_folder_path, file)):
812+
return valid_local_git
813+
814+
# Verify required directories exist
815+
for directory in required_dirs:
816+
if not os.path.isdir(os.path.join(git_folder_path, directory)):
817+
return valid_local_git
818+
819+
# If all checks pass, set valid_local_git to True
820+
valid_local_git = True
821+
822+
return valid_local_git
823+
797824
async def _process_blocked(self, message):
798825
_, blocked_emoji = await self.retrieve_emoji()
799826
if await self.is_blocked(message.author, channel=message.channel, send_message=True):
@@ -2160,6 +2187,12 @@ async def before_autoupdate(self):
21602187
self.autoupdate.cancel()
21612188
return
21622189

2190+
if not self.check_local_git():
2191+
logger.warning("Bot not installed via git.")
2192+
logger.warning("Autoupdates disabled.")
2193+
self.autoupdate.cancel()
2194+
return
2195+
21632196
@tasks.loop(hours=1, reconnect=False)
21642197
async def log_expiry(self):
21652198
log_expire_after = self.config.get("log_expiration")

cogs/modmail.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,61 @@ async def snippet_edit(self, ctx, name: str.lower, *, value):
480480
embed = create_not_found_embed(name, self.bot.snippets.keys(), "Snippet")
481481
await ctx.send(embed=embed)
482482

483+
@snippet.command(name="rename")
484+
@checks.has_permissions(PermissionLevel.SUPPORTER)
485+
async def snippet_rename(self, ctx, name: str.lower, *, value):
486+
"""
487+
Rename a snippet.
488+
489+
To rename a multi-word snippet name, use quotes: ```
490+
{prefix}snippet rename "two word" this is a new two word snippet.
491+
```
492+
"""
493+
if name in self.bot.snippets:
494+
if self.bot.get_command(value):
495+
embed = discord.Embed(
496+
title="Error",
497+
color=self.bot.error_color,
498+
description=f"A command with the same name already exists: `{value}`.",
499+
)
500+
return await ctx.send(embed=embed)
501+
elif value in self.bot.snippets:
502+
embed = discord.Embed(
503+
title="Error",
504+
color=self.bot.error_color,
505+
description=f"Snippet `{value}` already exists.",
506+
)
507+
return await ctx.send(embed=embed)
508+
509+
if value in self.bot.aliases:
510+
embed = discord.Embed(
511+
title="Error",
512+
color=self.bot.error_color,
513+
description=f"An alias that shares the same name exists: `{value}`.",
514+
)
515+
return await ctx.send(embed=embed)
516+
517+
if len(value) > 120:
518+
embed = discord.Embed(
519+
title="Error",
520+
color=self.bot.error_color,
521+
description="Snippet names cannot be longer than 120 characters.",
522+
)
523+
return await ctx.send(embed=embed)
524+
old_snippet_value = self.bot.snippets[name]
525+
self.bot.snippets.pop(name)
526+
self.bot.snippets[value] = old_snippet_value
527+
await self.bot.config.update()
528+
529+
embed = discord.Embed(
530+
title="Renamed snippet",
531+
color=self.bot.main_color,
532+
description=f'`{name}` has been renamed to "{value}".',
533+
)
534+
else:
535+
embed = create_not_found_embed(name, self.bot.snippets.keys(), "Snippet")
536+
await ctx.send(embed=embed)
537+
483538
@commands.command(usage="<category> [options]")
484539
@checks.has_permissions(PermissionLevel.MODERATOR)
485540
@checks.thread_only()

cogs/utility.py

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,6 +1282,58 @@ async def alias_edit(self, ctx, name: str.lower, *, value):
12821282
embed = await self.make_alias(name, value, "Edited")
12831283
return await ctx.send(embed=embed)
12841284

1285+
@alias.command(name="rename")
1286+
@checks.has_permissions(PermissionLevel.MODERATOR)
1287+
async def alias_rename(self, ctx, name: str.lower, *, value):
1288+
"""
1289+
Rename an alias.
1290+
"""
1291+
if name not in self.bot.aliases:
1292+
embed = utils.create_not_found_embed(name, self.bot.aliases.keys(), "Alias")
1293+
return await ctx.send(embed=embed)
1294+
1295+
embed = None
1296+
if self.bot.get_command(value):
1297+
embed = discord.Embed(
1298+
title="Error",
1299+
color=self.bot.error_color,
1300+
description=f"A command with the same name already exists: `{value}`.",
1301+
)
1302+
1303+
elif value in self.bot.aliases:
1304+
embed = discord.Embed(
1305+
title="Error",
1306+
color=self.bot.error_color,
1307+
description=f"Another alias with the same name already exists: `{value}`.",
1308+
)
1309+
1310+
elif value in self.bot.snippets:
1311+
embed = discord.Embed(
1312+
title="Error",
1313+
color=self.bot.error_color,
1314+
description=f"A snippet with the same name already exists: `{value}`.",
1315+
)
1316+
1317+
elif len(value) > 120:
1318+
embed = discord.Embed(
1319+
title="Error",
1320+
color=self.bot.error_color,
1321+
description="Alias names cannot be longer than 120 characters.",
1322+
)
1323+
1324+
if embed is None:
1325+
old_alias_value = self.bot.aliases[name]
1326+
self.bot.aliases.pop(name)
1327+
self.bot.aliases[value] = old_alias_value
1328+
await self.bot.config.update()
1329+
1330+
embed = discord.Embed(
1331+
title="Alias renamed",
1332+
color=self.bot.main_color,
1333+
description=f'`{name}` has been renamed to "{value}".',
1334+
)
1335+
return await ctx.send(embed=embed)
1336+
12851337
@commands.group(aliases=["perms"], invoke_without_command=True)
12861338
@checks.has_permissions(PermissionLevel.OWNER)
12871339
async def permissions(self, ctx):
@@ -2089,11 +2141,7 @@ async def update(self, ctx, *, flag: str = ""):
20892141
data = await self.bot.api.get_user_info()
20902142
if data:
20912143
user = data["user"]
2092-
embed.set_author(
2093-
name=user["username"],
2094-
icon_url=user["avatar_url"] if user["avatar_url"] else None,
2095-
url=user["url"],
2096-
)
2144+
embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"])
20972145
await ctx.send(embed=embed)
20982146
else:
20992147
error = None
@@ -2132,7 +2180,7 @@ async def update(self, ctx, *, flag: str = ""):
21322180

21332181
embed.set_author(
21342182
name=user["username"] + " - Updating bot",
2135-
icon_url=user["avatar_url"] if user["avatar_url"] else None,
2183+
icon_url=user["avatar_url"],
21362184
url=user["url"],
21372185
)
21382186

@@ -2150,13 +2198,18 @@ async def update(self, ctx, *, flag: str = ""):
21502198
color=self.bot.main_color,
21512199
)
21522200
embed.set_footer(text="Force update")
2153-
embed.set_author(
2154-
name=user["username"],
2155-
icon_url=user["avatar_url"] if user["avatar_url"] else None,
2156-
url=user["url"],
2157-
)
2201+
embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"])
21582202
await ctx.send(embed=embed)
21592203
else:
2204+
if self.bot.check_local_git() is False:
2205+
embed = discord.Embed(
2206+
title="Update Command Unavailable",
2207+
description="The bot cannot be updated due to not being installed via git."
2208+
"You need to manually update the bot according to your hosting method."
2209+
"If you face any issues please don´t hesitate to contact modmail support.",
2210+
color=discord.Color.red(),
2211+
)
2212+
return await ctx.send(embed=embed)
21602213
command = "git pull"
21612214
proc = await asyncio.create_subprocess_shell(
21622215
command,
@@ -2169,11 +2222,7 @@ async def update(self, ctx, *, flag: str = ""):
21692222
res = res.decode("utf-8").rstrip()
21702223

21712224
if err and not res:
2172-
embed = discord.Embed(
2173-
title="Update failed",
2174-
description=err,
2175-
color=self.bot.error_color,
2176-
)
2225+
embed = discord.Embed(title="Update failed", description=err, color=self.bot.error_color)
21772226
await ctx.send(embed=embed)
21782227

21792228
elif res != "Already up to date.":

core/config_help.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@
533533
"notes": [
534534
"When `recipient_thread_close` is enabled and the recipient closed their own thread, `thread_self_close_response` is used instead of this configuration.",
535535
"You may use the `{{closer}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that closed the thread.",
536-
"`{{loglink}}` can be used as a placeholder substitute for the full URL linked to the thread in the log viewer and `{{loglink}}` for the unique key (ie. s3kf91a) of the log.",
536+
"`{{loglink}}` can be used as a placeholder substitute for the full URL linked to the thread in the log viewer and `{{logkey}}` for the unique key (ie. s3kf91a) of the log.",
537537
"Discord flavoured markdown is fully supported in `thread_close_response`.",
538538
"See also: `thread_close_title`, `thread_close_footer`, `thread_self_close_response`, `thread_creation_response`."
539539
]
@@ -547,7 +547,7 @@
547547
"notes": [
548548
"When `recipient_thread_close` is disabled or the thread wasn't closed by the recipient, `thread_close_response` is used instead of this configuration.",
549549
"You may use the `{{closer}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that closed the thread.",
550-
"`{{loglink}}` can be used as a placeholder substitute for the full URL linked to the thread in the log viewer and `{{loglink}}` for the unique key (ie. s3kf91a) of the log.",
550+
"`{{loglink}}` can be used as a placeholder substitute for the full URL linked to the thread in the log viewer and `{{logkey}}` for the unique key (ie. s3kf91a) of the log.",
551551
"Discord flavoured markdown is fully supported in `thread_self_close_response`.",
552552
"See also: `thread_close_title`, `thread_close_footer`, `thread_close_response`."
553553
]

0 commit comments

Comments
 (0)