mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
[Downloader] Better user facing feedback on cog update (#2165)
This commit is contained in:
parent
fb839084fe
commit
d79996aeea
@ -3,8 +3,9 @@ from redbot.core import commands
|
|||||||
from .installable import Installable
|
from .installable import Installable
|
||||||
|
|
||||||
|
|
||||||
class InstalledCog(commands.Converter):
|
class InstalledCog(Installable):
|
||||||
async def convert(self, ctx: commands.Context, arg: str) -> Installable:
|
@classmethod
|
||||||
|
async def convert(cls, ctx: commands.Context, arg: str) -> Installable:
|
||||||
downloader = ctx.bot.get_cog("Downloader")
|
downloader = ctx.bot.get_cog("Downloader")
|
||||||
if downloader is None:
|
if downloader is None:
|
||||||
raise commands.CommandError("Downloader not loaded.")
|
raise commands.CommandError("Downloader not loaded.")
|
||||||
|
|||||||
@ -1,16 +1,20 @@
|
|||||||
|
import asyncio
|
||||||
|
import contextlib
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from sys import path as syspath
|
from sys import path as syspath
|
||||||
from typing import Tuple, Union
|
from typing import Tuple, Union, Iterable
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from redbot.core import checks, commands, Config
|
from redbot.core import checks, commands, Config
|
||||||
from redbot.core.bot import Red
|
from redbot.core.bot import Red
|
||||||
from redbot.core.data_manager import cog_data_path
|
from redbot.core.data_manager import cog_data_path
|
||||||
from redbot.core.i18n import Translator, cog_i18n
|
from redbot.core.i18n import Translator, cog_i18n
|
||||||
from redbot.core.utils.chat_formatting import box, pagify
|
from redbot.core.utils.chat_formatting import box, pagify, humanize_list, inline
|
||||||
|
from redbot.core.utils.menus import start_adding_reactions
|
||||||
|
from redbot.core.utils.predicates import MessagePredicate, ReactionPredicate
|
||||||
|
|
||||||
from . import errors
|
from . import errors
|
||||||
from .checks import do_install_agreement
|
from .checks import do_install_agreement
|
||||||
@ -108,7 +112,7 @@ class Downloader(commands.Cog):
|
|||||||
installed.remove(cog_json)
|
installed.remove(cog_json)
|
||||||
await self.conf.installed.set(installed)
|
await self.conf.installed.set(installed)
|
||||||
|
|
||||||
async def _reinstall_cogs(self, cogs: Tuple[Installable]) -> Tuple[Installable]:
|
async def _reinstall_cogs(self, cogs: Iterable[Installable]) -> Tuple[Installable]:
|
||||||
"""
|
"""
|
||||||
Installs a list of cogs, used when updating.
|
Installs a list of cogs, used when updating.
|
||||||
:param cogs:
|
:param cogs:
|
||||||
@ -122,7 +126,7 @@ class Downloader(commands.Cog):
|
|||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
return tuple(failed)
|
return tuple(failed)
|
||||||
|
|
||||||
async def _reinstall_libraries(self, cogs: Tuple[Installable]) -> Tuple[Installable]:
|
async def _reinstall_libraries(self, cogs: Iterable[Installable]) -> Tuple[Installable]:
|
||||||
"""
|
"""
|
||||||
Reinstalls any shared libraries from the repos of cogs that
|
Reinstalls any shared libraries from the repos of cogs that
|
||||||
were updated.
|
were updated.
|
||||||
@ -142,7 +146,7 @@ class Downloader(commands.Cog):
|
|||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
return tuple(failed)
|
return tuple(failed)
|
||||||
|
|
||||||
async def _reinstall_requirements(self, cogs: Tuple[Installable]) -> bool:
|
async def _reinstall_requirements(self, cogs: Iterable[Installable]) -> bool:
|
||||||
"""
|
"""
|
||||||
Reinstalls requirements for given cogs that have been updated.
|
Reinstalls requirements for given cogs that have been updated.
|
||||||
Returns a bool that indicates if all requirement installations
|
Returns a bool that indicates if all requirement installations
|
||||||
@ -356,6 +360,7 @@ class Downloader(commands.Cog):
|
|||||||
"""
|
"""
|
||||||
installed_cogs = set(await self.installed_cogs())
|
installed_cogs = set(await self.installed_cogs())
|
||||||
|
|
||||||
|
async with ctx.typing():
|
||||||
if cog_name is None:
|
if cog_name is None:
|
||||||
updated = await self._repo_manager.update_all_repos()
|
updated = await self._repo_manager.update_all_repos()
|
||||||
|
|
||||||
@ -366,18 +371,52 @@ class Downloader(commands.Cog):
|
|||||||
# Thrown if the repo no longer exists
|
# Thrown if the repo no longer exists
|
||||||
updated = {}
|
updated = {}
|
||||||
|
|
||||||
updated_cogs = set(cog for repo in updated.keys() for cog in repo.available_cogs)
|
updated_cogs = set(cog for repo in updated for cog in repo.available_cogs)
|
||||||
installed_and_updated = updated_cogs & installed_cogs
|
installed_and_updated = updated_cogs & installed_cogs
|
||||||
|
|
||||||
# noinspection PyTypeChecker
|
if installed_and_updated:
|
||||||
await self._reinstall_requirements(installed_and_updated)
|
await self._reinstall_requirements(installed_and_updated)
|
||||||
|
|
||||||
# noinspection PyTypeChecker
|
|
||||||
await self._reinstall_cogs(installed_and_updated)
|
await self._reinstall_cogs(installed_and_updated)
|
||||||
|
|
||||||
# noinspection PyTypeChecker
|
|
||||||
await self._reinstall_libraries(installed_and_updated)
|
await self._reinstall_libraries(installed_and_updated)
|
||||||
await ctx.send(_("Cog update completed successfully."))
|
message = _("Cog update completed successfully.")
|
||||||
|
|
||||||
|
cognames = [c.name for c in installed_and_updated]
|
||||||
|
message += _("\nUpdated: ") + humanize_list(tuple(map(inline, cognames)))
|
||||||
|
else:
|
||||||
|
await ctx.send(_("All installed cogs are already up to date."))
|
||||||
|
return
|
||||||
|
await ctx.send(message)
|
||||||
|
|
||||||
|
message = _("Would you like to reload the updated cogs?")
|
||||||
|
can_react = ctx.channel.permissions_for(ctx.me).add_reactions
|
||||||
|
if not can_react:
|
||||||
|
message += " (y/n)"
|
||||||
|
query: discord.Message = await ctx.send(message)
|
||||||
|
if can_react:
|
||||||
|
# noinspection PyAsyncCall
|
||||||
|
start_adding_reactions(query, ReactionPredicate.YES_OR_NO_EMOJIS, ctx.bot.loop)
|
||||||
|
pred = ReactionPredicate.yes_or_no(query, ctx.author)
|
||||||
|
event = "reaction_add"
|
||||||
|
else:
|
||||||
|
pred = MessagePredicate.yes_or_no(ctx)
|
||||||
|
event = "message"
|
||||||
|
try:
|
||||||
|
await ctx.bot.wait_for(event, check=pred, timeout=30)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await query.delete()
|
||||||
|
return
|
||||||
|
|
||||||
|
if pred.result is True:
|
||||||
|
if can_react:
|
||||||
|
with contextlib.suppress(discord.Forbidden):
|
||||||
|
await query.clear_reactions()
|
||||||
|
|
||||||
|
await ctx.invoke(ctx.bot.get_cog("Core").reload, *cognames)
|
||||||
|
else:
|
||||||
|
if can_react:
|
||||||
|
await query.delete()
|
||||||
|
else:
|
||||||
|
await ctx.send(_("OK then."))
|
||||||
|
|
||||||
@cog.command(name="list")
|
@cog.command(name="list")
|
||||||
async def _cog_list(self, ctx, repo_name: Repo):
|
async def _cog_list(self, ctx, repo_name: Repo):
|
||||||
|
|||||||
@ -545,12 +545,10 @@ class Core(commands.Cog, CoreLogic):
|
|||||||
|
|
||||||
@commands.command(name="reload")
|
@commands.command(name="reload")
|
||||||
@checks.is_owner()
|
@checks.is_owner()
|
||||||
async def reload_(self, ctx, *, cog_name: str):
|
async def reload(self, ctx, *cogs: str):
|
||||||
"""Reloads packages"""
|
"""Reloads packages"""
|
||||||
|
|
||||||
cog_names = [c.strip() for c in cog_name.split(" ")]
|
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
loaded, failed, not_found = await self._reload(cog_names)
|
loaded, failed, not_found = await self._reload(cogs)
|
||||||
|
|
||||||
if loaded:
|
if loaded:
|
||||||
fmt = "Package{plural} {packs} {other} reloaded."
|
fmt = "Package{plural} {packs} {other} reloaded."
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user