Example #1
0
    def index(self, code, state):
        user = User(**self.serializer.loads(state, max_age=300))

        evesso = OAuth2Session(settings.CLIENT_ID)
        token = evesso.fetch_token(settings.TOKEN_URL,
                                   authorization_response=cherrypy.request.base + cherrypy.request.path_info + "?" + cherrypy.request.query_string,
                                   state=state, method="POST", client_secret=settings.SECRET_KEY)

        r = evesso.get(settings.VERIFY_URL)
        userdata = r.json()

        if userdata['CharacterName']:
            server = self.discord_client.servers[0]
            assert isinstance(server, Server)
            member = find(lambda m: m.id == user.id, server.members)
            assert isinstance(member, Member)
            role = find(lambda r: r.name == 'Capsuleer', server.roles)
            assert isinstance(role, Role)

            self.discord_client.add_roles(member, role)
            self.discord_client.send_message(member, "Welcome %s! You should no be able to switch channels." % userdata[
                'CharacterName'])

            # self.discord_client.send_message(user, "Found you!")
            return "Welcome %s! You can now close this window." % userdata['CharacterName']

        return "Unknown Error."
Example #2
0
    async def weeb(self, ctx):
        """ Weeb is a lifestyle chosen once... Then stuck with you forever... """
        weeb = find(lambda r: r.name == "Weeb", ctx.message.server.roles)
        if weeb in ctx.message.author.roles:
            return

        normie = find(lambda r: r.name == "Normies", ctx.message.server.roles)
        await self.bot.add_roles(ctx.message.author, weeb)
        await self.bot.remove_roles(ctx.message.author, normie)
Example #3
0
async def join(con, *, channel=None):
    """JOIN A VOICE CHANNEL THAT THE USR IS IN OR MOVE TO A VOICE CHANNEL IF THE BOT IS ALREADY IN A VOICE CHANNEL"""

    # COMMAND IS IN DM
    if con.message.channel.is_private == True:
        await bot.send_message(con.message.channel, "**You must be in a `server text channel` to use this command**")

    # COMMAND NOT IN DM
    if con.message.channel.is_private == False:
        voice_status = bot.is_voice_connected(con.message.server)

        voice = find(lambda m: m.name == channel, con.message.server.channels)

        if voice_status == False and channel == None:  # VOICE NOT CONNECTED
            if con.message.author.voice_channel == None:
                await bot.send_message(con.message.channel, "**You must be in a voice channel or give a voice channel name to join**")
            if con.message.author.voice_channel != None:
                await bot.join_voice_channel(con.message.author.voice.voice_channel)

        if voice_status == False and channel != None:  # PICKING A VOICE CHANNEL
            await bot.join_voice_channel(voice)

        if voice_status == True:  # VOICE ALREADY CONNECTED
            if voice == None:
                await bot.send_message(con.message.channel, "**Bot is already connected to a voice channel**")

            if voice != None:
                if voice.type == discord.ChannelType.voice:
                    await bot.voice_client_in(con.message.server).move_to(voice)
Example #4
0
 async def bdo(self, ctx):
     """ Access to BDO channel """
     bdo = find(lambda r: r.name == "BDO", ctx.message.server.roles)
     if bdo in ctx.message.author.roles:
         await self.bot.remove_roles(ctx.message.author, bdo)
     else:
         await self.bot.add_roles(ctx.message.author, bdo)
Example #5
0
 async def normie(self, ctx):
     """ Get access to the server! """
     if len(ctx.message.author.roles) == 1:
         normie = find(lambda r: r.name == "Normies", ctx.message.server.roles)
         await self.bot.add_roles(ctx.message.author, normie)
         await self.bot.delete_message(ctx.message)
         await self.bot.send_message(ctx.message.server.default_channel, "Welcome {0} to the server!".format(ctx.message.author.mention))
Example #6
0
def last_game(client, arguments, message):
    if arguments and len(arguments) == 1:
        name = arguments[0]
        member = list(map(lambda server: find(lambda m: m.name == name, server.members), client.servers))
        if len(member) > 0 and member[0] is not None:
            player = member[0]
        elif len(message.mentions) > 0:
            player = message.mentions[0]
        else:
            client.send_message(message.channel, "Could not find %s" % (name))
    else:
        player = message.author

    if player.id not in Bot().dota_accounts.keys():
        client.send_message(message.channel, "%s not registered" % (player.name))
        return
        
    account_id = Bot().dota_accounts[player.id].id64()
    matches = Match.list(account_id)
    if not isinstance(matches,list):
        client.send_message(message.channel, matches)
        return 
    last_match = matches[0]


    if last_match.match_id not in Bot().match_cache.keys():
        client.send_typing(message.channel)
        result = BotResult.find(last_match.match_id)
        Bot().match_cache[last_match.match_id] = BotResult.schema().dump(result).data
        Bot().save_metadata()
    
    client.send_message(message.channel, Bot().renderer.render_name("match_result_short", {'result':Bot().match_cache[last_match.match_id]}))
Example #7
0
    def mentions(self):
        mentions = []
        for player in self.players:
            for k,v in Bot().dota_accounts.items():
                if player.account_id == v.id32():
                    mentions.append(list(map(lambda server: find(lambda m: m.id == k, server.members), self.discord.servers))[0])

        return mentions
Example #8
0
    def author_has_admin_role(self, msg_author, role: str=None):
        if role is None:
            role = self.admin_role

        #member = find(lambda m: m.id == message.author.id, message.server.members)

        has_role = find(lambda r: r.name == role, msg_author.roles)

        return has_role is not None
Example #9
0
 def is_discord_member(self):
     if self.account_id != 4294967295:
         for k,v in Bot().dota_accounts.items():
             if self.account_id == v.id32():
                 member = list(map(lambda server: find(lambda m: m.id == k, server.members), self.discord.servers))
                 if len(member) > 0:
                     return member[0]
     
     return False
Example #10
0
async def on_message(message):
    # check if client is in mentions
    if not find(lambda m: m.name == client.user.name, message.mentions):
        return
    # check if client is not talking to himself
    if message.author == client.user:
        return


    response = random.choice(quotes)
    await client.send_message(message.channel, response)
Example #11
0
async def role_link(ctx, role_name: str, level: int, remove_role: Optional[str] = None):
    """Associate a role with a level. Removes previous role if given."""
    guild = ctx.message.guild

    role_obj = find(lambda r: r.name == role_name, guild.roles)
    remove_role_obj = find(lambda r: r.name == remove_role, guild.roles)

    if role_obj is None:
        return await ctx.send("**Please make sure the `{}` role exists!**".format(role_name))
    if remove_role is not None and remove_role_obj is None:
        return await ctx.send("**Please make sure the `{}` role exists!**".format(remove_role))

    role_info = db.role(role_obj)
    await role_info.level.set(level)
    if remove_role_obj is not None:
        await role_info.remove_role.set(remove_role_obj.id)

    remove_role_msg = f"Will also remove `{remove_role}` role." if remove_role is not None else ""
    message = f"**The `{role_name}` role has been linked to level `{level}`. {remove_role_msg}**"
    await ctx.send(message)
Example #12
0
 async def contact(self, ctx, *, message: str):
     """Send a message to my owner"""
     author = ctx.message.author.name
     server = ctx.message.server.name
     owner = utils.find(lambda mem: str(mem.id) == settings.owner,
                        self.bot.get_all_members())
     message = "A message from {} on {}:\n\t{}".format(
         author, server, message)
     if owner is not None:
         await self.bot.send_message(owner, message)
     else:
         await self.bot.say("Sorry, my owner is offline, try again later?")
Example #13
0
 def watcher_callback(match):
     channels = []
     for server in set(map(lambda mention: mention.server, match.mentions())):
         channels.append(find(lambda channel: channel.name == "dotastats",server.channels))
 
     for channel in channels:
         Bot().client.send_typing(channel)
 
     result = BotResult.find(match.match_id)
     Bot().match_cache[match.match_id] = BotResult.schema().dump(result).data
     Bot().save_metadata()
     for channel in channels:
         Bot().client.send_message(channel, Bot().renderer.render_name("match_result_short", {'result':Bot().match_cache[match.match_id]}))
Example #14
0
def who(message):
    argname = message.content[5:]
    if len(argname) == 0:
        client.send_message(message.channel, 'Usage: !who [user]')
    elif len(argname) < 3:
        client.send_message(message.channel, 'You need to type more than 3 letters for the user!')
    else:
        userfound = False
        for member in message.channel.server.members:
            if member.name.lower() == argname.lower():
                userfound = True
                try:
                    gameplaying = find(lambda game: game['id'] == member.game_id, games)['name']
                except TypeError:
                    gameplaying = 'None'
                client.send_message(message.channel,
                                    '```Name: ' + member.name + '\nID: ' + member.id +
                                    '\nStatus: ' + member.status.capitalize() + '\nGame Playing: ' + gameplaying +
                                    '\nAvatar: ' + member.avatar_url() +
                                    '\nJoined on: ' + str(member.joined_at.month) + '/' +
                                    str(member.joined_at.day) + '/' + str(member.joined_at.year) + '```')

                break
        if not userfound:
            for member in message.channel.server.members:
                if member.name.lower().startswith(argname.lower()):
                    userfound = True
                    try:
                        gameplaying = find(lambda game: game['id'] == member.game_id, games)['name']
                    except TypeError:
                        gameplaying = 'None'
                    client.send_message(message.channel,
                                        'Name: ' + member.name + '\nStatus: ' + member.status.capitalize() + '\nGame Playing: ' + gameplaying + '\nJoined on: ' + str(
                                            member.joined_at.month) + '/' + str(member.joined_at.day) + '/' + str(
                                            member.joined_at.year))
                    break
        if not userfound:
            client.send_message(message.channel, "User not found.")
Example #15
0
    def leave(self, message, argument):
        """[id] - Leave a server by id. Uses this server if id is not given."""
        if argument is None:
            server_id = message.channel.server.id
        else:
            server_id = argument

        if server_id not in config['protected_servers']:
            server = utils.find(lambda s: s.id == server_id, self.servers)
            if server is not None:
                self.leave_server(server)
            else:
                self.send_message(message.channel, "Can't find server with id "
                                  "{}".format(server_id))
        else:
            self.send_message(message.channel,
                              "Refusing to leave protected server")
Example #16
0
async def role_unlink(ctx, role_name: str):
    """Delete a role/level association."""
    guild = ctx.message.guild

    role_obj = find(lambda r: r.name == role_name, guild.roles)
    if role_obj is None:
        return await ctx.send(f"**The `{role_name}` role doesn't exist!**")

    role_info = db.role(role_obj)
    role_level = await role_info.level()

    if role_level is not None:
        await ctx.send(f"**Role/Level association `{role_name}`/`{role_level}` removed.**")
        await role_info.level.clear()
        await role_info.remove_role.clear()
    else:
        await ctx.send(f"**The `{role_name}` role is not linked to any levels!**")
