Skip to content

Commit 6dc2ef5

Browse files
committed
Merge from "master"
1 parent f383e15 commit 6dc2ef5

File tree

5 files changed

+71
-47
lines changed

5 files changed

+71
-47
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ ENV/
105105
#Pycharm
106106
.idea/
107107

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

111-
# custom
111+
# Modmail
112112
config.json
113113
plugins/

bot.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@
2525
__version__ = '2.12.2'
2626

2727
import asyncio
28+
import os
2829
from datetime import datetime
29-
from os import listdir
3030
from textwrap import dedent
3131
from types import SimpleNamespace
3232

3333
import discord
34-
import uvloop
3534
from aiohttp import ClientSession
3635
from colorama import init, Fore, Style
3736
from discord.enums import ActivityType
@@ -59,7 +58,6 @@ def __init__(self):
5958
self._threads = None
6059
self._session = None
6160
self._config = None
62-
self._connected = asyncio.Event()
6361
self._db = None
6462

6563
if self.self_hosted:
@@ -120,9 +118,9 @@ def _load_extensions(self):
120118
'┴ ┴└─┘─┴┘┴ ┴┴ ┴┴┴─┘', sep='\n')
121119
print(f'v{__version__}')
122120
print('Authors: kyb3r, fourjr, Taaku18' + Style.RESET_ALL)
123-
print(LINE + Fore.CYAN)
121+
print(LINE)
124122

125-
for file in listdir('cogs'):
123+
for file in os.listdir('cogs'):
126124
if not file.endswith('.py'):
127125
continue
128126
cog = f'cogs.{file[:-3]}'
@@ -631,13 +629,13 @@ async def autoupdate_loop(self):
631629
await self.wait_until_ready()
632630

633631
if self.config.get('disable_autoupdates'):
634-
print('Autoupdates disabled.')
632+
print(Fore.CYAN + 'Autoupdates disabled.' + Style.RESET_ALL)
635633
print(LINE)
636634
return
637635

638636
if self.self_hosted and not self.config.get('github_access_token'):
639637
print('Github access token not found.')
640-
print('Autoupdates disabled.')
638+
print(Fore.CYAN + 'Autoupdates disabled.' + Style.RESET_ALL)
641639
print(LINE)
642640
return
643641

@@ -678,6 +676,8 @@ async def autoupdate_loop(self):
678676

679677

680678
if __name__ == '__main__':
681-
uvloop.install()
679+
if os.name != 'nt':
680+
import uvloop
681+
uvloop.install()
682682
bot = ModmailBot() # pylint: disable=invalid-name
683683
bot.run()

cogs/plugins.py

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
import subprocess
33
import shutil
44

5-
from discord.ext import commands
65
from colorama import Fore, Style
6+
from discord.ext import commands
77

88
from core.decorators import owner_only
9+
from core.models import Bot
910

1011

1112
class DownloadError(Exception):
@@ -15,15 +16,16 @@ class DownloadError(Exception):
1516
class Plugins:
1617
"""Plugins expand Mod Mail functionality by allowing third-party addons.
1718
18-
These addons could have a range of features from moderation to simply making
19-
your life as a moderator easier!
19+
These addons could have a range of features from moderation to simply
20+
making your life as a moderator easier!
2021
Learn how to create a plugin yourself here: https://link.com
2122
"""
22-
def __init__(self, bot):
23+
def __init__(self, bot: Bot):
2324
self.bot = bot
24-
self.bot.loop.create_task(self.download_initital_plugins())
25+
self.bot.loop.create_task(self.download_initial_plugins())
2526

26-
def parse_plugin(self, name):
27+
@staticmethod
28+
def parse_plugin(name):
2729
# returns: (username, repo, plugin_name)
2830
try:
2931
result = name.split('/')
@@ -32,35 +34,43 @@ def parse_plugin(self, name):
3234
return None
3335
return tuple(result)
3436

35-
async def download_initital_plugins(self):
37+
async def download_initial_plugins(self):
3638
await self.bot._connected.wait()
3739
for i in self.bot.config.plugins:
3840
parsed_plugin = self.parse_plugin(i)
3941

4042
try:
4143
await self.download_plugin_repo(*parsed_plugin[:-1])
42-
except DownloadError as e:
43-
print(Fore.RED + f'Unable to download plugin ({parsed_plugin[0]}/{parsed_plugin[1]} - {e}' + Style.RESET_ALL)
44+
except DownloadError as exc:
45+
msg = 'Unable to download plugin '
46+
msg += f'({parsed_plugin[0]}/{parsed_plugin[1]} - {exc}'
47+
print(Fore.RED + msg + Style.RESET_ALL)
4448

4549
await self.load_plugin(*parsed_plugin)
4650

47-
async def download_plugin_repo(self, username, repo):
51+
@staticmethod
52+
async def download_plugin_repo(username, repo):
4853
try:
49-
subprocess.run(f'git clone https://github.com/{username}/{repo} plugins/{username}-{repo} -q', check=True, capture_output=True)
50-
# -q for quiet so there's no terminal output unless there's an error
51-
except subprocess.CalledProcessError as e:
52-
error = e.stderr.decode('utf8').strip()
53-
if not error.endswith('already exists and is not an empty directory.'):
54+
cmd = f'git clone https://github.com/{username}/{repo} '
55+
cmd += 'plugins/{username}-{repo} -q'
56+
subprocess.run(cmd, check=True, capture_output=True)
57+
# -q (quiet) so there's no terminal output unless there's an error
58+
except subprocess.CalledProcessError as exc:
59+
error = exc.stderr.decode('utf-8').strip()
60+
if not error.endswith('already exists and is '
61+
'not an empty directory.'):
5462
# don't raise error if the plugin folder exists
55-
raise DownloadError(error) from e
63+
raise DownloadError(error) from exc
5664

