Skip to content

Commit 325ad1a

Browse files
authored
Merge pull request #135 from Taaku18/dev
Scheduled close event for thread save to config vars
2 parents eefece7 + 03560c9 commit 325ad1a

File tree

5 files changed

+217
-75
lines changed

5 files changed

+217
-75
lines changed

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,25 @@ 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

77

8+
# v2.5.0
9+
10+
Non-Breaking Changes:
11+
12+
### Background
13+
Bots hosted by Heroku restart at least once every 27 hours.
14+
During this period, local caches are deleted, which results in the inability to
15+
set the scheduled close time to longer than 24 hours. This update
16+
resolves this issue.
17+
[PR #135](https://github.com/kyb3r/modmail/pull/135)
18+
19+
20+
### Changed
21+
- Created a new internal config var: `closures`.
22+
- Store closure details into `closures` when the scheduled time isn't "now".
23+
- Loaded upon bot restart.
24+
- Deleted when a thread is closed.
25+
- Use `call_later()` instead of `sleep()` for scheduling.
26+
827
# v2.4.5
928

1029
### Fixed

bot.py

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

25-
__version__ = '2.4.5'
25+
__version__ = '2.5.0'
2626

2727
import asyncio
2828
import textwrap
@@ -202,8 +202,37 @@ async def on_ready(self):
202202
print(Fore.RED + Style.BRIGHT + 'WARNING - The GUILD_ID provided does not exist!' + Style.RESET_ALL)
203203
else:
204204
await self.threads.populate_cache()
205+
await self.config.update()
205206

207+
closures = self.config.closures.copy()
206208

209+
for recipient_id, items in closures.items():
210+
after = (datetime.datetime.fromisoformat(items['time']) -
211+
datetime.datetime.utcnow()).total_seconds()
212+
if after < 0:
213+
after = 0
214+
recipient = self.get_user(int(recipient_id))
215+
216+
thread = await self.threads.find(
217+
recipient=recipient)
218+
219+
if not thread:
220+
# If the recipient is gone or channel is deleted
221+
self.config.closures.pop(str(recipient_id))
222+
await self.config.update()
223+
continue
224+
225+
# TODO: Low priority,
226+
# Retrieve messages/replies when bot is down, from history?
227+
self.loop.create_task(
228+
thread.close(
229+
closer=self.get_user(items['closer_id']),
230+
after=after,
231+
silent=items['silent'],
232+
delete_channel=items['delete_channel'],
233+
message=items['message']
234+
)
235+
)
207236

208237
async def process_modmail(self, message):
209238
"""Processes messages sent to the bot."""

cogs/modmail.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,11 @@ async def _close(self, ctx, *, after: UserFriendlyTime=None):
174174
silent = str(message).lower() in {'silent', 'silently'}
175175
cancel = str(message).lower() == 'cancel'
176176

177-
if cancel and thread.close_task is not None and not thread.close_task.cancelled():
178-
thread.close_task.cancel()
179-
await ctx.send(embed=discord.Embed(color=discord.Color.red(), description='Scheduled close has been cancelled.'))
180-
return
181-
elif cancel:
177+
if cancel:
178+
if thread.close_task is not None:
179+
await thread.cancel_closure()
180+
await ctx.send(embed=discord.Embed(color=discord.Color.red(), description='Scheduled close has been cancelled.'))
181+
return
182182
return await ctx.send(embed=discord.Embed(color=discord.Color.red(), description='This thread has not already been scheduled to close.'))
183183

184184
if after and after.dt > now:

core/config.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,24 @@ class ConfigManager:
77
"""Class that manages a cached configuration"""
88

99
allowed_to_change_in_command = {
10-
'activity_message', 'activity_type', 'log_channel_id', 'mention', 'disable_autoupdates', 'prefix',
11-
'main_category_id', 'sent_emoji', 'blocked_emoji', 'thread_creation_response', 'twitch_url'
10+
'activity_message', 'activity_type', 'log_channel_id',
11+
'mention', 'disable_autoupdates', 'prefix',
12+
'main_category_id', 'sent_emoji', 'blocked_emoji',
13+
'thread_creation_response', 'twitch_url'
1214
}
1315

1416
internal_keys = {
15-
'snippets', 'aliases', 'blocked', 'notification_squad', 'subscriptions'
17+
'snippets', 'aliases', 'blocked',
18+
'notification_squad', 'subscriptions',
19+
'closures'
1620
}
1721

1822
protected_keys = {
1923
'token', 'owners', 'modmail_api_token', 'guild_id', 'modmail_guild_id',
2024
'mongo_uri', 'github_access_token', 'log_url'
2125
}
2226

23-
valid_keys = allowed_to_change_in_command.union(internal_keys).union(protected_keys)
27+
valid_keys = allowed_to_change_in_command | internal_keys | protected_keys
2428

2529
def __init__(self, bot):
2630
self.bot = bot
@@ -38,7 +42,8 @@ def populate_cache(self):
3842
'aliases': {},
3943
'blocked': {},
4044
'notification_squad': {},
41-
'subscriptions': {}
45+
'subscriptions': {},
46+
'closures': {},
4247
}
4348

4449
try:
@@ -47,7 +52,8 @@ def populate_cache(self):
4752
pass
4853
finally:
4954
data.update(os.environ)
50-
data = {k.lower(): v for k, v in data.items() if k.lower() in self.valid_keys}
55+
data = {k.lower(): v for k, v in data.items()
56+
if k.lower() in self.valid_keys}
5157
self.cache = data
5258

5359
async def update(self, data=None):

0 commit comments

Comments
 (0)