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

[Core] Guild scoped I18n #3896

Merged
merged 36 commits into from Oct 26, 2020
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
1e38984
Guild I18n
Kowlin May 29, 2020
2210270
Finish off guild scoped i18n
Kowlin Jun 2, 2020
77a5aee
Black formatting
Kowlin Jun 2, 2020
68afba7
Added guild only flags.
Kowlin Aug 30, 2020
761b0de
Merge remote-tracking branch 'origin/V3/develop' into pr/guild-i18n
Kowlin Aug 30, 2020
611fea7
Fix missing import.
Kowlin Aug 30, 2020
ed1af2f
Added listing of guild i18n settings
Kowlin Aug 30, 2020
73b9820
Added API support
Kowlin Aug 30, 2020
f570b01
Added API support... properly!
Kowlin Aug 30, 2020
c2f0b3e
Added API support... for realsies!
Kowlin Aug 31, 2020
33e0ec6
Auto-translate create_cases instances
Kowlin Aug 31, 2020
f6c424b
Fix get_regional_format to actually return properly
Kowlin Aug 31, 2020
9f07ae0
Cleanup `set showsettings`
Kowlin Aug 31, 2020
1984887
Style pass
Kowlin Aug 31, 2020
612ca79
Update redbot/core/core_commands.py
Kowlin Sep 20, 2020
5bc2aa2
Update redbot/core/events.py
Kowlin Sep 20, 2020
e1666e0
Update redbot/core/core_commands.py
Kowlin Sep 20, 2020
d05566a
Fix missing import
Kowlin Sep 20, 2020
7a56711
Improve caching
Kowlin Sep 20, 2020
807dd4e
Removal of unneeded function
Kowlin Sep 20, 2020
a4fe1d0
Fix some naming
Kowlin Sep 20, 2020
36df48a
IDFK anymore...
Kowlin Sep 20, 2020
14c9d86
Reformat
Kowlin Sep 20, 2020
c7507e9
Update redbot/core/settings_caches.py
Kowlin Sep 23, 2020
5955b90
Update redbot/core/settings_caches.py
Kowlin Sep 23, 2020
7971759
Update redbot/core/settings_caches.py
Kowlin Sep 23, 2020
d4c8d8a
Remove line number
Kowlin Sep 23, 2020
fd915bc
Fix global sets
Jackenmen Oct 13, 2020
bbb42d6
Set contextual locale manually where needed
Jackenmen Oct 13, 2020
35f0378
Reports cog is wonderful...
Jackenmen Oct 15, 2020
836121d
Merge branch 'V3/develop' into pr/guild-i18n
Jackenmen Oct 19, 2020
d106a5f
Update redbot/core/core_commands.py
Jackenmen Oct 19, 2020
e304619
Merge remote-tracking branch 'upstream/V3/develop' into pr/guild-i18n
Drapersniper Oct 23, 2020
d976dac
Merge branch 'V3/develop' into pr/guild-i18n
Jackenmen Oct 26, 2020
a1af6b3
Set contextual locale manually where needed in Mutes cog
Jackenmen Oct 26, 2020
d835929
s
Jackenmen Oct 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion redbot/cogs/alias/alias.py
Expand Up @@ -170,7 +170,7 @@ async def get_prefix(self, message: discord.Message) -> str:
for p in prefixes:
if content.startswith(p):
return p
raise ValueError(_("No prefix found."))
raise ValueError("No prefix found.")

async def call_alias(self, message: discord.Message, prefix: str, alias: AliasEntry):
new_message = copy(message)
Expand Down
4 changes: 4 additions & 0 deletions redbot/cogs/audio/core/events/lavalink.py
Expand Up @@ -5,6 +5,8 @@
import discord
import lavalink

from redbot.core.i18n import set_contextual_locales_from_guild

