Skip to content

Commit 56cef8d

Browse files
committed
Formatting and changelog change
1 parent 722db7b commit 56cef8d

File tree

10 files changed

+220
-146
lines changed

10 files changed

+220
-146
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ however, insignificant breaking changes does not guarantee a major version bump,
4343
- The placeholder channel for the streaming status changed to https://www.twitch.tv/discordmodmail/.
4444
- Removed unclear `rm` alias for some `remove` commands.
4545
- Paginate `?config options`.
46+
- All users configured with a permission level greater than REGULAR has access to the main Modmail category.
47+
- Category overrides also changes when a level is removed or added to a user or role.
48+
- `@everyone` is now accepted for `?perms add`.
4649

4750
### Fixes
4851

bot.py

Lines changed: 53 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from pymongo.errors import ConfigurationError
2323

2424
try:
25+
# noinspection PyUnresolvedReferences
2526
from colorama import init
2627

2728
init()
@@ -94,7 +95,17 @@ def __init__(self):
9495
sys.exit(0)
9596

9697
self.plugin_db = PluginDatabaseClient(self)
98+
99+
logger.line()
100+
logger.info("┌┬┐┌─┐┌┬┐┌┬┐┌─┐┬┬")
101+
logger.info("││││ │ │││││├─┤││")
102+
logger.info("┴ ┴└─┘─┴┘┴ ┴┴ ┴┴┴─┘")
103+
logger.info("v%s", __version__)
104+
logger.info("Authors: kyb3r, fourjr, Taaku18")
105+
logger.line()
106+
97107
self._load_extensions()
108+
logger.line()
98109

99110
@property
100111
def uptime(self) -> str:
@@ -168,14 +179,6 @@ async def get_prefix(self, message=None):
168179

169180
def _load_extensions(self):
170181
"""Adds commands automatically"""
171-
logger.line()
172-
logger.info("┌┬┐┌─┐┌┬┐┌┬┐┌─┐┬┬")
173-
logger.info("││││ │ │││││├─┤││")
174-
logger.info("┴ ┴└─┘─┴┘┴ ┴┴ ┴┴┴─┘")
175-
logger.info("v%s", __version__)
176-
logger.info("Authors: kyb3r, fourjr, Taaku18")
177-
logger.line()
178-
179182
for file in os.listdir("cogs"):
180183
if not file.endswith(".py"):
181184
continue
@@ -232,9 +235,12 @@ async def is_owner(self, user: discord.User) -> bool:
232235
def log_channel(self) -> typing.Optional[discord.TextChannel]:
233236
channel_id = self.config["log_channel_id"]
234237
if channel_id is not None:
235-
channel = self.get_channel(int(channel_id))
236-
if channel is not None:
237-
return channel
238+
try:
239+
channel = self.get_channel(int(channel_id))
240+
if channel is not None:
241+
return channel
242+
except ValueError:
243+
pass
238244
logger.debug("LOG_CHANNEL_ID was invalid, removed.")
239245
self.config.remove("log_channel_id")
240246
if self.main_category is not None:
@@ -255,10 +261,6 @@ def log_channel(self) -> typing.Optional[discord.TextChannel]:
255261
)
256262
return None
257263

258-
@property
259-
def is_connected(self) -> bool:
260-
return self._connected.is_set()
261-
262264
async def wait_for_connected(self) -> None:
263265
await self.wait_until_ready()
264266
await self._connected.wait()
@@ -277,7 +279,7 @@ def token(self) -> str:
277279
token = self.config["token"]
278280
if token is None:
279281
logger.critical(
280-
"TOKEN must be set, set this as bot token found on the Discord Dev Portal."
282+
"TOKEN must be set, set this as bot token found on the Discord Developer Portal."
281283
)
282284
sys.exit(0)
283285
return token
@@ -289,6 +291,7 @@ def guild_id(self) -> typing.Optional[int]:
289291
try:
290292
return int(str(guild_id))
291293
except ValueError:
294+
self.config.remove("guild_id")
292295
logger.critical("Invalid GUILD_ID set.")
293296
return None
294297