Example #17
0
    async def parse_message(self, message, guild_data=None):
        guild = message.guild
        content = message.content
        author = message.author
        channel = message.channel

        channel_id = channel and str(channel.id)
        guild_id = guild and str(guild.id)

        trello_board = guild and await get_board(guild)
        prefix, _ = await get_prefix(guild, trello_board)

        client_match = re.search(f"<@!?{self.client.user.id}>", content)
        check = (content[:len(prefix)].lower() == prefix.lower() and prefix) or client_match and client_match.group(0)
        check_verify_channel = False

        trello_options = {}
        trello_options_checked = True

        if check:
            after = content[len(check):].strip()
            args = after.split(" ")
            command_name = args[0] and args[0].lower()
            del args[0]

            if command_name:
                enabled_addons = guild and await get_enabled_addons(guild) or {}

                for index, command in commands.items():
                    if index == command_name or command_name in command.aliases:
                        if command.addon:
                            if str(command.addon) not in enabled_addons:
                                return

                        donator_profile = None
                        actually_dm = command.dm_allowed and not guild
                        guild_data = guild_data or (guild and (await self.r.table("guilds").get(guild_id).run() or {"id": guild_id})) or {}

                        fn = command.fn
                        subcommand_attrs = {}
                        subcommand = False

                        if args:
                            # subcommand checking
                            subcommand = command.subcommands.get(args[0])
                            if subcommand:
                                fn = subcommand
                                subcommand_attrs = getattr(fn, "__subcommandattrs__", None)
                                del args[0]

                        after = args and " ".join(args) or ""

                        CommandArgs = Args(
                            command_name = index,
                            real_command_name = command_name,
                            message = message,
                            guild_data = guild_data,
                            flags = {},
                            prefix = prefix,
                            has_permission = False,
                        )

                        if getattr(fn, "__flags__", False):
                            flags, flags_str = command.parse_flags(after)
                            content = content.replace(flags_str, "")
                            message.content = content
                            after = after.replace(flags_str, "")
                            CommandArgs.flags = flags

                        locale = Locale(guild_data and guild_data.get("locale", "en") or "en")
                        response = Response(CommandArgs)

                        if guild and RELEASE == "PRO" and command_name not in ("donate", "transfer", "eval", "status", "prefix"):
                            donator_profile, _ = await get_features(Object(id=guild.owner_id), guild=guild)

                            if not donator_profile.features.get("pro"):
                                await response.error(f"Server not authorized to use Pro. Please use the ``{prefix}donate`` command to see information on "
                                                      "how to get Bloxlink Pro.")

                                return

                        if guild:
                            ignored_channels = guild_data.get("ignoredChannels", {})
                            disabled_commands = guild_data.get("disabledCommands", {})

                            author_perms = author.guild_permissions

                            if guild.owner != author and not (find(lambda r: r.name in MAGIC_ROLES, author.roles) or author_perms.manage_guild or author_perms.administrator):
                                if ignored_channels.get(channel_id):
                                    await response.send(f"The server admins have **disabled** all commands in channel {channel.mention}.", dm=True, strict_post=True, no_dm_post=True)

                                    try:
                                        await message.delete()
                                    except Forbidden:
                                        pass

                                    return

                                if command.name in disabled_commands.get("global", []):
                                    await response.send(f"The server admins have **disabled** the command ``{command_name}`` globally.", dm=True, strict_post=True, no_dm_post=True)

                                    try:
                                        await message.delete()
                                    except Forbidden:
                                        pass

                                    return

                                elif disabled_commands.get("channels", {}).get(channel_id) == command.name:
                                    await response.send(f"The server admins have **disabled** the command ``{command_name}`` in channel {channel.mention}.", dm=True, strict_post=True, no_dm_post=True)

                                    try:
                                        await message.delete()
                                    except Forbidden:
                                        pass

                                    return

                            if not isinstance(author, Member):
                                try:
                                    author = await guild.fetch_member(author.id)
                                except NotFound:
                                    return

                        blacklisted_discord = await cache_get(f"blacklist:discord_ids:{author.id}", primitives=True)

                        if blacklisted_discord is not None:
                            blacklist_text = blacklisted_discord and f"has an active restriction for: ``{blacklisted_discord}``" or "has an active restriction from Bloxlink."

                            await response.send(f"{author.mention} {blacklist_text}")
                            return

                        if command.cooldown and self.cache:
                            redis_cooldown_key = f"cooldown_cache:{index}:{author.id}"

                            if not donator_profile or (donator_profile and not donator_profile.features.get("premium")):
                                donator_profile, _ = await get_features(author)

                            if not donator_profile.features.get("premium"):
                                on_cooldown = await self.cache.get(redis_cooldown_key)

                                if on_cooldown:
                                    cooldown_time = await self.redis.ttl(redis_cooldown_key)

                                    embed = Embed(title="Slow down!")
                                    embed.description = "This command has a short cooldown since it's relatively expensive for the bot. " \
                                                        f"You'll need to wait **{cooldown_time}** more second(s).\n\nDid you know? " \
                                                        "**[Bloxlink Premium](https://www.patreon.com/join/bloxlink?)** subscribers NEVER " \
                                                        f"see any cooldowns. Find out more information with ``{prefix}donate``."

                                    try:
                                        m = await channel.send(embed=embed)
                                    except (NotFound, Forbidden):
                                        pass
                                    else:
                                        await asyncio.sleep(10)

                                        try:
                                            await m.delete()
                                            await message.delete()
                                        except (NotFound, Forbidden):
                                            pass

                                    return

                                await self.cache.set(redis_cooldown_key, True, expire_time=command.cooldown)

                        if not (command.dm_allowed or guild):
                            try:
                                await channel.send("This command does not support DM; please run it in a server.")
                            except Forbidden:
                                pass
                            finally:
                                return

                        CommandArgs.add(locale=locale, response=response, trello_board=trello_board)

                        try:
                            await command.check_permissions(author, guild, locale, dm=actually_dm, **subcommand_attrs)
                        except PermissionError as e:
                            if subcommand_attrs.get("allow_bypass"):
                                CommandArgs.has_permission = False
                            elif command.permissions.allow_bypass:
                                CommandArgs.has_permission = False
                            else:
                                await response.error(e)

                                return

                        except Message as e:
                            message_type = "send" if e.type == "info" else e.type
                            response_fn = getattr(response, message_type, response.send)

                            if e.args:
                                await response_fn(e)

                            if subcommand_attrs.get("allow_bypass"):
                                CommandArgs.has_permission = False
                            elif command.permissions.allow_bypass:
                                CommandArgs.has_permission = False
                            else:
                                return

                        else:
                            CommandArgs.has_permission = True

                        if subcommand:
                            command_args = subcommand_attrs.get("arguments")
                        else:
                            command_args = command.arguments

                        arguments = Arguments(CommandArgs)

                        try:
                            parsed_args, string_args = await self.more_args(after, CommandArgs, command_args, arguments)
                            CommandArgs.add(parsed_args=parsed_args, string_args=string_args, prompt=arguments.prompt)
                            response.prompt = arguments.prompt # pylint: disable=no-member

                            await fn(CommandArgs)
                        except PermissionError as e:
                            if e.args:
                                await response.error(e)
                            else:
                                await response.error(locale("permissions.genericError"))
                        except Forbidden as e:
                            if e.args:
                                await response.error(e)
                            else:
                                await response.error(locale("permissions.genericError"))
                        except NotFound:
                            await response.error("A channel or message which was vital to this command was deleted before the command could finish.")
                        except RobloxAPIError:
                            await response.error("The Roblox API returned an error; are you supplying the correct ID to this command?")
                        except RobloxDown:
                            await response.error("The Roblox API is currently offline; please wait until Roblox is back online before re-running this command.")
                        except CancelledPrompt as e:
                            arguments.cancelled = True

                            if trello_board:
                                trello_options, _ = await get_options(trello_board)
                                guild_data.update(trello_options)
                                trello_options_checked = True

                            if (e.type == "delete" and not e.dm) and guild_data.get("promptDelete", DEFAULTS.get("promptDelete")):
                                try:
                                    await message.delete()
                                except (Forbidden, NotFound):
                                    pass
                            else:
                                if e.args:
                                    await response.send(f"**{locale('prompt.cancelledPrompt')}:** {e}", dm=e.dm, no_dm_post=True)
                                else:
                                    await response.send(f"**{locale('prompt.cancelledPrompt')}.**", dm=e.dm, no_dm_post=True)

                        except Message as e:
                            message_type = "send" if e.type == "send" else e.type
                            response_fn = getattr(response, message_type, response.send)

                            if e.args:
                                await response_fn(e)
                            else:
                                await response_fn("This command closed unexpectedly.")
                        except Error as e:
                            if e.args:
                                await response.error(e)
                            else:
                                await response.error("This command has unexpectedly errored.")
                        except CancelCommand as e:
                            if e.args:
                                await response.send(e)
                        except NotImplementedError:
                            await response.error("The option you specified is currently not implemented, but will be coming soon!")
                        except CancelledError:
                            pass
                        except Exception as e:
                            """
                            error_id = Bloxlink.error(e, command=command_name, user=(author.id, str(author)), guild=guild and f"id:{guild.id}")

                            if error_id:
                                await response.error("We've experienced an unexpected error. You may report this "
                                                     f"error with ID ``{error_id}`` in our support server: {SERVER_INVITE}.")
                            else:
                                await response.error("An unexpected error occured.")
                            """

                            await response.error(locale("errors.commandError"))
                            Bloxlink.error(traceback.format_exc(), title=f"Error source: {command_name}.py")

                        finally:
                            messages = arguments.messages + response.delete_message_queue

                            if arguments.dm_post:
                                if arguments.cancelled:
                                    content = f"{author.mention}, **this DM prompt has been cancelled.**"
                                else:
                                    content = f"{author.mention}, **this DM prompt has finished.**"

                                try:
                                    await arguments.dm_post.edit(content=content)
                                except (NotFound, Forbidden):
                                    pass


                            if messages:
                                if not trello_options_checked and trello_board:
                                    trello_options, _ = await get_options(trello_board)
                                    guild_data.update(trello_options)
                                    trello_options_checked = True

                                if not actually_dm and guild_data.get("promptDelete", DEFAULTS.get("promptDelete")):
                                    try:
                                        await channel.purge(limit=100, check=lambda m: m.id in (*arguments.messages, *response.delete_message_queue))
                                    except (Forbidden, HTTPException):
                                        pass

                        break

                else:
                    check_verify_channel = True
            else:
                check_verify_channel = True
        else:
            check_verify_channel = True

        if check_verify_channel and guild:
            if not isinstance(author, Member):
                try:
                    author = await guild.fetch_member(author.id)
                except NotFound:
                    return

            verify_channel_id = await get_guild_value(guild, "verifyChannel")

            if verify_channel_id and channel_id == verify_channel_id:
                if not find(lambda r: r.name in MAGIC_ROLES, author.roles):
                    try:
                        await message.delete()
                    except (Forbidden, NotFound):
                        pass
Example #18
0
async def get_role_by_name(ctx, name):
    role = utils.find(lambda m: m.name == name, ctx.guild.roles)
    if role:
        return role
    else:
        raise AttributeError(f"Role '{name}' could not be found.")
Example #19
0
 async def _remove_user_role(self, guild, role_name, user):
     role = utils.find(
         lambda r: r.name == role_name,
         getattr(guild, "roles", []),
     )
     role and await user.remove_roles(role)
Example #20
0
    async def on_guild_join(self, guild: discord.Guild):
        await self.wait_until_ready()
        chan_logger = self.get_channel(692815717078270052)
        try:
            general = find(lambda x: x.name == "general", guild.text_channels)
            if general and general.permissions_for(guild.me).send_messages:
                embed = discord.Embed(
                    description=
                    "You can support me on <:kofi:693473314433138718>[Kofi](https://ko-fi.com/takitsu) and vote on [top.gg](https://top.gg/bot/682946560417333283/vote) for the bot. <:github:693519776022003742> [Source code](https://github.com/takitsu21/covid-19-tracker)",
                    timestamp=utils.discord_timestamp(),
                    color=utils.COLOR)
                embed.set_author(name="Coronavirus COVID-19 Tracker",
                                 icon_url=guild.me.avatar_url)
                embed.set_thumbnail(url=self.thumb)
                embed.add_field(
                    name="Vote",
                    value=
                    "[Click here](https://top.gg/bot/682946560417333283/vote)")
                embed.add_field(
                    name="Invite Coronavirus COVID-19",
                    value=
                    "[Click here](https://discordapp.com/oauth2/authorize?client_id=682946560417333283&scope=bot&permissions=313408)"
                )
                embed.add_field(
                    name="Discord Support",
                    value="[Click here](https://discordapp.com/invite/wTxbQYb)"
                )
                embed.add_field(
                    name="Source code",
                    value=
                    "[Click here](https://github.com/takitsu21/covid-19-tracker)"
                )
                embed.add_field(name="Help command", value="c!help")
                embed.add_field(name="Prefix", value="c!")
                nb_users = 0
                channels = 0
                for s in self.guilds:
                    nb_users += len(s.members)
                    channels += len(s.channels)
                embed.add_field(
                    name="<:confirmed:688686089548202004> Confirmed",
                    value=self._data["total"]["confirmed"])
                embed.add_field(name="<:recov:688686059567185940> Recovered",
                                value=self._data["total"]["recovered"])
                embed.add_field(name="<:_death:688686194917244928> Deaths",
                                value=self._data["total"]["deaths"])
                embed.add_field(name="<:servers:693053697453850655> Servers",
                                value=len(self.guilds))
                embed.add_field(name="<:users:693053423494365214> Members",
                                value=nb_users)
                embed.add_field(name="<:hashtag:693056105076621342> Channels",
                                value=channels)
                embed.add_field(
                    name="<:stack:693054261512110091> Shards",
                    value=f"{ctx.guild.shard_id + 1}/{self.bot.shard_count}")
                embed.set_footer(text="Made by Taki#0853 (WIP) " +
                                 utils.last_update(utils.DATA_PATH),
                                 icon_url=guild.me.avatar_url)
                await general.send(embed=embed)
        except:
            pass

        embed = discord.Embed(title="Bot added to " + guild.name,
                              timestamp=datetime.datetime.utcnow(),
                              color=utils.COLOR)
        embed.add_field(name="<:users:693053423494365214> Members",
                        value=len(guild.members))
        embed.add_field(name="<:hashtag:693056105076621342> Channels",
                        value=len(guild.channels))
        embed.set_thumbnail(url=guild.icon_url)
        embed.set_footer(icon_url=guild.me.avatar_url)
        await chan_logger.send(embed=embed)
Example #21
0
async def _handle_levelup(bot, user, channel):
    guild = user.guild

    guild_info = db.guild(guild)
    user_info = db.user(user)
    member_info = db.member(user)
    name = await get_user_name(user)
    level = await member_info.level()

    if await db.guild(guild).lvl_msg():  # if lvl msg is enabled
        lock_channel = await db.guild(guild).lvl_msg_lock()
        if lock_channel:
            channel = find(lambda m: m.id == lock_channel, guild.channels)

        guild_identifier = ""
        # private message takes precedent, of course
        if await db.guild(guild).private_lvl_msg():
            guild_identifier = f" on {guild.name}"
            channel = user
            name = "You"

        image = await draw_levelup(bot, user)
        image_buffer = BytesIO()
        image.save(image_buffer, "png")
        image_buffer.seek(0)

        await channel.send(
            f"**{name} just gained a level{guild_identifier}!**",
            file=discord.File(filename="levelup.png", fp=image_buffer),
        )

    # add to appropriate role if necessary
    for role in guild.roles:
        role_info = db.role(role)
        if await role_info.level() == level:
            await user.add_roles(role)

            remove_role = await role_info.remove_role()
            if remove_role is not None:
                remove_role_obj = discord.utils.find(
                    lambda r: r.id == remove_role,
                    guild.roles,
                )
                if remove_role_obj is not None:
                    await user.remove_roles(remove_role_obj)
            else:
                await channel.send("Error. Could not find role to remove")

    # add appropriate badge if necessary
    try:
        linked_badges = await guild_info.badge_links()
        for badge_name, badge_level in linked_badges.items():
            if badge_level == level:
                guild_badges = await guild_info.badges()
                user_badges = await user_info.badges()
                badge_id = f"{badge_name}_{guild.id}"

                user_badges[badge_id] = guild_badges[badge_name]
                await user_info.badges.set(user_badges)
    except:
        await channel.send("Error. Badge was not given!")
