Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve and error handling for update and autoupdate features. #3161

Merged
merged 2 commits into from
Jul 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 45 additions & 28 deletions bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import discord
import isodate
from aiohttp import ClientSession
from aiohttp import ClientSession, ClientResponseError
from discord.ext import commands, tasks
from discord.ext.commands.view import StringView
from emoji import UNICODE_EMOJI
Expand Down Expand Up @@ -630,6 +630,8 @@ async def on_ready(self):
)
logger.warning("If the external servers are valid, you may ignore this message.")

self.post_metadata.start()
self.autoupdate.start()
self._started = True

async def convert_emoji(self, name: str) -> str:
Expand Down Expand Up @@ -1581,6 +1583,7 @@ async def before_post_metadata(self):
await self.wait_for_connected()
if not self.config.get("data_collection") or not self.guild:
self.post_metadata.cancel()
return

logger.debug("Starting metadata loop.")
logger.line("debug")
Expand All @@ -1591,44 +1594,55 @@ async def autoupdate(self):
latest = changelog.latest_version

if self.version < parse_version(latest.version):
if self.hosting_method == HostingMethod.HEROKU:
error = None
data = {}
try:
# update fork if gh_token exists
data = await self.api.update_repository()
except InvalidConfigError:
pass
except ClientResponseError as exc:
error = exc
if self.hosting_method == HostingMethod.HEROKU:
if error is not None:
logger.error(f"Autoupdate failed! Status: {error.status}.")
logger.error(f"Error message: {error.message}")
self.autoupdate.cancel()
return

embed = discord.Embed(color=self.main_color)
commit_data = data.get("data")
if not commit_data:
return

logger.info("Bot has been updated.")

if not self.config["update_notifications"]:
return

commit_data = data["data"]
embed = discord.Embed(color=self.main_color)
message = commit_data["commit"]["message"]
html_url = commit_data["html_url"]
short_sha = commit_data["sha"][:6]
user = data["user"]
embed.add_field(
name="Merge Commit",
value=f"[`{short_sha}`]({html_url}) " f"{message} - {user['username']}",
)
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.set_footer(text=f"Updating Modmail v{self.version} -> 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("Bot has been updated.")
channel = self.log_channel
if self.config["update_notifications"]:
await channel.send(embed=embed)
channel = self.update_channel
await channel.send(embed=embed)
else:
try:
# update fork if gh_token exists
await self.api.update_repository()
except InvalidConfigError:
pass

command = "git pull"
proc = await asyncio.create_subprocess_shell(
command,
Expand All @@ -1642,7 +1656,7 @@ async def autoupdate(self):

if err and not res:
logger.warning(f"Autoupdate failed: {err}")
self.autoupdate_loop.cancel()
self.autoupdate.cancel()
return

elif res != "Already up to date.":
Expand All @@ -1659,7 +1673,7 @@ async def autoupdate(self):
description="If you do not have an auto-restart setup, please manually start the bot.",
color=self.main_color,
)
embed.set_footer(text=f"Updating Modmail v{self.version} " f"-> v{latest.version}")
embed.set_footer(text=f"Updating Modmail v{self.version} -> v{latest.version}")
if self.config["update_notifications"]:
await channel.send(embed=embed)
return await self.close()
Expand All @@ -1671,16 +1685,19 @@ async def before_autoupdate(self):

if self.config.get("disable_autoupdates"):
logger.warning("Autoupdates disabled.")
self.autoupdate_loop.cancel()
self.autoupdate.cancel()
return

if self.hosting_method == HostingMethod.DOCKER:
logger.warning("Autoupdates disabled as using Docker.")
self.autoupdate_loop.cancel()
self.autoupdate.cancel()
return

if not self.config.get("github_token") and self.hosting_method == HostingMethod.HEROKU:
logger.warning("GitHub access token not found.")
logger.warning("Autoupdates disabled.")
self.autoupdate_loop.cancel()
self.autoupdate.cancel()
return

def format_channel_name(self, author, exclude_channel=None, force_null=False):
"""Sanitises a username for use with text channel names
Expand Down
42 changes: 29 additions & 13 deletions cogs/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -1931,15 +1931,15 @@ async def github(self, ctx):
async def update(self, ctx, *, flag: str = ""):
"""
Update Modmail.
To stay up-to-date with the latest commit rom GitHub, specify "force" as the flag.
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)"
"(https://github.com/kyb3r/modmail/blob/master/bot.py#L1)"
)

if self.bot.version >= parse_version(latest.version) and flag.lower() != "force":
Expand All @@ -1951,16 +1951,39 @@ async def update(self, ctx, *, flag: str = ""):
embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"])
await ctx.send(embed=embed)
else:
if self.bot.hosting_method == HostingMethod.HEROKU:
error = None
data = {}
try:
# update fork if gh_token exists
data = await self.bot.api.update_repository()
except InvalidConfigError:
pass
except ClientResponseError as exc:
error = exc

if self.bot.hosting_method == HostingMethod.HEROKU:
if error is not None:
embed = discord.Embed(
title="Update failed",
description=f"Error status: {error.status}.\nError message: {error.message}",
color=self.bot.error_color,
)
return await ctx.send(embed=embed)
if not data:
# invalid gh_token
embed = discord.Embed(
title="Update failed",
description="Invalid Github token.",
color=self.bot.error_color,
)
return await ctx.send(embed=embed)

commit_data = data["data"]
user = data["user"]

if commit_data and commit_data.get("html_url"):
embed = discord.Embed(color=self.bot.main_color)

embed.set_footer(text=f"Updating Modmail v{self.bot.version} " f"-> v{latest.version}")
embed.set_footer(text=f"Updating Modmail v{self.bot.version} -> v{latest.version}")

embed.set_author(
name=user["username"] + " - Updating bot",
Expand All @@ -1978,21 +2001,14 @@ async def update(self, ctx, *, flag: str = ""):
else:
embed = discord.Embed(
title="Already up to date",
description="No further updates required",
description="No further updates required.",
color=self.bot.main_color,
)
embed.set_footer(text="Force update")
embed.set_author(name=user["username"], icon_url=user["avatar_url"], url=user["url"])
await ctx.send(embed=embed)
else:
# update fork if gh_token exists
try:
await self.bot.api.update_repository()
except InvalidConfigError:
pass

command = "git pull"

proc = await asyncio.create_subprocess_shell(
command,
stderr=PIPE,
Expand Down
Loading