@@ -309,9 +312,12 @@ def modmail_guild(self) -> typing.Optional[discord.Guild]:
309312
modmail_guild_id = self.config["modmail_guild_id"]
310313
if modmail_guild_id is None:
311314
return self.guild
312-
guild = discord.utils.get(self.guilds, id=int(modmail_guild_id))
313-
if guild is not None:
314-
return guild
315+
try:
316+
guild = discord.utils.get(self.guilds, id=int(modmail_guild_id))
317+
if guild is not None:
318+
return guild
319+
except ValueError:
320+
pass
315321
self.config.remove("modmail_guild_id")
316322
logger.critical("Invalid MODMAIL_GUILD_ID set.")
317323
return self.guild
@@ -325,11 +331,14 @@ def main_category(self) -> typing.Optional[discord.CategoryChannel]:
325331
if self.modmail_guild is not None:
326332
category_id = self.config["main_category_id"]
327333
if category_id is not None:
328-
cat = discord.utils.get(
329-
self.modmail_guild.categories, id=int(category_id)
330-
)
331-
if cat is not None:
332-
return cat
334+
try:
335+
cat = discord.utils.get(
336+
self.modmail_guild.categories, id=int(category_id)
337+
)
338+
if cat is not None:
339+
return cat
340+
except ValueError:
341+
pass
333342
self.config.remove("main_category_id")
334343
logger.debug("MAIN_CATEGORY_ID was invalid, removed.")
335344
cat = discord.utils.get(self.modmail_guild.categories, name="Modmail")
@@ -353,41 +362,34 @@ def blocked_whitelisted_users(self) -> typing.List[str]:
353362
def prefix(self) -> str:
354363
return str(self.config["prefix"])
355364

356-
@property
357-
def mod_color(self) -> int:
358-
color = self.config["mod_color"]
365+
def _parse_color(self, conf_name):
366+
color = self.config[conf_name]
359367
try:
360368
return int(color.lstrip("#"), base=16)
361369
except ValueError:
362-
logger.error("Invalid mod_color provided.")
363-
return int(self.config.remove("mod_color").lstrip("#"), base=16)
370+
logger.error("Invalid %s provided.", conf_name)
371+
return int(self.config.remove(conf_name).lstrip("#"), base=16)
372+
373+
@property
374+
def mod_color(self) -> int:
375+
return self._parse_color("mod_color")
364376

365377
@property
366378
def recipient_color(self) -> int:
367-
color = self.config["recipient_color"]
368-
try:
369-
return int(color.lstrip("#"), base=16)
370-
except ValueError:
371-
logger.error("Invalid recipient_color provided.")
372-
return int(self.config.remove("recipient_color").lstrip("#"), base=16)
379+
return self._parse_color("recipient_color")
373380

374381
@property
375382
def main_color(self) -> int:
376-
color = self.config["main_color"]
377-
try:
378-
return int(color.lstrip("#"), base=16)
379-
except ValueError:
380-
logger.error("Invalid main_color provided.")
381-
return int(self.config.remove("main_color").lstrip("#"), base=16)
383+
return self._parse_color("main_color")
382384

383385
async def on_connect(self):
384386
logger.line()
385387
try:
386388
await self.validate_database_connection()
387389
except Exception:
390+
logger.debug("Logging out due to failed database connection.")
388391
return await self.logout()
389392

390-
logger.line()
391393
logger.info("Connected to gateway.")
392394
await self.config.refresh()
393395
await self.setup_indexes()
@@ -436,6 +438,8 @@ async def on_ready(self):
436438
logger.info("Prefix: %s", self.prefix)
437439
logger.info("Guild Name: %s", self.guild.name)
438440
logger.info("Guild ID: %s", self.guild.id)
441+
if self.using_multiple_server_setup:
442+
logger.info("Receiving guild ID: %s", self.modmail_guild.id)
439443
logger.line()
440444