Example #22
0
    async def command_checks(self,
                             command,
                             prefix,
                             response,
                             guild_data,
                             author,
                             channel,
                             locale,
                             CommandArgs,
                             message=None,
                             guild=None,
                             subcommand_attrs=None,
                             slash_command=False):
        channel_id = str(channel.id) if channel else None
        donator_profile = None
        dm = not bool(guild)
        subcommand_attrs = subcommand_attrs or {}

        if guild:
            if command.addon:
                enabled_addons = guild and await get_enabled_addons(guild
                                                                    ) or {}

                if str(command.addon) not in enabled_addons:
                    raise CancelCommand

                if getattr(command.addon, "premium", False):
                    donator_profile, _ = await get_features(
                        Object(id=guild.owner_id), guild=guild)

                    if not donator_profile.features.get("premium"):
                        await response.error(
                            f"This add-on requires premium! You may use `{prefix}donate` for instructions on donating.\n"
                            f"You may also disable this add-on with `{prefix}addon change`.",
                            hidden=True)

                        raise CancelCommand

            if RELEASE == "PRO" and command.name not in ("donate", "transfer",
                                                         "eval", "status",
                                                         "prefix"):
                donator_profile, _ = await get_features(
                    Object(id=guild.owner_id), guild=guild)

                if not donator_profile.features.get("pro"):
                    await response.error(
                        f"Server not authorized to use Pro. Please use the `{prefix}donate` command to see information on "
                        "how to get Bloxlink Pro.",
                        hidden=True)

                    raise CancelCommand

            ignored_channels = guild_data.get("ignoredChannels", {})
            disabled_commands = guild_data.get("disabledCommands", {})

            if isinstance(author, User):
                try:
                    author = await guild.fetch_member(author.id)
                except NotFound:
                    raise CancelCommand

            author_perms = author.guild_permissions

            if guild.owner != author and not (
                    find(lambda r: r.name in MAGIC_ROLES, author.roles) or
                    author_perms.manage_guild or author_perms.administrator):
                if ignored_channels.get(channel_id):
                    await response.send(
                        f"The server admins have **disabled** all commands in channel {channel.mention}.",
                        dm=True,
                        hidden=True,
                        strict_post=True,
                        no_dm_post=True)

                    if message:
                        try:
                            await message.delete()
                        except (Forbidden, NotFound):
                            pass

                    raise CancelCommand

                if command.name in disabled_commands.get("global", []):
                    await response.send(
                        f"The server admins have **disabled** the command `{command.name}` globally.",
                        dm=True,
                        hidden=True,
                        strict_post=True,
                        no_dm_post=True)

                    if message:
                        try:
                            await message.delete()
                        except (Forbidden, NotFound):
                            pass

                    raise CancelCommand

                elif disabled_commands.get("channels",
                                           {}).get(channel_id) == command.name:
                    await response.send(
                        f"The server admins have **disabled** the command `{command.name}` in channel {channel.mention}.",
                        dm=True,
                        hidden=True,
                        strict_post=True,
                        no_dm_post=True)

                    if message:
                        try:
                            await message.delete()
                        except (Forbidden, NotFound):
                            pass

                    raise CancelCommand

            if not isinstance(author, Member):
                try:
                    author = await guild.fetch_member(author.id)
                except NotFound:
                    raise CancelCommand

        restriction = await get_restriction("discord_ids", author.id)

        if restriction:
            restrction_text = isinstance(
                restriction, str
            ) and f"has an active restriction for: `{restriction}`" or "has an active restriction from Bloxlink."

            await response.send(f"{author.mention} {restrction_text}",
                                hidden=True)
            raise CancelCommand

        if command.cooldown and self.cache:
            redis_cooldown_key = f"cooldown_cache:{command.name}:{author.id}"

            if not donator_profile or (
                    donator_profile
                    and not donator_profile.features.get("premium")):
                donator_profile, _ = await get_features(author)

            if not donator_profile.features.get("premium"):
                on_cooldown = await self.cache.get(redis_cooldown_key)

                if on_cooldown:
                    cooldown_time = await self.redis.ttl(redis_cooldown_key)

                    embed = Embed(title="Slow down!")
                    embed.description = "This command has a short cooldown since it's relatively expensive for the bot. " \
                                        f"You'll need to wait **{cooldown_time}** more second(s).\n\nDid you know? " \
                                        "**[Bloxlink Premium](https://www.patreon.com/join/bloxlink?)** subscribers NEVER " \
                                        f"see any cooldowns. Find out more information with `{prefix}donate`."

                    m = await response.send(embed=embed, hidden=True)

                    if m:
                        await asyncio.sleep(10)

                        try:
                            await m.delete()

                            if message:
                                await message.delete()

                        except (NotFound, Forbidden):
                            pass

                    raise CancelCommand

                await self.cache.set(redis_cooldown_key,
                                     True,
                                     expire_time=command.cooldown)

        if not (command.dm_allowed or guild):
            await response.send(
                "This command does not support DM; please run it in a server.",
                hidden=True)
            raise CancelCommand

        try:
            await command.check_permissions(author,
                                            guild,
                                            locale,
                                            dm=dm,
                                            **subcommand_attrs)
        except PermissionError as e:
            if subcommand_attrs.get("allow_bypass"):
                CommandArgs.has_permission = False
            elif command.permissions.allow_bypass:
                CommandArgs.has_permission = False
            else:
                await response.error(e, hidden=True)
                raise CancelCommand

        except Message as e:
            message_type = "send" if e.type == "info" else e.type
            response_fn = getattr(response, message_type, response.send)

            if e.message:
                await response_fn(e, hidden=True)

            if subcommand_attrs.get("allow_bypass"):
                CommandArgs.has_permission = False
            elif command.permissions.allow_bypass:
                CommandArgs.has_permission = False
            else:
                raise CancelCommand

        else:
            CommandArgs.has_permission = True
Example #23
0
 def username_and_discriminator_to_userid(cls, username: str,
                                          discriminator: str) -> str:
     return find(
         lambda m: m.name == username and m.discriminator == discriminator,
         DiscordBackend.client.get_all_members())
Example #24
0
def find_channel(guild, channel='geral'):
    return utils.find(lambda g: g.name == channel, guild.text_channels)
 async def remove_role_from_user(self, channel, user_id, role_name):
     member = find(lambda m: m.id == user_id, self.get_guild().members)
     await self.remove_role_from_member(member, role_name)
 async def add_role_to_user(self, channel, user_id, role_name):
     member = find(lambda m: m.id == user_id, self.get_guild().members)
     await self.add_role_to_member(member, role_name)
Example #27
0
async def on_guild_join(guild):
    general = find(lambda x: x.name == 'bots', guild.text_channels)
    if general and general.permissions_for(guild.me).send_messages:
        await general.send(
            'Hello {}! Press !help for a full list of commands'.format(
                guild.name))
Example #28
0
async def on_guild_join(guild):
    general = find(lambda x: x.name == 'general', guild.text_channels)
    if general and general.permissions_for(guild.me).send_messages:
        await general.send(
            'Hello {}! Glad to be here :grinning: \n\nPlease enter the channel ID with the command $id [channelId] to set the annoucements channel'
            .format(guild.name))
