cog info and cog install additions (#290)

* Allow owners to have an install message unique to each cog
* `!cog info repo_name` now attempts to pull from an info.json at the root directory of the repo
* info.json *breaking* change
  * Add SHORT key, for the short desc that appears in `!cog list`
  * NAME is now the actual name of the cog/repo
This commit is contained in:
Will 2016-06-05 09:18:16 -04:00 committed by Twentysix
parent 496b122059
commit f6352dda8e

View File

@ -1,5 +1,5 @@
from discord.ext import commands from discord.ext import commands
from cogs.utils.dataIO import fileIO from cogs.utils.dataIO import dataIO, fileIO
from cogs.utils import checks from cogs.utils import checks
from cogs.utils.chat_formatting import box from cogs.utils.chat_formatting import box
from __main__ import send_cmd_help, set_cog from __main__ import send_cmd_help, set_cog
@ -67,6 +67,11 @@ class Downloader:
self.update_repo(repo_name) self.update_repo(repo_name)
self.populate_list(repo_name) self.populate_list(repo_name)
self.save_repos() self.save_repos()
data = self.get_info_data(repo_name)
if data:
msg = data.get("INSTALL_MSG")
if msg:
await self.bot.say(msg[:2000])
await self.bot.say("Repo '{}' added.".format(repo_name)) await self.bot.say("Repo '{}' added.".format(repo_name))
@repo.command(name="remove") @repo.command(name="remove")
@ -90,12 +95,17 @@ class Downloader:
continue continue
data = self.get_info_data(repo_name, cog) data = self.get_info_data(repo_name, cog)
if data: if data:
retlist.append([cog, data['NAME']]) retlist.append([cog, data.get("SHORT", "")])
else: else:
retlist.append([cog, '']) retlist.append([cog, ''])
else: else:
msg = "Available repos:\n" msg = "Available repos:\n"
retlist = sorted([[k, ''] for k in self.repos]) for repo_name in sorted(self.repos.keys()):
data = self.get_info_data(repo_name)
if data:
retlist.append([repo_name, data.get("SHORT", "")])
else:
retlist.append([repo_name, ""])
col_width = max(len(row[0]) for row in retlist) + 2 col_width = max(len(row[0]) for row in retlist) + 2
for row in retlist: for row in retlist:
@ -103,20 +113,34 @@ class Downloader:
await self.bot.say(box(msg)) # Need to deal with over 2000 characters await self.bot.say(box(msg)) # Need to deal with over 2000 characters
@cog.command() @cog.command()
async def info(self, repo_name: str, cog: str): async def info(self, repo_name: str, cog: str=None):
"""Shows info about the specified cog""" """Shows info about the specified cog"""
cogs = self.list_cogs(repo_name) if cog is not None:
if cog in cogs: cogs = self.list_cogs(repo_name)
data = self.get_info_data(repo_name, cog) if cog in cogs:
if data: data = self.get_info_data(repo_name, cog)
msg = "{} by {}\n\n".format(cog, data["AUTHOR"]) if data:
msg += data["NAME"] + "\n\n" + data["DESCRIPTION"] msg = "{} by {}\n\n".format(cog, data["AUTHOR"])
await self.bot.say(box(msg)) msg += data["NAME"] + "\n\n" + data["DESCRIPTION"]
await self.bot.say(box(msg))
else:
await self.bot.say("The specified cog has no info file.")
else: else:
await self.bot.say("The specified cog has no info file.") await self.bot.say("That cog doesn't exist."
" Use cog list to see the full list.")
else: else:
await self.bot.say("That cog doesn't exist." data = self.get_info_data(repo_name)
" Use cog list to see the full list.") if data is None:
await self.bot.say("That repo does not exist or the"
" information file is missing for that repo"
".")
return
name = data.get("NAME", None)
name = repo_name if name is None else name
author = data.get("AUTHOR", "tekulvw ;)")
desc = data.get("DESCRIPTION", "")
msg = ("```{} by {}```\n\n{}".format(name, author, desc))
await self.bot.say(msg)
@cog.command(hidden=True) @cog.command(hidden=True)
async def search(self, *terms: str): async def search(self, *terms: str):
@ -151,6 +175,23 @@ class Downloader:
await self.bot.say("Ok then, you can reload cogs with" await self.bot.say("Ok then, you can reload cogs with"
" `{}reload <cog_name>`".format(ctx.prefix)) " `{}reload <cog_name>`".format(ctx.prefix))
@cog.command(pass_context=True)
async def uninstall(self, ctx, repo_name, cog):
"""Uninstalls a cog"""
if repo_name not in self.repos:
await self.bot.say("That repo doesn't exist.")
return
if cog not in self.repos[repo_name]:
await self.bot.say("That cog isn't available from that repo.")
return
set_cog("cogs." + cog, False)
self.repos[repo_name][cog]['INSTALLED'] = False
self.save_repos()
os.remove(os.path.join("cogs", cog + ".py"))
owner = self.bot.get_cog('Owner')
await owner.unload.callback(owner, module=cog)
await self.bot.say("Cog successfully uninstalled.")
@cog.command(name="install", pass_context=True) @cog.command(name="install", pass_context=True)
async def _install(self, ctx, repo_name: str, cog: str): async def _install(self, ctx, repo_name: str, cog: str):
"""Installs specified cog""" """Installs specified cog"""
@ -161,6 +202,11 @@ class Downloader:
await self.bot.say("That cog isn't available from that repo.") await self.bot.say("That cog isn't available from that repo.")
return return
install_cog = await self.install(repo_name, cog) install_cog = await self.install(repo_name, cog)
data = self.get_info_data(repo_name, cog)
if data is not None:
install_msg = data.get("INSTALL_MSG", None)
if install_msg is not None:
await self.bot.say(install_msg[:2000])
if install_cog: if install_cog:
await self.bot.say("Installation completed. Load it now? (yes/no)") await self.bot.say("Installation completed. Load it now? (yes/no)")
answer = await self.bot.wait_for_message(timeout=15, answer = await self.bot.wait_for_message(timeout=15,
@ -170,9 +216,8 @@ class Downloader:
" `{}load {}`".format(ctx.prefix, cog)) " `{}load {}`".format(ctx.prefix, cog))
elif answer.content.lower().strip() == "yes": elif answer.content.lower().strip() == "yes":
set_cog("cogs." + cog, True) set_cog("cogs." + cog, True)
self.bot.unload_extension("cogs." + cog) owner = self.bot.get_cog('Owner')
self.bot.load_extension("cogs." + cog) await owner.load.callback(owner, module=cog)
await self.bot.say("Done.")
else: else:
await self.bot.say("Ok then, you can load it with" await self.bot.say("Ok then, you can load it with"
" `{}load {}`".format(ctx.prefix, cog)) " `{}load {}`".format(ctx.prefix, cog))
@ -190,7 +235,7 @@ class Downloader:
cog_folder_path = self.repos[repo_name][cog]['folder'] cog_folder_path = self.repos[repo_name][cog]['folder']
cog_data_path = os.path.join(cog_folder_path, 'data') cog_data_path = os.path.join(cog_folder_path, 'data')
to_path = os.path.join("cogs/", cog+".py") to_path = os.path.join("cogs/", cog + ".py")
print("Copying {}...".format(cog)) print("Copying {}...".format(cog))
shutil.copy(path, to_path) shutil.copy(path, to_path)
@ -203,16 +248,25 @@ class Downloader:
self.save_repos() self.save_repos()
return True return True
def get_info_data(self, repo_name, cog): def get_info_data(self, repo_name, cog=None):
cogs = self.list_cogs(repo_name) if cog is not None:
if cog in cogs: cogs = self.list_cogs(repo_name)
info_file = os.path.join(cogs[cog].get('folder'), "info.json") if cog in cogs:
if os.path.isfile(info_file): info_file = os.path.join(cogs[cog].get('folder'), "info.json")
if os.path.isfile(info_file):
try:
data = fileIO(info_file, "load")
except:
return None
return data
else:
repo_info = os.path.join(self.path, repo_name, 'info.json')
if os.path.isfile(repo_info):
try: try:
data = fileIO(info_file, "load") data = dataIO.load_json(repo_info)
return data
except: except:
return None return None
return data
return None return None
def list_cogs(self, repo_name): def list_cogs(self, repo_name):
@ -269,6 +323,7 @@ class Downloader:
# It's blocking but it shouldn't matter # It's blocking but it shouldn't matter
call(["git", "clone", url, "data/downloader/" + name]) call(["git", "clone", url, "data/downloader/" + name])
else: else:
Popen(["git", "-C", "data/downloader/" + name, "stash", "-q"])
Popen(["git", "-C", "data/downloader/" + name, "pull", "-q"]) Popen(["git", "-C", "data/downloader/" + name, "pull", "-q"])
@ -287,6 +342,7 @@ def check_files():
print("Creating default data/downloader/repos.json") print("Creating default data/downloader/repos.json")
fileIO(f, "save", repos) fileIO(f, "save", repos)
def setup(bot): def setup(bot):
check_folders() check_folders()
check_files() check_files()