441445
await self.threads.populate_cache()
@@ -508,15 +512,16 @@ async def retrieve_emoji(self) -> typing.Tuple[str, str]:
508512
except commands.BadArgument:
509513
logger.warning("Removed sent emoji (%s).", sent_emoji)
510514
sent_emoji = self.config.remove("sent_emoji")
515+
await self.config.update()
511516

512517
if blocked_emoji != "disable":
513518
try:
514519
blocked_emoji = await self.convert_emoji(blocked_emoji)
515520
except commands.BadArgument:
516521
logger.warning("Removed blocked emoji (%s).", blocked_emoji)
517522
blocked_emoji = self.config.remove("blocked_emoji")
523+
await self.config.update()
518524

519-
await self.config.update()
520525
return sent_emoji, blocked_emoji
521526

522527
async def _process_blocked(self, message: discord.Message) -> bool:
@@ -531,7 +536,7 @@ async def _process_blocked(self, message: discord.Message) -> bool:
531536
try:
532537
await message.add_reaction(sent_emoji)
533538
except (discord.HTTPException, discord.InvalidArgument):
534-
pass
539+
logger.warning("Failed to add sent_emoji.", exc_info=True)
535540

536541
return False
537542

@@ -761,6 +766,7 @@ async def get_context(self, message, *, cls=commands.Context):
761766
async def update_perms(
762767
self, name: typing.Union[PermissionLevel, str], value: int, add: bool = True
763768
) -> None:
769+
value = int(value)
764770
if isinstance(name, PermissionLevel):
765771
permissions = self.config["level_permissions"]
766772
name = name.name
@@ -1043,19 +1049,6 @@ async def on_command_error(self, context, exception):
10431049
else:
10441050
logger.error("Unexpected exception:", exc_info=exception)
10451051

1046-
@staticmethod
1047-
def overwrites(ctx: commands.Context) -> dict:
1048-
"""Permission overwrites for the guild."""
1049-
overwrites = {
1050-
ctx.guild.default_role: discord.PermissionOverwrite(read_messages=False),
1051-
ctx.guild.me: discord.PermissionOverwrite(read_messages=True),
1052-
}
1053-
1054-
for role in ctx.guild.roles:
1055-
if role.permissions.administrator:
1056-
overwrites[role] = discord.PermissionOverwrite(read_messages=True)
1057-
return overwrites
1058-
10591052
async def validate_database_connection(self):
10601053
try:
10611054
await self.db.command("buildinfo")
@@ -1113,12 +1106,14 @@ async def before_post_metadata(self):
11131106
if not self.guild:
11141107
self.metadata_loop.cancel()
11151108

1116-
async def after_post_metadata(self):
1109+
@staticmethod
1110+
async def after_post_metadata():
11171111
logger.info("Metadata loop has been cancelled.")
11181112

11191113

11201114
if __name__ == "__main__":
11211115
try:
1116+
# noinspection PyUnresolvedReferences
11221117
import uvloop
11231118

11241119
logger.debug("Setting up with uvloop.")

cogs/modmail.py

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from datetime import datetime
44
from itertools import zip_longest
55
from typing import Optional, Union
6-
from types import SimpleNamespace as param
6+
from types import SimpleNamespace
77