Example #29
0
    async def __main__(self, CommandArgs):
        guild = CommandArgs.guild
        response = CommandArgs.response
        guild_data = CommandArgs.guild_data
        trello_board = CommandArgs.trello_board
        prefix = CommandArgs.prefix
        author = CommandArgs.author
        locale = CommandArgs.locale

        role_binds_trello, group_ids_trello, trello_binds_list = await get_binds(
            guild=guild, trello_board=trello_board)

        bind_count = count_binds(guild_data,
                                 role_binds=role_binds_trello,
                                 group_ids=group_ids_trello)

        if bind_count >= FREE_BIND_COUNT:
            profile, _ = await get_features(Object(id=guild.owner_id),
                                            guild=guild)

            if not profile.features.get("premium"):
                raise Error(
                    locale("commands.bind.errors.noPremiumBindLimitExceeded",
                           prefix=prefix,
                           free_bind_count=FREE_BIND_COUNT,
                           prem_bind_count=PREM_BIND_COUNT))

            if bind_count >= PREM_BIND_COUNT:
                raise Error(
                    locale("commands.bind.errors.premiumBindLimitExceeded",
                           prefix=prefix,
                           prem_bind_count=PREM_BIND_COUNT))

        parsed_args = await CommandArgs.prompt([{
            "prompt":
            f"{locale('commands.bind.prompts.bindTypePrompt.line_1', arrow=ARROW)}\n"
            f"{locale('commands.bind.prompts.bindTypePrompt.line_2', arrow=ARROW)}\n"
            f"{locale('commands.bind.prompts.bindTypePrompt.line_3', arrow=ARROW)}\n"
            f"{locale('commands.bind.prompts.bindTypePrompt.line_4', arrow=ARROW)}\n"
            f"{locale('commands.bind.prompts.bindTypePrompt.line_5', arrow=ARROW)}",
            "name":
            "bind_choice",
            "type":
            "choice",
            "choices":
            locale("commands.bind.prompts.bindTypePrompt.choices"),
            "formatting":
            False
        }, {
            "prompt":
            locale("commands.bind.prompts.nicknamePrompt.line",
                   prefix=prefix,
                   nickname_templates=NICKNAME_TEMPLATES),
            "name":
            "nickname",
            "max":
            100,
            "type":
            "string",
            "footer":
            locale("commands.bind.prompts.nicknamePrompt.footer"),
            "formatting":
            False
        }, {
            "prompt":
            "Should any roles be **removed from the user** if they meet the bind conditions? You can specify multiple roles.\n\n"
            "Note that this is an **advanced option**, so you most likely should `skip` this.",
            "name":
            "remove_roles",
            "multiple":
            True,
            "type":
            "role",
            "max":
            10,
            "exceptions": ("skip", ),
            "footer":
            "Say **skip** to skip this option."
        }])

        bind_choice = parsed_args["bind_choice"].lower()
        nickname = parsed_args["nickname"]

        if "display-name" in nickname:
            display_name_confirm = (await CommandArgs.prompt([{
                "prompt":
                "**Warning!** You chose Display Names for your Nickname Template.\n"
                "Display Names **aren't unique** and can **lead to impersonation.** Are you sure you want to use this? yes/no",
                "type":
                "choice",
                "choices": ("yes", "no"),
                "name":
                "confirm",
                "embed_title":
                "Display Names Confirmation",
                "embed_color":
                BROWN_COLOR,
                "formatting":
                False
            }]))["confirm"]

            if display_name_confirm == "no":
                raise CancelledPrompt

        remove_roles = [str(r.id) for r in parsed_args["remove_roles"]
                        ] if parsed_args["remove_roles"] != "skip" else []
        remove_roles_trello = [
            str(r) for r in parsed_args["remove_roles"]
        ] if parsed_args["remove_roles"] != "skip" else []

        if trello_board:
            trello_binds_list = await trello_board.get_list(
                lambda l: l.name.lower() == "bloxlink binds")

            if not trello_binds_list:
                try:
                    trello_binds_list = await trello_board.create_list(
                        name="Bloxlink Binds")
                except TrelloUnauthorized:
                    await response.error(
                        locale("commands.bind.errors.trelloError"))
                except (TrelloNotFound, TrelloBadRequest):
                    pass

            trello_card_binds, _ = await parse_trello_binds(
                trello_board=trello_board, trello_binds_list=trello_binds_list)
        else:
            trello_binds_list = None
            trello_group_bind = None
            trello_card_binds = {
                "groups": {
                    "entire group": {},
                    "binds": {}
                },
                "assets": {},
                "badges": {},
                "gamePasses": {}
            }

        if nickname.lower() in (locale("prompt.skip"), locale("prompt.done"),
                                locale("prompt.next")):
            nickname = None
            nickname_lower = None
        else:
            nickname_lower = nickname.lower()

        if bind_choice == locale("commands.bind.group"):
            parsed_args_group = await CommandArgs.prompt([{
                "prompt":
                locale("commands.bind.prompts.groupPrompt.line"),
                "name":
                "group",
                "validation":
                self.validate_group
            }, {
                "prompt":
                f"{locale('commands.bind.prompts.groupBindMode.line_1', arrow=ARROW)}\n"
                f"{locale('commands.bind.prompts.groupBindMode.line_2', arrow=ARROW)}\n"
                f"{locale('commands.bind.prompts.groupBindMode.line_3', arrow=ARROW)}",
                "name":
                "type",
                "type":
                "choice",
                "choices":
                locale("commands.bind.prompts.groupBindMode.choices")
            }])

            group = parsed_args_group["group"]
            group_id = group.group_id

            group_ids = guild_data.get("groupIDs", {})
            found_group = trello_card_binds["groups"]["entire group"].get(
                group_id) or group_ids.get(group_id)

            trello_group_bind = trello_card_binds["groups"][
                "entire group"].get(group_id)

            if parsed_args_group["type"] == locale(
                    "commands.bind.entireGroup"):
                if found_group:
                    if (nickname and found_group["nickname"] != nickname) or (
                            sorted(remove_roles) != sorted(
                                found_group.get("removeRoles", []))):
                        group_ids[group_id] = {
                            "nickname": nickname,
                            "groupName": group.name,
                            "removeRoles": remove_roles
                        }
                        guild_data["groupIDs"] = group_ids

                        await self.r.table("guilds").insert(
                            guild_data, conflict="update").run()

                        trello_group_bind = trello_card_binds["groups"][
                            "entire group"].get(group_id)

                        make_trello_card = True

                        if trello_group_bind and trello_group_bind["nickname"]:
                            for card_data in trello_group_bind["trello"].get(
                                    "cards", []):
                                card = card_data["card"]

                                try:
                                    await card.edit(
                                        desc=card.description.replace(
                                            trello_group_bind["nickname"],
                                            nickname or 'None'))
                                except TrelloUnauthorized:
                                    await response.error(
                                        "In order for me to edit your Trello binds, please add `@bloxlink` to your "
                                        "Trello board.")
                                except (TrelloNotFound, TrelloBadRequest):
                                    pass

                                make_trello_card = False

                            if make_trello_card:
                                card_bind_data = [
                                    f"Group: {group_id}",
                                    f"Nickname: {nickname}"
                                ]

                                if remove_roles:
                                    card_bind_data.append(
                                        f"Remove roles: {', '.join(remove_roles_trello)}"
                                    )

                                try:
                                    await trello_binds_list.create_card(
                                        name="Bloxlink Group Bind",
                                        desc="\n".join(card_bind_data))
                                except TrelloUnauthorized:
                                    await response.error(
                                        "In order for me to edit your Trello binds, please add `@bloxlink` to your "
                                        "Trello board.")
                                except (TrelloNotFound, TrelloBadRequest):
                                    pass

                            if trello_binds_list:
                                trello_binds_list.parsed_bind_data = None

                        ending_s = group.name.endswith("s") and "'" or "'s"

                        await post_event(
                            guild, guild_data, "bind",
                            f"{author.mention} ({author.id}) has **changed** `{group.name}`{ending_s} nickname template.",
                            BLURPLE_COLOR)

                        await clear_guild_data(guild)

                        raise Message(
                            "Since your group is already linked, the nickname was updated.",
                            type="success")

                    else:
                        raise Message("This group is already linked!",
                                      type="silly")

                for _, roleset_data in group.rolesets.items():
                    discord_role = find(lambda r: r.name == roleset_data[0],
                                        guild.roles)

                    if not discord_role:
                        try:
                            discord_role = await guild.create_role(
                                name=roleset_data[0])
                        except Forbidden:
                            raise PermissionError(
                                "I was unable to create the Discord role. Please ensure my role has the `Manage Roles` permission."
                            )

                # add group to guild_data.groupIDs
                group_ids[group_id] = {
                    "nickname": nickname not in ("skip", "next") and nickname,
                    "groupName": group.name,
                    "removeRoles": remove_roles
                }
                guild_data["groupIDs"] = group_ids

                await self.r.table("guilds").insert(guild_data,
                                                    conflict="update").run()

                if trello_binds_list:
                    card_bind_data = [
                        f"Group: {group_id}", f"Nickname: {nickname}"
                    ]

                    if remove_roles:
                        card_bind_data.append(
                            f"Remove roles: {', '.join(remove_roles_trello)}")

                    try:
                        await trello_binds_list.create_card(
                            name="Bloxlink Group Bind",
                            desc="\n".join(card_bind_data))
                    except TrelloUnauthorized:
                        await response.error(
                            "In order for me to edit your Trello binds, please add `@bloxlink` to your "
                            "Trello board.")
                    except (TrelloNotFound, TrelloBadRequest):
                        pass

                await post_event(
                    guild, guild_data, "bind",
                    f"{author.mention} ({author.id}) has **linked** group `{group.name}`.",
                    BLURPLE_COLOR)
                await clear_guild_data(guild)

                raise Message("Success! Your group was successfully linked.",
                              type="success")

            else:
                # select ranks from their group
                # ask if they want to auto-create the binds or select a specific role
                # shows confirmation embed with arrows from rank to discord role

                discord_role = await CommandArgs.prompt([{
                    "prompt":
                    "Please provide **Discord role name(s)** for this bind, separated by commas.",
                    "name": "role",
                    "type": "role",
                    "multiple": True,
                    "max": 10
                }])

                discord_roles = discord_role["role"]
                new_ranks = {"binds": [], "ranges": []}
                role_binds = guild_data.get("roleBinds") or {}

                if isinstance(role_binds, list):
                    role_binds = role_binds[0]

                role_binds["groups"] = role_binds.get("groups") or {
                }  # {"groups": {"ranges": {}, "binds": {}}}
                role_binds["groups"][group_id] = role_binds["groups"].get(
                    group_id) or {}
                role_binds["groups"][group_id]["binds"] = role_binds["groups"][
                    group_id].get("binds") or {}
                role_binds["groups"][group_id]["ranges"] = role_binds[
                    "groups"][group_id].get("ranges") or {}
                role_binds["groups"][group_id]["groupName"] = group.name
                role_binds["groups"][group_id]["removeRoles"] = remove_roles

                rolesets_embed = Embed(title=f"{group.name} Rolesets",
                                       description="\n".join(
                                           f"**{x[0]}** {ARROW} {x[1]}"
                                           for x in group.rolesets.values()))
                rolesets_embed = await CommandArgs.response.send(
                    embed=rolesets_embed)
                response.delete(rolesets_embed)

                failures = 0

                while True:
                    if failures == 5:
                        raise Error(
                            "Too many failed attempts. Please run this command again."
                        )

                    selected_ranks = await CommandArgs.prompt([{
                        "prompt":
                        f"Please select the rolesets that should receive the role(s) **{', '.join([r.name for r in discord_roles])}**. "
                        "You may specify the roleset name or ID. You may provide them in a list, "
                        "or as a range. You may also say `everyone` to capture everyone in the group; "
                        "and you can negate the number to catch everyone with the rank _and above._\n"
                        "You can also say `guest` to include **all non-group members**.\n\n"
                        "Example 1: `1,4,-6,VIP, 10, 50-100, Staff Members, 255`.\nExample 2: `"
                        "-100` means everyone with rank 100 _and above._\nExample 3: `everyone` "
                        "means everyone in the group.\n\n"
                        "For your convenience, your Rolesets' names and IDs were sent above.",
                        "name":
                        "ranks",
                        "formatting":
                        False
                    }],
                                                              last=True)

                    for rank in selected_ranks["ranks"].split(","):
                        rank = rank.strip()

                        if rank.isdigit() and rank != "0":
                            if 1 <= int(rank) <= 255:
                                new_ranks["binds"].append(str(rank))
                            else:
                                response.delete(await response.error(
                                    "Ranks must be an integer between [1-255]"
                                ))
                                failures += 1
                                break
                        elif rank in ("all", "everyone"):
                            new_ranks["binds"].append("all")
                        elif rank in ("0", "guest"):
                            new_ranks["binds"].append("0")
                        elif rank[:1] == "-":
                            try:
                                int(rank)
                            except ValueError:
                                pass
                            else:
                                new_ranks["binds"].append(rank)
                        else:
                            range_search = bind_num_range.search(rank)

                            if range_search:
                                num1, num2 = range_search.group(
                                    1), range_search.group(2)
                                if (1 <= int(num1) <= 255) and (1 <= int(num2)
                                                                <= 255):
                                    new_ranks["ranges"].append([num1, num2])
                                else:
                                    response.delete(await response.error(
                                        "Ranges must be between [1-255]."))
                                    failures += 1
                                    break
                            else:
                                # they specified a roleset name as a string
                                roleset_find = group.rolesets.get(rank.lower())

                                if roleset_find:
                                    new_ranks["binds"].append(
                                        str(roleset_find[1]))
                                else:
                                    response.delete(await response.error(
                                        "Could not find a matching Roleset name. Please try again."
                                    ))
                                    failures += 1
                                    break
                    else:
                        break

                if new_ranks["binds"]:
                    for x in new_ranks["binds"]:
                        rank = role_binds["groups"][group_id].get("binds",
                                                                  {}).get(
                                                                      x, {})

                        if not isinstance(rank, dict):
                            rank = {
                                "nickname": nickname_lower,
                                "roles": [str(rank)],
                                "removeRoles": remove_roles
                            }

                            for discord_role in discord_roles:
                                role_id = str(discord_role.id)

                                if role_id not in rank["roles"]:
                                    rank["roles"].append(role_id)
                        else:
                            for discord_role in discord_roles:
                                role_id = str(discord_role.id)

                                if role_id not in rank.get("roles", []):
                                    rank["roles"] = rank.get("roles") or []
                                    rank["roles"].append(role_id)

                            if nickname_lower:
                                rank["nickname"] = nickname
                            else:
                                if not rank.get("nickname"):
                                    rank["nickname"] = None

                            rank["removeRoles"] = remove_roles

                        role_binds["groups"][group_id]["binds"][x] = rank
                        # trello binds:
                        # rank is in list of ranks
                        # update nickname
                        # append role
                        # else: make new card

                        if trello_binds_list:
                            make_binds_card = True

                            if trello_card_binds:
                                trello_bind_group = trello_card_binds[
                                    "groups"]["binds"].get(group_id,
                                                           {}).get("binds")

                                if trello_bind_group:
                                    card_data_ = trello_bind_group.get(x)

                                    if card_data_:
                                        for card in card_data_.get(
                                                "trello", {}).get("cards", []):
                                            trello_card = card["card"]
                                            trello_ranks = card.get(
                                                "ranks") or []

                                            if (x in trello_ranks or x == "all"
                                                ) and len(trello_ranks) == 1:
                                                trello_bind_roles = card.get(
                                                    "roles", set())
                                                card_bind_data = [
                                                    f"Group: {group_id}",
                                                    f"Nickname: {(nickname != 'skip' and nickname) or rank.get('nickname') or card_data_.get('nickname') or 'None'}",
                                                ]

                                                if remove_roles:
                                                    card_bind_data.append(
                                                        f"Remove roles: {', '.join(remove_roles_trello)}"
                                                    )

                                                for discord_role in discord_roles:
                                                    trello_bind_roles.add(
                                                        discord_role.name)

                                                card_bind_data.append(
                                                    f"Roles: {', '.join(trello_bind_roles)}"
                                                )
                                                card_bind_data.append(
                                                    f"Ranks: {card['trello_str']['ranks']}"
                                                )

                                                trello_card_desc = "\n".join(
                                                    card_bind_data)

                                                if trello_card_desc != trello_card.description:
                                                    trello_card.description = trello_card_desc

                                                    try:
                                                        await trello_card.edit(
                                                            desc=trello_card_desc
                                                        )
                                                    except TrelloUnauthorized:
                                                        await response.error(
                                                            "In order for me to edit your Trello binds, please add `@bloxlink` to your "
                                                            "Trello board.")
                                                    except (TrelloNotFound,
                                                            TrelloBadRequest):
                                                        pass

                                                    trello_binds_list.parsed_bind_data = None
                                                    make_binds_card = False

                                                    break

                            if make_binds_card:
                                card_bind_data = [
                                    f"Group: {group_id}",
                                    f"Nickname: {nickname != 'skip' and nickname or 'None'}",
                                    f"Roles: {', '.join([r.name for r in discord_roles])}",
                                ]

                                if remove_roles:
                                    card_bind_data.append(
                                        f"Remove roles: {', '.join(remove_roles_trello)}"
                                    )

                                if x != "all":
                                    card_bind_data.append(f"Ranks: {x}")

                                trello_card_desc = "\n".join(card_bind_data)

                                try:
                                    card = await trello_binds_list.create_card(
                                        name="Bloxlink Bind",
                                        desc=trello_card_desc)
                                except TrelloUnauthorized:
                                    await response.error(
                                        "In order for me to edit your Trello binds, please add `@bloxlink` to your "
                                        "Trello board.")
                                except (TrelloNotFound, TrelloBadRequest):
                                    pass

                                trello_binds_list.parsed_bind_data = None

                if new_ranks["ranges"]:
                    role_binds["groups"][group_id]["ranges"] = role_binds[
                        "groups"][group_id].get("ranges") or []

                    for x in new_ranks[
                            "ranges"]:  # list of dictionaries: [{"high": 10, "low": 1, "nickname": ""},...]
                        range_, num = self.find_range(
                            x, role_binds["groups"][group_id]["ranges"])
                        found = bool(range_)

                        for discord_role in discord_roles:
                            role_id = str(discord_role.id)

                            if not role_id in range_.get("roles", []):
                                range_["roles"] = range_.get("roles") or []
                                range_["roles"].append(role_id)

                        if nickname_lower:
                            range_["nickname"] = nickname
                        else:
                            if not range_.get("nickname"):
                                range_["nickname"] = None

                        range_["removeRoles"] = remove_roles

                        if found:
                            role_binds["groups"][group_id]["ranges"][
                                num] = range_
                        else:
                            range_["low"] = int(x[0])
                            range_["high"] = int(x[1])
                            role_binds["groups"][group_id]["ranges"].append(
                                range_)

                        if trello_binds_list:
                            make_binds_card = True

                            if trello_card_binds:
                                trello_range_group = trello_card_binds[
                                    "groups"]["binds"].get(group_id,
                                                           {}).get("ranges")

                                if trello_range_group:
                                    for trello_range in trello_range_group:
                                        trello_data = trello_range["trello"]

                                        for card in trello_data.get(
                                                "cards", []):
                                            trello_card = card["card"]
                                            trello_ranks = card.get(
                                                "ranks", [])

                                            if trello_range["low"] == range_[
                                                    "low"] and trello_range[
                                                        "high"] == range_[
                                                            "high"] and len(
                                                                trello_ranks
                                                            ) == 1:
                                                trello_data = trello_range[
                                                    "trello"]
                                                trello_bind_roles = trello_range.get(
                                                    "roles", set())
                                                card_bind_data = [
                                                    f"Group: {group_id}",
                                                    f"Nickname: {(nickname != 'skip' and nickname) or trello_range.get('nickname') or 'None'}",
                                                ]

                                                if remove_roles:
                                                    card_bind_data.append(
                                                        f"Remove roles: {', '.join(remove_roles_trello)}"
                                                    )

                                                for discord_role in discord_roles:
                                                    trello_bind_roles.add(
                                                        discord_role.name)

                                                card_bind_data.append(
                                                    f"Roles: {', '.join(trello_bind_roles)}"
                                                )
                                                card_bind_data.append(
                                                    f"Ranks: {card['trello_str']['ranks']}"
                                                )

                                                trello_card_desc = "\n".join(
                                                    card_bind_data)

                                                if trello_card_desc != trello_card.description:
                                                    trello_card.description = trello_card_desc

                                                    try:
                                                        await trello_card.edit(
                                                            desc=trello_card_desc
                                                        )
                                                    except TrelloUnauthorized:
                                                        await response.error(
                                                            "In order for me to edit your Trello binds, please add `@bloxlink` to your "
                                                            "Trello board.")
                                                    except (TrelloNotFound,
                                                            TrelloBadRequest):
                                                        pass

                                                    trello_binds_list.parsed_bind_data = None
                                                    make_binds_card = False

                                                    break

                            if make_binds_card:
                                card_bind_data = [
                                    f"Group: {group_id}",
                                    f"Nickname: {nickname != 'skip' and nickname or 'None'}",
                                    f"Roles: {', '.join([r.name for r in discord_roles])}",
                                    f"Ranks: {range_['low']}-{range_['high']}"
                                ]

                                if remove_roles:
                                    card_bind_data.append(
                                        f"Remove roles: {', '.join(remove_roles_trello)}"
                                    )

                                trello_card_desc = "\n".join(card_bind_data)

                                try:
                                    card = await trello_binds_list.create_card(
                                        name="Bloxlink Range Bind",
                                        desc=trello_card_desc)
                                except TrelloUnauthorized:
                                    await response.error(
                                        "In order for me to edit your Trello binds, please add `@bloxlink` to your "
                                        "Trello board.")
                                except (TrelloNotFound, TrelloBadRequest):
                                    pass

                                trello_binds_list.parsed_bind_data = None

            await self.r.table("guilds").insert(
                {
                    "id": str(guild.id),
                    "roleBinds": role_binds
                },
                conflict="update").run()

            text = ["Successfully **bound** rank ID(s): `"]
            if new_ranks["binds"]:
                text.append(", ".join(new_ranks["binds"]))

            if new_ranks["ranges"]:
                text2 = ""

                if new_ranks["binds"]:
                    text2 = "; "

                text.append(
                    f"{text2}ranges: {', '.join([r[0] + ' - ' + r[1] for r in new_ranks['ranges']])}"
                )

            text.append(
                f"` with Discord role(s) **{', '.join([r.name for r in discord_roles])}**."
            )

            text = "".join(text)

            await post_event(
                guild, guild_data, "bind",
                f"{author.mention} ({author.id}) has **bound** group `{group.name}`.",
                BLURPLE_COLOR)

            await clear_guild_data(guild)

            await response.success(text)

        elif bind_choice in ("asset", "badge", "gamepass"):
            if bind_choice == "gamepass":
                bind_choice_title = "GamePass"
                bind_choice_plural = "gamePasses"
            else:
                bind_choice_title = bind_choice.title()
                bind_choice_plural = f"{bind_choice}s"

            vg_parsed_args = await CommandArgs.prompt([
                {
                    "prompt":
                    f"Please provide the **{bind_choice_title} ID** to use for this bind.",
                    "name": "bind_id",
                    "type": "number",
                    "formatting": False
                },
                {
                    "prompt":
                    "Please provide **Discord role name(s)** for this bind, separated by commas.",
                    "name": "role",
                    "type": "role",
                    "multiple": True,
                    "max": 10
                },
            ],
                                                      last=True)

            discord_roles = vg_parsed_args["role"]
            bind_id = str(vg_parsed_args["bind_id"])

            if bind_choice == "asset":
                try:
                    text, response_ = await fetch(
                        f"{API_URL}/marketplace/productinfo?assetId={bind_id}")
                except RobloxNotFound:
                    raise Error(
                        f"An Asset with ID `{bind_id}` does not exist.")

                json_data = await response_.json()

                display_name = json_data.get("Name")

            elif bind_choice == "badge":
                try:
                    text, response_ = await fetch(
                        f"https://badges.roblox.com/v1/badges/{bind_id}")
                except RobloxNotFound:
                    raise Error(f"A Badge with ID `{bind_id}` does not exist.")

                json_data = await response_.json()

                display_name = json_data.get("displayName")

            elif bind_choice == "gamepass":
                bind_choice_title = "GamePass"
                bind_choice_plural = "gamePasses"

                try:
                    text, response_ = await fetch(
                        f"http://api.roblox.com/marketplace/game-pass-product-info?gamePassId={bind_id}"
                    )
                except (RobloxNotFound, RobloxAPIError):
                    raise Error(
                        f"A GamePass with ID `{bind_id}` does not exist.")

                json_data = await response_.json()

                if json_data.get("ProductType") != "Game Pass":
                    raise Error(
                        f"A GamePass with ID `{bind_id}` does not exist.")

                display_name = json_data.get("Name")

            role_binds = guild_data.get("roleBinds") or {}

            if isinstance(role_binds, list):
                role_binds = role_binds[0]

            role_binds[bind_choice_plural] = role_binds.get(
                bind_choice_plural) or {}
            role_binds[bind_choice_plural][
                bind_id] = role_binds[bind_choice_plural].get(bind_id) or {}

            role_binds[bind_choice_plural][bind_id]["nickname"] = nickname
            role_binds[bind_choice_plural][bind_id][
                "displayName"] = display_name
            role_binds[bind_choice_plural][bind_id][
                "removeRoles"] = remove_roles
            role_binds[bind_choice_plural][bind_id]["roles"] = role_binds[
                bind_choice_plural][bind_id].get("roles", [])

            roles = role_binds[bind_choice_plural][bind_id]["roles"]

            for discord_role in discord_roles:
                role_id = str(discord_role.id)

                if not role_id in roles:
                    roles.append(role_id)

            role_binds[bind_choice_plural][bind_id]["roles"] = roles

            if trello_binds_list:
                make_binds_card = True

                if trello_card_binds:
                    trello_bind_vg = trello_card_binds.get(
                        bind_choice_plural, {}).get(bind_id)

                    if trello_bind_vg:
                        trello_bind_roles = set(
                            trello_bind_vg.get("roles", set()))

                        for card in trello_bind_vg.get("trello", {})["cards"]:
                            trello_card = card["card"]

                            card_bind_data = [
                                f"{bind_choice_title} ID: {bind_id}",
                                f"Display Name: {display_name}",
                                f"Nickname: {(nickname != 'skip' and nickname) or trello_bind_vg.get('nickname') or 'None'}",
                            ]

                            for discord_role in discord_roles:
                                trello_bind_roles.add(discord_role.name)

                            card_bind_data.append(
                                f"Roles: {', '.join(trello_bind_roles)}")

                            trello_card_desc = "\n".join(card_bind_data)

                            if trello_card_desc != trello_card.description:
                                trello_card.description = trello_card_desc

                                try:
                                    await trello_card.edit(
                                        desc=trello_card_desc)
                                except TrelloUnauthorized:
                                    await response.error(
                                        "In order for me to edit your Trello binds, please add `@bloxlink` to your "
                                        "Trello board.")
                                except (TrelloNotFound, TrelloBadRequest):
                                    pass

                                trello_binds_list.parsed_bind_data = None
                                make_binds_card = False

                                break

                if make_binds_card:
                    card_bind_data = [
                        f"{bind_choice_title} ID: {bind_id}",
                        f"Display Name: {display_name}",
                        f"Nickname: {nickname != 'skip' and nickname or 'None'}",
                        f"Roles: {', '.join([d.name for d in discord_roles])}",
                    ]

                    if remove_roles:
                        card_bind_data.append(
                            f"Remove roles: {', '.join(remove_roles_trello)}")

                    trello_card_desc = "\n".join(card_bind_data)

                    try:
                        card = await trello_binds_list.create_card(
                            name=f"Bloxlink {bind_choice_title} Bind",
                            desc=trello_card_desc)
                    except TrelloUnauthorized:
                        await response.error(
                            "In order for me to edit your Trello binds, please add `@bloxlink` to your "
                            "Trello board.")
                    except (TrelloNotFound, TrelloBadRequest):
                        pass

                    trello_binds_list.parsed_bind_data = None

            await self.r.table("guilds").insert(
                {
                    "id": str(guild.id),
                    "roleBinds": role_binds
                },
                conflict="update").run()

            await post_event(
                guild, guild_data, "bind",
                f"{author.mention} ({author.id}) has **bound** {bind_choice_title} `{display_name}`.",
                BLURPLE_COLOR)

            await clear_guild_data(guild)

            await response.success(
                f"Successfully **bound** {bind_choice_title} `{display_name}` ({bind_id}) with Discord role(s) **{', '.join([r.name for r in discord_roles])}!**"
            )