from ...errors import DatabaseError, TrackEnqueueError
from ..abc import MixinMeta
from ..cog_utils import CompositeMetaClass, _
Expand All @@ -28,6 +30,8 @@ async def lavalink_event_handler(
guild_id = self.rgetattr(guild, "id", None)
if not guild:
return
await set_contextual_locales_from_guild(self.bot, guild)

current_requester = self.rgetattr(current_track, "requester", None)
current_stream = self.rgetattr(current_track, "is_stream", None)
current_length = self.rgetattr(current_track, "length", None)
Expand Down
6 changes: 5 additions & 1 deletion redbot/cogs/filter/filter.py
Expand Up @@ -5,7 +5,7 @@

from redbot.core import checks, Config, modlog, commands
from redbot.core.bot import Red
from redbot.core.i18n import Translator, cog_i18n
from redbot.core.i18n import Translator, cog_i18n, set_contextual_locales_from_guild
from redbot.core.utils import AsyncIter
from redbot.core.utils.chat_formatting import pagify, humanize_list

Expand Down Expand Up @@ -396,6 +396,8 @@ async def on_message(self, message: discord.Message):
if await self.bot.is_automod_immune(message):
return

await set_contextual_locales_from_guild(self.bot, message.guild)

await self.check_filter(message)

@commands.Cog.listener()
Expand Down Expand Up @@ -429,6 +431,8 @@ async def maybe_filter_name(self, member: discord.Member):
if not guild_data["filter_names"]:
return

await set_contextual_locales_from_guild(self.bot, guild)

if await self.filter_hits(member.display_name, member.guild):

name_to_use = guild_data["filter_default_name"]
Expand Down
3 changes: 3 additions & 0 deletions redbot/cogs/mod/events.py
Expand Up @@ -151,6 +151,9 @@ async def on_message(self, message):
# As are anyone configured to be
if await self.bot.is_automod_immune(message):
return

await i18n.set_contextual_locales_from_guild(self.bot, message.guild)

deleted = await self.check_duplicates(message)
if not deleted:
await self.check_mention_spam(message)
Expand Down
6 changes: 5 additions & 1 deletion redbot/cogs/reports/reports.py
Expand Up @@ -11,7 +11,7 @@
from redbot.core.utils.chat_formatting import pagify, box
from redbot.core.utils.antispam import AntiSpam
from redbot.core.bot import Red
from redbot.core.i18n import Translator, cog_i18n
from redbot.core.i18n import Translator, cog_i18n, set_contextual_locales_from_guild
from redbot.core.utils.predicates import MessagePredicate
from redbot.core.utils.tunnel import Tunnel

Expand Down Expand Up @@ -346,8 +346,10 @@ async def on_raw_reaction_add(self, payload: discord.RawReactionActionEvent):

if t is None:
return
guild = t[0][0]
tun = t[1]["tun"]
if payload.user_id in [x.id for x in tun.members]:
await set_contextual_locales_from_guild(self.bot, guild)
await tun.react_close(
uid=payload.user_id, message=_("{closer} has closed the correspondence")
)
Expand All @@ -365,6 +367,7 @@ async def on_message(self, message: discord.Message):
to_remove.append(k)
continue

await set_contextual_locales_from_guild(self.bot, guild)
topic = _("Re: ticket# {ticket_number} in {guild.name}").format(
ticket_number=ticket_number, guild=guild
)
Expand All @@ -376,6 +379,7 @@ async def on_message(self, message: discord.Message):
for key in to_remove:
if tun := self.tunnel_store.pop(key, None):
guild, ticket = key
await set_contextual_locales_from_guild(self.bot, guild)
await tun["tun"].close_because_disabled(
_(
"Correspondence about ticket# {ticket_number} in "
Expand Down
5 changes: 4 additions & 1 deletion redbot/cogs/streams/streams.py
@@ -1,7 +1,7 @@
import discord
from redbot.core.bot import Red
from redbot.core import checks, commands, Config
from redbot.core.i18n import cog_i18n, Translator
from redbot.core.i18n import cog_i18n, Translator, set_contextual_locales_from_guild
from redbot.core.utils._internal_utils import send_to_owners_with_prefix_replaced
from redbot.core.utils.chat_formatting import escape, pagify

Expand Down Expand Up @@ -714,6 +714,9 @@ async def check_streams(self):
ignore_reruns = await self.config.guild(channel.guild).ignore_reruns()
if ignore_reruns and is_rerun:
continue

await set_contextual_locales_from_guild(self.bot, channel.guild)

mention_str, edited_roles = await self._get_mention_str(
channel.guild, channel
)
Expand Down
6 changes: 4 additions & 2 deletions redbot/core/bot.py
Expand Up @@ -41,14 +41,13 @@
from .dev_commands import Dev
from .events import init_events
from .global_checks import init_global_checks

from .settings_caches import (
PrefixManager,
IgnoreManager,
WhitelistBlacklistManager,
DisabledCogCache,
I18nManager,
)

from .rpc import RPCMixin
from .utils import common_filters, AsyncIter
from .utils._internal_utils import send_to_owners_with_prefix_replaced
Expand Down Expand Up @@ -142,6 +141,8 @@ def __init__(self, *args, cli_flags=None, bot_dir: Path = Path.cwd(), **kwargs):
disabled_commands=[],
autoimmune_ids=[],
delete_delay=-1,
locale=None,
regional_format=None,
)

self._config.register_channel(embeds=None, ignored=False)
Expand All @@ -159,6 +160,7 @@ def __init__(self, *args, cli_flags=None, bot_dir: Path = Path.cwd(), **kwargs):
self._disabled_cog_cache = DisabledCogCache(self._config)
self._ignored_cache = IgnoreManager(self._config)
self._whiteblacklist_cache = WhitelistBlacklistManager(self._config)
self._i18n_cache = I18nManager(self._config)

async def prefix_manager(bot, message) -> List[str]:
prefixes = await self._prefix_cache.get_prefixes(message.guild)
Expand Down
118 changes: 105 additions & 13 deletions redbot/core/core_commands.py
Expand Up @@ -1569,25 +1569,39 @@ async def set_showsettings(self, ctx: commands.Context):
mod_role_ids = guild_data["mod_role"]
mod_role_names = [r.name for r in guild.roles if r.id in mod_role_ids]
mod_roles_str = humanize_list(mod_role_names) if mod_role_names else "Not Set."
guild_settings = _("Admin roles: {admin}\nMod roles: {mod}\n").format(
admin=admin_roles_str, mod=mod_roles_str

guild_locale = await i18n.get_locale_from_guild(self.bot, ctx.guild)
guild_regional_format = (
await i18n.get_regional_format_from_guild(self.bot, ctx.guild) or guild_locale
)

guild_settings = _(
"Admin roles: {admin}\n"
"Mod roles: {mod}\n"
"Locale: {guild_locale}\n"
"Regional format: {guild_regional_format}\n"
).format(
admin=admin_roles_str,
mod=mod_roles_str,
guild_locale=guild_locale,
guild_regional_format=guild_regional_format,
)
else:
guild_settings = ""

prefixes = await ctx.bot._prefix_cache.get_prefixes(ctx.guild)
global_data = await ctx.bot._config.all()
locale = global_data["locale"]
regional_format = global_data["regional_format"] or _("Same as bot's locale")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was intentional. It makes it obvious that the regional format is currently set to use bot's locale.
Same suggestion applies to guild regional format (which can be "Same as server's locale") as well as to guild's locale (which can be "Same as bot's locale").

regional_format = global_data["regional_format"] or locale
colour = discord.Colour(global_data["color"])

prefix_string = " ".join(prefixes)
settings = _(
"{bot_name} Settings:\n\n"
"Prefixes: {prefixes}\n"
"{guild_settings}"
"Locale: {locale}\n"
"Regional format: {regional_format}\n"
"Global locale: {locale}\n"
"Global regional format: {regional_format}"
Jackenmen marked this conversation as resolved.
Show resolved Hide resolved
"Default embed colour: {colour}"
).format(
bot_name=ctx.bot.user.name,
Expand Down Expand Up @@ -2018,9 +2032,10 @@ async def serverprefix(self, ctx: commands.Context, *prefixes: str):

@_set.command()
@checks.is_owner()
async def locale(self, ctx: commands.Context, language_code: str):
async def globallocale(self, ctx: commands.Context, language_code: str):
"""
Changes bot's locale.
Changes the bot's default locale.
This will be used when a server has not set a locale, or in DMs.

`<language_code>` can be any language code with country code included,
e.g. `en-US`, `de-DE`, `fr-FR`, `pl-PL`, etc.
Expand All @@ -2042,12 +2057,51 @@ async def locale(self, ctx: commands.Context, language_code: str):
return
standardized_locale_name = f"{locale.language}-{locale.territory}"
i18n.set_locale(standardized_locale_name)
await ctx.bot._config.locale.set(standardized_locale_name)
await self.bot._i18n_cache.set_locale(None, standardized_locale_name)
await i18n.set_contextual_locales_from_guild(self.bot, ctx.guild)
await ctx.send(_("Global locale has been set."))

@_set.command()
@commands.guild_only()
@checks.guildowner_or_permissions(manage_guild=True)
async def locale(self, ctx: commands.Context, language_code: str):
Kowlin marked this conversation as resolved.
Show resolved Hide resolved
"""
Changes the bot's locale in this server.

`<language_code>` can be any language code with country code included,
e.g. `en-US`, `de-DE`, `fr-FR`, `pl-PL`, etc.

Go to Red's Crowdin page to see locales that are available with translations:
https://translate.discord.red

Use "default" to return to the bot's default set language.
To reset to English, use "en-US".
"""
if language_code.lower() == "default":
global_locale = await self.bot._config.locale()
i18n.set_contextual_locale(global_locale)
await self.bot._i18n_cache.set_locale(ctx.guild, None)
await ctx.send(_("Locale has been set to the default."))
return
try:
locale = BabelLocale.parse(language_code, sep="-")
except (ValueError, UnknownLocaleError):
await ctx.send(_("Invalid language code. Use format: `en-US`"))
return
if locale.territory is None:
await ctx.send(
_("Invalid format - language code has to include country code, e.g. `en-US`")
)
return
standardized_locale_name = f"{locale.language}-{locale.territory}"
i18n.set_contextual_locale(standardized_locale_name)
await self.bot._i18n_cache.set_locale(ctx.guild, standardized_locale_name)
await ctx.send(_("Locale has been set."))

@_set.command(aliases=["region"])
@_set.command(aliases=["globalregion"])
@commands.guild_only()
@checks.is_owner()
async def regionalformat(self, ctx: commands.Context, language_code: str = None):
async def globalregionalformat(self, ctx: commands.Context, language_code: str = None):
"""
Changes bot's regional format. This is used for formatting date, time and numbers.

Expand All @@ -2058,8 +2112,8 @@ async def regionalformat(self, ctx: commands.Context, language_code: str = None)
"""
if language_code is None:
i18n.set_regional_format(None)
await ctx.bot._config.regional_format.set(None)
await ctx.send(_("Regional formatting will now be based on bot's locale."))
await self.bot._i18n_cache.set_regional_format(None, None)
await ctx.send(_("Global regional formatting will now be based on bot's locale."))
return

try:
Expand All @@ -2074,7 +2128,45 @@ async def regionalformat(self, ctx: commands.Context, language_code: str = None)
return
standardized_locale_name = f"{locale.language}-{locale.territory}"
i18n.set_regional_format(standardized_locale_name)
await ctx.bot._config.regional_format.set(standardized_locale_name)
await self.bot._i18n_cache.set_regional_format(None, standardized_locale_name)
await ctx.send(
_("Global regional formatting will now be based on `{language_code}` locale.").format(
language_code=standardized_locale_name
)
)

@_set.command(aliases=["region"])
@checks.guildowner_or_permissions(manage_guild=True)
async def regionalformat(self, ctx: commands.Context, language_code: str = None):
Kowlin marked this conversation as resolved.
Show resolved Hide resolved
"""
Changes bot's regional format in this server. This is used for formatting date, time and numbers.

`<language_code>` can be any language code with country code included,
e.g. `en-US`, `de-DE`, `fr-FR`, `pl-PL`, etc.

Leave `<language_code>` empty to base regional formatting on bot's locale in this server.
"""
if language_code is None:
i18n.set_contextual_regional_format(None)
await self.bot._i18n_cache.set_regional_format(ctx.guild, None)
await ctx.send(
_("Regional formatting will now be based on bot's locale in this server.")
)
return

try:
locale = BabelLocale.parse(language_code, sep="-")
except (ValueError, UnknownLocaleError):
await ctx.send(_("Invalid language code. Use format: `en-US`"))
return
if locale.territory is None:
await ctx.send(
_("Invalid format - language code has to include country code, e.g. `en-US`")
)
return
standardized_locale_name = f"{locale.language}-{locale.territory}"
i18n.set_contextual_regional_format(standardized_locale_name)
await self.bot._i18n_cache.set_regional_format(ctx.guild, standardized_locale_name)
await ctx.send(
_("Regional formatting will now be based on `{language_code}` locale.").format(
language_code=standardized_locale_name
Expand Down
9 changes: 8 additions & 1 deletion redbot/core/events.py
Expand Up @@ -15,7 +15,12 @@
from redbot.core import data_manager

from redbot.core.commands import RedHelpFormatter, HelpSettings
from redbot.core.i18n import Translator
from redbot.core.i18n import (
Translator,
set_contextual_locale,
set_contextual_regional_format,
set_contextual_locales_from_guild,
)
from .utils import AsyncIter
from .. import __version__ as red_version, version_info as red_version_info, VersionInfo
from . import commands
Expand Down Expand Up @@ -313,6 +318,8 @@ async def on_command_error(ctx, error, unhandled_by_cog=False):

@bot.event
async def on_message(message):
await set_contextual_locales_from_guild(bot, message.guild)

await bot.process_commands(message)
discord_now = message.created_at
if (
Expand Down