From b101faca5f93b4e0031765e7474d7aff69d89cf9 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Jan 2019 01:37:08 +0100 Subject: [PATCH] Created a localizer wrapper Added prefix as an optional argument to the format methods of localizer Added the option to specify kvpairs for formating, all kvpairs has to have a _ as prefix Updated music.py to use the localizer wrapper --- cogs/misc.py | 19 ++-- cogs/music.py | 195 +++++++++++++++++++++------------------- cogs/utils/localizer.py | 59 ++++++++---- 3 files changed, 155 insertions(+), 118 deletions(-) diff --git a/cogs/misc.py b/cogs/misc.py index 6edd245..dc49309 100644 --- a/cogs/misc.py +++ b/cogs/misc.py @@ -70,25 +70,30 @@ class Misc: avatar = self.bot.user.avatar_url_as(format=None, static_format='png', size=1024) - infotext = '{info.infotext}' - spectext = self.bot.localizer.get("info.spectext").format(_python_v=platform.python_version, _discord_v=discord.__version__, _lavalink_v=LavalinkVersion) - stattext = self.bot.localizer.get("info.stattext").format(_guilds=guilds, _members=members) + uptimetext = f'{days}d {hours}t {minutes}m {seconds}s' embed = discord.Embed(color=0xD9C04D) embed.set_author(name=self.bot.user.name, icon_url=avatar) embed.set_thumbnail(url=avatar) embed.add_field(name="{info.what}", - value=infotext, inline=False) + value='{info.infotext}', inline=False) embed.set_footer(icon_url="https://cdn.discordapp.com/icons/297798952538079233/0198dc7b01ccf288b985b8a394cb1d44.jpg?size=64", text="{info.footer_text}") embed.add_field(name="{info.how}", - value=spectext) + value='{info.spectext}') embed.add_field(name="{info.how_many}", - value=stattext) + value='{info.stattext}') embed.add_field(name="{info.how_long}", value=uptimetext) - embed = self.bot.localizer.format_embed(embed, self.bot.settings.get_locale(ctx.guild.id)) + embed = self.bot.localizer.format_embed(embed, + self.bot.settings.get_locale(ctx.guild.id), + _python_v=platform.python_version(), + _discord_v=discord.__version__, + _lavalink_v=LavalinkVersion, + _guilds=guilds, + _members=members + ) await ctx.send(embed=embed) @commands.command() diff --git a/cogs/music.py b/cogs/music.py index 679da9c..b19b972 100644 --- a/cogs/music.py +++ b/cogs/music.py @@ -18,6 +18,8 @@ from typing import Optional from .utils.embedscroller import QueueScroller from lavasettings import * +from .utils.localizer import LocalizerWrapper + time_rx = re.compile('[0-9]+') url_rx = re.compile('https?:\\/\\/(?:www\\.)?.+') @@ -36,6 +38,11 @@ class Music: def __unload(self): self.bot.lavalink._event_hooks.clear() + def getLocalizer(self, guild_id): + lang = self.bot.settings.get_locale(guild_id) + return LocalizerWrapper(self.bot.localizer, lang, "music.response") + + async def track_hook(self, event): if isinstance(event, lavalink.events.TrackEndEvent): pass # Send track ended message to channel. @@ -63,7 +70,7 @@ class Music: async def play(self, ctx, *, query: str): """ Searches and plays a song from a given query. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) query = query.strip('<>') if not url_rx.match(query): @@ -72,7 +79,7 @@ class Music: results = await player.node.get_tracks(query) if not results or not results['tracks']: - return await ctx.send(self.bot.localizer.get("music.response.nothing_found", lang)) + return await ctx.send(localizer.format_str("{nothing_found}")) embed = discord.Embed(color=0xEFD26C) @@ -82,14 +89,14 @@ class Music: for track in tracks: player.add(requester=ctx.author.id, track=track) - embed.title = '{music.response.playlist_enqued}' - embed.description = f'{results["playlistInfo"]["name"]} - {len(tracks)} {{music.response.tracks}}' - embed = self.bot.localizer.format_embed(embed, lang) + embed.title = '{playlist_enqued}' + embed.description = f'{results["playlistInfo"]["name"]} - {len(tracks)} {{tracks}}' + embed = localizer.format_embed(embed) await ctx.send(embed=embed) else: track = results['tracks'][0] await self.enqueue(ctx, track, embed) - embed = self.bot.localizer.format_embed(embed, lang) + embed = localizer.format_embed(embed) await ctx.send(embed=embed) if not player.is_playing: @@ -100,17 +107,17 @@ class Music: async def seek(self, ctx, *, time: str): """ Seeks to a given position in a track. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if not player.is_playing: - return await ctx.send(self.bot.localizer.get("music.response.not_playing", lang)) + return await ctx.send(localizer.format_str("{not_playing}")) if ctx.author not in player.listeners: - return await ctx.send(self.bot.localizer.get("music.response.have_to_listen", lang)) + return await ctx.send(localizer.format_str("{have_to_listen}")) seconds = time_rx.search(time) if not seconds: - return await ctx.send(self.bot.localizer.get("music.response.seek.missing_amount", lang)) + return await ctx.send(localizer.format_str("{seek.missing_amount}")) seconds = int(seconds.group()) * 1000 if time.startswith('-'): @@ -118,27 +125,27 @@ class Music: track_time = player.position + seconds await player.seek(track_time) - msg = self.bot.localizer.get("music.response.seek.track_moved", lang).format(_position=lavalink.utils.format_time(track_time)) + msg = localizer.format_str("{seek.track_moved}",_position=lavalink.utils.format_time(track_time)) await ctx.send(msg) @commands.command() async def skip(self, ctx): """ Skips the current track. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if not player.is_playing: - return await ctx.send(self.bot.localizer.get("music.response.not_playing", lang)) + return await ctx.send(localizer.format_str("{not_playing}")) player.add_skipper(ctx.author) total = len(player.listeners) skips = len(player.skip_voters) if skips >= math.ceil(total/2) or player.current.requester == ctx.author.id: await player.skip() - await ctx.send(self.bot.localizer.get("music.response.skip.skipped", lang)) + await ctx.send(localizer.format_str("{skip.skipped}")) else: if skips != 0: - msg = self.bot.localizer.get("music.response.skip.require_vote", lang).format(_skips=skips, _total=math.ceil(total/2)) + msg = localizer.format_str("{skip.require_vote}", _skips=skips, _total=math.ceil(total/2)) await ctx.send(msg) @commands.command(name='skipto', aliases=['st','skip_to','forceskip']) @@ -146,17 +153,17 @@ class Music: async def skip_to(self, ctx, pos: int=1): """ Plays the queue from a specific point. Disregards tracks before the pos. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if ctx.author not in player.listeners: - return await ctx.send(self.bot.localizer.get("music.response.have_to_listen", lang)) + return await ctx.send(localizer.format_str("{have_to_listen}")) if pos < 1: - return await ctx.send(self.bot.localizer.get("music.response.skip_to.invalid_pos", lang)) + return await ctx.send(localizer.format_str("{skip_to.invalid_pos}")) if len(player.queue) < pos: - return await ctx.send(self.bot.localizer.get("music.response.skip_to.exceeds_queue", lang)) + return await ctx.send(localizer.format_str("{skip_to.exceeds_queue}")) await player.skip(pos - 1) - msg = self.bot.localizer.get("music.response.skipped_to", lang).format(_title=player.current.title,_pos=pos) + msg = localizer.format_str("{skipped_to}", _title=player.current.title, _pos=pos) await ctx.send(msg) @commands.command() @@ -164,36 +171,36 @@ class Music: async def stop(self, ctx): """ Stops the player and clears its queue. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if ctx.author not in player.listeners: - return await ctx.send(self.bot.localizer.get("music.response.have_to_listen", lang)) + return await ctx.send(localizer.format_str("{have_to_listen}")) if not player.is_playing: - return await ctx.send(self.bot.localizer.get("music.response.not_playing", lang)) + return await ctx.send(localizer.format_str("{not_playing}")) player.queue.clear() await player.stop() - await ctx.send(self.bot.localizer.get("music.response.stop", lang)) + await ctx.send(localizer.format_str("{stop}")) @commands.command(aliases=['np', 'n', 'playing','current']) async def now(self, ctx): """ Shows some stats about the currently playing song. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if not player.current: - return await ctx.send(self.bot.localizer.get("music.response.not_playing", lang)) + return await ctx.send(localizer.format_str("{not_playing}")) position = lavalink.utils.format_time(player.position) if player.current.stream: - duration = '{music.response.live}' + duration = '{live}' else: duration = lavalink.utils.format_time(player.current.duration) song = f'**[{player.current.title}]({player.current.uri})**\n({position}/{duration})' member = ctx.guild.get_member(player.current.requester) - embed = discord.Embed(color=0xEFD26C, description=song, title='{music.response.now}') + embed = discord.Embed(color=0xEFD26C, description=song, title='{now}') thumbnail_url = await RoxUtils.ThumbNailer.identify(self,player.current.identifier, player.current.uri) if thumbnail_url: embed.set_thumbnail(url=thumbnail_url) @@ -202,19 +209,19 @@ class Music: member_identifier = member.nick else: member_identifier = member.name - embed.set_footer(text=f'{{music.response.requested_by}} {member_identifier}', icon_url=member.avatar_url) + embed.set_footer(text=f'{{requested_by}} {member_identifier}', icon_url=member.avatar_url) - embed = self.bot.localizer.format_embed(embed, lang) + embed = localizer.format_embed(embed) await ctx.send(embed=embed) @commands.command(aliases=['q']) async def queue(self, ctx, user: discord.Member=None): """ Shows the player's queue. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if player.queue.empty: - return await ctx.send(self.bot.localizer.get("music.response.queue.empty", lang)) + return await ctx.send(localizer.format_str("{queue.empty}")) if user is None: queue = player.global_queue() @@ -224,7 +231,7 @@ class Music: else: user_queue = player.user_queue(user.id, dual=True) if not user_queue: - return await ctx.send(self.bot.localizer.get("music.response.queue.empty", lang).format(_user=user.name)) + return await ctx.send(localizer.format_str("{queue.empty}", _user=user.name)) scroller = QueueScroller(ctx, user_queue, lines_per_page=10, user_name=user.name) await scroller.start_scrolling() @@ -233,11 +240,11 @@ class Music: async def _myqueue(self, ctx): """ Shows your queue. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) user_queue = player.user_queue(ctx.author.id, dual=True) if not user_queue: - return await ctx.send(self.bot.localizer.get("music.response.my_queue", lang)) + return await ctx.send(localizer.format_str("{my_queue}")) scroller = QueueScroller(ctx, user_queue, lines_per_page=10, user_name=ctx.author.name) await scroller.start_scrolling() @@ -247,57 +254,57 @@ class Music: async def pause(self, ctx): """ Pauses/Resumes the current track. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if not player.is_playing: - return await ctx.send(self.bot.localizer.get("music.response.not_playing", lang)) + return await ctx.send(localizer.format_str("{not_playing}")) if player.paused: await player.set_pause(False) - await ctx.send(self.bot.localizer.get("music.response.resume.resumed", lang)) + await ctx.send(localizer.format_str("{resume.resumed}")) else: await player.set_pause(True) - await ctx.send(self.bot.localizer.get("music.response.resume.paused", lang)) + await ctx.send(localizer.format_str("{resume.paused}")) @commands.command(name='shuffle') async def _shuffle(self, ctx): """ Shuffles your queue. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) user_queue = player.user_queue(ctx.author.id) if not user_queue: - return await ctx.send(self.bot.localizer.get("music.response.my_queue", lang)) + return await ctx.send(localizer.format_str("{my_queue}")) player.shuffle_user_queue(ctx.author.id) - await ctx.send(self.bot.localizer.get("music.response.shuffle", lang)) + await ctx.send(localizer.format_str("{shuffle}")) @commands.command(name='move', aliases=["m"]) async def _move(self, ctx, from_pos: int, to_pos: int): """ Moves a song in your queue. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) user_queue = player.user_queue(ctx.author.id) if not user_queue: - return await ctx.send(self.bot.localizer.get("music.response.my_queue", lang)) + return await ctx.send(localizer.format_str("{my_queue}")) if not all(x in range(1,len(user_queue)+1) for x in [from_pos, to_pos]): - return await ctx.send(self.bot.localizer.get("music.response.my_queue", lang).format(_len=len(user_queue))) + return await ctx.send(localizer.format_str("{out_of_range}", _len=len(user_queue))) moved = player.move_user_track(ctx.author.id, from_pos - 1, to_pos - 1) if moved is None: - return await ctx.send(self.bot.localizer.get("music.response.move.not_in_queue", lang)) + return await ctx.send(localizer.format_str("{move.not_in_queue}")) - msg = self.bot.localizer.get("music.response.move.moved_to", lang).format(_title=moved.title, _from=from_pos, _to=to_pos) + msg = localizer.format_str("{move.moved_to}", _title=moved.title, _from=from_pos, _to=to_pos) await ctx.send(msg) @commands.command() async def remove(self, ctx, pos: int): """ Removes an item from the player's queue with the given pos. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if player.queue.empty: return @@ -307,29 +314,29 @@ class Music: return if pos > len(user_queue) or pos < 1: - return await ctx.send(self.bot.localizer.get("music.response.out_of_range", lang).format(_len=len(user_queue))) + return await ctx.send(localizer.format_str("{out_of_range}", _len=len(user_queue))) removed = player.remove_user_track(ctx.author.id, pos - 1) - await ctx.send(self.bot.localizer.get("music.response.remove", lang).format(_title=removed.title)) + await ctx.send(localizer.format_str("{remove}", _title=removed.title)) @commands.command(name="DJremove") @checks.DJ_or() async def _djremove(self, ctx, pos: int, user: discord.Member=None): """ Remove a song from either the global queue or a users queue""" player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if user is None: if player.queue.empty: return if pos > len(player.queue) or pos < 1: - return await ctx.send(self.bot.localizer.get("music.response.out_of_range", lang).format(_len=len(player.queue))) + return await ctx.send(localizer.format_str("{out_of_range}", _len=len(player.queue))) removed = player.remove_global_track(pos - 1) requester = self.bot.get_user(removed.requester) - await ctx.send(self.bot.localizer.get("music.response.dj_removed", lang).format(_title=removed.title, _user=requester.name)) + await ctx.send(localizer.format_str("{dj_removed}", _title=removed.title, _user=requester.name)) else: if player.queue.empty: @@ -340,17 +347,17 @@ class Music: return if pos > len(user_queue) or pos < 1: - return await ctx.send(self.bot.localizer.get("music.response.out_of_range", lang).format(_len=len(user_queue))) + return await ctx.send(localizer.format_str("{out_of_range}", _len=len(user_queue))) removed = player.remove_user_track(user.id, pos - 1) - await ctx.send(self.bot.localizer.get("music.response.dj_removed", lang).format(_title=removed.title, _user=requester.name)) + await ctx.send(localizer.format_str("{dj_removed}", _title=removed.title, _user=requester.name)) @commands.command(name="removeuser") @checks.DJ_or(alone=True) async def _user_queue_remove(self, ctx, user: discord.Member): """ Remove a song from either the global queue or a users queue""" player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if player.queue.empty: return @@ -361,23 +368,24 @@ class Music: player.remove_user_queue(user.id) embed = discord.Embed(color=0x36393F) - embed.description = self.bot.localizer.get("music.response.dj_remove_user", lang).format(_id=user.id) + embed.description = "{dj_remove_user}" + embed = localizer.format_embed(embed, _id=user.id) await ctx.send(embed=embed) @commands.command() async def search(self, ctx, *, query): """ Lists the first 10 search results from a given query. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if not query.startswith('ytsearch:') and not query.startswith('scsearch:'): query = 'ytsearch:' + query results = await player.node.get_tracks(query) - embed = discord.Embed(description='{music.response.nothing_found}', color=0x36393F) + embed = discord.Embed(description='{nothing_found}', color=0x36393F) if not results or not results['tracks']: - embed = self.bot.localizer.format_embed(embed, lang) + embed = localizer.format_embed(embed) return await ctx.send(embed=embed) tracks = results['tracks'] @@ -417,8 +425,8 @@ class Music: return True return False - embed.description = '{music.response.search}' - embed = self.bot.localizer.format_embed(embed, lang) + embed.description = '{search}' + embed = localizer.format_embed(embed) result_msg = await ctx.send(embed=embed) for emoji, index in choices[:result_count]: @@ -426,9 +434,9 @@ class Music: await result_msg.add_reaction('❌') embed.description = search_results - embed.title = '{music.response.results}' + embed.title = '{results}' embed.color = 0xEFD26C - embed = self.bot.localizer.format_embed(embed, lang) + embed = localizer.format_embed(embed) await result_msg.edit(embed=embed) try: @@ -438,8 +446,8 @@ class Music: except asyncio.TimeoutError: await result_msg.clear_reactions() embed.title = '' - embed.description='{music.response.time_expired}' - embed = self.bot.localizer.format_embed(embed, lang) + embed.description='{time_expired}' + embed = localizer.format_embed(embed) await result_msg.edit(embed=embed) await asyncio.sleep(5) await result_msg.delete() @@ -450,7 +458,7 @@ class Music: await result_msg.clear_reactions() track = tracks[choice - 1] await self.enqueue(ctx, track, embed) - embed = self.bot.localizer.format_embed(embed, lang) + embed = localizer.format_embed(embed) await result_msg.edit(embed=embed) if not player.is_playing: await player.play() @@ -460,19 +468,19 @@ class Music: async def disconnect(self, ctx): """ Disconnects the player from the voice channel and clears its queue. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if not player.is_connected: - return await ctx.send(self.bot.localizer.get("music.response.not_connected", lang)) + return await ctx.send(localizer.format_str("{not_connected}")) if not ctx.author.voice or (player.is_connected and ctx.author.voice.channel.id != int(player.channel_id)): - return await ctx.send(self.bot.localizer.get("music.response.disconnect.not_in_voice", lang)) + return await ctx.send(localizer.format_str("{disconnect.not_in_voice}")) player.queue.clear() await player.stop() await self.connect_to(ctx.guild.id, None) - embed = discord.Embed(description='{music.response.disconnect.disconnected}', color=0x36393F) - embed = self.bot.localizer.format_embed(embed, lang) + embed = discord.Embed(description='{disconnect.disconnected}', color=0x36393F) + embed = localizer.format_embed(embed) await ctx.send(embed=embed) @commands.command(aliases=['vol']) @@ -480,18 +488,19 @@ class Music: async def volume(self, ctx, volume: int = None): """ Changes the player's volume. Must be between 0 and 1000. Error Handling for that is done by Lavalink. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if not volume: return await ctx.send(f'🔈 | {player.volume}%') if int(player.current.requester) == ctx.author.id: if not 50 <= volume <= 125: - return await ctx.send(f'you can only set the volume between 50 and 125') + return await ctx.send(localizer.format_str("{volume.out_of_range}")) await player.set_volume(volume) embed = discord.Embed(color=0x36393F) - embed.description = self.bot.localizer.get("music.response.volume.set_to", lang).format(_volume=player.volume) + embed.description = "{volume.set_to}" + embed = localizer.format_embed(embed, _volume=player.volume) await ctx.send(embed=embed) @commands.command(aliases=['normal','nl']) @@ -499,13 +508,13 @@ class Music: async def normalize(self, ctx): """ Reset the equalizer and """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) await player.set_volume(100) await player.bassboost(False) embed = discord.Embed(color=0x36393F) - embed.description = '{music.response.volume.reset}' - embed = self.bot.localizer.format_embed(embed, lang) + embed.description = '{volume.reset}' + embed = localizer.format_embed(embed) await ctx.send(embed=embed) @commands.command(name='boost', aliases=['boo']) @@ -513,7 +522,7 @@ class Music: async def _boost(self, ctx, boost: bool=None): """ Set the equalizer to bass boost the music """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if boost is not None: await player.bassboost(boost) @@ -521,11 +530,11 @@ class Music: embed = discord.Embed(color=0x36393F) if player.boosted: - embed.description = '{music.response.boost.on}' + embed.description = '{boost.on}' else: - embed.description = '{music.response.boost.off}' + embed.description = '{boost.off}' - embed = self.bot.localizer.format_embed(embed, lang) + embed = localizer.format_embed(embed) await ctx.send(embed=embed) @commands.command(name='history', aliases=['h','hist']) @@ -555,11 +564,11 @@ class Music: async def scrub(self, ctx): """ Lists the first 10 search results from a given query. """ player = self.bot.lavalink.players.get(ctx.guild.id) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) - controls = '{music.response.scrub.controls}' - embed = discord.Embed(description='{music.response.nothing_playing}', color=0x36393F) - embed = self.bot.localizer.format_embed(embed, lang) + controls = '{scrub.controls}' + embed = discord.Embed(description='{nothing_playing}', color=0x36393F) + embed = localizer.format_embed(embed) if player.current is None: return await ctx.send(embed=embed) @@ -591,15 +600,15 @@ class Music: return True return False - embed.description = '{music.response.scrub.add}' - embed = self.bot.localizer.format_embed(embed, lang) + embed.description = '{scrub.add}' + embed = localizer.format_embed(embed) msg = await ctx.send(embed=embed) for (emoji, _, _) in scrubber: await msg.add_reaction(emoji) embed.description = controls - embed = self.bot.localizer.format_embed(embed, lang) + embed = localizer.format_embed(embed) await msg.edit(embed=embed) scrubbing = True while scrubbing: @@ -688,7 +697,7 @@ class Music: player = self.bot.lavalink.players.get(ctx.guild.id) track, pos_global, pos_local = player.add(requester=ctx.author.id, track=track) - lang = self.bot.settings.get_locale(ctx.guild.id) + localizer = self.getLocalizer(ctx.guild.id) if player.current is not None: queue_duration = 0 @@ -699,10 +708,10 @@ class Music: until_play = queue_duration + player.current.duration - player.position until_play = lavalink.utils.format_time(until_play) - embed.add_field(name="{music.response.enqueue.position}", value=f"`{pos_local + 1}({pos_global + 1})`", inline=True) - embed.add_field(name="{music.response.enqueue.playing_in}", value=f"`{until_play} ({{music.response.enqueue.estimated}})`", inline=True) + embed.add_field(name="{enqueue.position}", value=f"`{pos_local + 1}({pos_global + 1})`", inline=True) + embed.add_field(name="{enqueue.playing_in}", value=f"`{until_play} ({{enqueue.estimated}})`", inline=True) - embed.title = '{music.response.enqueue.enqueued}' + embed.title = '{enqueue.enqueued}' thumb_url = await RoxUtils.ThumbNailer.identify(self, track.identifier, track.uri) diff --git a/cogs/utils/localizer.py b/cogs/utils/localizer.py index c846576..c4e27cc 100644 --- a/cogs/utils/localizer.py +++ b/cogs/utils/localizer.py @@ -15,7 +15,7 @@ from discord import Embed Localizer for bot """ -kmatch = re.compile('({[^{}]+})') +kmatch = re.compile('({(?!_)([^{}]+)})') class Localizer: def __init__(self, localization_folder, default_lang): @@ -75,22 +75,30 @@ class Localizer: # parses and interpolates translation dictionary @staticmethod - def _parse_localization_dictionary(d, lookup): + def _parse_localization_dictionary(d, lookup, prefix=None): n_dict = {} for k, v in d.items(): if type(v) is str: - n_dict[k] = Localizer._parse_localization_string(v, lookup) + n_dict[k] = Localizer._parse_localization_string(v, lookup, prefix) else: n_dict[k] = v return n_dict + @staticmethod + def _replace_keys(value, prefix=None): + for outer, inner in kmatch.findall(value): + nstr = inner + if prefix is not None: + nstr = f'{prefix}.{inner}' + nstr = f'{{{nstr}}}' + nstr = nstr.replace(".", "/") + value = value.replace(outer, nstr) + return value # parses and interpolates strings @staticmethod - def _parse_localization_string(value, d): + def _parse_localization_string(value, d, prefix=None): d = SafeDict(d) - for match in kmatch.findall(value): - nstr = match.replace(".", "/") - value = value.replace(match, nstr) + value = Localizer._replace_keys(value, prefix) return value.format_map(d) # returns true if localization is currently loaded @@ -109,16 +117,17 @@ class Localizer: return self.localization_table.get(lang, {}).get(key.replace(".", "/")) # inserts translations into a string - def format_str(self, s, lang=None): + def format_str(self, s, lang=None, prefix=None, **kvpairs): lang = lang or self.default_lang if not self.isLoaded(lang): self._load_localization(lang) - - ns = Localization._parse_localization_string(s, self.localization_table.get(lang, {})) - return Localization._parse_localization_string(s, self.all_localizations) - + + ns = Localizer._parse_localization_string(s, self.localization_table.get(lang, {}), prefix) + ns = Localizer._parse_localization_string(ns, self.all_localizations, prefix) + return ns.format_map(SafeDict(kvpairs)) + # inserts translations into a values of a dictionary - def format_dict(self, d, lang=None): + def format_dict(self, d, lang=None, prefix=None, **kvpairs): lang = lang or self.default_lang if not self.isLoaded(lang): self._load_localization(lang) @@ -130,15 +139,29 @@ class Localizer: for k, v in (cursor.items() if type(cursor) == dict else enumerate(cursor)): if type(v) == str: # insert translations based on lang - v = Localizer._parse_localization_string(v, self.localization_table.get(lang, {})) - # insert translations based on key prefix, e.g 'global.', 'en_en.' - cursor[k] = Localizer._parse_localization_string(v, self.all_localizations) + cursor[k] = self.format_str(v, lang, prefix, **kvpairs) elif type(v) == dict or type(v) == list: cursorQueue.append(v) return nd # inserts translations into a values of a embed - def format_embed(self, embed, lang=None): + def format_embed(self, embed, lang=None, prefix=None, **kvpairs): raw = embed.to_dict() - return Embed.from_data(self.format_dict(raw, lang)) \ No newline at end of file + return Embed.from_data(self.format_dict(raw, lang, prefix, **kvpairs)) + + +class LocalizerWrapper: + def __init__(self, localizer, lang=None, prefix=None): + self.localizer = localizer + self.lang = lang + self.prefix = prefix + + def format_str(self, s, **kvpairs): + return self.localizer.format_str(s, self.lang, self.prefix, **kvpairs) + + def format_dict(self, d, **kvpairs): + return self.localizer.format_dict(d, self.lang, self.prefix, **kvpairs) + + def format_embed(self, embed, **kvpairs): + return self.localizer.format_embed(embed, self.lang, self.prefix, **kvpairs) \ No newline at end of file