Example #30
0
    async def __main__(self, CommandArgs):
        author = CommandArgs.author
        response = CommandArgs.response
        prefix = CommandArgs.prefix

        if not SELF_HOST:
            author_data = await self.r.db("bloxlink").table("users").get(
                str(author.id)).run() or {
                    "id": str(author.id)
                }

            try:
                primary_account, accounts = await get_user("username",
                                                           author=author,
                                                           everything=False,
                                                           basic_details=True)

                if accounts:
                    parsed_accounts = await parse_accounts(accounts)
                    parsed_accounts_str = ", ".join(parsed_accounts.keys())

                    parsed_args = await CommandArgs.prompt([{
                        "prompt":
                        "This command will allow you to switch into an account you verified as in the past.\n"
                        f"If you would like to link __a new account__, then please use `{prefix}verify add`.\n\n"
                        "**__WARNING:__** This will remove __all of your roles__ in the server and give you "
                        "new roles depending on the server configuration.",
                        "footer":
                        "Say **next** to continue.",
                        "type":
                        "choice",
                        "choices": ["next"],
                        "name":
                        "_",
                        "formatting":
                        False
                    }, {
                        "prompt":
                        "Are you trying to change your account for _this_ server? If so, simply say `next`.\nIf not, please provide "
                        "the __Server ID__ of the server to switch as. Please see this article to find the Server ID: "
                        "[click here](https://support.discordapp.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID->).",
                        "name":
                        "guild",
                        "validation":
                        self.validate_server,
                    }, {
                        "prompt":
                        "We'll switch your account for the server **{guild.name}**.\n"
                        "Please select an account to switch into:```" +
                        parsed_accounts_str + "```",
                        "name":
                        "account",
                        "type":
                        "choice",
                        "choices":
                        list(parsed_accounts.keys())
                    }, {
                        "prompt":
                        "Would you like to make this your __primary__ account? Please say **yes** or **no**.",
                        "name":
                        "primary",
                        "type":
                        "choice",
                        "choices": ("yes", "no")
                    }],
                                                           last=True)

                    guild = parsed_args["guild"]
                    username = parsed_args["account"]
                    roblox_id = (parsed_accounts.get(username)).id

                    guild_data = await self.r.table("guilds").get(str(
                        guild.id)).run() or {
                            "id": str(guild.id)
                        }

                    trello_board = await get_board(guild_data=guild_data,
                                                   guild=guild)

                    if trello_board:
                        options_trello, _ = await get_options(trello_board)
                        guild_data.update(options_trello)

                    allow_reverify = guild_data.get(
                        "allowReVerify", DEFAULTS.get("allowReVerify"))
                    roblox_accounts = author_data.get("robloxAccounts", {})

                    if guild and not allow_reverify:
                        guild_accounts = roblox_accounts.get("guilds", {})
                        chosen_account = guild_accounts.get(str(guild.id))

                        if chosen_account and chosen_account != roblox_id:
                            raise Error(
                                "You already selected your account for this server. `allowReVerify` must be "
                                "enabled for you to change it.")

                    try:
                        member = await guild.fetch_member(author.id)
                    except (Forbidden, NotFound):
                        await verify_member(
                            author,
                            roblox_id,
                            guild=guild,
                            author_data=author_data,
                            allow_reverify=allow_reverify,
                            primary_account=parsed_args["primary"] == "yes")
                        raise Message(
                            "You're not a member of the provided server, so I was only able to update your account internally.",
                            type="success")

                    try:
                        username = await verify_as(
                            member,
                            guild,
                            response=response,
                            primary=parsed_args["primary"] == "yes",
                            roblox_id=roblox_id,
                            trello_board=trello_board,
                            update_user=False)

                    except Message as e:
                        if e.type == "error":
                            await response.error(e)
                        else:
                            await response.send(e)
                    except Error as e:
                        await response.error(e)
                    else:
                        role_binds, group_ids, _ = await get_binds(
                            guild_data=guild_data, trello_board=trello_board)

                        if count_binds(
                                guild_data,
                                role_binds=role_binds,
                                group_ids=group_ids) and not find(
                                    lambda r: r.name == "Bloxlink Bypass",
                                    member.roles):
                            for role in list(member.roles):
                                if role != guild.default_role and role.name != "Muted":
                                    try:
                                        await member.remove_roles(
                                            role, reason="Switched User")
                                    except Forbidden:
                                        pass
                        try:
                            added, removed, nickname, errors, warnings, roblox_user = await update_member(
                                member,
                                guild=guild,
                                roles=True,
                                nickname=True,
                                response=response,
                                cache=False)

                        except BloxlinkBypass:
                            await response.info(
                                "Since you have the `Bloxlink Bypass` role, I was unable to update your roles/nickname; however, your account was still changed."
                            )

                            return

                        except Blacklisted as b:
                            if isinstance(b.message, str):
                                raise Error(
                                    f"{author.mention} has an active restriction for: `{b}`."
                                )
                            else:
                                raise Error(
                                    f"{author.mention} has an active restriction from Bloxlink."
                                )
                        else:
                            welcome_message = guild_data.get(
                                "welcomeMessage") or DEFAULTS.get(
                                    "welcomeMessage")

                            welcome_message = await get_nickname(
                                author,
                                welcome_message,
                                guild_data=guild_data,
                                roblox_user=roblox_user,
                                is_nickname=False)

                            await post_event(
                                guild, guild_data, "verification",
                                f"{author.mention} ({author.id}) has **switched their user** to `{username}`.",
                                GREEN_COLOR)

                            await CommandArgs.response.send(welcome_message)

                else:
                    raise Message(
                        f"You only have one account linked! Please use `{prefix}verify add` to add another.",
                        type="info")

            except UserNotVerified:
                raise Error(
                    f"You're not linked to Bloxlink. Please use `{prefix}verify add`."
                )

        else:
            raise Message(f"{author.mention}, to verify with Bloxlink, please visit our website at " \
                          f"<{VERIFY_URL}>. It won't take long!\nStuck? See this video: <https://www.youtube.com/watch?v=hq496NmQ9GU>")