5765
async def load_plugin(self, username, repo, plugin_name):
5866
try:
59-
self.bot.load_extension(f'plugins.{username}-{repo}.{plugin_name}.{plugin_name}')
60-
except ModuleNotFoundError as e:
61-
raise DownloadError('Invalid plugin structure') from e
67+
ext = f'plugins.{username}-{repo}.{plugin_name}.{plugin_name}'
68+
self.bot.load_extension(ext)
69+
except ModuleNotFoundError as exc:
70+
raise DownloadError('Invalid plugin structure') from exc
6271
else:
63-
print(Fore.LIGHTCYAN_EX + f'Loading plugins.{username}-{repo}.{plugin_name}' + Style.RESET_ALL)
72+
msg = f'Loading plugins.{username}-{repo}.{plugin_name}'
73+
print(Fore.LIGHTCYAN_EX + msg + Style.RESET_ALL)
6474

6575
@commands.group(aliases=['plugins'])
6676
@owner_only()
@@ -80,44 +90,54 @@ async def add(self, ctx, *, plugin_name):
8090

8191
try:
8292
await self.download_plugin_repo(*parsed_plugin[:-1])
83-
except DownloadError as e:
84-
return await ctx.send(f'Unable to fetch plugin from Github: {e}')
93+
except DownloadError as exc:
94+
return await ctx.send(
95+
f'Unable to fetch plugin from Github: {exc}'
96+
)
8597

8698
try:
8799
await self.load_plugin(*parsed_plugin)
88-
except DownloadError as e:
89-
return await ctx.send(f'Unable to start plugin: {e}')
100+
except DownloadError as exc:
101+
return await ctx.send(f'Unable to start plugin: {exc}')
90102

91103
# if it makes it here, it has passed all checks and should
92104
# be entered into the config
93105

94106
self.bot.config.plugins.append(plugin_name)
95107
await self.bot.config.update()
96-
await ctx.send('Plugin installed. Any plugin that you install is of your OWN RISK.')
108+
109+
await ctx.send('Plugin installed. Any plugin that '
110+
'you install is of your OWN RISK.')
97111
else:
98-
await ctx.send('Invalid plugin name format. Use username/repo/plugin.')
112+
await ctx.send('Invalid plugin name format. '
113+
'Use username/repo/plugin.')
99114

100115
@plugin.command()
101116
async def remove(self, ctx, *, plugin_name):
102117
"""Removes a certain plugin"""
103118
if plugin_name in self.bot.config.plugins:
104119
username, repo, name = self.parse_plugin(plugin_name)
105-
self.bot.unload_extension(f'plugins.{username}-{repo}.{name}.{name}')
120+
self.bot.unload_extension(
121+
f'plugins.{username}-{repo}.{name}.{name}'
122+
)
106123

107124
self.bot.config.plugins.remove(plugin_name)
108125

109126
try:
110-
if not any(i.startswith(f'{username}/{repo}') for i in self.bot.config.plugins):
127+
if not any(i.startswith(f'{username}/{repo}')
128+
for i in self.bot.config.plugins):
111129
# if there are no more of such repos, delete the folder
112-
shutil.rmtree(f'plugins/{username}-{repo}', ignore_errors=True)
130+
shutil.rmtree(f'plugins/{username}-{repo}',
131+
ignore_errors=True)
113132
await ctx.send('')
114-
except Exception as e:
115-
print(e)
133+
except Exception as exc:
134+
print(exc)
116135
self.bot.config.plugins.append(plugin_name)
117-
raise e
136+
raise exc
118137

119138
await self.bot.config.update()
120-
await ctx.send('Plugin uninstalled and all related data is erased.')
139+
await ctx.send('Plugin uninstalled and '
140+
'all related data is erased.')
121141
else:
122142
await ctx.send('Plugin not installed.')
123143

@@ -126,9 +146,11 @@ async def update(self, ctx, *, plugin_name):
126146
async with ctx.typing():
127147
username, repo, name = self.parse_plugin(plugin_name)
128148
try:
129-
cmd = subprocess.run(f'cd plugins/{username}-{repo} && git pull', shell=True, check=True, capture_output=True)
130-
except subprocess.CalledProcessError as e:
131-
error = e.stdout.decode('utf8').strip()
149+
cmd = f'cd plugins/{username}-{repo} && git pull'
150+
cmd = subprocess.run(cmd, shell=True, check=True,
151+
capture_output=True)
152+
except subprocess.CalledProcessError as exc:
153+
error = exc.stdout.decode('utf8').strip()
132154
await ctx.send(f'Error when updating: {error}')
133155
else:
134156
output = cmd.stdout.decode('utf8').strip()

core/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ class ConfigManager(ConfigManagerABC):
2626
internal_keys = {
2727
'snippets', 'aliases', 'blocked',
2828
'notification_squad', 'subscriptions',
29-
'closures', 'activity_message', 'activity_type'
29+
'closures', 'activity_message', 'activity_type',
30+
'plugins'
3031
}
3132

3233
protected_keys = {

core/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class Bot(abc.ABC, commands.Bot):
1414
def __init__(self, *args, **kwargs):
1515
super().__init__(*args, **kwargs)
1616
self.start_time = datetime.utcnow()
17+
self._connected = asyncio.Event()
1718

1819
@property
1920
def uptime(self) -> str:

0 commit comments

Comments
 (0)