diff --git a/akuma.py b/akuma.py index 8cd2348..f0fcd5a 100644 --- a/akuma.py +++ b/akuma.py @@ -16,7 +16,7 @@ class Akuma(commands.Bot): #configuration objects for internal use self.cfg = self.loadJSON("settings.json", {"token": "", "prefix": ">>", "description": "A Discord Bot written b" - "y Akuma#7346", "game": "", "extensions": ["core", "server", "fun", "user"]}) + "y Akuma#7346", "game": "", "extensions": ["core", "server", "fun", "user", "updater"]}) if self.cfg["token"] == "": self.cfg["token"] = input("Please insert the Bot Token: ") self.writeJSON("settings.json", self.cfg) @@ -36,7 +36,7 @@ class Akuma(commands.Bot): def run(self): super().run(self.cfg["token"]) - print("Bot running") + print("Bot stopped") def loadJSON(self, s : str, default : dict = None): if not os.path.isfile(os.path.join(self.cfgPath, s)): diff --git a/extensions/core.py b/extensions/core.py index 12e9f4e..1fde4bf 100644 --- a/extensions/core.py +++ b/extensions/core.py @@ -4,6 +4,11 @@ import discord, io class Core(commands.Cog): def __init__(self, bot): self.bot = bot + self.update = { + "allowUpdate": True, + "url": "https://raw.github.com/Akumatic/Akuma-Matata/master/extensions/core.py", + "private": False + } def detectSetGame(self): return f" | {self.bot.cfg['game']}" if self.bot.cfg["game"] != "" else "" @@ -52,6 +57,9 @@ class Core(commands.Cog): @commands.command() @commands.is_owner() async def stop(self, ctx): + ext = self.bot.extensions + while len(ext) > 0: + self.bot.unload_extension(list(ext.keys())[0]) await self.bot.close() @commands.command() diff --git a/extensions/fun.py b/extensions/fun.py index 988a119..f10b0ae 100644 --- a/extensions/fun.py +++ b/extensions/fun.py @@ -4,6 +4,11 @@ from discord.ext import commands class Fun(commands.Cog): def __init__(self, bot): self.bot = bot + self.update = { + "allowUpdate": True, + "url": "https://raw.github.com/Akumatic/Akuma-Matata/master/extensions/fun.py", + "private": False + } @commands.command() async def ping(self, ctx): diff --git a/extensions/server.py b/extensions/server.py index 3d9b6aa..896cdb1 100644 --- a/extensions/server.py +++ b/extensions/server.py @@ -5,6 +5,11 @@ from datetime import datetime class Server(commands.Cog): def __init__(self, bot): self.bot = bot + self.update = { + "allowUpdate": True, + "url": "https://raw.github.com/Akumatic/Akuma-Matata/master/extensions/server.py", + "private": False + } def serverCfgCheck(self, id : int, key : str, default): if str(id) not in self.bot.serverCfg: diff --git a/extensions/updater.py b/extensions/updater.py new file mode 100644 index 0000000..4f68fcd --- /dev/null +++ b/extensions/updater.py @@ -0,0 +1,79 @@ +from discord.ext import commands +import urllib.request, urllib.error, json, os, discord, sys + +class Updater(commands.Cog): + def __init__(self, bot): + self.bot = bot + self.update = { + "allowUpdate": True, + "url": "https://raw.github.com/Akumatic/Akuma-Matata/master/extensions/updater.py", + "private": False + } + self.cfg = self.bot.loadJSON("updater.json", {"token":""}) + + def updaterCfgCheck(self, key : str, default): + if key not in self.cfg[key]: + self.bot.serverCfg[key] = default + self.bot.writeJSON("updater.json", self.serverCfg) + + @commands.command() + async def setPrivateToken(self, ctx, token: str = None): + self.updaterCfgCheck("token", "") + e = discord.Embed(title="<< Set Private Token >>") + if token == None: + e.color = discord.Color.red() + e.add_field(name="No Token given", value="Please spcify the token.") + return await ctx.send(embed=e) + await ctx.message.delete() + e.color = discord.Color.green() + self.cfg["token"] = token + self.bot.writeJSON("updater.json", self.serverCfg) + e.add_field(name="Token set", value="The given token was stored successfully.") + await ctx.send(embed=e) + + def getRequest(self, update: dict): + r = urllib.request.Request(update["url"]) + if update["private"]: + r.add_header("Authorization", f"token {self.cfg['token']}") + return r + + @commands.command() + async def update(self, ctx): + e = discord.Embed(title="<< Updating Modules >>") + cog = None + extensions = self.bot.extensions + botRootDir = os.path.sep.join(os.path.abspath(sys.argv[0]).split(os.path.sep)[:-1]) + for ext in extensions: + temp = ext.split(".") + cog = self.bot.get_cog(temp[-1].capitalize()) + if cog is not None and hasattr(cog, "update"): + if cog.update["allowUpdate"]: + path = f"{os.path.join(botRootDir, *temp)}.py" + #print(f"Comparing {path} with {cog.update['url']}") + try: + local = urllib.request.urlopen(f"file://{path}").read().decode("utf-8") + remote = urllib.request.urlopen(self.getRequest(cog.update)).read().decode("utf-8") + if local != remote: + self.unload(temp[-1]) + with open(path, "w") as f: + f.write(remote) + self.load(temp[-1]) + e.add_field(name=f"{temp[-1]}", value="Updated") + else: + e.add_field(name=f"{temp[-1]}", value="No update found") + except urllib.error.HTTPError as ex: + e.add_field(name=f"{temp[-1]}", value=f"Error {ex.code}: {ex.msg}") + else: + e.add_field(name=f"{temp[-1]}", value="Update not allowed.") + await ctx.send(embed=e) + + + def load(self, ext : str): + self.bot.load_extension("extensions." + ext) + + def unload(self, ext : str): + self.bot.unload_extension("extensions." + ext) + +#Setup +def setup(bot): + bot.add_cog(Updater(bot)) \ No newline at end of file diff --git a/extensions/user.py b/extensions/user.py index 2d9715a..234c27f 100644 --- a/extensions/user.py +++ b/extensions/user.py @@ -4,6 +4,11 @@ import discord, io class User(commands.Cog): def __init__(self, bot): self.bot = bot + self.update = { + "allowUpdate": True, + "url": "https://raw.github.com/Akumatic/Akuma-Matata/master/extensions/user.py", + "private": False + } @commands.Cog.listener() async def on_message(self, message):