Example #31
0
async def launch_santa(context):
    """
    Quick note about Discord user mentions before you read this function:
    Discord users all have a unique ID that can be used to mention them as if you were to @ their name.
    I'll call this the user mention. It looks something like this: <@162606971705491458> or <@!179067358369939456>
    Your user mention may or may not have an '!' as it's third character. This is dynamic as far as I know.
    Because of this, user-rsn pairs are saved by the bot based on your ID number, not the extraneous symbols.
    When creating SENDER_LIST, the bot looks up users based on their mention. There is a check in there that removes the
    extra '!' if the user does not have one in their mention
    """

    user_roles = context.message.author.roles       #gets user role list
    for role in user_roles:                         #loops through user roles
        if '🗝️ FiH Leader' == role.name:            #checks if user has role to use command
            santa_file = open('secret_santa.txt', 'r')  #opens secret santa roster
            participants = santa_file.read()            #reads in participant list (set of RSNs)
            santa_file.close()                          #closes secret santa roster

            participant_list = participants.split('\n') #splits participants into list
            participant_users = []                      #creates user array

            for p in participant_list:              #loops through participant list
                user = get_user(p)                  #gets the user associated with given RSN
                if user is not None:                #checks if RSN has been claimed by a user
                    participant_users.append(user)  #adds user to participant list

            JAYCOLE = find(lambda m: m.mention == get_user("Jaycole"), context.message.channel.server.members)  #stores info for me for testing purposes
            if JAYCOLE is None:                     #check if it used the wrong mention
                j_user = get_user("Jaycole")        #gets my user mention again
                j_user = re.sub("!", "", j_user)    #removes ! from mention
                JAYCOLE = find(lambda m: m.mention == j_user, context.message.channel.server.members)   #re-saves me


            SENDER_LIST = []    #initialize sender list, which will be an array of Members

            # Member is a subclass of User, member is a Member
            # participant_users is an array of mentions

            for p in participant_users:                                                             #loop through participants
                member = find(lambda m: m.mention == p, context.message.channel.server.members)     #find the person's User based on their mention
                if member is None:                                                                  #checks if it used the wrong mention
                    p = re.sub("!", "", p)                                                          #removes ! from mention
                    member = find(lambda m: m.mention == p, context.message.channel.server.members) #re checks for User based on new mention
                SENDER_LIST.append(member)                                                          #adds user to sender list

            receivers = participant_list    #stores receivers as a pointer to participant list so I don't have to read in twice.

            f = open("santa_log.txt", "w+") #opens log file

            for user in SENDER_LIST:
                s = random.uniform(0, receivers.__len__())      #gets random value within list bounds
                s = round(s)                                    #rounds random number to a usable index
                receiver = receivers[s - 1]                     #gets receiver at that index

                while receiver == get_rsn(user.mention) and receiver is not None:   #redraws if user gets themself or an error
                    s = random.uniform(0, receivers.__len__())
                    s = round(s)
                    receiver = receivers[s - 1]

                receivers.pop(s - 1)                            #removes receiver from list
                try:                                            #tries to send target to user
                    await client.send_message(user, "Hey " + get_rsn(user.mention) + ", Your secret santa target is " + receiver + "!")
                except:                                         #catches if user private messages are set to private, sends target to me
                    await client.send_message(JAYCOLE, "Hey " + get_rsn(user.mention) + ", your secret santa target is " + receiver + "!")

                #await client.send_message(JAYCOLE, "Hey " + get_rsn(user.mention) + ", your secret santa target is " + receiver + "!") - test line to send all targets to me to test function
                f.write((user.name + " got " + receiver + '\n'))        #writes matches to log

                time.sleep(1)                                           #waits one second to avoid overrunning action limits

            f.close()                                                   #closes santa log
            await client.say("Secret Santa targets have been sent out! Check your inbox for your person!")  #announces that santa targets have been sent.
Example #32
0
async def on_guild_join(guild):
    starboard = find(lambda x: x.name == 'starboard', guild.text_channels)
    if not starboard:
        await guild.create_text_channel('starboard')
Example #33
0
def get_channel(i):
    p_i = C.channels[i] if i in C.channels else i
    return (C.client.get_channel(p_i) or C.client.get_channel(
        p_i.translate(C.punct2space).replace(' ', ''))
            or find(C.client.get_all_channels(), name=i)
            or find(C.client.get_all_channels(), name=i.replace('#', '')))
Example #34
0
    async def __main__(self, CommandArgs):
        prefix = CommandArgs.prefix
        guild = CommandArgs.message.guild
        response = CommandArgs.response

        my_permissions = guild.me.guild_permissions

        if not (my_permissions.manage_channels
                and my_permissions.manage_roles):
            raise Error(
                "I need both the ``Manage Channels`` and ``Manage Roles`` permissions."
            )

        setup_args = await CommandArgs.prompt([{
            "prompt":
            "**Thank you for choosing Bloxlink!** In a few simple prompts, **we'll configure this add-on "
            "for your server.**\n\n**The Court Add-on**\nThis add-on allows you to assign judges which have "
            "the power to create cases within your Discord server. Created cases reside in Discord channels where "
            "the messages are all saved and can be exported later.",
            "name":
            "_",
            "footer":
            "Say **next** to continue.",
            "type":
            "choice",
            "choices": ["next"],
            "embed_title":
            "Setup Prompt"
        }, {
            "prompt":
            "Which **role(s)** are considered the ``Judge`` roles? Members with these roles will be able to "
            "create new cases and use certain judicial administrative commands.",
            "name":
            "judge_roles",
            "type":
            "role",
            "multiple":
            True,
            "embed_title":
            "Setup Prompt"
        }, {
            "prompt":
            "Which ``channel`` would you like to use for logging case events?",
            "name": "log_channel",
            "footer": "Say **skip** to skip this step.",
            "exceptions": ("skip", ),
            "type": "channel",
        }, {
            "prompt":
            "Which ``category`` would you like to use for archiving closed cases? If you skip this, then old cases "
            "will simply be deleted.",
            "name":
            "archive_category",
            "footer":
            "Say **skip** to skip this step.",
            "exceptions": ("skip", ),
            "type":
            "category",
        }, {
            "prompt":
            "Please specify the **groups** to use with your set-up.\n\nA group holds members for each trial. For example, typical groups "
            "for a USA style court room include the ``prosecution``, ``defence``, ``jurors``, and ``witnesses``. Please **give a list separated by "
            "commas** of your group names.\n\nFor example, you may write: ``prosecution, defense, jurors``\n\nJudges will be able to add people into these groups to fit their trial.\n\n__It's fine if you include groups "
            "which aren't used__, groups __can be__ blank. ",
            "name":
            "groups",
            "type":
            "list",
        }],
                                              last=True)

        judge_roles = setup_args["judge_roles"]
        log_channel = setup_args["log_channel"]
        groups = setup_args["groups"]
        archive_category = setup_args["archive_category"]

        addon_data = await self.r.table("addonData").get(str(guild.id)
                                                         ).run() or {}
        court_data = addon_data.get("court") or {}

        category = None
        create_category = False

        if archive_category != "skip":
            overwrites = {
                guild.default_role: PermissionOverwrite(read_messages=False),
                guild.me: PermissionOverwrite(read_messages=True),
            }
            overwrites.update({
                k: PermissionOverwrite(read_messages=True)
                for k in judge_roles
            })

            try:
                await archive_category.edit(overwrites=overwrites)
            except Forbidden:
                raise Error(
                    "I need both the ``Manage Channels`` and ``Manage Roles`` permissions."
                )

        if court_data.get("category"):
            category = find(lambda c: c.id == int(court_data["category"]),
                            guild.categories)

            if not category:
                create_category = True
        else:
            create_category = True

        if create_category:
            overwrites = {
                guild.default_role: PermissionOverwrite(read_messages=False),
                guild.me: PermissionOverwrite(read_messages=True),
            }
            overwrites.update({
                k: PermissionOverwrite(read_messages=True)
                for k in judge_roles
            })

            try:
                category = find(lambda c: c.name == "Cases", guild.categories) or \
                           await guild.create_category("Cases", overwrites=overwrites)

            except Forbidden:
                raise Error(
                    "I need both the ``Manage Channels`` and ``Manage Roles`` permissions."
                )

        addon_data["court"] = {
            "judgeRoles": [str(x.id) for x in judge_roles],
            "logChannel":
            str(log_channel.id) if log_channel != "skip" else None,
            "archiveCategory":
            str(archive_category.id) if archive_category != "skip" else None,
            "category":
            str(category.id) if category else None,
            "groups":
            groups
        }

        await self.r.table("addonData").insert(
            {
                "id": str(guild.id),
                **addon_data
            }, conflict="update").run()

        embed = Embed(
            title="Additional Information",
            description=
            f"- Use ``{prefix}case create`` to make a new case chat.\n"
            "- Need to change your groups? You will need to run this command again.\n"
            f"- It's recommended to give your cases IDs! You'll be able to run ``{prefix}case lookup`` to find its information.\n"
            f"- You will need to add case members with ``{prefix}case add`` and assign them to a group. Remove them with ``{prefix}case remove``.\n"
            f"- Run ``{prefix}case end`` inside your case chat to archive the case.\n"
            f"- If you manually delete case channels, then you will need to run ``{prefix}case cleanup`` to free them from the database; otherwise, they will count against your case limit.\n"
            f"- Case members can be easily muted/unmuted with ``{prefix}case mute`` or ``{prefix}case unmute``."
        )

        await response.send(embed=embed)

        await response.success(
            f"Successfully saved your **Court add-on!** Now, judges (people with the {', '.join([r.mention for r in judge_roles])} role(s)) will be "
            f"able to run ``{prefix}case create`` to create a new case chat.",
            allowed_mentions=AllowedMentions(roles=False))
Example #35
0
def on_member_remove(member):
    channel = find(lambda chan: chan.name == 'public', member.server.channels)
    client.send_message(channel, '{name} has left the server.'.format(name=member))
Example #36
0
    async def parse_message(self, message, guild_data=None):
        guild = message.guild
        content = message.content
        author = message.author
        channel = message.channel

        if guild:
            guild_restriction = await get_restriction("guilds", guild.id)

            if guild_restriction:
                await guild.leave()
                raise CancelCommand

        guild_permissions = guild and guild.me.guild_permissions

        channel_id = channel and str(channel.id)
        guild_id = guild and str(guild.id)

        trello_board = guild and await get_board(guild)
        prefix, _ = await get_prefix(guild, trello_board)

        client_match = re.search(f"<@!?{self.client.user.id}>", content)
        check = (content[:len(prefix)].lower() == prefix.lower()
                 and prefix) or client_match and client_match.group(0)
        check_verify_channel = False

        if check:
            after = content[len(check):].strip()
            args = after.split(" ")
            command_name = args[0] and args[0].lower()
            del args[0]

            if command_name:
                for index, command in commands.items():
                    if index == command_name or command_name in command.aliases:
                        guild_data = guild_data or (
                            guild and
                            (await self.r.table("guilds").get(guild_id).run()
                             or {
                                 "id": guild_id
                             })) or {}

                        fn = command.fn
                        subcommand_attrs = {}
                        subcommand = False

                        if args:
                            # subcommand checking
                            subcommand = command.subcommands.get(args[0])
                            if subcommand:
                                fn = subcommand
                                subcommand_attrs = getattr(
                                    fn, "__subcommandattrs__", None)
                                del args[0]

                        after = args and " ".join(args) or ""

                        CommandArgs = Args(command_name=index,
                                           real_command_name=command_name,
                                           message=message,
                                           channel=message.channel,
                                           author=message.author,
                                           guild=message.guild,
                                           guild_data=guild_data,
                                           flags={},
                                           prefix=prefix,
                                           has_permission=False,
                                           command=command)

                        if getattr(fn, "__flags__", False):
                            flags, flags_str = command.parse_flags(after)
                            content = content.replace(flags_str, "")
                            message.content = content
                            after = after.replace(flags_str, "")
                            CommandArgs.flags = flags

                        locale = Locale(
                            guild_data and guild_data.get("locale", "en")
                            or "en")
                        response = Response(CommandArgs,
                                            author,
                                            channel,
                                            guild,
                                            message,
                                            slash_command=False)

                        CommandArgs.add(locale=locale,
                                        response=response,
                                        trello_board=trello_board)

                        await self.command_checks(command,
                                                  prefix,
                                                  response,
                                                  guild_data,
                                                  author,
                                                  channel,
                                                  locale,
                                                  CommandArgs,
                                                  message,
                                                  guild,
                                                  subcommand_attrs,
                                                  slash_command=False)

                        arguments = Arguments(CommandArgs,
                                              author,
                                              channel,
                                              command,
                                              guild,
                                              message,
                                              subcommand=(subcommand,
                                                          subcommand_attrs)
                                              if subcommand else None,
                                              slash_command=False)

                        await self.execute_command(command, fn, response,
                                                   CommandArgs, author,
                                                   channel, arguments, locale,
                                                   guild_data, guild, message,
                                                   trello_board, after, False)

                        break

                else:
                    check_verify_channel = True
            else:
                check_verify_channel = True
        else:
            check_verify_channel = True

        if guild and guild_permissions.manage_messages:
            if not isinstance(author, Member):
                try:
                    author = await guild.fetch_member(author.id)
                except NotFound:
                    return

            if check_verify_channel:
                verify_channel_id = await get_guild_value(
                    guild, "verifyChannel")

                if verify_channel_id and channel_id == verify_channel_id:
                    if not find(lambda r: r.name in MAGIC_ROLES, author.roles):
                        try:
                            await message.delete()
                        except (Forbidden, NotFound):
                            pass
Example #37
0
def finder(predicate, seq):
    data = find(predicate, seq)
    return data
Example #38
0
  "Set the universal nickname template. Note that `{prefix}bind` nicknames will override this."
  ),
 "unverifiedRoleName":
 (None, "string", 100, False,
  "Set the 'Unverified' role name -- the role that Unverified users get."),
 "shorterNicknames":
 (None, "boolean", None, False,
  "Brackets in group rank names will be captured instead of the full rank name, resulting in a shorter nickname."
  ),
 "ageLimit":
 (None, "number", None, True,
  "Set the minimum Roblox age in days a user must be to enter your server. People who are less than this value will be kicked."
  ),
 "inactiveRole":
 (lambda g, gd: gd.get("inactiveRole") and
  find(lambda r: r.id == int(gd["inactiveRole"]), g.roles), "role", None,
  True,
  "Set the role given to people who declared themselves as \"inactive\" from `{prefix}profile`."
  ),
 "banRelatedAccounts":
 (None, "boolean", None, True,
  "If this is enabled: when members are banned, their known alts are also banned from the server."
  ),
 "unbanRelatedAccounts":
 (None, "boolean", None, True,
  "If this is enabled: when members are unbanned, their known alts are also unbanned from the server."
  ),
 "disallowAlts":
 (None, "boolean", None, True,
  "If this is enabled: when someone joins the server and already has a linked account in the server, kick the old alt out."
  ),