88
import discord
99
from discord.ext import commands
@@ -39,6 +39,11 @@ async def setup(self, ctx):
3939
once after configuring Modmail.
4040
"""
4141

42+
if ctx.guild != self.bot.modmail_guild:
43+
return await ctx.send(
44+
f"You can only setup in the Modmail guild: {self.bot.modmail_guild}."
45+
)
46+
4247
if self.bot.main_category is not None:
4348
logger.debug("Can't re-setup server, main_category is found.")
4449
return await ctx.send(f"{self.bot.modmail_guild} is already set up.")
@@ -51,8 +56,31 @@ async def setup(self, ctx):
5156
)
5257
return await ctx.send(embed=embed)
5358

59+
overwrites = {
60+
self.bot.modmail_guild.default_role: discord.PermissionOverwrite(
61+
read_messages=False
62+
),
63+
self.bot.modmail_guild.me: discord.PermissionOverwrite(read_messages=True),
64+
}
65+
66+
for level in PermissionLevel:
67+
if level <= PermissionLevel.REGULAR:
68+
continue
69+
permissions = self.bot.config["level_permissions"].get(level.name, [])
70+
for perm in permissions:
71+
perm = int(perm)
72+
if perm == -1:
73+
key = self.bot.modmail_guild.default_role
74+
else:
75+
key = self.bot.modmail_guild.get_member(perm)
76+
if key is None:
77+
key = self.bot.modmail_guild.get_role(perm)
78+
if key is not None:
79+
logger.info("Granting %s access to Modmail category.", key.name)
80+
overwrites[key] = discord.PermissionOverwrite(read_messages=True)
81+
5482
category = await self.bot.modmail_guild.create_category(
55-
name="Modmail", overwrites=self.bot.overwrites(ctx)
83+
name="Modmail", overwrites=overwrites
5684
)
5785

5886
await category.edit(position=0)
@@ -86,10 +114,12 @@ async def setup(self, ctx):
86114

87115
await self.bot.config.update()
88116
await ctx.send(
89-
"Successfully set up server.\n"
90-
"Consider setting permission levels to give access "
91-
"to roles or users the ability to use Modmail.\n"
92-
f"Type `{self.bot.prefix}permissions` for more info."
117+
"**Successfully set up server.**\n"
118+
"Consider setting permission levels "
119+
"to give access to roles or users the ability to use Modmail.\n\n"
120+
f"Type:\n- `{self.bot.prefix}permissions` and `{self.bot.prefix}permissions add` "
121+
"for more info on setting permissions.\n"
122+
f"- `{self.bot.prefix}config help` for a list of available customizations."
93123
)
94124

95125
if (
@@ -612,7 +642,7 @@ async def logs(self, ctx, *, user: User = None):
612642
if not user:
613643
thread = ctx.thread
614644
if not thread:
615-
raise commands.MissingRequiredArgument(param(name="member"))
645+
raise commands.MissingRequiredArgument(SimpleNamespace(name="member"))
616646
user = thread.recipient
617647

618648
default_avatar = "https://cdn.discordapp.com/embed/avatars/0.png"
@@ -977,7 +1007,7 @@ async def block(
9771007
if thread:
9781008
user = thread.recipient
9791009
elif after is None:
980-
raise commands.MissingRequiredArgument(param(name="user"))
1010+
raise commands.MissingRequiredArgument(SimpleNamespace(name="user"))
9811011
else:
9821012
raise commands.BadArgument(f'User "{after.arg}" not found')
9831013

@@ -1058,7 +1088,7 @@ async def unblock(self, ctx, *, user: User = None):
10581088
if thread:
10591089
user = thread.recipient
10601090
else:
1061-
raise commands.MissingRequiredArgument(param(name="user"))
1091+
raise commands.MissingRequiredArgument(SimpleNamespace(name="user"))
10621092

10631093
mention = getattr(user, "mention", f"`{user.id}`")
10641094
name = getattr(user, "name", f"`{user.id}`")

cogs/plugins.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ def parse_plugin(name):
6262
if "@" in result[2]:
6363
# branch is specified
6464
# for example, fourjr/modmail-plugins/welcomer@develop is a valid name
65-
branchsplit_result = result[2].split("@")
66-
result.append(branchsplit_result[-1])
67-
result[2] = "@".join(branchsplit_result[:-1])
65+
branch_split_result = result[2].split("@")
66+
result.append(branch_split_result[-1])
67+
result[2] = "@".join(branch_split_result[:-1])
6868
else:
6969
result.append("master")
7070

0 commit comments

Comments
 (0)