Use correct prefixes when sending messages to owners (#3632)

* use correct prefixes when sending messages to owners

* make internal util for this instead

* oops

* fix circular import

* let's add back the actual fix I made this PR for...

* fix wrong logger name

* improve log message
This commit is contained in:
jack1142 2020-03-12 17:31:33 +01:00 committed by GitHub
parent 3ff127d514
commit 4afe1ff569
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 31 deletions

View File

@ -1,4 +1,5 @@
import asyncio import asyncio
import logging
import re import re
from abc import ABC from abc import ABC
from collections import defaultdict from collections import defaultdict
@ -8,6 +9,7 @@ import discord
from redbot.core import Config, modlog, commands from redbot.core import Config, modlog, commands
from redbot.core.bot import Red from redbot.core.bot import Red
from redbot.core.i18n import Translator, cog_i18n from redbot.core.i18n import Translator, cog_i18n
from redbot.core.utils._internal_utils import send_to_owners_with_prefix_replaced
from .casetypes import CASETYPES from .casetypes import CASETYPES
from .events import Events from .events import Events
from .kickban import KickBanMixin from .kickban import KickBanMixin
@ -104,14 +106,12 @@ class Mod(
await self.settings.guild(discord.Object(id=guild_id)).delete_repeats.set(val) await self.settings.guild(discord.Object(id=guild_id)).delete_repeats.set(val)
await self.settings.version.set("1.0.0") # set version of last update await self.settings.version.set("1.0.0") # set version of last update
if await self.settings.version() < "1.1.0": if await self.settings.version() < "1.1.0":
prefixes = await self.bot.get_valid_prefixes()
prefix = re.sub(rf"<@!?{self.bot.user.id}>", f"@{self.bot.user.name}", prefixes[0])
msg = _( msg = _(
"Ignored guilds and channels have been moved. " "Ignored guilds and channels have been moved. "
"Please use `{prefix}moveignoredchannels` if " "Please use `[p]moveignoredchannels` if "
"you were previously using these functions." "you were previously using these functions."
).format(prefix=prefix) )
self.bot.loop.create_task(self.bot.send_to_owners(msg)) self.bot.loop.create_task(send_to_owners_with_prefix_replaced(self.bot, msg))
await self.settings.version.set(__version__) await self.settings.version.set(__version__)
@commands.command() @commands.command()

View File

@ -2,6 +2,7 @@ import discord
from redbot.core.bot import Red from redbot.core.bot import Red
from redbot.core import checks, commands, Config from redbot.core import checks, commands, Config
from redbot.core.i18n import cog_i18n, Translator from redbot.core.i18n import cog_i18n, Translator
from redbot.core.utils._internal_utils import send_to_owners_with_prefix_replaced
from redbot.core.utils.chat_formatting import escape, pagify from redbot.core.utils.chat_formatting import escape, pagify
from .streamtypes import ( from .streamtypes import (
@ -111,8 +112,6 @@ class Streams(commands.Cog):
try: try:
tokens["client_secret"] tokens["client_secret"]
except KeyError: except KeyError:
prefixes = await self.bot.get_valid_prefixes()
prefix = re.sub(rf"<@!?{self.bot.user.id}>", f"@{self.bot.user.name}", prefixes[0])
message = _( message = _(
"You need a client secret key to use correctly Twitch API on this cog.\n" "You need a client secret key to use correctly Twitch API on this cog.\n"
"Follow these steps:\n" "Follow these steps:\n"
@ -120,12 +119,12 @@ class Streams(commands.Cog):
'2. Click "Manage" on your application.\n' '2. Click "Manage" on your application.\n'
'3. Click on "New secret".\n' '3. Click on "New secret".\n'
"5. Copy your client ID and your client secret into:\n" "5. Copy your client ID and your client secret into:\n"
"`{prefix}set api twitch client_id <your_client_id_here> " "`[p]set api twitch client_id <your_client_id_here> "
"client_secret <your_client_secret_here>`\n\n" "client_secret <your_client_secret_here>`\n\n"
"Note: These tokens are sensitive and should only be used in a private channel " "Note: These tokens are sensitive and should only be used in a private channel "
"or in DM with the bot." "or in DM with the bot."
).format(prefix=prefix) )
await self.bot.send_to_owners(message) await send_to_owners_with_prefix_replaced(self.bot, message)
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.post( async with session.post(
"https://id.twitch.tv/oauth2/token", "https://id.twitch.tv/oauth2/token",

View File

@ -43,11 +43,12 @@ from .settings_caches import PrefixManager, IgnoreManager, WhitelistBlacklistMan
from .rpc import RPCMixin from .rpc import RPCMixin
from .utils import common_filters from .utils import common_filters
from .utils._internal_utils import send_to_owners_with_prefix_replaced
CUSTOM_GROUPS = "CUSTOM_GROUPS" CUSTOM_GROUPS = "CUSTOM_GROUPS"
SHARED_API_TOKENS = "SHARED_API_TOKENS" SHARED_API_TOKENS = "SHARED_API_TOKENS"
log = logging.getLogger("redbot") log = logging.getLogger("red")
__all__ = ["RedBase", "Red", "ExitCodes"] __all__ = ["RedBase", "Red", "ExitCodes"]
@ -548,18 +549,6 @@ class RedBase(
last_system_info = await self._config.last_system_info() last_system_info = await self._config.last_system_info()
async def notify_owners(content: str) -> None:
destinations = await self.get_owner_notification_destinations()
for destination in destinations:
prefixes = await self.get_valid_prefixes(getattr(destination, "guild", None))
prefix = re.sub(rf"<@!?{self.bot.user.id}>", f"@{self.bot.user.name}", prefixes[0])
try:
await destination.send(content.format(prefix=prefix))
except Exception as _exc:
log.exception(
f"I could not send an owner notification to ({destination.id}){destination}"
)
ver_info = list(sys.version_info[:2]) ver_info = list(sys.version_info[:2])
python_version_changed = False python_version_changed = False
LIB_PATH = cog_data_path(raw_name="Downloader") / "lib" LIB_PATH = cog_data_path(raw_name="Downloader") / "lib"
@ -569,13 +558,14 @@ class RedBase(
shutil.rmtree(str(LIB_PATH)) shutil.rmtree(str(LIB_PATH))
LIB_PATH.mkdir() LIB_PATH.mkdir()
self.loop.create_task( self.loop.create_task(
notify_owners( send_to_owners_with_prefix_replaced(
self,
"We detected a change in minor Python version" "We detected a change in minor Python version"
" and cleared packages in lib folder.\n" " and cleared packages in lib folder.\n"
"The instance was started with no cogs, please load Downloader" "The instance was started with no cogs, please load Downloader"
" and use `{prefix}cog reinstallreqs` to regenerate lib folder." " and use `[p]cog reinstallreqs` to regenerate lib folder."
" After that, restart the bot to get" " After that, restart the bot to get"
" all of your previously loaded cogs loaded again." " all of your previously loaded cogs loaded again.",
) )
) )
python_version_changed = True python_version_changed = True
@ -603,11 +593,12 @@ class RedBase(
if system_changed and not python_version_changed: if system_changed and not python_version_changed:
self.loop.create_task( self.loop.create_task(
notify_owners( send_to_owners_with_prefix_replaced(
self,
"We detected a possible change in machine's operating system" "We detected a possible change in machine's operating system"
" or architecture. You might need to regenerate your lib folder" " or architecture. You might need to regenerate your lib folder"
" if 3rd-party cogs stop working properly.\n" " if 3rd-party cogs stop working properly.\n"
"To regenerate lib folder, load Downloader and use `{prefix}cog reinstallreqs`." "To regenerate lib folder, load Downloader and use `[p]cog reinstallreqs`.",
) )
) )
@ -1202,8 +1193,11 @@ class RedBase(
try: try:
await location.send(content, **kwargs) await location.send(content, **kwargs)
except Exception as _exc: except Exception as _exc:
log.exception( log.error(
f"I could not send an owner notification to ({location.id}){location}" "I could not send an owner notification to %s (%s)",
location,
location.id,
exc_info=_exc,
) )
sends = [wrapped_send(d, content, **kwargs) for d in destinations] sends = [wrapped_send(d, content, **kwargs) for d in destinations]

View File

@ -1,13 +1,15 @@
from __future__ import annotations from __future__ import annotations
import asyncio
import json import json
import logging import logging
import os import os
import re
import shutil import shutil
import tarfile import tarfile
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import List, Optional, Set, Union, TYPE_CHECKING from typing import Awaitable, Callable, List, Optional, Set, Union, TYPE_CHECKING
import discord import discord
from fuzzywuzzy import fuzz, process from fuzzywuzzy import fuzz, process
@ -16,8 +18,11 @@ from redbot.core import data_manager
from redbot.core.utils.chat_formatting import box from redbot.core.utils.chat_formatting import box
if TYPE_CHECKING: if TYPE_CHECKING:
from redbot.core.bot import Red
from redbot.core.commands import Command, Context from redbot.core.commands import Command, Context
main_log = logging.getLogger("red")
__all__ = ("safe_delete", "fuzzy_command_search", "format_fuzzy_results", "create_backup") __all__ = ("safe_delete", "fuzzy_command_search", "format_fuzzy_results", "create_backup")
@ -200,3 +205,63 @@ async def create_backup(dest: Path = Path.home()) -> Optional[Path]:
for f in to_backup: for f in to_backup:
tar.add(str(f), arcname=str(f.relative_to(data_path)), recursive=False) tar.add(str(f), arcname=str(f.relative_to(data_path)), recursive=False)
return backup_fpath return backup_fpath
# this might be worth moving to `bot.send_to_owners` at later date
async def send_to_owners_with_preprocessor(
bot: Red,
content: str,
*,
content_preprocessor: Optional[
Callable[[Red, discord.abc.Messageable, str], Awaitable[str]]
] = None,
**kwargs,
):
"""
This sends something to all owners and their configured extra destinations.
This acts the same as `Red.send_to_owners`, with
one added keyword argument as detailed below in *Other Parameters*.
Other Parameters
----------------
content_preprocessor: Optional[Callable[[Red, discord.abc.Messageable, str], Awaitable[str]]]
Optional async function that takes
bot object, owner notification destination and message content
and returns the content that should be sent to given location.
"""
destinations = await bot.get_owner_notification_destinations()
async def wrapped_send(bot, location, content=None, preprocessor=None, **kwargs):
try:
if preprocessor is not None:
content = await preprocessor(bot, location, content)
await location.send(content, **kwargs)
except Exception as _exc:
main_log.error(
"I could not send an owner notification to %s (%s)",
location,
location.id,
exc_info=_exc,
)
sends = [wrapped_send(bot, d, content, content_preprocessor, **kwargs) for d in destinations]
await asyncio.gather(*sends)
async def send_to_owners_with_prefix_replaced(bot: Red, content: str, **kwargs):
"""
This sends something to all owners and their configured extra destinations.
This acts the same as `Red.send_to_owners`, with one addition - `[p]` in ``content`` argument
is replaced with a clean prefix for each specific destination.
"""
async def preprocessor(bot: Red, destination: discord.abc.Messageable, content: str) -> str:
prefixes = await bot.get_valid_prefixes(getattr(destination, "guild", None))
prefix = re.sub(rf"<@!?{bot.user.id}>", f"@{bot.user.name}", prefixes[0])
return content.replace("[p]", prefix)
await send_to_owners_with_preprocessor(bot, content, content_preprocessor=preprocessor)