Example #39
0
async def elections_timed(Demobot):

    dev = False
    # Making the election day not wednesday for dev purposes

    while True:
        currt = datetime.now(tz=pytz.utc)
        nextelection = currt + timedelta((2 - currt.weekday()) % 7 +
                                         (0 if dev else 1))
        nextelection = nextelection.replace(hour=2,
                                            minute=0,
                                            second=0,
                                            microsecond=0)
        await asyncio.sleep((nextelection -
                             currt).total_seconds() if not dev else 1)
        for a in server_data:
            chann = nested_get(a, "channels", "announcements")
            citizen_m = nested_get(a, "roles", "citizen").mention
            tim = nextelection.astimezone(
                pytz.timezone('US/Pacific')).strftime('%H:%M')
            if chann:
                await Demobot.send_message(
                    chann, citizen_m +
                    "! Elections have now started. They end in two days at " +
                    tim + ".")

            next = nested_get(a, 'channels', 'elections')
            if next:
                await Demobot.send_message(
                    next, '```\n```\n\n**Elections Start Here**\n\n' +
                    'Leader: Candidate with the largest difference between up and down wins.\n'
                    +
                    'Representative: Candidates with at least a third of the generic win.\n\n'
                    +
                    'Click the reactions to toggle a vote. You can vote more than once.\n'
                    + '**Remember to vote the generic!**')
                nested_set({}, a, 'elections', 'msg')
                le = nested_get(a, 'elections', 'leader')
                for b in le:
                    c = await Demobot.send_message(
                        next, '.\n\n**Leader Candidate**\n' +
                        nested_get(a, 'elections', 'leader', b).desc +
                        '\n\nVotes: **0 - 0**')
                    await Demobot.add_reaction(c, '👍')
                    await Demobot.add_reaction(c, '👎')
                    nested_set(
                        nested_get(a, 'elections', 'leader', b).ii, a,
                        'elections', 'msg', c.id)
                er = nested_get(a, 'elections', 'representative')
                out = '.\n\n**Representative Candidates**\nYou must vote the generic vote!\n\n'
                key = 127462
                count = ('\n\nVotes: **0 | ' + '0 - ' * len(er))[:-3] + '**'
                for b in er:
                    out += chr(key) + ' ' + nested_get(
                        a, 'elections', 'representative', b).desc + '\n'
                    nested_set(
                        nested_get(a, 'elections', 'representative', b).ii, a,
                        'elections', 'msg', key)
                    key += 1
                c = await Demobot.send_message(next, out + count)
                await Demobot.add_reaction(c, '🗳')
                for d in range(127462, key):
                    await Demobot.add_reaction(c, chr(d))
                nested_set('rep', a, 'elections', 'msg', c.id)
        await asyncio.sleep(172800 if not dev else 1)
        for a in server_data:
            chann = nested_get(a, 'channels', 'announcements')
            citizen_m = nested_get(a, "roles", "citizen").mention

            for l in nested_get(a, 'members', 'leader'):
                await Demobot.remove_roles(l, nested_get(a, 'roles', 'leader'))

            le = nested_get(a, 'elections', 'leader')
            winner = 1000
            user = None
            for b in le:
                c = nested_get(a, 'elections', 'leader', b)
                if winner == 1000 or len(c.up) - len(c.down) > winner:
                    winner = len(c.up) - len(c.down)
                    user = find(lambda m: m.id == c.ii,
                                Demobot.get_server(a).members)

            for l in nested_get(a, 'members', 'representative'):
                await Demobot.remove_roles(
                    l, nested_get(a, 'roles', 'representative'))

            generic = len(nested_get(a, 'elections', 'generic'))
            er = nested_get(a, 'elections', 'representative')
            users = []
            nested_pop(a, 'elections', 'representatives')
            for b in er:
                c = nested_get(a, 'elections', 'representative', b)
                nested_set(Backup(time(),
                                  len(c.up) / generic), a, 'elections',
                           'backup', c.ii)
                if len(c.up) / generic >= 1 / 3 and not c.ii == user.id:
                    users.append(
                        find(lambda m: m.id == c.ii,
                             Demobot.get_server(a).members))

            secondary = []
            forbid = [user.id]
            for b in range(max(0, 3 - len(users))):
                thing = next_backup(a, forbid)
                secondary.append(
                    find(lambda m: m.id == thing,
                         Demobot.get_server(a).members))
                forbid.append(thing)

            await Demobot.remove_roles(
                user, nested_get(a, 'roles', 'representative'))
            await Demobot.add_roles(user, nested_get(a, 'roles', 'leader'))

            out = ''
            for u in users:
                await Demobot.add_roles(
                    u, nested_get(a, 'roles', 'representative'))
                out += u.mention + ', '

            out = 'No one was elected representative.\n' \
                if out == '' else out[:-2] + " have been elected representative!\n"
            for u in secondary:
                await Demobot.add_roles(
                    u, nested_get(a, 'roles', 'representative'))
                out += u.mention + ', '

            if chann:
                await Demobot.send_message(
                    chann, citizen_m + "! Elections have now ended.")
                await Demobot.send_message(
                    chann, user.mention + " has been elected leader!")
                await Demobot.send_message(
                    chann,
                    out[:-2] + " have been made reps from the backup list.")

            if not dev:
                nested_set({}, a, 'elections')
                nested_set(set([]), a, 'elections', 'generic')
        await asyncio.sleep(100000)
Example #40
0
    async def on_message(self, message, **kwargs):
        # Things
        assert isinstance(message, Message)
        client = self.client

        # Prefixes
        prefix = kwargs.get("prefix")

        # Custom commands registered for the server
        server_commands = self.handler.get_custom_commands(
            message.channel.server)

        # Checks for server specific commands
        for command in server_commands:
            # UPDATE 2.1.4: not .startswith anymore!
            if str(message.content) == command:
                # Maybe same replacement logic in the future update?
                # /todo implement advanced replacement logic
                await client.send_message(message.channel,
                                          server_commands.get(command))
                self.stats.add(MESSAGE)

                return

        if not is_valid_command(message.content, valid_commands,
                                prefix=prefix):
            return
        else:
            self.stats.add(MESSAGE)

        # A shortcut
        def startswith(*msg):
            for b in msg:
                if message.content.startswith(b):
                    return True

            return False

        # COMMANDS

        # !hello
        if startswith(prefix + "hello"):
            if len(message.mentions) >= 1:
                await client.send_message(message.channel,
                                          "Hi " + message.mentions[0].mention)
            elif len(message.mentions) == 0:
                await client.send_message(message.channel,
                                          "Hi " + message.author.mention)

        # !uptime
        elif startswith(prefix + "uptime"):
            d = datetime(
                1, 1, 1) + timedelta(seconds=time.time() - self.nano.boot_time)
            uptime = "I have been tirelessly answering people for\n" \
                     "**{} days, {} hours, {} minutes and {} seconds!**".format(d.day - 1, d.hour, d.minute, d.second)

            await client.send_message(message.channel, uptime)

        # !nano, nano.info
        elif startswith((prefix + "nano", "nano.info")):
            await client.send_message(
                message.channel,
                nano_info.replace("<version>", self.nano.version))

        # !github
        elif startswith(prefix + "github"):
            await client.send_message(message.channel, nano_github)

        # !roll
        elif startswith(prefix + "roll"):
            if startswith(prefix + "roll"):
                num = message.content[len(prefix + "roll "):]
            else:
                num = message.content[len(prefix + "rng "):]

            if not str(num).isnumeric():
                await client.send_message(message.channel, "Not a number.")
                return

            rn = randint(0, int(num))
            result = "**{}**. {}".format(rn,
                                         "**GG**" if rn == int(num) else "")

            await client.send_message(
                message.channel,
                "{}, you rolled {}".format(message.author.mention, result))

        # !dice
        elif startswith(prefix + "dice"):
            rn = randint(1, 6)
            await client.send_message(
                message.channel,
                "{}, the dice shows... **{}**".format(message.author.mention,
                                                      rn))

        # !ping
        elif startswith(prefix + "ping"):
            base_time = datetime.now() - message.timestamp
            base_taken = int(divmod(base_time.total_seconds(), 60)[1] * 100)

            a = await client.send_message(message.channel, PING_MSG)
            self.pings[a.id] = [
                time.monotonic(), message.channel.id, base_taken
            ]

            await client.add_reaction(a, "\U0001F44D")
            self.stats.add(PING)

        # !decide
        elif startswith(prefix + "decide"):
            cut = str(message.content)[len(prefix + "decide "):]

            if len(cut.split("|")) == 1:
                await client.send_message(
                    message.channel,
                    "Guess what? It's " + str(cut) + ". **ba dum tss.**")

            else:
                split = cut.split("|")
                rn = randint(0, len(split) - 1)
                await client.send_message(
                    message.channel,
                    "**drum roll**... I have decided: {}".format(split[rn]))

        # !8ball
        elif startswith(prefix + "8ball"):
            answer = eight_ball[randint(0, len(eight_ball) - 1)]
            await client.send_message(
                message.channel, "The magic 8ball says: *{}*.".format(answer))

        # !quote
        elif startswith(prefix + "quote"):
            chosen = str(quotes[randint(0, len(quotes) - 1)])

            # Find the part where the author is mentioned
            place = chosen.rfind("–")
            await client.send_message(
                message.channel, "{}\n- __{}__".format(chosen[:place],
                                                       chosen[place + 1:]))

        # !invite
        elif startswith(prefix + "invite", "nano.invite"):
            application = await client.application_info()

            # Most of the permissions that Nano uses
            perms = "1543765079"
            url = "<https://discordapp.com/oauth2/" \
                  "authorize?client_id={}&scope=bot&permissions={}>".format(application.id, perms)

            await client.send_message(message.channel,
                                      invite.replace("<link>", url))

        # !avatar
        elif startswith(prefix + "avatar"):
            # Selects the proper user
            if len(message.mentions) == 0:
                name = str(str(message.content)[len(prefix + "avatar "):])
                member = utils.find(lambda m: m.name == name,
                                    message.channel.server.members)
            else:
                member = message.mentions[0]

            if not member:
                member = message.author

            url = member.avatar_url

            if url:
                await client.send_message(
                    message.channel,
                    "**{}**'s avatar: {}".format(member.name, url))
            else:
                await client.send_message(
                    message.channel,
                    "**{}** does not have an avatar. {}".format(
                        member.name, StandardEmoji.EXPRESSIONLESS))

        # !say
        elif startswith(prefix + "say"):
            if not self.handler.is_mod(message.author, message.server):
                await client.send_message(message.channel,
                                          StandardEmoji.WARNING + not_mod)
                return "return"

            content = str(message.content[len(prefix + "say "):]).strip(" ")

            if len(message.channel_mentions) != 0:
                channel = message.channel_mentions[0]
                content = content.replace(channel.mention, "").strip(" ")
            else:
                channel = message.channel

            content = self.at_everyone_filter(content, message.author,
                                              message.server)

            await client.send_message(channel, content)

            await self.log_say_command(message, content, prefix)

        # !selfrole [role name]
        elif startswith(prefix + "selfrole"):
            role = str(message.content[len(prefix + "selfrole"):]).strip(" ")
            s_role = self.handler.get_selfrole(message.server.id)

            if is_disabled(s_role):
                await client.send_message(
                    message.channel, StandardEmoji.WARNING +
                    " This feature is not enabled on this server.")
            elif (role != s_role) and len(message.role_mentions) == 0:
                await client.send_message(
                    message.channel, StandardEmoji.CROSS + " Wrong role name.")
            else:
                if len(message.role_mentions) != 0:
                    role = message.role_mentions[0]
                else:
                    role = utils.find(lambda r: r.name == s_role,
                                      message.server.roles)

                if not role:
                    return

                # If user already has the role, remove it
                if role in message.author.roles:
                    await client.remove_roles(message.author, role)
                    await client.send_message(
                        message.channel, StandardEmoji.PERFECT +
                        " Removed **{}** from your list of roles.".format(
                            s_role))
                else:
                    await client.add_roles(message.author, role)
                    await client.send_message(message.channel,
                                              StandardEmoji.PERFECT)
Example #41
0
    "Linked Groups":         (None,  None, None,     False, "Bind groups to your server so group members get specific roles."),
    "allowOldRoles":         (None, "boolean", None, False, "Bloxlink will NOT remove roles if this is enabled."),
    "autoRoles":             (None, "boolean", None, False, "Bloxlink will give all matching/corresponding roles to people who join the server. Set eligible roles with ``{prefix}bind``. Note that this being enabled will override 'autoVerification'."),
    "autoVerification":      (None, "boolean", None, False, "Bloxlink will give the Verified role to people who join the server and are linked to Bloxlink.\nNote that 'autoRoles' being enabled overrides this setting."),
    #"dmVerifications":       (None, "boolean", None, False, "Set whether verifications default to DMs."),
    "dynamicRoles":          (None, "boolean", None, False, "Bloxlink will make missing group roles from your Linked Groups as people need them."),
    "welcomeMessage":        (None, "string", 1500,  False, "The welcome message is used on ``{prefix}verify`` responses. Note that you can use these templates: ```{templates}```"),
    "joinDM":                (lambda g, gd: bool(gd.get("verifiedDM", True)) or bool(gd.get("unverifiedDM")), None, None, False, "Customize the join DM messages of people who join the server."),
    "persistRoles":          (None, "boolean", None, True,  "Update members' roles/nickname as they type."),
    "allowReVerify":         (None, "boolean", None, True,  "If this is enabled: members can change their Roblox account as many times as they want in your server; otherwise, only allow 1 account change."),
    "trelloID":              (None,  None, None,     False, "Link a Trello board that can change Bloxlink settings!"),
    "nicknameTemplate":      (None,  "string", 100,  False, "Set the universal nickname template. Note that ``{prefix}bind`` nicknames will override this."),
    "unverifiedRoleName":    (None,  "string", 100,  False, "Set the 'Unverified' role name -- the role that Unverified users get."),
    "shorterNicknames":      (None,  "boolean", None,False, "Brackets in group rank names will be captured instead of the full rank name, resulting in a shorter nickname."),
    "ageLimit":              (None,  "number", None, True,  "Set the minimum Roblox age in days a user must be to enter your server. People who are less than this value will be kicked."),
    "inactiveRole":          (lambda g, gd: gd.get("inactiveRole") and find(lambda r: r.id == int(gd["inactiveRole"]), g.roles), "role", None, True, "Set the role given to people who declared themselves as \"inactive\" from ``{prefix}profile``."),
    "banRelatedAccounts":    (None, "boolean", None, True,  "If this is enabled: when members are banned, their known alts are also banned from the server."),
    "unbanRelatedAccounts":  (None, "boolean", None, True,  "If this is enabled: when members are unbanned, their known alts are also unbanned from the server."),
    "disallowAlts":          (None, "boolean", None, True,  "If this is enabled: when someone joins the server and already has a linked account in the server, kick the old alt out."),
    "disallowBanEvaders":    (None, "choice", ("ban", "kick"), True,  "If this is enabled: when members join, and they have a banned account in the server, their new account will also be actioned."),
    #"groupShoutChannel":     (lambda g, gd: g.get_channel(int(gd.get("groupShoutChannel", "0"))),  None, None, True, "Group shouts will be sent to your Discord channel."),
    "whiteLabel":            (lambda g, gd: bool(gd.get("customBot")),  None, None, True,      "Modify the username and profile picture of __most__ Bloxlink responses."),
    "promptDelete":          (None, "boolean", None, False, "Toggle the deleting of prompt messages after it finishes."),
    "deleteCommands":        (None, "number", 25, False, "Set X higher than 0 to delete every command after X seconds."),
    "trelloBindMode":        (None, "choice", ("merge", "replace"), False, "Choose 'replace' if trello binds should replace the server binds, or 'merge' if trello binds should be merged with the server binds. Default = merge."),
}

