diff --git a/Leveler/__init__.py b/Leveler/__init__.py new file mode 100644 index 0000000..59958ae --- /dev/null +++ b/Leveler/__init__.py @@ -0,0 +1,7 @@ +from .leveler import Leveler + + +def setup(bot): + n = Leveler(bot) + bot.add_listener(n.listener, "on_message") + bot.add_cog(n) diff --git a/Leveler/data/cambria.ttc b/Leveler/data/cambria.ttc new file mode 100644 index 0000000..d061ecf Binary files /dev/null and b/Leveler/data/cambria.ttc differ diff --git a/Leveler/info.json b/Leveler/info.json new file mode 100644 index 0000000..bb23044 --- /dev/null +++ b/Leveler/info.json @@ -0,0 +1,11 @@ +{ + "author": ["Malarne (Malarne#1418)"], + "min_bot_version": "3.0.2", + "description": "A leveler cog for Red V3\nInspired by Stevy's v2 leveler cog\nPlease consult the docs at ayrobot.netlify.com for setup informations.\nThanks for using my cog !\nNB:Channel whitelist is enabled by default, you can manage that under `[p]levelerset channel whitelist` command !", + "hidden": false, + "install_msg": "Thank you for installing this leveler !\nPlease consult the docs at https://discord-cogs.readthedocs.io/en/latest/leveler.html for setup informations.\nPlease note that this cog come with bundled data, mostly the font for profile image.", + "required_cogs": {}, + "requirements": ["pillow"], + "short": "Leveler tool, better than MEE6", + "tags": ["leveler", "pillow", "fun"] +} diff --git a/Leveler/leveler.py b/Leveler/leveler.py new file mode 100644 index 0000000..2147dbf --- /dev/null +++ b/Leveler/leveler.py @@ -0,0 +1,641 @@ +# -*- coding: utf-8 -*- +import re +from redbot.core import checks, Config +import discord +from redbot.core import commands +from redbot.core.data_manager import bundled_data_path +from redbot.core.utils.menus import menu, DEFAULT_CONTROLS +import asyncio +import datetime +from .userprofile import UserProfile +from PIL import Image, ImageDraw, ImageFont +from math import floor, ceil +import os +import aiohttp +from redbot.core.i18n import Translator, cog_i18n +from io import BytesIO +import functools +import textwrap + + +_ = Translator("Leveler", __file__) + + +@cog_i18n(_) +class Leveler(commands.Cog): + """A leveler cog !""" + + def __init__(self, bot): + self.bot = bot + self.profiles = UserProfile() + self.loop = self.bot.loop.create_task(self.start()) + self.restart = True + self.defaultrole = _("New") + self._session = aiohttp.ClientSession() + + __version__ = "1.0.0" + __author__ = "Malarne#1418" + __info__ = { + "bot_version": "3.0.0rc2", + "description": ( + "A leveler cog for Red V3\n", + "Inspired by Stevy's v2 leveler cog\n", + "Please consult the docs at ayrobot.netlify.com for setup informations.\n", + "Thanks for using my cog !", + ), + "hidden": False, + "install_msg": ( + "Thank you for installing this leveler !\n", + "Please consult the docs at ayrobot.netlify.com for setup informations.", + ), + "required_cogs": [], + "requirements": ["pillow"], + "short": "Leveler tool, better than MEE6", + "tags": ["leveler", "pillow", "fun"], + } + + def cog_unload(self): + self.bot.remove_listener(self.listener) + asyncio.get_event_loop().create_task(self._session.close()) + self.loop.cancel() + + async def start(self): + await self.bot.wait_until_ready() + while True: + if not self.restart: + guilds = self.bot.guilds + for i in guilds: + profils = await self.profiles.data.all_members(i) + for j in profils.keys(): + member = i.get_member(j) + if member is None: + await self._reset_member(i, j) + else: + await self.profiles.data.member(member).today.set(0) + self.restart = True + if datetime.datetime.now().strftime("%H:%M") in [ + "05:00", + "05:01", + "05:02", + "05:03", + "05:04", + "05:05", + ]: + self.restart = False + await asyncio.sleep(30) + + async def _reset_member(self, guild, memberid): + try: + base = self.profiles.data._get_base_group(self.profiles.data.MEMBER) + await base.clear_raw(str(guild.id), memberid) + except: + pass + + @commands.command(hidden=True) + @checks.is_owner() + async def testreset(self, ctx): + self.restart = False + await ctx.send(_("Resets in 30 seconds max"), delete_after=30) + + async def get_avatar(self, user): + try: + res = BytesIO() + await user.avatar_url_as(format="png", size=1024).save(res, seek_begin=True) + return res + except: + async with self._session.get(user.avatar_url_as(format="png", size=1024)) as r: + img = await r.content.read() + return BytesIO(img) + + async def get_background(self, url): + async with self._session.get(url) as f: + data = await f.read() + return Image.open(BytesIO(data)) + + def round_corner(self, radius): + """Draw a round corner""" + corner = Image.new("L", (radius, radius), 0) + draw = ImageDraw.Draw(corner) + draw.pieslice((0, 0, radius * 2, radius * 2), 180, 270, fill=255) + return corner + + def add_corners(self, im, rad): + # https://stackoverflow.com/questions/7787375/python-imaging-library-pil-drawing-rounded-rectangle-with-gradient + width, height = im.size + alpha = Image.new("L", im.size, 255) + origCorner = self.round_corner(rad) + corner = origCorner + alpha.paste(corner, (0, 0)) + corner = origCorner.rotate(90) + alpha.paste(corner, (0, height - rad)) + corner = origCorner.rotate(180) + alpha.paste(corner, (width - rad, height - rad)) + corner = origCorner.rotate(270) + alpha.paste(corner, (width - rad, 0)) + im.putalpha(alpha) + return im + + def make_full_profile(self, avatar_data, user, xp, nxp, lvl, minone, elo, ldb, desc, bg=None): + img = Image.new("RGBA", (340, 390), (17, 17, 17, 255)) + if bg is not None: + bg_width, bg_height = bg.size + ratio = bg_height / 390 + bg = bg.resize((int(bg_width / (ratio)), int(bg_height / ratio))) + if bg.size[0] < 340: + ratio = bg_width / 340 + bg = bg.resize((int(bg_width / (ratio)), int(bg_height / ratio))) + bg = bg.convert("RGBA") + bg.putalpha(128) + offset = 0 + if bg.size[0] >= 340: + offset = (int((-(bg.size[0] - 340) / 2)), 0) + if bg.size[0] < 340: + offset = (0, int((-(bg.size[1] - 390) / 2))) + + img.paste(bg, offset, bg) + img = self.add_corners(img, 10) + draw = ImageDraw.Draw(img) + usercolor = (255, 255, 0) # user.color.to_rgb() + aviholder = self.add_corners(Image.new("RGBA", (140, 140), (255, 255, 255, 255)), 10) + nameplate = self.add_corners(Image.new("RGBA", (180, 60), (0, 0, 0, 255)), 10) + xptot = self.add_corners(Image.new("RGBA", (310, 20), (215, 215, 215, 255)), 10) + img.paste(aviholder, (10, 10), aviholder) + img.paste(nameplate, (155, 10), nameplate) + img.paste(xptot, (15, 340), xptot) + + fontpath = str(bundled_data_path(self) / "cambria.ttc") + + font1 = ImageFont.truetype(fontpath, 18) + font2 = ImageFont.truetype(fontpath, 22) + font3 = ImageFont.truetype(fontpath, 32) + + avatar = Image.open(avatar_data) + avatar_size = 130, 130 + avatar.thumbnail(avatar_size) + img.paste(avatar, (15, 15)) + lxp = xp - minone + lnxp = nxp - minone + lprc = ceil(lxp / (lnxp / 100)) + b_offset = floor(lprc * 3.1) + xpbar = self.add_corners(Image.new("RGBA", (b_offset, 20), usercolor), 10) + img.paste(xpbar, (12, 340), xpbar) + + lvl_str = _("Level:") + ldb_str = _("Ranking:") + rank_str = _("Role:") + prog_str = _("Progress:") + + draw.text((10, 180), lvl_str, fill="white", font=font3) + draw.text((10, 220), ldb_str, fill="white", font=font3) + draw.text((10, 260), rank_str, fill="white", font=font3) + nick = user.display_name + if font2.getsize(nick)[0] > 150: + nick = nick[:15] + "..." + + draw.text((154, 316), f"{lprc}%", fill=usercolor, font=font1) + draw.text((100, 360), (prog_str + f" {xp}/{nxp}"), fill=usercolor, font=font1) + draw.text(((font3.getsize(lvl_str)[0] + 20), 180), f"{lvl}", fill=usercolor, font=font3) + draw.text(((font3.getsize(ldb_str)[0] + 20), 220), f"{ldb}", fill=usercolor, font=font3) + draw.text(((font3.getsize(rank_str)[0] + 20), 260), f"{elo}", fill=usercolor, font=font3) + + draw.text((162, 14), f"{nick}", fill=usercolor, font=font2) + draw.text((162, 40), f"{user.name}#{user.discriminator}", fill=usercolor, font=font1) + margin = 162 + offset = 70 + count = 0 + for line in textwrap.wrap(desc, width=20): + count += 1 + if count == 6: + draw.text((margin, offset), f"{line}...", fill=usercolor, font=font1) + break + draw.text((margin, offset), f"{line}", fill=usercolor, font=font1) + offset += font1.getsize(line)[1] + temp = BytesIO() + img.save(temp, format="PNG") + temp.name = "profile.png" + return temp + + async def profile_data(self, user): + """Async get user profile data to pass to image creator""" + avatar = await self.get_avatar(user) + try: + bg = await self.get_background(await self.profiles._get_background(user)) + except: + bg = None + default = await self.profiles.data.guild(user.guild).defaultrole() + data = { + "avatar_data": avatar, + "user": user, + "xp": 0, + "nxp": 100, + "lvl": 1, + "minone": 0, + "elo": default if default else _("New"), + "ldb": 0, + "desc": "", + "bg": bg, + } + if not await self.profiles._is_registered(user): + return data + else: + data["xp"] = await self.profiles._get_exp(user) + data["nxp"] = await self.profiles._get_level_exp(user) + data["lvl"] = lvl = await self.profiles._get_level(user) + data["ldb"] = await self.profiles._get_leaderboard_pos(user.guild, user) + data["desc"] = await self.profiles._get_description(user) + if data["lvl"] != 1: + data["minone"] = self.profiles.level_func(lvl - 1) + else: + data["minone"] = 0 + roles = await self.profiles._get_guild_roles(user.guild) + if len(roles) == 0: + default = await self.profiles.data.guild(user.guild).defaultrole() + data["elo"] = default if default else self.defaultrole + else: + if str(lvl) in roles.keys(): + data["elo"] = discord.utils.get(user.guild.roles, id=roles[str(lvl)]).name + else: + tmp = 0 + for k, v in roles.items(): + if int(k) < lvl: + tmp = int(v) + pass + if tmp == 0: + data["elo"] = default if default else self.defaultrole + else: + rl = discord.utils.get(user.guild.roles, id=tmp) + data["elo"] = rl.name + return data + + @commands.command() + @commands.guild_only() + async def profile(self, ctx, user: discord.Member = None): + """Show your leveler progress. Default to yourself.""" + if user is None: + user = ctx.author + data = await self.profile_data(user) + + task = functools.partial(self.make_full_profile, **data) + task = self.bot.loop.run_in_executor(None, task) + try: + img = await asyncio.wait_for(task, timeout=60) + except asyncio.TimeoutError: + return + + img.seek(0) + await ctx.send(file=discord.File(img)) + + async def listener(self, message): + if type(message.author) != discord.Member: + # throws an error when webhooks talk, this fixes it + return + if type(message.channel) != discord.channel.TextChannel: + return + if message.author.bot: + return + if await self.profiles.data.guild(message.guild).whitelist(): + if message.channel.id not in await self.profiles._get_guild_channels(message.author.guild): + return + elif await self.profiles.data.guild(message.guild).blacklist(): + if message.channel.id in await self.profiles._get_guild_blchannels(message.author.guild): + return + + if not await self.profiles._is_registered(message.author): + if await self.profiles._get_auto_register(message.guild): + await self.profiles._register_user(message.author) + return + + elif await self.profiles._is_registered(message.author): + if message.content: + pre = await self.bot.get_valid_prefixes(message.guild) + for p in pre: + if message.content[: len(p)] == p: + return + timenow = datetime.datetime.now().timestamp() + lastmessage = await self.profiles._get_user_lastmessage(message.author) + cooldown = await self.profiles._get_cooldown(message.guild) + if timenow - lastmessage < cooldown: + # check if we've passed the cooldown + # return None if messages are sent too soon + return + mots = len(message.content.split(" ")) + if mots <= 10: + xp = 1 + elif mots > 10: + xp = 2 + oldlvl = await self.profiles._get_level(message.author) + await self.profiles._today_addone(message.author) + await self.profiles._give_exp(message.author, xp) + await self.profiles._set_user_lastmessage(message.author, timenow) + lvl = await self.profiles._get_level(message.author) + if lvl == oldlvl + 1 and await self.profiles.data.guild(message.guild).lvlup_announce(): + await message.channel.send(_("{} is now level {} !".format(message.author.mention, lvl))) + await self.profiles._check_exp(message.author) + await self.profiles._check_role_member(message.author) + + @commands.command() + @commands.guild_only() + async def register(self, ctx): + """Allow you to start earning experience !""" + if await self.profiles._is_registered(ctx.author): + await ctx.send(_("You are already registered !")) + return + else: + await self.profiles._register_user(ctx.author) + await ctx.send(_("You have been successfully registered !")) + return + + @commands.command() + @commands.guild_only() + async def toplevel(self, ctx): + """Show the server leaderboard !""" + ld = await self.profiles._get_leaderboard(ctx.guild) + emb = discord.Embed(title=_("Ranking")) + for i in range(len(ld)): + cur = ld[i] + user = ctx.guild.get_member(cur["id"]) + if user is None: + await self._reset_member(ctx.guild, cur["id"]) + else: + txt = ( + _("Level:") + " {} | {} XP | {} ".format(cur["lvl"], cur["xp"], cur["today"]) + _("Messages Today!") + ) + emb.add_field(name="{}".format(user.display_name), value=txt) + await ctx.send(embed=emb) + + @commands.group() + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def levelerset(self, ctx): + """Configuration commands.""" + pass + + @levelerset.group() + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def channel(self, ctx): + """Configure channels whitelist/blacklist.""" + pass + + @channel.group() + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def whitelist(self, ctx): + """Whitelist configuration.""" + pass + + @channel.group() + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def blacklist(self, ctx): + """Blacklist configuration.""" + pass + + @levelerset.group() + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def roles(self, ctx): + """Configuration of roles obtainable from experience.""" + pass + + @commands.group() + @commands.guild_only() + async def profileset(self, ctx): + """Change settings of your profile.""" + pass + + @profileset.command() + @commands.guild_only() + async def background(self, ctx, *, link: str = None): + """Change background image of your profile.""" + await self.profiles._set_background(ctx.author, link) + await ctx.send(_("Background image is now:") + str(link)) + + @profileset.command() + @commands.guild_only() + async def description(self, ctx, *, description: str = ""): + """Change your profile description""" + await self.profiles._set_description(ctx.author, description) + if description == "": + await ctx.send(_("Cleared profile description!")) + else: + await ctx.send(_("Profile description set to: ") + str(description)) + + @roles.command() + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def add(self, ctx, level: int, role: discord.Role): + """Add a role to be given at chosen level.""" + await self.profiles._add_guild_role(ctx.guild, level, role.id) + await ctx.send(_("Role configured")) + + @roles.command() + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def remove(self, ctx, role: discord.Role): + """Remove a role from the config.""" + if role.id in (await self.profiles._get_guild_roles(ctx.guild)).values(): + await self.profiles._remove_guild_role(ctx.guild, role) + await ctx.send(_("Role deleted.")) + else: + await ctx.send(_("Remove a role from the list.")) + + @roles.command() + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def show(self, ctx): + """Show the list of roles in the order which you get them from experience.""" + emb = discord.Embed() + emb.title = _("List of roles configured for this server.") + emb.description = _("Guaranteed 100% almost no bugs.") + tmp = 0 + emblist = [] + roles = await self.profiles._get_guild_roles(ctx.guild) + if len(roles) == 0: + await ctx.send(_("No roles yet configured for this guild !")) + return + for k, v in roles.items(): + try: + emb.add_field(name=str(k), value=discord.utils.get(ctx.guild.roles, id=v).name) + tmp += 1 + if tmp == 25: + emblist.append(emb) + emb = discord.Embed() + tmp = 0 + except: + # role no longer exists + pass + emblist.append(emb) if emb else emblist + await menu(ctx, emblist, DEFAULT_CONTROLS) + + @whitelist.command(name="add") + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def _add(self, ctx, channel: discord.TextChannel = None): + """Add a channel to the whitelist.""" + if channel is None: + channel = ctx.channel + if channel.id not in await self.profiles._get_guild_channels(ctx.guild): + await self.profiles._add_guild_channel(ctx.guild, channel.id) + await ctx.send(_("Channel added")) + else: + await ctx.send(_("Channel already whitelisted")) + + @whitelist.command(name="toggle") + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def toggle(self, ctx): + """Toggle whitelist on/off.""" + new = await self.profiles._toggle_whitelist(ctx.guild) + verb = _("activated.") if new else _("deactivated.") + await ctx.send(_("Whitelist is {verb}").format(verb=verb)) + + @whitelist.command(name="remove") + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def _remove(self, ctx, channel: discord.TextChannel = None): + """Delete a channel from the whitelist.""" + if channel is None: + channel = ctx.channel + if channel.id not in await self.profiles._get_guild_channels(ctx.guild): + await ctx.send(_("This channel isn't whitelisted.")) + else: + await self.profiles._remove_guild_channel(ctx.guild, channel.id) + await ctx.send(_("Channel deleted")) + + @whitelist.command(name="show") + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def _show(self, ctx): + """Show the list of channels configured to allow earning experience.""" + emb = discord.Embed() + emb.title = _("List of channels configured to allow earning experience on this server.") + emb.description = _("More or less, it's not an exact science") + channels = await self.profiles._get_guild_channels(ctx.guild) + if not len(channels): + return await ctx.send(_("No channels configured")) + emb.add_field(name="Channels:", value="\n".join([ctx.guild.get_channel(x).mention for x in channels])) + await ctx.send(embed=emb) + + @blacklist.command(name="add") + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def __add(self, ctx, channel: discord.TextChannel = None): + """Add a channel to the blacklist.""" + if channel is None: + channel = ctx.channel + if channel.id not in await self.profiles._get_guild_blchannels(ctx.guild): + await self.profiles._add_guild_blacklist(ctx.guild, channel.id) + await ctx.send(_("Channel blacklisted")) + else: + await ctx.send(_("Channel already blacklisted")) + + @blacklist.command(name="toggle") + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def _toggle(self, ctx): + """Toggle blacklist on/off.""" + new = await self.profiles._toggle_blacklist(ctx.guild) + verb = _("activated.") if new else _("deactivated.") + await ctx.send(_("Blacklist is {verb}").format(verb=verb)) + + @blacklist.command(name="remove") + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def __remove(self, ctx, channel: discord.TextChannel = None): + """Remove a channel from the blacklist.""" + if channel is None: + channel = ctx.channel + if channel.id not in await self.profiles._get_guild_blchannels(ctx.guild): + await ctx.send(_("This channel isn't whitelisted.")) + else: + await self.profiles._remove_guild_blacklist(ctx.guild, channel.id) + await ctx.send(_("Channel deleted")) + + @blacklist.command(name="show") + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def __show(self, ctx): + """Show the list of blacklisted channels.""" + emb = discord.Embed() + emb.title = _("List of blacklisted channels on this server.") + emb.description = _("More or less, it's not an exact science") + channels = await self.profiles._get_guild_blchannels(ctx.guild) + if not len(channels): + return await ctx.send(_("No channels configured")) + emb.add_field(name="Channels:", value="\n".join([ctx.guild.get_channel(x).mention for x in channels])) + await ctx.send(embed=emb) + + @levelerset.command() + @commands.guild_only() + async def autoregister(self, ctx): + """Toggle auto register of users""" + if await self.profiles._get_auto_register(ctx.guild): + await self.profiles._set_auto_register(ctx.guild, False) + await ctx.send(_("Auto register turned off")) + else: + await self.profiles._set_auto_register(ctx.guild, True) + await ctx.send(_("Auto register turned on")) + + @levelerset.command() + @commands.guild_only() + async def cooldown(self, ctx, cooldown: float): + """Modify the cooldown of xp gain, default to 60 seconds""" + await self.profiles._set_cooldown(ctx.guild, cooldown) + await ctx.send(_("Cooldown is now: ") + str(cooldown)) + + @levelerset.command() + @checks.is_owner() + @commands.guild_only() + async def setlevel(self, ctx, level: int, member: discord.Member = None): + """Modify an user's level""" + if member is None: + member = ctx.message.author + if await self.profiles._is_registered(member): + await self.profiles._set_exp(member, 5 * ((level - 1) ** 2) + (50 * (level - 1)) + 100) + else: + await ctx.send(_("That user is not registered.")) + await ctx.send(member.name + _(" Level set to ") + str(level)) + + @levelerset.command() + @checks.is_owner() + @commands.guild_only() + async def setxp(self, ctx, xp: int, member: discord.Member = None): + """Modify an user's xp.""" + if member is None: + member = ctx.message.author + if await self.profiles._is_registered(member): + await self.profiles._set_exp(member, xp) + else: + await ctx.send(_("That user is not registered.")) + await ctx.send(member.name + _("'s XP set to ") + str(xp)) + + @levelerset.command() + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def defaultbackground(self, ctx, url): + """Allow you to set a default background for your server members.""" + bg = re.findall(r"(?:http\:|https\:)?\/\/.*\.(?:png|jpg|gif)", url) + if not bg: + await ctx.send(_("Please give a direct link to an image on format png, jpg or gif !")) + else: + background = bg[0] + await self.profiles._set_guild_background(ctx.guild, background) + await ctx.send(f"Default background set to {background}.") + + @roles.command(name="defaultrole") + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def default_role(self, ctx, *, name): + """Allow you to rename default role for your guild.""" + await self.profiles.data.guild(ctx.author.guild).defaultrole.set(name) + await ctx.send(_(f"Default role name set to {name}")) + + @levelerset.command() + @checks.mod_or_permissions(manage_messages=True) + @commands.guild_only() + async def announce(self, ctx, status: bool): + """Toggle whether the bot will announce levelups. + args are True/False.""" + await self.profiles.data.guild(ctx.guild).lvlup_announce.set(status) + await ctx.send(_("Levelup announce is now {}.").format(_("enabled") if status else _("disabled"))) diff --git a/Leveler/locales/en-US.po b/Leveler/locales/en-US.po new file mode 100644 index 0000000..63116af --- /dev/null +++ b/Leveler/locales/en-US.po @@ -0,0 +1,297 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2018-12-27 17:34+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=cp1252\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: redgettext 2.1\n" + + +#: leveler.py:95 +msgid "Reset dans max 30 secondes" +msgstr "Resets in 30 seconds max" + +#: leveler.py:161 +msgid "Niveau:" +msgstr "Level:" + +#: leveler.py:162 +msgid "Classement:" +msgstr "Ranking:" + +#: leveler.py:163 +msgid "Elo:" +msgstr "Role:" + +#: leveler.py:164 +msgid "Le progrès:" +msgstr "Progress" + +#: leveler.py:211 leveler.py:230 +msgid "Nouveau" +msgstr "New" + +#: leveler.py:241 +#, docstring +msgid "Affiche la progression sur le Leveler. Defaut a soi-même s'il n'y a pas de tag après la commande." +msgstr "Show your leveler progress. Default to yourself." + +#: leveler.py:314 +#, docstring +msgid "Vous permets de commencer a gagner de l'expérience !" +msgstr "Allow you to start earning experience." + +#: leveler.py:316 +msgid "Vous êtes déjà enregistré !" +msgstr "You are already registered !" + +#: leveler.py:320 +msgid "Vous avez été enregistré avec succés !" +msgstr "You have been successfully registered !" + +#: leveler.py:325 +#, docstring +msgid "Affiche le classement des meilleures blablateurs !" +msgstr "Show the server leaderboard." + +#: leveler.py:327 +msgid "Le classement des PGM !" +msgstr "Ranking" + +#: leveler.py:334 +msgid "Niveau" +msgstr "Level" + +#: leveler.py:334 +msgid "Messages Today!" +msgstr "Messages Today!" + +#: leveler.py:341 +#, docstring +msgid "Commandes de configuration." +msgstr "Configuration commands" + +#: leveler.py:347 +#, docstring +msgid "Configuration des channels permettant de gagner de l'expérience." +msgstr "Configure channels whitelist/blacklist." + +#: leveler.py:353 +#, docstring +msgid "Configuration des channels whitelistés" +msgstr "Whitelist configuration." + +#: leveler.py:359 +#, docstring +msgid "Configuration des channels blacklistés" +msgstr "Blacklist configuration." + +#: leveler.py:365 +#, docstring +msgid "Configuration des roles obtenables grâce à l'expérience." +msgstr "Configuration of roles obtainable from experience." + +#: leveler.py:370 +#, docstring +msgid "Définir divers paramètres de profil" +msgstr "Change settings of your profile." + +#: leveler.py:375 +#, docstring +msgid "Définir l'image de fond du profil" +msgstr "Change background image of your profile." + +#: leveler.py:377 +msgid "Profil de fond défini sur: " +msgstr "Background image is now:" + +#: leveler.py:381 +#, docstring +msgid "Définir la description du profil" +msgstr "Change your profile description." + +#: leveler.py:383 +msgid "Description du profil définie sur: " +msgstr "Profile description set to:" + +#: leveler.py:388 +#, docstring +msgid "Ajoute un role a la liste des roles obtenables grâce à l'expérience." +msgstr "Add a role to the list of roles you can get with experience." + +#: leveler.py:390 +msgid "Role configuré" +msgstr "Role configured." + +#: leveler.py:395 +#, docstring +msgid "Supprime un role de la liste des roles obtenables grâce à l'expérience." +msgstr "Remove a role from the whitelist." + +#: leveler.py:398 +msgid "Role supprimé" +msgstr "Role deleted." + +#: leveler.py:400 leveler.py:410 +msgid "Role inconnu dans la config" +msgstr "Remove a role from the list." + +#: leveler.py:405 +#, docstring +msgid "Permet de déplacer un role, modifiant l'expérience necessaire pour l'obtenir." +msgstr "Allow you to move a role." + +#: leveler.py:408 +msgid "Role déplacé" +msgstr "Role moved" + +#: leveler.py:415 +#, docstring +msgid "Affiche la liste des roles dans l'ordre auquel ils sont obtenables." +msgstr "Show the list of roles in the order which you get them from experience." + +#: leveler.py:417 +msgid "Liste des roles configurés pour le leveler de ce serveur." +msgstr "List of roles configured for this server." + +#: leveler.py:418 +msgid "Garanti 100% presque pas bugué." +msgstr "Guaranteed 100% almost no bugs." + +#: leveler.py:429 +#, docstring +msgid "Ajoute un channel, permettant aux utilisateurs de gagner de l'expérience lorsqu'ils parlent dans ce channel là." +msgstr "Add a channel to the whitelist." + +#: leveler.py:434 +msgid "Channel ajouté" +msgstr "Channel added" + +#: leveler.py:436 +msgid "Channel déjà enregistré" +msgstr "Channel already whitelisted" + +#: leveler.py:447 +#, docstring +msgid "Supprime un channel, les utilisateurs qui y parleront ne gagneront ainsi plus d'expérience." +msgstr "Delete a channel from the whitelist." + +#: leveler.py:451 leveler.py:493 +msgid "Ce channel n'est pas dans la liste configurée." +msgstr "This channel isn't whitelisted" + +#: leveler.py:454 leveler.py:496 +msgid "Channel supprimé" +msgstr "Channel deleted" + +#: leveler.py:459 +#, docstring +msgid "Affiche la liste des channels configurés pour donner de l'expérience." +msgstr "Show the list of channels configured to allow earning experience." + +#: leveler.py:461 +msgid "Liste des channels autorisés a faire gagner de l'experience sur ce serveur." +msgstr "List of channels configured to allow earning experience on this server." + +#: leveler.py:462 leveler.py:506 +msgid "A une vache près, c'pas une science exacte" +msgstr "More or less, it's not an exact science" + +#: leveler.py:465 leveler.py:509 +msgid "Aucun channel configuré" +msgstr "No channels configured" + +#: leveler.py:473 +#, docstring +msgid "Ajoute un channel à ignorer dans le gain d'xp." +msgstr "Add a channel to the blacklist." + +#: leveler.py:478 +msgid "Channel ignoré" +msgstr "Channel blacklisted" + +#: leveler.py:480 +msgid "Channel déjà ignoré" +msgstr "Channel already blacklisted" + +#: leveler.py:491 +#, docstring +msgid "Supprime un channel, les utilisateurs qui y parleront gagneront ainsi de l'expérience." +msgstr "Remove a channel from the blacklist." + +#: leveler.py:503 +#, docstring +msgid "Affiche la liste des channels configurés pour être ignorés." +msgstr "Show the list of blacklisted channels." + +#: leveler.py:505 +msgid "Liste des channels non autorisés a faire gagner de l'experience sur ce serveur." +msgstr "List of blacklisted channels on this server." + +#: leveler.py:509 +msgid "Aucun channel configuré" +msgstr "No channel set" + +#: leveler.py:515 +#, docstring +msgid "Bascule l'enregistrement automatique des utilisateurs" +msgstr "Toggle auto register of users" + +#: leveler.py:518 +msgid "Enregistrement automatique dêsactivê" +msgstr "Auto register turned off" + +#: leveler.py:521 +msgid "Enregistrement automatique activê" +msgstr "Auto register turned on" + +#: leveler.py:525 +#, docstring +msgid "Définir le temps de recharge pour le gain xp, la valeur par défaut est 60 secondes" +msgstr "Modify the cooldown of xp gain, default to 60 seconds." + +#: leveler.py:527 +msgid "Le temps de recharge est réglé sur: " +msgstr "Cooldown is now:" + +#: leveler.py:532 +#, docstring +msgid "Définir un niveau de membres, principalement pour les tests" +msgstr "Modify an user's level." + +#: leveler.py:536 +msgid " niveau réglé à " +msgstr "Level set to:" + +#: leveler.py:541 +#, docstring +msgid "définir un membre xp, principalement pour les tests" +msgstr "Modify an user's xp." + +#: leveler.py:545 +msgid " xp mis à" +msgstr "XP set to:" + +#: leveler.py:460 +msgid "La whitelist est désormais {verb}" +msgstr "Whitelist is {verb}" + +#: leveler.py:505 +msgid "La blacklist est désormais {verb}" +msgstr "Blacklist is {verb}" + +#: leveler.py:459 leveler.py:504 +msgid "activée." +msgstr "activated." + +#: leveler.py:459 leveler.py:504 +msgid "désactivée." +msgstr "deactivated." diff --git a/Leveler/locales/fr-FR.po b/Leveler/locales/fr-FR.po new file mode 100644 index 0000000..10941ab --- /dev/null +++ b/Leveler/locales/fr-FR.po @@ -0,0 +1,294 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2019-01-18 18:48+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=cp1252\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: redgettext 2.1\n" + + +#: leveler.py:95 +msgid "Resets in 30 seconds max" +msgstr "Réintialisation dans 30 secondes max" + +#: leveler.py:175 leveler.py:349 +msgid "Level:" +msgstr "Niveau:" + +#: leveler.py:176 +msgid "Ranking:" +msgstr "Classement:" + +#: leveler.py:177 +msgid "Role:" +msgstr "Rôle:" + +#: leveler.py:178 +msgid "Progress:" +msgstr "Progres:" + +#: leveler.py:223 leveler.py:242 +msgid "New" +msgstr "Nouveau" + +#: leveler.py:253 +#, docstring +msgid "Show your leveler progress. Default to yourself." +msgstr "Affiche votre progression sur le Leveler. Par défaut le vôtre." + +#: leveler.py:329 +#, docstring +msgid "Allow you to start earning experience !" +msgstr "Vous permet de commencer à gagner de l'expérience !" + +#: leveler.py:331 +msgid "You are already registered !" +msgstr "Vous êtes déjà enregistré !" + +#: leveler.py:335 +msgid "You have been successfully registered !" +msgstr "Vous avez bien été enregistré !" + +#: leveler.py:340 +#, docstring +msgid "Show the server leaderboard !" +msgstr "Affiche le classement du serveur !" + +#: leveler.py:342 +msgid "Ranking" +msgstr "Classement" + +#: leveler.py:351 +msgid "Messages Today!" +msgstr "Messages Aujourd'hui !" + +#: leveler.py:358 +#, docstring +msgid "Configuration commands." +msgstr "Commande de configuration." + +#: leveler.py:364 +#, docstring +msgid "Configure channels whitelist/blacklist." +msgstr "Cofiguration des salons whitelist/blacklist" + +#: leveler.py:370 +#, docstring +msgid "Whitelist configuration." +msgstr "Configuration de la whitelist." + +#: leveler.py:376 +#, docstring +msgid "Blacklist configuration." +msgstr "Configuration de la blacklist." + +#: leveler.py:382 +#, docstring +msgid "Configuration of roles obtainable from experience." +msgstr "Configuration des rôles obtenables grâce depuis l'expérience." + +#: leveler.py:387 +#, docstring +msgid "Change settings of your profile." +msgstr "Permet de personnaliser votre profil." + +#: leveler.py:392 +#, docstring +msgid "Change background image of your profile." +msgstr "Modifie l'arrière-plan de votre profil." + +#: leveler.py:394 +msgid "Background image is now:" +msgstr "Votre arrière-plan est maintenant:" + +#: leveler.py:398 +#, docstring +msgid "Change your profile description" +msgstr "Modifie la description de votre profil" + +#: leveler.py:400 +msgid "Profile description set to: " +msgstr "Description du profil modifié en :" + +#: leveler.py:405 +#, docstring +msgid "Add a role to the list of roles you can get with experience." +msgstr "Ajoute un rôle a la liste des rôles obtenable avec l'expérience." + +#: leveler.py:407 +msgid "Role configured" +msgstr "Rôle configuré" + +#: leveler.py:412 +#, docstring +msgid "Remove a role from the config." +msgstr "Supprime un rôle de la configuration." + +#: leveler.py:415 +msgid "Role deleted." +msgstr "Rôle supprimé." + +#: leveler.py:417 +msgid "Remove a role from the list." +msgstr "Supprime un rôle de la liste." + +#: leveler.py:422 +#, docstring +msgid "Allow you to move a role." +msgstr "Vous permet de déplacer un role." + +#: leveler.py:425 +msgid "Role moved" +msgstr "Role déplacé" + +#: leveler.py:427 +msgid "Remove a role from the list" +msgstr "Supprime un role de la liste" + +#: leveler.py:432 +#, docstring +msgid "Show the list of roles in the order which you get them from experience." +msgstr "Affiche la liste des roles configurés dans l'ordre ou ils sont obtenables." + +#: leveler.py:434 +msgid "List of roles configured for this server." +msgstr "Liste des roles configurés pour ce serveur." + +#: leveler.py:435 +msgid "Guaranteed 100% almost no bugs." +msgstr "Garanti presque pas bugué." + +#: leveler.py:446 +#, docstring +msgid "Add a channel to the whitelist." +msgstr "Ajoute un channel a la whitelist." + +#: leveler.py:451 +msgid "Channel added" +msgstr "Channel ajouté." + +#: leveler.py:453 +msgid "Channel already whitelisted" +msgstr "Channel deja whitelisté" + +#: leveler.py:459 leveler.py:504 +msgid "activated." +msgstr "activé" + +#: leveler.py:459 leveler.py:504 +msgid "deactivated." +msgstr "désactivé" + +#: leveler.py:460 +msgid "Whitelist is {verb}" +msgstr "La whitelist est maintenant {verb}" + +#: leveler.py:465 +#, docstring +msgid "Delete a channel from the whitelist." +msgstr "Supprime un channel de la whitelist" + +#: leveler.py:469 leveler.py:514 +msgid "This channel isn't whitelisted." +msgstr "Ce channel n'est pas whitelisté." + +#: leveler.py:472 leveler.py:517 +msgid "Channel deleted" +msgstr "Channel supprimé" + +#: leveler.py:477 +#, docstring +msgid "Show the list of channels configured to allow earning experience." +msgstr "Affiche la liste des channels whitelistés." + +#: leveler.py:479 +msgid "List of channels configured to allow earning experience on this server." +msgstr "Liste des channels whitelistés." + +#: leveler.py:480 leveler.py:525 +msgid "More or less, it's not an exact science" +msgstr "A une vache près, c'est pas une science exacte." + +#: leveler.py:483 leveler.py:528 +msgid "No channels configured" +msgstr "Aucun channel configuré" + +#: leveler.py:491 +#, docstring +msgid "Add a channel to the blacklist." +msgstr "Ajoute un channel à la blacklist." + +#: leveler.py:496 +msgid "Channel blacklisted" +msgstr "Channel blacklisté" + +#: leveler.py:498 +msgid "Channel already blacklisted" +msgstr "Channel deja blacklisté" + +#: leveler.py:505 +msgid "Blacklist is {verb}" +msgstr "La blacklist est maintenant {verb}" + +#: leveler.py:510 +#, docstring +msgid "Remove a channel from the blacklist." +msgstr "Supprime un channel de la blacklist." + +#: leveler.py:522 +#, docstring +msgid "Show the list of blacklisted channels." +msgstr "Affiche la liste des channels blacklistés." + +#: leveler.py:524 +msgid "List of blacklisted channels on this server." +msgstr "Liste des channels blacklistés sur ce serveur." + +#: leveler.py:534 +#, docstring +msgid "Toggle auto register of users" +msgstr "Active/désactive l'enregistrement automatique des utilisateurs" + +#: leveler.py:537 +msgid "Auto register turned off" +msgstr "Enregistrement automatique désactivé" + +#: leveler.py:540 +msgid "Auto register turned on" +msgstr "Enregistrement automatique activé" + +#: leveler.py:544 +#, docstring +msgid "Modify the cooldown of xp gain, default to 60 seconds" +msgstr "Modifie le cooldown entre 2 gains d'XP, par défaut 60 secondes" + +#: leveler.py:546 +msgid "Cooldown is now: " +msgstr "Le cooldown est maintenant réglé sur: " + +#: leveler.py:551 +#, docstring +msgid "Modify an user's level" +msgstr "Modifie le niveau d'un utilisateur" + +#: leveler.py:555 +msgid " Level set to " +msgstr " est maintenant niveau " + +#: leveler.py:560 +#, docstring +msgid "Modify an user's xp." +msgstr "Modifie l'XP d'un utilisateur" + +#: leveler.py:564 +msgid "'s XP set to " +msgstr " a maintenant une XP de " + diff --git a/Leveler/locales/nl-NL.po b/Leveler/locales/nl-NL.po new file mode 100644 index 0000000..ce6a064 --- /dev/null +++ b/Leveler/locales/nl-NL.po @@ -0,0 +1,297 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2018-12-27 17:34+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=cp1252\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: redgettext 2.1\n" + + +#: leveler.py:95 +msgid "Reset dans max 30 secondes" +msgstr "Resetten in maximaal 30 seconden" + +#: leveler.py:161 +msgid "Niveau:" +msgstr "Level:" + +#: leveler.py:162 +msgid "Classement:" +msgstr "Ranking:" + +#: leveler.py:163 +msgid "Elo:" +msgstr "Rol:" + +#: leveler.py:164 +msgid "Le progrès:" +msgstr "Progressie" + +#: leveler.py:211 leveler.py:230 +msgid "Nouveau" +msgstr "Nieuw" + +#: leveler.py:241 +#, docstring +msgid "Affiche la progression sur le Leveler. Defaut a soi-même s'il n'y a pas de tag après la commande." +msgstr "Toon de voortgang van je leveller. Standaard voor jezelf." + +#: leveler.py:314 +#, docstring +msgid "Vous permets de commencer a gagner de l'expérience !" +msgstr "Hiermee kan je beginnen punten te verdienen." + +#: leveler.py:316 +msgid "Vous êtes déjà enregistré !" +msgstr "Je bent al geregistreerd!" + +#: leveler.py:320 +msgid "Vous avez été enregistré avec succés !" +msgstr "Je bent succesvol geregistreerd!" + +#: leveler.py:325 +#, docstring +msgid "Affiche le classement des meilleures blablateurs !" +msgstr "Toon de server leaderboard." + +#: leveler.py:327 +msgid "Le classement des PGM !" +msgstr "Ranking" + +#: leveler.py:334 +msgid "Niveau" +msgstr "Level" + +#: leveler.py:334 +msgid "Messages Today!" +msgstr "Berichten vandaag!" + +#: leveler.py:341 +#, docstring +msgid "Commandes de configuration." +msgstr "Configuratie opdrachten." + +#: leveler.py:347 +#, docstring +msgid "Configuration des channels permettant de gagner de l'expérience." +msgstr "Configureer kanalen witte lijst / zwarte lijst." + +#: leveler.py:353 +#, docstring +msgid "Configuration des channels whitelistés" +msgstr "Witte lijst configuratie" + +#: leveler.py:359 +#, docstring +msgid "Configuration des channels blacklistés" +msgstr "Zwarte lijst configuratie" + +#: leveler.py:365 +#, docstring +msgid "Configuration des roles obtenables grâce à l'expérience." +msgstr "Configuratie van rollen verkrijgbaar uit punten." + +#: leveler.py:370 +#, docstring +msgid "Définir divers paramètres de profil" +msgstr "Verander je profielinstellingen" + +#: leveler.py:375 +#, docstring +msgid "Définir l'image de fond du profil" +msgstr "Verander je profiel achtergrondafbeelding." + +#: leveler.py:377 +msgid "Profil de fond défini sur: " +msgstr "Achtergrondafbeelding is nu:" + +#: leveler.py:381 +#, docstring +msgid "Définir la description du profil" +msgstr "Wijzig je profielbeschrijving." + +#: leveler.py:383 +msgid "Description du profil définie sur: " +msgstr "Profielbeschrijving ingesteld op:" + +#: leveler.py:388 +#, docstring +msgid "Ajoute un role a la liste des roles obtenables grâce à l'expérience." +msgstr "Voeg een rol toe aan de lijst met rollen die je kan krijgen met punten." + +#: leveler.py:390 +msgid "Role configuré" +msgstr "Rol ingesteld." + +#: leveler.py:395 +#, docstring +msgid "Supprime un role de la liste des roles obtenables grâce à l'expérience." +msgstr "Verwijder een rol van de witte lijst." + +#: leveler.py:398 +msgid "Role supprimé" +msgstr "Rol verwijderd." + +#: leveler.py:400 leveler.py:410 +msgid "Role inconnu dans la config" +msgstr "Verwijder een rol van de lijst." + +#: leveler.py:405 +#, docstring +msgid "Permet de déplacer un role, modifiant l'expérience necessaire pour l'obtenir." +msgstr "Hiermee kan je een rol verplaatsen." + +#: leveler.py:408 +msgid "Role déplacé" +msgstr "Rol verplaatst" + +#: leveler.py:415 +#, docstring +msgid "Affiche la liste des roles dans l'ordre auquel ils sont obtenables." +msgstr "Toon de lijst met rollen in de volgorde hoe je ze krijgt met punten." + +#: leveler.py:417 +msgid "Liste des roles configurés pour le leveler de ce serveur." +msgstr "Lijst met rollen geconfigureerd voor deze server." + +#: leveler.py:418 +msgid "Garanti 100% presque pas bugué." +msgstr "Bijna geen bugs!" + +#: leveler.py:429 +#, docstring +msgid "Ajoute un channel, permettant aux utilisateurs de gagner de l'expérience lorsqu'ils parlent dans ce channel là." +msgstr "Voeg een kanaal toe aan de witte lijst." + +#: leveler.py:434 +msgid "Channel ajouté" +msgstr "Kanaal toegevoegd" + +#: leveler.py:436 +msgid "Channel déjà enregistré" +msgstr "Kanaal staat al op de witte lijst" + +#: leveler.py:447 +#, docstring +msgid "Supprime un channel, les utilisateurs qui y parleront ne gagneront ainsi plus d'expérience." +msgstr "Verwijder een kanaal van de witte lijst." + +#: leveler.py:451 leveler.py:493 +msgid "Ce channel n'est pas dans la liste configurée." +msgstr "Dit kanaal staat niet op de witte lijst" + +#: leveler.py:454 leveler.py:496 +msgid "Channel supprimé" +msgstr "Kanaal verwijderd" + +#: leveler.py:459 +#, docstring +msgid "Affiche la liste des channels configurés pour donner de l'expérience." +msgstr "Toon de lijst met kanalen die zijn geconfigureerd om punten verdiening mogelijk te maken." + +#: leveler.py:461 +msgid "Liste des channels autorisés a faire gagner de l'experience sur ce serveur." +msgstr "Lijst met kanalen die zijn geconfigureerd om ervaring op deze server punten te verdienen." + +#: leveler.py:462 leveler.py:506 +msgid "A une vache près, c'pas une science exacte" +msgstr "Het is min of meer geen exacte wetenschap." + +#: leveler.py:465 leveler.py:509 +msgid "Aucun channel configuré" +msgstr "Geen kanalen ingesteld." + +#: leveler.py:473 +#, docstring +msgid "Ajoute un channel à ignorer dans le gain d'xp." +msgstr "Voeg een kanaal toe aan de zwarte lijst." + +#: leveler.py:478 +msgid "Channel ignoré" +msgstr "Kanaal toegevoegd aan zwarte lijst." + +#: leveler.py:480 +msgid "Channel déjà ignoré" +msgstr "Kanaal staat al op de zwarte lijst." + +#: leveler.py:491 +#, docstring +msgid "Supprime un channel, les utilisateurs qui y parleront gagneront ainsi de l'expérience." +msgstr "Verwijder een kanaal van de zwarte lijst." + +#: leveler.py:503 +#, docstring +msgid "Affiche la liste des channels configurés pour être ignorés." +msgstr "Toon kanalen van de zwarte lijst." + +#: leveler.py:505 +msgid "Liste des channels non autorisés a faire gagner de l'experience sur ce serveur." +msgstr "Lijst van kanalen op de zwarte lijst in deze server." + +#: leveler.py:509 +msgid "Aucun channel configuré" +msgstr "Geen kanaal ingesteld." + +#: leveler.py:515 +#, docstring +msgid "Bascule l'enregistrement automatique des utilisateurs" +msgstr "Schakel automatisch register van gebruikers in." + +#: leveler.py:518 +msgid "Enregistrement automatique dêsactivê" +msgstr "Auto register uitgeschakeld" + +#: leveler.py:521 +msgid "Enregistrement automatique activê" +msgstr "Auto register ingeschakeld" + +#: leveler.py:525 +#, docstring +msgid "Définir le temps de recharge pour le gain xp, la valeur par défaut est 60 secondes" +msgstr "Wijzig de cooldown van xp verdiensten, standaard op 60 seconden." + +#: leveler.py:527 +msgid "Le temps de recharge est réglé sur: " +msgstr "Cooldown is nu:" + +#: leveler.py:532 +#, docstring +msgid "Définir un niveau de membres, principalement pour les tests" +msgstr "Pas level aan van gebruiker." + +#: leveler.py:536 +msgid " niveau réglé à " +msgstr "Level ingesteld op:" + +#: leveler.py:541 +#, docstring +msgid "définir un membre xp, principalement pour les tests" +msgstr "Pas gebruikers xp aan." + +#: leveler.py:545 +msgid " xp mis à" +msgstr "XP ingesteld op:" + +#: leveler.py:460 +msgid "La whitelist est désormais {verb}" +msgstr "Witte lijst is {verb}" + +#: leveler.py:505 +msgid "La blacklist est désormais {verb}" +msgstr "Zwarte lijst is {verb}" + +#: leveler.py:459 leveler.py:504 +msgid "activée." +msgstr "ingeschakeld." + +#: leveler.py:459 leveler.py:504 +msgid "désactivée." +msgstr "uitgeschakeld." diff --git a/Leveler/userprofile.py b/Leveler/userprofile.py new file mode 100644 index 0000000..78e0222 --- /dev/null +++ b/Leveler/userprofile.py @@ -0,0 +1,233 @@ +from redbot.core import Config +import asyncio +import discord + + +class UserProfile: + def __init__(self): + self.data = Config.get_conf(self, identifier=1099710897114110101) + default_guild = { + "wlchannels": [], + "blchannels": [], + "defaultrole": None, + "defaultbg": None, + "roles": {}, + "database": [], + "autoregister": False, + "cooldown": 60.0, + "whitelist": True, + "blacklist": False, + "lvlup_announce": False, + } + default_member = {"exp": 0, "level": 1, "today": 0, "lastmessage": 0.0, "background": None, "description": ""} + self.data.register_member(**default_member) + self.data.register_guild(**default_guild) + + @staticmethod + def level_func(curr_level: int): + return 5 * ((curr_level - 1) ** 2) + (50 * (curr_level - 1)) + 50 + + async def _set_guild_background(self, guild, bg): + await self.data.guild(guild).defaultbg.set(bg) + + async def _give_exp(self, member, exp): + current = await self.data.member(member).exp() + await self.data.member(member).exp.set(current + exp) + await self._check_exp(member) + + async def _set_exp(self, member, exp): + await self.data.member(member).exp.set(exp) + await self._check_exp(member) + + async def _set_level(self, member, level): + await self.data.member(member).level.set(level) + + async def _is_registered(self, member): + async with self.data.guild(member.guild).database() as db: + return member.id in db + + async def _register_user(self, member): + data = await self.data.guild(member.guild).database() + if data is None: + await self.data.guild(member.guild).database.set([]) + async with self.data.guild(member.guild).database() as db: + db.append(member.id) + await self.data.member(member).exp.set(0) + + async def _set_user_lastmessage(self, member, lastmessage: float): + await self.data.member(member).lastmessage.set(lastmessage) + + async def _get_user_lastmessage(self, member): + return await self.data.member(member).lastmessage() + + async def _downgrade_level(self, member): + lvl = await self.data.member(member).level() + pastlvl = self.level_func(lvl - 1) + xp = await self.data.member(member).exp() + while xp < pastlvl and not lvl <= 1: + lvl -= 1 + pastlvl = self.level_func(lvl) + await self.data.member(member).level.set(lvl) + + async def _check_exp(self, member): + lvl = await self.data.member(member).level() + lvlup = self.level_func(lvl) + xp = await self.data.member(member).exp() + if xp >= lvlup: + lvl += 1 + await self.data.member(member).level.set(lvl) + lvlup = self.level_func(lvl) + if xp >= lvlup: + await self._check_exp(member) + elif xp < lvlup and lvl > 1: + await self._downgrade_level(member) + + async def _check_role_member(self, member): + roles = await self.data.guild(member.guild).roles() + lvl = await self.data.member(member).level() + for k, v in roles.items(): + if lvl == int(k): + rl = discord.utils.get(member.guild.roles, id=v) + # TODO: remove after purge + ids = {r.id for r in member.roles} + if ( + rl in member.roles + or 508505296797171713 in ids + or 532720959824592917 in ids + or 508497255838253077 in ids + ): + return True + else: + await member.add_roles(rl) + return True + else: + pass + return False + + async def _add_guild_role(self, guild, level, roleid): + role = discord.utils.get(guild.roles, id=roleid) + if role is None: + return False + rl = await self.data.guild(guild).roles() + if isinstance(rl, list): + rl = {} + rl.update({str(level): roleid}) + await self.data.guild(guild).roles.set(rl) + + async def _remove_guild_role(self, guild, role): + rolelist = await self.data.guild(guild).roles() + for k, v in rolelist.items(): + if v == role.id: + del rolelist[k] + await self.data.guild(guild).roles.set(rolelist) + return + + async def _get_guild_roles(self, guild): + return await self.data.guild(guild).roles() + + async def _add_guild_channel(self, guild, channel): + async with self.data.guild(guild).wlchannels() as chanlist: + chanlist.append(channel) + + async def _remove_guild_channel(self, guild, channel): + async with self.data.guild(guild).wlchannels() as chanlist: + chanlist.remove(channel) + + async def _get_guild_channels(self, guild): + return await self.data.guild(guild).wlchannels() + + async def _add_guild_blacklist(self, guild, channel): + async with self.data.guild(guild).blchannels() as chanlist: + chanlist.append(channel) + + async def _remove_guild_blacklist(self, guild, channel): + async with self.data.guild(guild).blchannels() as chanlist: + chanlist.remove(channel) + + async def _get_guild_blchannels(self, guild): + return await self.data.guild(guild).blchannels() + + async def _toggle_whitelist(self, guild): + wl = await self.data.guild(guild).whitelist() + if wl: + await self.data.guild(guild).whitelist.set(False) + return False + else: + await self.data.guild(guild).whitelist.set(True) + return True + + async def _toggle_blacklist(self, guild): + bl = await self.data.guild(guild).blacklist() + if bl: + await self.data.guild(guild).blacklist.set(False) + return False + else: + await self.data.guild(guild).blacklist.set(True) + return True + + async def _get_exp(self, member): + return await self.data.member(member).exp() + + async def _get_level(self, member): + return await self.data.member(member).level() + + async def _get_level_exp(self, member): + lvl = await self.data.member(member).level() + return self.level_func(lvl) + + async def _get_today(self, member): + return await self.data.member(member).today() + + async def _today_addone(self, member): + await self.data.member(member).today.set(await self._get_today(member) + 1) + + async def _set_auto_register(self, guild, autoregister: bool): + await self.data.guild(guild).autoregister.set(autoregister) + + async def _get_auto_register(self, guild): + return await self.data.guild(guild).autoregister() + + async def _set_cooldown(self, guild, cooldown: float): + await self.data.guild(guild).cooldown.set(cooldown) + + async def _get_cooldown(self, guild): + return await self.data.guild(guild).cooldown() + + async def _set_background(self, member, background): + await self.data.member(member).background.set(background) + + async def _get_background(self, member): + userbg = await self.data.member(member).background() + if userbg is None: + return await self.data.guild(member.guild).defaultbg() + else: + return userbg + + async def _set_description(self, member, description: str): + await self.data.member(member).description.set(description) + + async def _get_description(self, member): + return await self.data.member(member).description() + + async def _get_leaderboard_pos(self, guild, member): + datas = await self.data.all_members(guild) + infos = sorted(datas, key=lambda x: datas[x]["exp"], reverse=True) + return infos.index(member.id) + 1 + + async def _get_leaderboard(self, guild): + datas = await self.data.all_members(guild) + infos = sorted(datas, key=lambda x: datas[x]["exp"], reverse=True) + res = [] + count = 1 + for i in infos: + tmp = {} + tmp["id"] = i + cur = datas[i] + tmp["xp"] = cur["exp"] + tmp["lvl"] = cur["level"] + tmp["today"] = cur["today"] + res.append(tmp) + count += 1 + if count == 10: + break + return res