Skip to content

Commit b70f9b0

Browse files
committed
Add PIP requirements support (requirements.txt file in the plugin folder
1 parent c3d5109 commit b70f9b0

File tree

1 file changed

+34
-8
lines changed

1 file changed

+34
-8
lines changed

cogs/plugins.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,14 @@ async def download_initial_plugins(self):
4848
try:
4949
await self.download_plugin_repo(*parsed_plugin[:-1])
5050
except DownloadError as exc:
51-
msg = f'{exc} ({parsed_plugin[0]}/{parsed_plugin[1]} - {exc}'
51+
msg = f'{parsed_plugin[0]}/{parsed_plugin[1]} - {exc}'
5252
print(Fore.RED + msg + Style.RESET_ALL)
53-
54-
await self.load_plugin(*parsed_plugin)
53+
else:
54+
try:
55+
await self.load_plugin(*parsed_plugin)
56+
except DownloadError as exc:
57+
msg = f'{parsed_plugin[0]}/{parsed_plugin[1]} - {exc}'
58+
print(Fore.RED + msg + Style.RESET_ALL)
5559

5660
async def download_plugin_repo(self, username, repo):
5761
try:
@@ -72,6 +76,19 @@ async def download_plugin_repo(self, username, repo):
7276

7377
async def load_plugin(self, username, repo, plugin_name):
7478
ext = f'plugins.{username}-{repo}.{plugin_name}.{plugin_name}'
79+
if 'requirements.txt' in os.listdir(f'plugins/{username}-{repo}/{plugin_name}'):
80+
# Install PIP requirements
81+
try:
82+
await self.bot.loop.run_in_executor(
83+
None, self._asubprocess_run,
84+
f'python3 -m pip install -U -r plugins/{username}-{repo}/{plugin_name}/requirements.txt --user -q -q'
85+
)
86+
# -q -q (quiet) so there's no terminal output unless there's an error
87+
except subprocess.CalledProcessError as exc:
88+
error = exc.stderr.decode('utf8').strip()
89+
if error:
90+
raise DownloadError(f'Unable to download requirements: ```\n{error}\n```') from exc
91+
7592
try:
7693
self.bot.load_extension(ext)
7794
except ModuleNotFoundError as exc:
@@ -91,6 +108,9 @@ async def plugin(self, ctx):
91108
@plugin.command()
92109
async def add(self, ctx, *, plugin_name):
93110
"""Adds a plugin"""
111+
if plugin_name in self.bot.config.plugins:
112+
return await ctx.send('Plugin already installed')
113+
94114
message = await ctx.send('Downloading plugin...')
95115
async with ctx.typing():
96116
if len(plugin_name.split('/')) >= 3:
@@ -107,7 +127,7 @@ async def add(self, ctx, *, plugin_name):
107127
try:
108128
await self.load_plugin(*parsed_plugin)
109129
except DownloadError as exc:
110-
return await ctx.send(f'Unable to start plugin: {exc}')
130+
return await ctx.send(f'Unable to load plugin: `{exc}`')
111131

112132
# if it makes it here, it has passed all checks and should
113133
# be entered into the config
@@ -157,6 +177,9 @@ def onerror(func, path, exc_info):
157177
@plugin.command()
158178
async def update(self, ctx, *, plugin_name):
159179
"""Updates a certain plugin"""
180+
if plugin_name not in self.bot.config.plugins:
181+
return await ctx.send('Plugin not installed')
182+
160183
async with ctx.typing():
161184
username, repo, name = self.parse_plugin(plugin_name)
162185
try:
@@ -167,18 +190,21 @@ async def update(self, ctx, *, plugin_name):
167190
cmd
168191
)
169192
except subprocess.CalledProcessError as exc:
170-
error = exc.stdout.decode('utf8').strip()
171-
await ctx.send(f'Error when updating: {error}')
193+
error = exc.stderr.decode('utf8').strip()
194+
await ctx.send(f'Error while updating: {error}')
172195
else:
173196
output = cmd.stdout.decode('utf8').strip()
197+
await ctx.send(f'```\n{output}\n```')
174198

175199
if output != 'Already up to date.':
176200
# repo was updated locally, now perform the cog reload
177201
ext = f'plugins.{username}-{repo}.{name}.{name}'
178202
importlib.reload(importlib.import_module(ext))
179-
self.load_plugin(username, repo, name)
180203

181-
await ctx.send(f'```\n{output}\n```')
204+
try:
205+
self.load_plugin(username, repo, name)
206+
except DownloadError:
207+
await ctx.send(f'Unable to start plugin: `{exc}`')
182208

183209
@plugin.command(name='list')
184210
async def list_(self, ctx):

0 commit comments

Comments
 (0)