Skip to content

Commit 5c314a2

Browse files
committed
Merge from master
2 parents 60a27f0 + 7cfcd64 commit 5c314a2

File tree

6 files changed

+85
-33
lines changed

6 files changed

+85
-33
lines changed

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
8+
# v2.19.0
9+
10+
### What's new?
11+
12+
- New config variable `guild_age`, similar to `account_age`, `guild_age` sets a limit as to how long a user has to wait after they joined the server to message Modmail.
13+
- `guild_age` can be set the same way as `account_age`.
14+
15+
# v2.18.5
16+
17+
Fix help command bug when using external plugins.
18+
719
# v2.18.4
820

921
Fix the teams permission bug.
@@ -64,7 +76,6 @@ When updating to this version, all prior permission settings with guild-based pe
6476

6577
- The help message no longer conceals inaccessible commands due to check failures.
6678

67-
6879
# v2.17.2
6980

7081
### Changed

README.md

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
<a href="https://heroku.com/deploy?template=https://github.com/kyb3r/modmail">
99
<img src="https://img.shields.io/badge/deploy_to-heroku-997FBC.svg?style=for-the-badge">
1010
</a>
11-
11+
<a href="https://github.com/kyb3r/modmail/">
12+
<img src="https://api.modmail.tk/badges/instances.svg" alt="Bot instances">
13+
</a>
1214
<a href="https://discord.gg/j5e9p8w">
1315
<img src="https://img.shields.io/discord/515071617815019520.svg?style=for-the-badge&colorB=7289DA" alt="Support">
1416
</a>
@@ -22,7 +24,6 @@
2224
</a>
2325
</div>
2426

25-
---
2627

2728
## How Does Modmail Work?
2829

@@ -36,23 +37,16 @@ Currently, the easiest and fastest way to set up the bot is by using Heroku, whi
3637

