Skip to content

Commit 9c324fc

Browse files
authored
Merge branch 'master' into queue
2 parents eca11f3 + 77a6b09 commit 9c324fc

File tree

14 files changed

+449
-56
lines changed

14 files changed

+449
-56
lines changed

.gitignore

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,15 @@ ENV/
102102
*.json
103103
!app.json
104104

105-
#Pycharm
105+
# Pycharm
106106
.idea/
107107

108-
#MacOs
108+
# MacOS
109109
.DS_Store
110110

111+
# VS Code
112+
.vscode/
113+
114+
# Modmail
111115
config.json
116+
plugins/

CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,43 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
- `thread.create` is now synchronous so that the first message sent can be queued to be sent as soon as a thread is created.
1111
- This fixes a problem where if multiple messages are sent in quick succession, the first message sent (which triggers the thread creation) is not sent in order.
1212

13+
# v2.13.4
14+
15+
### Changed
16+
- `?contact` no longer raise a silent error in Heroku logs when the recipient is a bot. Now Modmail respond with an error message.
17+
18+
# v2.13.3
19+
20+
### Fixed
21+
- a typo in the config options.
22+
23+
# v2.13.2
24+
25+
### Fixed
26+
- Installing `requirements.txt` files in plugins.
27+
28+
29+
# v2.13.1
30+
31+
### Fixed
32+
- Reading `requirements.txt` files in plugins.
33+
34+
35+
# v2.13.0
36+
37+
### Added
38+
- Plugins
39+
- Think of it like addons! Anyone (with the skills) can create a plugin, make it public and distribute it.
40+
Add a welcome message to Modmail, or moderation commands? It's all up to your imagination!
41+
Have a niche feature request that you think only your server would benefit from? Plugins are your go-to!
42+
- [Creating Plugins Documention](https://github.com/kyb3r/modmail/wiki/Plugins).
43+
44+
# v2.12.5
45+
46+
### Fixed
47+
48+
- `config del` command will now work properly on self-hosted db bots.
49+
1350
# v2.12.4
1451

1552
### Added

bot.py

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,28 @@
2222
SOFTWARE.
2323
"""
2424

25-
__version__ = '2.12.4'
25+
__version__ = '2.13.4'
2626

2727
import asyncio
28+
import traceback
29+
import os
2830
from datetime import datetime
29-
from os import listdir
3031
from textwrap import dedent
3132
from types import SimpleNamespace
3233

3334
import discord
34-
import uvloop
35-
from aiohttp import ClientSession
36-
from colorama import init, Fore, Style
3735
from discord.enums import ActivityType
3836
from discord.ext import commands
3937
from discord.ext.commands.view import StringView
38+
39+
from aiohttp import ClientSession
40+
from colorama import init, Fore, Style
4041
from emoji import UNICODE_EMOJI
4142
from motor.motor_asyncio import AsyncIOMotorClient
4243

4344
from core.changelog import Changelog
4445
from core.clients import ModmailApiClient, SelfHostedClient
46+
from core.clients import PluginDatabaseClient
4547
from core.config import ConfigManager
4648
from core.models import Bot
4749
from core.thread import ThreadManager
@@ -59,14 +61,14 @@ def __init__(self):
5961
self._threads = None
6062
self._session = None
6163
self._config = None
62-
self._connected = asyncio.Event()
6364
self._db = None
6465

6566
if self.self_hosted:
6667
self._db = AsyncIOMotorClient(self.config.mongo_uri).modmail_bot
6768
self._api = SelfHostedClient(self)
6869
else:
6970
self._api = ModmailApiClient(self)
71+
self.plugin_db = PluginDatabaseClient(self)
7072

7173
self.data_task = self.loop.create_task(self.data_loop())
7274
self.autoupdate_task = self.loop.create_task(self.autoupdate_loop())
@@ -120,17 +122,18 @@ def _load_extensions(self):
120122
'┴ ┴└─┘─┴┘┴ ┴┴ ┴┴┴─┘', sep='\n')
121123
print(f'v{__version__}')
122124
print('Authors: kyb3r, fourjr, Taaku18' + Style.RESET_ALL)
123-
print(LINE + Fore.CYAN)
125+
print(LINE)
124126

125-
for file in listdir('cogs'):
127+
for file in os.listdir('cogs'):
126128
if not file.endswith('.py'):
127129
continue
128130
cog = f'cogs.{file[:-3]}'
129-
print(f'Loading {cog}')
131+
print(Fore.CYAN + f'Loading {cog}' + Style.RESET_ALL)
130132
try:
131133
self.load_extension(cog)
132134
except Exception:
133135
print(f'Failed to load {cog}')
136+
traceback.print_exc()
134137

135138
async def is_owner(self, user):
136139
allowed = {int(x) for x in
@@ -145,8 +148,21 @@ async def logout(self):
145148

146149
def run(self, *args, **kwargs):
147150
try:
148-
super().run(self.token, *args, **kwargs)
151+
self.loop.run_until_complete(self.start(self.token))
152+
except discord.LoginFailure:
153+
print('Invalid token')
154+
except KeyboardInterrupt:
155+
pass
156+
except Exception:
157+
print('Fatal exception')
158+
traceback.print_exc()
149159
finally:
160+
self.data_task.cancel()
161+
self.autoupdate_task.cancel()
162+
163+
self.loop.run_until_complete(self.logout())
164+
self.loop.run_until_complete(self.session.close())
165+
self.loop.close()
150166
print(Fore.RED + ' - Shutting down bot' + Style.RESET_ALL)
151167

152168
@property
@@ -294,7 +310,7 @@ async def setup_indexes(self):
294310
await coll.create_index([
295311
('messages.content', 'text'),
296312
('messages.author.name', 'text')
297-
])
313+
])
298314

299315
async def on_ready(self):
300316
"""Bot startup, sets uptime."""
@@ -647,17 +663,19 @@ async def autoupdate_loop(self):
647663
await self.wait_until_ready()
648664

649665
if self.config.get('disable_autoupdates'):
650-
print('Autoupdates disabled.')
666+
print(Fore.CYAN + 'Autoupdates disabled.' + Style.RESET_ALL)
651667
print(LINE)
652668
return
653669

654670
if self.self_hosted and not self.config.get('github_access_token'):
671+
print('Github access token not found.')
672+
print(Fore.CYAN + 'Autoupdates disabled.' + Style.RESET_ALL)
655673
print('GitHub access token not found.')
656674
print('Autoupdates disabled.')
657675
print(LINE)
658676
return
659677

660-
while True:
678+
while not self.is_closed():
661679
metadata = await self.api.get_metadata()
662680

663681
if metadata['latest_version'] != self.version:
@@ -694,6 +712,8 @@ async def autoupdate_loop(self):
694712

695713

696714
if __name__ == '__main__':
697-
uvloop.install()
715+
if os.name != 'nt':
716+
import uvloop
717+
uvloop.install()
698718
bot = ModmailBot() # pylint: disable=invalid-name
699719
bot.run()

cogs/modmail.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
from typing import Optional, Union
44

55
import discord
6-
from dateutil import parser
76
from discord.ext import commands
7+
8+
from dateutil import parser
89
from natural.date import duration
910

1011
from core import checks
@@ -98,6 +99,7 @@ async def snippets(self, ctx):
9899
await session.run()
99100

100101
@snippets.command(name='add')
102+
@checks.has_permissions(manage_messages=True)
101103
async def add_(self, ctx, name: str.lower, *, value):
102104
"""Add a snippet to the bot config."""
103105
if 'snippets' not in self.bot.config.cache:
@@ -115,6 +117,7 @@ async def add_(self, ctx, name: str.lower, *, value):
115117
await ctx.send(embed=embed)
116118

117119
@snippets.command(name='del')
120+
@checks.has_permissions(manage_messages=True)
118121
async def del_(self, ctx, *, name: str.lower):
119122
"""Removes a snippet from bot config."""
120123

@@ -601,12 +604,19 @@ async def contact(self, ctx,
601604
user: Union[discord.Member, discord.User]):
602605
"""Create a thread with a specified member."""
603606

607+
if user.bot:
608+
embed = discord.Embed(
609+
color=discord.Color.red(),
610+
description='Cannot start a thread with a bot.'
611+
)
612+
return await ctx.send(embed=embed)
613+
604614
exists = await self.bot.threads.find(recipient=user)
605615
if exists:
606616
embed = discord.Embed(
607617
color=discord.Color.red(),
608618
description='A thread for this user already '
609-
f'exists in {exists.channel.mention}.'
619+
f'exists in {exists.channel.mention}.'
610620
)
611621

612622
else:
@@ -619,7 +629,7 @@ async def contact(self, ctx,
619629
color=self.bot.main_color
620630
)
621631

622-
return await ctx.send(embed=embed)
632+
await ctx.send(embed=embed)
623633

624634
@commands.command()
625635
@trigger_typing

0 commit comments

Comments
 (0)