PROMPT = {
	"PROMPT_TIMEOUT": 300,
	"PROMPT_ERROR_COUNT": 5
}
Example #42
0
def on_member_join(member):
    channel = find(lambda chan: chan.name == 'public', member.server.channels)
    client.send_message(channel, 'Please welcome {name} to the server!'.format(name=member.mention()))
async def on_guild_join(guild):
    await client.change_presence(activity=discord.Game(name=f"P!help | Serving pizza in {len(client.guilds)} servers"), status=discord.Status.online)
    general = find(lambda x: x.name == 'general', guild.text_channels)
    if general and general.permissions_for(guild.me).send_messages:
        await general.send(f"Hello {guild.name}! Do P!help and I'll DM you with info about how to make an order!")
Example #44
0
    async def __main__(self, CommandArgs):
        response = CommandArgs.response
        guild_data = CommandArgs.guild_data
        prefix = CommandArgs.prefix

        guild = CommandArgs.guild

        async with response.loading():
            try:
                category = find(lambda c: c.name == "Verification", guild.categories) or \
                        await guild.create_category("Verification")

                verify_info = find(lambda t: t.name == "verify-instructions", category.channels) or \
                            await guild.create_text_channel("verify-instructions", category=category)

                verify_channel = find(lambda t: t.name == "verify", category.channels) or \
                                await guild.create_text_channel("verify", category=category)

                sample_channel = await guild.create_text_channel("sample-channel")

            except Forbidden:
                raise PermissionError("I was unable to create the necessary channels. Please ensure I have the "
                                    "`Manage Channels` permission.")

            except HTTPException:
                raise Error("You have too many channels or categories! Please delete some before continuing.")

            try:
                await verify_info.send("This server uses Bloxlink to manage Roblox verification. In "
                                    "order to unlock all the features of this server, you'll need "
                                    "to verify your Roblox account with your Discord account!\n\nTo "
                                    f"do this, run `{prefix}getrole` in {verify_channel.mention} and follow the instructions.")

                await sample_channel.send("This is a sample channel that only Verified users " \
                                        "can read. This channel is not important, you may freely delete it.\n" \
                                        "To create another sample channel, right click this channel and click 'Clone " \
                                        "Text Channel', or just run this command again.")

            except (Forbidden, NotFound):
                raise PermissionError("I was unable to send messages to the created channels. Please give me the "
                                    "proper permissions.")


            try:
                await verify_info.set_permissions(guild.me, send_messages=True, read_messages=True)

                verified_role_name = guild_data.get("verifiedRoleName", DEFAULTS.get("verifiedRoleName"))

                for role in guild.roles:
                    if role.name != guild.me.name:
                        await verify_info.set_permissions(role, send_messages=False, read_messages=True)
                        await verify_channel.set_permissions(role, send_messages=True, read_messages=True)

                    if role.name == verified_role_name:
                        for target, overwrite in sample_channel.overwrites.items():
                            await sample_channel.set_permissions(target, overwrite=None)

                        await sample_channel.set_permissions(guild.default_role, send_messages=False, read_messages=False)
                        await sample_channel.set_permissions(role, send_messages=True, read_messages=True)


            except Forbidden:
                raise PermissionError("Unable to set permissions to the channels. Please ensure I have the "
                                    "`Manage Channels` and `Manage Roles` permission.")

            except NotFound:
                raise Error("Please do not delete the created channels while I'm setting them up...")


        await self.r.table("guilds").insert({
            "id": str(guild.id),
            "verifyChannel": str(verify_channel.id)
        }, conflict="update").run()

        await response.success(f"All done! Your new verification channel is {verify_channel.mention} and " \
                                "is now managed by Bloxlink.")
Example #45
0
async def on_member_join(member):
    if member.server.id == '393603672778604544':
        await client.add_roles(
            member,
            find(lambda r: r.id == '393637330700861441', member.server.roles))
Example #46
0
async def on_guild_join(guild):
    general = find(lambda x: x.name == 'general',  guild.text_channels)
    if general and general.permissions_for(guild.me).send_messages:
        await general.send('Hey it\'s me, AraonJR {} sure looks cozy!'.format(guild.name))
Example #47
0
    async def check_permissions(self, author, guild, locale, dm=False, permissions=None, **kwargs):
        permissions = permissions or self.permissions

        if author.id == OWNER:
            return True

        if permissions.developer_only or self.developer_only:
            if author.id != OWNER:
                raise PermissionError("This command is reserved for the Bloxlink Developer.")

        if (kwargs.get("premium", self.premium) or permissions.premium) and not kwargs.get("free_to_use", self.free_to_use):
            prem, _ = await get_features(Object(id=guild.owner_id), guild=guild)

            if not prem.features.get("premium"):
                prem, _ = await get_features(author)

                if not prem.attributes["PREMIUM_ANYWHERE"]:
                    raise Message("This command is reserved for Bloxlink Premium subscribers!\n"
                                  "The server owner must have premium for this to work. If you "
                                  "would like the server owner to have premium instead, please use the ``!transfer`` "
                                  "command.\nYou may subscribe to Bloxlink Premium on Patreon: https://patreon.com/bloxlink", type="silly")

        try:
            if not dm:
                author_perms = author.guild_permissions

                for role_exception in permissions.exceptions["roles"]:
                    if find(lambda r: r.name == role_exception, author.roles):
                        return True

                if permissions.bloxlink_role:
                    role_name = permissions.bloxlink_role

                    if find(lambda r: r.name == "Bloxlink Admin", author.roles):
                        return True
                    else:
                        if role_name == "Bloxlink Manager":
                            if author_perms.manage_guild or author_perms.administrator:
                                pass
                            else:
                                raise PermissionError("You need the ``Manage Server`` permission to run this command.")

                        elif role_name == "Bloxlink Moderator":
                            if author_perms.kick_members or author_perms.ban_members or author_perms.administrator:
                                pass
                            else:
                                raise PermissionError("You need the ``Kick`` or ``Ban`` permission to run this command.")

                        elif role_name == "Bloxlink Updater":
                            if author_perms.manage_guild or author_perms.administrator or author_perms.manage_roles or find(lambda r: r.name == "Bloxlink Updater", author.roles):
                                pass
                            else:
                                raise PermissionError("You either need: a role called ``Bloxlink Updater``, the ``Manage Roles`` "
                                                      "role permission, or the ``Manage Server`` role permission.")

                        elif role_name == "Bloxlink Admin":
                            if author_perms.administrator:
                                pass
                            else:
                                raise PermissionError("You need the ``Administrator`` role permission to run this command.")

                if permissions.allowed.get("discord_perms"):
                    for perm in permissions.allowed["discord_perms"]:
                        if perm == "Manage Server":
                            if author_perms.manage_guild or author_perms.administrator:
                                pass
                            else:
                                raise PermissionError("You need the ``Manage Server`` permission to run this command.")
                        else:
                            if not getattr(author_perms, perm, False) and not perm.administrator:
                                raise PermissionError(f"You need the ``{perm}`` permission to run this command.")


                for role in permissions.allowed["roles"]:
                    if not find(lambda r: r.name == role, author.roles):
                        raise PermissionError(f"Missing role: ``{role}``")

            if permissions.allowed.get("functions"):
                for function in permissions.allowed["functions"]:

                    if iscoroutinefunction(function):
                        data = [await function(author)]
                    else:
                        data = [function(author)]

                    if not data[0]:
                        raise PermissionError

                    if isinstance(data[0], tuple):
                        if not data[0][0]:
                            raise PermissionError(data[0][1])

        except PermissionError as e:
            if e.args:
                raise PermissionError(e)

            raise PermissionError("You do not meet the required permissions for this command.")
Example #48
0
 async def buy_ticket(self, ctx: SlashContext, name: str):
     # ticket buying logic
     await ensure_registered(ctx.author.id)
     can_control_bot = find(lambda _: _.name in ROLES_CAN_CONTROL_BOT,
                            ctx.author.roles)
     async with in_transaction(
     ):  # prevent race conditions via select_for_update + in_transaction
         # select user 2nd time to lock it's row
         user = await User.filter(id=ctx.author.id
                                  ).select_for_update().get(id=ctx.author.id
                                                            )
         # validate that lottery exists
         lottery = await Lottery.get_or_none(name=name)
         if not lottery:
             return await ctx.send(
                 f"{ctx.author.mention}, error, sweepstake `{name}` doesn't exist",
                 delete_after=DELETE_AFTER,
             )
         # validate that we allow selling tickets
         if lottery.status == LotteryStatus.STOP_SALES:
             return await ctx.send(
                 f"{ctx.author.mention}, tickets can't be bought for `{name}` because there are no tickets left or it's close to strike date",  # noqa: E501
                 delete_after=DELETE_AFTER,
             )
         elif lottery.status == LotteryStatus.STRIKED:
             return await ctx.send(
                 f"{ctx.author.mention}, tickets can't be bought for `{name}` because winning tickets were already selected",  # noqa: E501
                 delete_after=DELETE_AFTER,
             )
         elif lottery.status == LotteryStatus.ENDED:
             return await ctx.send(
                 f"{ctx.author.mention}, tickets can't be bought for `{name}` because it has ended",
                 delete_after=DELETE_AFTER,
             )
         elif lottery.is_whitelisted and not can_control_bot:
             return await ctx.send(
                 f"{ctx.author.mention}, tickets can't be bought for `{name}` because it is of `whitelisted` type",
                 delete_after=DELETE_AFTER,
             )
         # validate user balance
         if user.balance < lottery.ticket_price:
             return await ctx.send(
                 f"{ctx.author.mention}, not enough points, you only have `{pp_points(user.balance)}`{POINTS_EMOJI} in your sweepstake wallet and ticket price is `{int(lottery.ticket_price)}`{POINTS_EMOJI}. To add points to your sweepstake wallet, `!send @{ctx.bot.user.display_name}#{ctx.bot.user.discriminator} [number of points]`",  # noqa: E501
                 delete_after=DELETE_AFTER,
             )
         # handle whitelisted lotteries
         is_whitelisted_ticket = lottery.is_whitelisted and can_control_bot
         if is_whitelisted_ticket:
             try:
                 await ctx.send(
                     f"Hello, {ctx.author.mention}, this sweepstake is of whitelisted type, please mention user for whom you want to buy a ticket",  # noqa: E501
                     delete_after=DELETE_AFTER,
                 )
                 message = await self.bot.wait_for(
                     "message",
                     check=lambda m: m.guild is not None and m.author == ctx
                     .author,
                     timeout=300,
                 )
                 if len(message.raw_mentions) != 1:
                     return await ctx.send(
                         f"{ctx.author.mention}, you need to mention only one person",
                         delete_after=DELETE_AFTER)  # noqa: E501
                 owner_id = message.raw_mentions[0]
                 await ensure_registered(owner_id)
                 owner = await User.get(id=owner_id)
             except asyncio.TimeoutError:
                 return
         else:
             owner = user
         # to generate random ticket number that doesn't have collisions we will need to grab all ticket numbers
         # from database and then check in python which numbers are available
         ticket_numbers = await Ticket.filter(lottery=lottery
                                              ).values_list("ticket_number",
                                                            flat=True)
         # create ticket for user
         try:
             ticket = await Ticket.create(
                 user=owner,
                 lottery=lottery,
                 ticket_number=cryptogen.choice([
                     _
                     # make range to behave as inclusive range, this way ticket with max_number could be won
                     for _ in range(lottery.ticket_min_number,
                                    lottery.ticket_max_number + 1)
                     if _ not in ticket_numbers
                 ]),
             )
             user.balance = user.balance - lottery.ticket_price
             await user.save(update_fields=["balance", "modified_at"])
             if is_whitelisted_ticket:
                 await ctx.send(
                     f":tickets: Congratulations <@!{owner.id}>, you just had {lottery.name} purchased for you by {ctx.author.mention}.  Your ticket number is: {ticket.ticket_number}:tickets:"  # noqa: E501
                 )
             else:
                 await ctx.send(
                     f"{ctx.author.mention}, you bought {lottery.name} ticket with number: `{ticket.ticket_number}`, your balance is: `{pp_points(user.balance)}`{POINTS_EMOJI}"  # noqa: E501
                 )
         except IndexError:
             # it means that all tickets were sold, stop ticket sales for lottery
             lottery.status = LotteryStatus.STOP_SALES
             await lottery.save(update_fields=["status", "modified_at"])
             await ctx.send(
                 f"{ctx.author.mention}, ouch, the last ticket was sold a moment ago",
                 delete_after=DELETE_AFTER,
             )
Example #49
0
async def blue(ctx, member: discord.Member = None):
    '''changes role colour'''
    if member is None:
        member = ctx.message.author
    await eight.replace_roles(
        member, find(lambda r: r.name == 'Blue', ctx.message.server.roles))