3738
Interactive installation: [**https://taaku18.github.io/modmail/installation**](https://taaku18.github.io/modmail/installation)
3839

39-
---
4040

4141
# Notable Features
4242

4343
## Customizability
4444

45-
Modmail has a range of configuration variables that you can dynamically alter with the `?config` command. You can use them to change the different aspects of the bot, for example, the embed color, responses, reactions, status, etc. Snippets and custom command aliases are also supported. Snippets are shortcuts for predefined messages that you can send. Add or remove snippets with the `?snippets` command. The level of customization is ever growing thanks to our exceptional contributors.
46-
47-
## Linked Messages
48-
49-
<img src="https://i.imgur.com/6L9aaNw.png" align="right" height="350">
50-
51-
Have you sent something with the `?reply` command by accident? Don't fret, you can delete your original message, and the bot will automatically delete the corresponding message sent to the recipient of the thread! You can also use the `?edit` command to edit a message you sent.
45+
Modmail has a range of configuration variables that you can dynamically alter with the `?config` command. You can use them to change the different aspects of the bot, for example, the embed color, responses, reactions, status, etc. Snippets and custom command aliases are also supported. The level of customization is ever growing thanks to our exceptional contributors.
5246

5347
## Thread Logs
5448

55-
Thread conversations are automatically logged with a generated viewable website of the complete thread. Logs are rendered with styled HTML and presented in an aesthetically pleasing way—it blends seamlessly with the mobile version of Discord. An example of a logged conversation: https://modmail-logs.herokuapp.com/logs/02032d65a6f3.
49+
Thread conversations are automatically logged with a generated viewable website of the complete thread. Logs are rendered with styled HTML and presented in an aesthetically pleasing way—it blends seamlessly with the mobile version of Discord. You have the ability to query and search through logs using the bot via commands. An example of a logged conversation: https://logs.modmail.tk/example.
5650

5751
# Contributing
5852

bot.py

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
SOFTWARE.
2323
"""
2424

25-
__version__ = '2.18.4'
25+
__version__ = '2.19.0'
2626

2727
import asyncio
2828
import logging
@@ -467,8 +467,10 @@ async def retrieve_emoji(self):
467467
async def process_modmail(self, message):
468468
"""Processes messages sent to the bot."""
469469
sent_emoji, blocked_emoji = await self.retrieve_emoji()
470+
now = datetime.utcnow()
470471

471472
account_age = self.config.get('account_age')
473+
guild_age = self.config.get('guild_age')
472474
if account_age is None:
473475
account_age = isodate.duration.Duration()
474476
else:
@@ -483,19 +485,41 @@ async def process_modmail(self, message):
483485
await self.config.update()
484486
account_age = isodate.duration.Duration()
485487

488+
if guild_age is None:
489+
guild_age = isodate.duration.Duration()
490+
else:
491+
try:
492+
guild_age = isodate.parse_duration(guild_age)
493+
except isodate.ISO8601Error:
494+
logger.warning('The guild join age limit needs to be a '
495+
'ISO-8601 duration formatted duration string '
496+
f'greater than 0 days, not "%s".', str(guild_age))
497+
del self.config.cache['guild_age']
498+
await self.config.update()
499+
guild_age = isodate.duration.Duration()
500+
486501
reason = self.blocked_users.get(str(message.author.id))
487502
if reason is None:
488503
reason = ''
504+
489505
try:
490506
min_account_age = message.author.created_at + account_age
491507
except ValueError as e:
492508
logger.warning(e.args[0])
493509
del self.config.cache['account_age']
494510
await self.config.update()
495-
min_account_age = message.author.created_at
511+
min_account_age = now
496512

497-
if min_account_age > datetime.utcnow():
498-
# user account has not reached the required time
513+
try:
514+
min_guild_age = self.guild.get_member(message.author.id).joined_at + guild_age
515+
except ValueError as e:
516+
logger.warning(e.args[0])
517+
del self.config.cache['guild_age']
518+
await self.config.update()
519+
min_guild_age = now
520+
521+
if min_account_age > now:
522+
# User account has not reached the required time
499523
reaction = blocked_emoji
500524
changed = False
501525
delta = human_timedelta(min_account_age)
@@ -514,6 +538,26 @@ async def process_modmail(self, message):
514538
color=discord.Color.red()
515539
))
516540

541+
elif min_guild_age > now:
542+
# User has not stayed in the guild for long enough
543+
reaction = blocked_emoji
544+
changed = False
545+
delta = human_timedelta(min_guild_age)
546+
547+
if str(message.author.id) not in self.blocked_users:
548+
new_reason = f'System Message: Recently Joined. Required to wait for {delta}.'
549+
self.config.blocked[str(message.author.id)] = new_reason
550+
await self.config.update()
551+
changed = True
552+
553+
if reason.startswith('System Message: Recently Joined.') or changed:
554+
await message.channel.send(embed=discord.Embed(
555+
title='Message not sent!',
556+
description=f'Your must wait for {delta} '
557+
f'before you can contact {self.user.mention}.',
558+
color=discord.Color.red()
559+
))
560+
517561
elif str(message.author.id) in self.blocked_users:
518562
reaction = blocked_emoji
519563
if reason.startswith('System Message: New Account.'):
@@ -524,8 +568,7 @@ async def process_modmail(self, message):
524568
else:
525569
end_time = re.search(r'%(.+?)%$', reason)
526570
if end_time is not None:
527-
after = (datetime.fromisoformat(end_time.group(1)) -
528-
datetime.utcnow()).total_seconds()
571+
after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds()
529572
if after <= 0:
530573
# No longer blocked
531574
reaction = sent_emoji
@@ -922,7 +965,7 @@ async def metadata_loop(self):
922965

923966
try:
924967
await self.session.post('https://api.modmail.tk/metadata', json=data)
925-
logger.debug(info('Posted metadata'))
968+
logger.debug(info('Uploading metadata to Modmail server.'))
926969
except:
927970
pass
928971

cogs/utility.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from core.decorators import github_access_token_required, trigger_typing
2424
from core.models import Bot, InvalidConfigError, PermissionLevel
2525
from core.paginator import PaginatorSession, MessagePaginatorSession
26-
from core.utils import cleanup_code, info, error, User
26+
from core.utils import cleanup_code, info, error, User, get_perm_level
2727

2828
logger = logging.getLogger('Modmail')
2929

@@ -34,22 +34,13 @@ class Utility:
3434
def __init__(self, bot: Bot):
3535
self.bot = bot
3636

37-
@staticmethod
38-
def get_perms_required(cmd) -> PermissionLevel:
39-
for c in cmd.checks:
40-
perm_level = getattr(c, 'permission_level',
41-
PermissionLevel.INVALID)
42-
if perm_level is not PermissionLevel.INVALID:
43-
return perm_level
44-
return PermissionLevel.INVALID
45-
4637
async def format_cog_help(self, ctx, cog):
4738
"""Formats the text for a cog help"""
4839

4940
prefix = self.bot.prefix
5041

5142
fmts = ['']
52-
for perm_level, cmd in sorted(((self.get_perms_required(c), c) for c in self.bot.commands),
43+
for perm_level, cmd in sorted(((get_perm_level(c), c) for c in self.bot.commands),
5344
key=itemgetter(0)):
5445
if cmd.instance is cog and not cmd.hidden:
5546
if perm_level is PermissionLevel.INVALID:
@@ -93,7 +84,7 @@ async def format_command_help(self, cmd):
9384

9485
prefix = self.bot.prefix
9586

96-
perm_level = self.get_perms_required(cmd)
87+
perm_level = get_perm_level(cmd)
9788
if perm_level is not PermissionLevel.INVALID:
9889
perm_level = f'{perm_level.name} [{perm_level}]'
9990
else:

core/config.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ class ConfigManager(ConfigManagerABC):
1919

2020
# bot settings
2121
'main_category_id', 'disable_autoupdates', 'prefix', 'mention',
22-
'main_color', 'user_typing', 'mod_typing', 'account_age', 'reply_without_command',
22+
'main_color', 'user_typing', 'mod_typing', 'account_age', 'guild_age',
23+
'reply_without_command',
2324

2425
# logging
2526
'log_channel_id',
@@ -71,7 +72,7 @@ class ConfigManager(ConfigManagerABC):
7172
}
7273

7374
time_deltas = {
74-
'account_age'
75+
'account_age', 'guild_age'
7576
}
7677

7778
valid_keys = allowed_to_change_in_command | internal_keys | protected_keys

core/utils.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from discord.ext import commands
77

88
from colorama import Fore, Style
9+
from core.models import PermissionLevel
910

1011

1112
def info(*msgs):
@@ -187,6 +188,17 @@ def match_user_id(text: str) -> int:
187188
return -1
188189

189190

191+
def get_perm_level(cmd) -> PermissionLevel:
192+
for c in cmd.checks:
193+
perm = getattr(c, 'permission_level', None)
194+
if perm is not None:
195+
return perm
196+
for c in cmd.checks:
197+
if 'is_owner' in str(c):
198+
return PermissionLevel.OWNER
199+
return PermissionLevel.INVALID
200+
201+
190202
async def ignore(coro):
191203
try:
192204
await coro

0 commit comments

Comments
 (0)