From af0294cf8d7402e3a7e320bb31547471e2eab69f Mon Sep 17 00:00:00 2001 From: Kyber Date: Thu, 20 Jun 2019 01:53:58 +1000 Subject: [PATCH] Revert "Remove update functionality from the bot. (#293)" This reverts commit 4222da3c0112c9fba3264985de00e73b7dc57e94. --- CHANGELOG.md | 8 +---- bot.py | 62 +++++++++++++++++++++++++++++++++++++ cogs/utility.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++ core/decorators.py | 19 +++++++++++- 4 files changed, 158 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2aac41b89b..da7e959818 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,18 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -# [Unreleased] (3.0.0) +# [Unreleased] ### Added - Sponsors command that will list sponsors. -### Removed - -- Removed autoupdate functionality and the `update` command in favour of the [Pull app](https://github.com/apps/pull). - -Read more about updating your bot [here](https://github.com/kyb3r/modmail/wiki/updating) - ### Changed - Channel names now can contain unicode characters. - Debug logs are now located in a unique file for each bot. (Internal change) diff --git a/bot.py b/bot.py index 6cdd8f4522..116735d6af 100644 --- a/bot.py +++ b/bot.py @@ -74,6 +74,7 @@ def __init__(self): self.plugin_db = PluginDatabaseClient(self) self.metadata_task = self.loop.create_task(self.metadata_loop()) + self.autoupdate_task = self.loop.create_task(self.autoupdate_loop()) self._load_extensions() @property @@ -191,6 +192,11 @@ def run(self, *args, **kwargs): self.loop.run_until_complete(self.metadata_task) except asyncio.CancelledError: logger.debug(info("data_task has been cancelled.")) + try: + self.autoupdate_task.cancel() + self.loop.run_until_complete(self.autoupdate_task) + except asyncio.CancelledError: + logger.debug(info("autoupdate_task has been cancelled.")) self.loop.run_until_complete(self.logout()) for task in asyncio.Task.all_tasks(): @@ -898,6 +904,62 @@ async def validate_database_connection(self): else: logger.info(info("Successfully connected to the database.")) + async def autoupdate_loop(self): + await self.wait_until_ready() + + if self.config.get("disable_autoupdates"): + logger.warning(info("Autoupdates disabled.")) + logger.info(LINE) + return + + if not self.config.get("github_access_token"): + logger.warning(info("GitHub access token not found.")) + logger.warning(info("Autoupdates disabled.")) + logger.info(LINE) + return + + logger.info(info("Autoupdate loop started.")) + + while not self.is_closed(): + changelog = await Changelog.from_url(self) + latest = changelog.latest_version + + if parse_version(self.version) < parse_version(latest.version): + data = await self.api.update_repository() + + embed = discord.Embed(color=discord.Color.green()) + + commit_data = data["data"] + user = data["user"] + embed.set_author( + name=user["username"] + " - Updating Bot", + icon_url=user["avatar_url"], + url=user["url"], + ) + + embed.set_footer( + text=f"Updating Modmail v{self.version} " f"-> v{latest.version}" + ) + + embed.description = latest.description + for name, value in latest.fields.items(): + embed.add_field(name=name, value=value) + + if commit_data: + message = commit_data["commit"]["message"] + html_url = commit_data["html_url"] + short_sha = commit_data["sha"][:6] + embed.add_field( + name="Merge Commit", + value=f"[`{short_sha}`]({html_url}) " + f"{message} - {user['username']}", + ) + logger.info(info("Bot has been updated.")) + channel = self.log_channel + await channel.send(embed=embed) + + await asyncio.sleep(3600) + async def metadata_loop(self): await self.wait_until_ready() if not self.guild: diff --git a/cogs/utility.py b/cogs/utility.py index d3c4cff095..8782872388 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -423,6 +423,83 @@ async def github(self, ctx): embed.set_thumbnail(url=user["avatar_url"]) await ctx.send(embed=embed) + @commands.command() + @checks.has_permissions(PermissionLevel.OWNER) + @github_access_token_required + @trigger_typing + async def update(self, ctx, *, flag: str = ""): + """ + Update Modmail. + + This only works for Heroku users who have configured their bot for updates. + + To stay up-to-date with the latest commit + from GitHub, specify "force" as the flag. + """ + + changelog = await Changelog.from_url(self.bot) + latest = changelog.latest_version + + desc = ( + f"The latest version is [`{self.bot.version}`]" + "(https://github.com/kyb3r/modmail/blob/master/bot.py#L25)" + ) + + if ( + parse_version(self.bot.version) >= parse_version(latest.version) + and flag.lower() != "force" + ): + embed = Embed( + title="Already up to date", description=desc, color=self.bot.main_color + ) + + data = await self.bot.api.get_user_info() + if not data.get("error"): + user = data["user"] + embed.set_author( + name=user["username"], icon_url=user["avatar_url"], url=user["url"] + ) + else: + data = await self.bot.api.update_repository() + + commit_data = data["data"] + user = data["user"] + + if commit_data: + embed = Embed(color=self.bot.main_color) + + embed.set_footer( + text=f"Updating Modmail v{self.bot.version} " + f"-> v{latest.version}" + ) + + embed.set_author( + name=user["username"] + " - Updating bot", + icon_url=user["avatar_url"], + url=user["url"], + ) + + embed.description = latest.description + for name, value in latest.fields.items(): + embed.add_field(name=name, value=value) + # message = commit_data['commit']['message'] + html_url = commit_data["html_url"] + short_sha = commit_data["sha"][:6] + embed.add_field( + name="Merge Commit", value=f"[`{short_sha}`]({html_url})" + ) + else: + embed = Embed( + title="Already up to date with master repository.", + description="No further updates required", + color=self.bot.main_color, + ) + embed.set_author( + name=user["username"], icon_url=user["avatar_url"], url=user["url"] + ) + + return await ctx.send(embed=embed) + @commands.command(aliases=["presence"]) @checks.has_permissions(PermissionLevel.ADMINISTRATOR) async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): diff --git a/core/decorators.py b/core/decorators.py index c87f34129b..03deb09e61 100644 --- a/core/decorators.py +++ b/core/decorators.py @@ -10,4 +10,21 @@ async def wrapper(self, ctx: commands.Context, *args, **kwargs): await ctx.trigger_typing() return await func(self, ctx, *args, **kwargs) - return wrapper \ No newline at end of file + return wrapper + + +def github_access_token_required(func): + @functools.wraps(func) + async def wrapper(self, ctx: commands.Context, *args, **kwargs): + if self.bot.config.get("github_access_token"): + return await func(self, ctx, *args, **kwargs) + + desc = ( + "You can only use this command if you have a " + "configured `GITHUB_ACCESS_TOKEN`. Get a " + "personal access token from developer settings." + ) + embed = Embed(color=Color.red(), title="Unauthorized", description=desc) + await ctx.send(embed=embed) + + return wrapper