Exemplo n.º 1
0
    async def execute_time_triggers(self, scope, command, options, lines,
                                    **kwargs):
        """
		List all time triggers.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        args = await self.parse_options(scope, parser, options)
        if not args:
            return

        stream = praxisbot.MessageStream(scope)
        await stream.send("__**List of time triggers**__")

        with scope.shell.dbcon:
            c = scope.shell.dbcon.cursor()
            for row in c.execute(
                    "SELECT id, script, start_time as 'start_time_ [timestamp]' FROM "
                    + scope.shell.dbtable("time_triggers") +
                    " WHERE discord_sid = ? ORDER BY start_time",
                [int(scope.server.id)]):
                start_time = timezone('UTC').localize(row[2])
                start_time = start_time.astimezone(timezone('Europe/Paris'))

                await stream.send("\n\n:timer: **Time trigger #" +
                                  str(row[0]) + ":** `" +
                                  start_time.strftime("%Y-%m-%d %H:%M:%S") +
                                  "`\n```\n" + row[1] + "\n```")

        await stream.finish()
Exemplo n.º 2
0
    async def execute_boards(self, scope, command, options, lines, **kwargs):
        """
		List all boards.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        args = await self.parse_options(scope, parser, options)
        if not args:
            return

        stream = praxisbot.MessageStream(scope)
        await stream.send("**List of boards**\n")

        with scope.shell.dbcon:
            c = scope.shell.dbcon.cursor()
            for row in c.execute(
                    "SELECT name, discord_cid FROM " +
                    scope.shell.dbtable("boards") +
                    " WHERE discord_sid = ? ORDER BY name",
                [int(scope.guild.id)]):

                chan = scope.shell.find_channel(str(row[1]), scope.guild)
                if not chan:
                    continue
                if scope.permission < praxisbot.UserPermission.Script and not chan.permissions_for(
                        scope.user).read_messages:
                    continue
                await stream.send("\n - `" + row[0] + "` in " + chan.mention)

        await stream.finish()
Exemplo n.º 3
0
    async def execute_role_members(self, scope, command, options, lines,
                                   **kwargs):
        """
		Display members of a role.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        parser.add_argument('role', help='Role to edit.')
        args = await self.parse_options(scope, parser, options)
        if not args:
            return

        role = scope.shell.find_role(args.role, scope.server)
        if not role:
            await scope.shell.print_error(
                scope, "Role `" + args.role + "` not found.")
            return

        stream = praxisbot.MessageStream(scope)
        await stream.send("__**Members of the role " + role.name + "**__\n")

        members = []
        for m in scope.server.members:
            for r in m.roles:
                if r.id == role.id:
                    members.append(m.name + "#" + m.discriminator)
                    break
        members.sort()
        for m in members:
            await stream.send_monospace("\n" + m)

        await stream.finish()
Exemplo n.º 4
0
	async def execute_cf_sessions(self, scope, command, options, lines, **kwargs):
		"""
		List active conversational sessions
		"""

		parser = argparse.ArgumentParser(description=kwargs["description"], prog=command)
		args = await self.parse_options(scope, parser, options)
		if not args:
			return

		stream = praxisbot.MessageStream(scope)

		await stream.send("__**List of conversational sessions**__")

		for s in self.sessions:
			if scope.guild.id != s[2]:
				continue

			user = scope.shell.find_member(s[0], scope.guild)
			if not user:
				continue
			channel = scope.shell.find_channel(s[1], scope.guild)
			if not channel:
				continue

			await stream.send("\n\n:speech_balloon: **Session with "+user.name+"#"+user.discriminator+" in "+channel.mention+"**")
			await stream.send("\n - Current node: "+self.sessions[s].current_node)
			await stream.send("\n - Start time: "+self.sessions[s].start_time.strftime("%Y-%m-%d %H:%M:%S"))
			await stream.send("\n - Last execution time: "+self.sessions[s].last_time.strftime("%Y-%m-%d %H:%M:%S"))

		await stream.finish()
Exemplo n.º 5
0
    async def execute_message_triggers(self, scope, command, options, lines,
                                       **kwargs):
        """
		List all message triggers.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        args = await self.parse_options(scope, parser, options)
        if not args:
            return

        stream = praxisbot.MessageStream(scope)
        await stream.send("__**List of message triggers**__")

        with scope.shell.dbcon:
            c = scope.shell.dbcon.cursor()
            for row in c.execute(
                    "SELECT id, script, regex FROM " +
                    scope.shell.dbtable("message_triggers") +
                    " WHERE discord_sid = ?", [int(scope.server.id)]):

                await stream.send("\n\n**:scroll: Message trigger #" +
                                  str(row[0]) + ":** `" + row[2] + "`\n```\n" +
                                  row[1] + "\n```")

        await stream.finish()
Exemplo n.º 6
0
    async def execute_list_channels(self, scope, command, options, lines,
                                    **kwargs):
        """
		List all channels of the server.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        parser.add_argument(
            '--user',
            help='List channels from the point of view of this user.')
        args = await self.parse_options(scope, parser, options)
        if not args:
            return

        if not args.user:
            user = scope.user
        else:
            user = scope.shell.find_member(args.user, scope.server)
            if not user:
                await scope.shell.print_error(scope, "User not found.")
                return

        clist = []
        for c in scope.server.channels:
            if c.permissions_for(
                    scope.user).read_messages and c.permissions_for(
                        user).read_messages:
                if c.type == discord.ChannelType.text:
                    pos = (c.position + 1) * 10
                    cat = c.server.get_channel(c.parent_id)
                    if cat:
                        pos = pos + 1000 * (cat.position + 1)

                    if c.permissions_for(user).send_messages:
                        clist.append((pos, " :pencil2: " + c.name))
                    else:
                        clist.append((pos, " :eye: " + c.name))
                elif c.type == discord.ChannelType.voice:
                    pos = (c.position + 1) * 10
                    cat = c.server.get_channel(c.parent_id)
                    if cat:
                        pos = pos + 1000 * (cat.position + 1)

                    clist.append((pos, " :microphone2: " + c.name))
                elif c.type == discord.ChannelType.category:
                    pos = (c.position + 1) * 1000
                    clist.append((pos, "\n**" + c.name + "**"))

        clist = sorted(clist, key=lambda x: x[0])

        stream = praxisbot.MessageStream(scope)
        for c in clist:
            await stream.send(c[1] + "\n")
        await stream.finish()
Exemplo n.º 7
0
    async def execute_polls(self, scope, command, options, lines, **kwargs):
        """
		List all current polls.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        args = await self.parse_options(scope, parser, options)
        if not args:
            return

        stream = praxisbot.MessageStream(scope)
        await stream.send("__**List of polls**__")

        with scope.shell.dbcon:
            c0 = scope.shell.dbcon.cursor()
            c1 = scope.shell.dbcon.cursor()
            for row in c0.execute(
                    "SELECT id, description, discord_cid, end_time as 'end_time_ [timestamp]' FROM "
                    + scope.shell.dbtable("polls") +
                    " WHERE discord_sid = ? ORDER BY end_time",
                [int(scope.guild.id)]):
                chan = scope.shell.find_channel(str(row[2]), scope.guild)
                chan_name = "an unknown channel"
                if chan:
                    chan_name = chan.mention

                end_time = timezone('UTC').localize(row[3])
                end_time = end_time.astimezone(timezone('Europe/Paris'))

                counter = scope.shell.get_sql_data("votes", ["COUNT(id)"],
                                                   {"poll": row[0]})

                await stream.send("\n\n:bar_chart: **Poll #" + str(row[0]) +
                                  " in " + chan_name + "**")
                await stream.send("\n - Closing time: " +
                                  end_time.strftime("%Y-%m-%d %H:%M:%S"))
                choices = []
                for choice in c1.execute(
                        "SELECT emoji, description FROM " +
                        scope.shell.dbtable("poll_choices") +
                        " WHERE poll = ?", [row[0]]):
                    choices.append(choice[0] + " " + choice[1])
                await stream.send("\n - Voters: " + str(counter[0]))
                await stream.send("\n - Choices: " + ", ".join(choices))
                if len(row[1]) > 0:
                    description = "```\n" + row[1] + "\n```"

        await stream.finish()
Exemplo n.º 8
0
    async def execute_help(self, scope, command, options, lines, **kwargs):
        """
		Help page of PraxisBot.
		"""

        stream = praxisbot.MessageStream(scope)
        for p in scope.shell.plugins:
            await stream.send("\n**" + p.name + "**\n\n")
            for c in p.cmds:
                desc = inspect.getdoc(p.cmds[c])
                if desc:
                    await stream.send(" - `" + c + "` : " + desc + "\n")
                else:
                    await stream.send(" - `" + c + "`\n")

        await stream.finish()
Exemplo n.º 9
0
    async def execute_emojis(self, scope, command, options, lines, **kwargs):
        """
		List of all custom emojis
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        args = await self.parse_options(scope, parser, options)
        if not args:
            return

        stream = praxisbot.MessageStream(scope)
        await stream.send("**List of emojis**\n")
        for e in scope.server.emojis:
            await stream.send("\n - <:" + e.name + ":" + e.id + "> `" +
                              e.name + "`")

        await stream.finish()
Exemplo n.º 10
0
    async def execute_mod_levels(self, scope, command, options, lines,
                                 **kwargs):
        """
		List all moderator levels.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        args = await self.parse_options(scope, parser, options)
        if not args:
            return scope

        stream = praxisbot.MessageStream(scope)
        await stream.send("**__List of moderator levels__**\n")

        with scope.shell.dbcon:
            c = scope.shell.dbcon.cursor()
            for row in c.execute(
                    "SELECT name, priority, ban_timelimit, ban_prioritylimit, purge FROM "
                    + scope.shell.dbtable("mod_levels") +
                    " WHERE discord_sid = ? ORDER BY priority DESC",
                [int(scope.server.id)]):
                await stream.send("\n:label: **" + row[0] + "**")
                await stream.send("\n   - Priority: " + str(row[1]))
                if not row[2] or row[2] < 0:
                    tlimit = 0
                else:
                    tlimit = row[2]
                await stream.send("\n   - Duration bewteen two bans: " +
                                  str(tlimit) + "h")
                if not row[3] or row[3] < 0:
                    plimit = row[1] - 1
                else:
                    plimit = min(row[3], row[1])
                await stream.send(
                    "\n   - Maximum priority that can be banned: " +
                    str(plimit))
                if not row[4] or row[4] <= 0:
                    purge = "Can't use purge command"
                else:
                    purge = "Can use purge command"
                await stream.send("\n   - " + purge)

        await stream.finish()
Exemplo n.º 11
0
	async def execute_cf_nodes(self, scope, command, options, lines, **kwargs):
		"""
		List all nodes and links
		"""

		parser = argparse.ArgumentParser(description=kwargs["description"], prog=command)
		args = await self.parse_options(scope, parser, options)
		if not args:
			return

		stream = praxisbot.MessageStream(scope)

		with scope.shell.dbcon:
			c0 = scope.shell.dbcon.cursor()
			c1 = scope.shell.dbcon.cursor()

			await stream.send("__**List of nodes**__")
			for row in c0.execute("SELECT name, script FROM "+scope.shell.dbtable("cf_nodes")+" WHERE discord_sid = ? ORDER BY name", [int(scope.guild.id)]):
				await stream.send("\n\n:triangular_flag_on_post: **"+row[0]+"**")
				for link in c1.execute("SELECT node_start, script FROM "+scope.shell.dbtable("cf_links")+" WHERE discord_sid = ? AND node_start = ? AND node_end == node_start ORDER BY node_start, priority DESC", [int(scope.guild.id), str(row[0])]):
					await stream.send("\n - Self link: **"+str(row[0])+"** → **"+str(row[0])+"**")
				for link in c1.execute("SELECT node_start, script FROM "+scope.shell.dbtable("cf_links")+" WHERE discord_sid = ? AND node_end = ? AND node_end != node_start ORDER BY node_start, priority DESC", [int(scope.guild.id), str(row[0])]):
					await stream.send("\n - Incoming link: "+link[0]+" → **"+str(row[0])+"**")
				for link in c1.execute("SELECT node_end, script FROM "+scope.shell.dbtable("cf_links")+" WHERE discord_sid = ? AND node_start = ? AND node_end != node_start ORDER BY node_end, priority DESC", [int(scope.guild.id), str(row[0])]):
					await stream.send("\n - Outcoming link: **"+str(row[0])+"** → "+link[0])
				if len(row[1]) > 0:
					await stream.send("\n - Script:")
					await stream.send("\n```\n"+row[1]+"\n```")

			await stream.send("\n\n__**List of links**__")
			for row in c0.execute("SELECT node_start, node_end, script, type, value, priority FROM "+scope.shell.dbtable("cf_links")+" WHERE discord_sid = ? ORDER BY node_start, node_end", [int(scope.guild.id)]):
				await stream.send("\n\n:link: **"+row[0]+" → "+row[1]+"**")
				await stream.send("\n - Priority: "+str(row[5]))
				if row[3] == LinkType.UserRegex:
					await stream.send("\n - Condition: user message match `"+row[4]+"`")
				elif row[3] == LinkType.Timeout:
					await stream.send("\n - Condition: timeout of "+row[4]+"")
				elif row[3] == LinkType.Reaction:
					await stream.send("\n - Condition: reaction added "+row[4]+"")
				if len(row[2]) > 0:
					await stream.send("\n - Script:")
					await stream.send("\n```\n"+row[2]+"\n```")

		await stream.finish()
Exemplo n.º 12
0
    async def execute_variables(self, scope, command, options, lines,
                                **kwargs):
        """
		List all current variables.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        args = await self.parse_options(scope, parser, options)
        if not args:
            return

        stream = praxisbot.MessageStream(scope)
        await stream.send("**List of variables**\n")
        for v in scope.vars:
            if scope.vars[v].find("\n") >= 0:
                await stream.send("\n" + v + " = \n```" + scope.vars[v] +
                                  "```")
            else:
                await stream.send("\n" + v + " = `" + scope.vars[v] + "`")
        await stream.finish()
Exemplo n.º 13
0
    async def execute_last_bans(self, scope, command, options, lines,
                                **kwargs):
        """
		List last bans.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        args = await self.parse_options(scope, parser, options)
        if not args:
            return scope

        stream = praxisbot.MessageStream(scope)
        await stream.send("**__Last bans__**")

        bans = await scope.shell.client.get_ban_logs(scope.server, limit=5)
        for b in bans:
            author = b.author
            target = b.target
            reason = b.reason

            if b.author.id == scope.shell.client.user.id:
                #Try to find the true author in the reason
                res = re.search("(.+#[0-9][0-9][0-9][0-9]) using ban command",
                                b.reason)
                if res:
                    u = scope.shell.find_member(res.group(1), scope.server)
                    if u:
                        author = u

                res = re.search("using ban command:(.+)", b.reason)
                if res:
                    reason = res.group(1).strip()

            await stream.send("\n\n**" + target.name + "#" +
                              target.discriminator + " by " + author.name +
                              "#" + author.discriminator + "**\n" + reason)

        await stream.finish()
Exemplo n.º 14
0
    async def execute_last_bans(self, scope, command, options, lines,
                                **kwargs):
        """
		List last bans.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        args = await self.parse_options(scope, parser, options)
        if not args:
            return scope

        stream = praxisbot.MessageStream(scope)
        await stream.send("**__Last bans__**")

        async for b in scope.guild.audit_logs(
                action=discord.AuditLogAction.ban, limit=5):
            user = b.user
            target = b.target
            reason = b.reason

            if b.user.id == scope.shell.client.user.id:
                #Try to find the true author (user) in the reason
                res = re.search("(.+#[0-9][0-9][0-9][0-9]) using ban command",
                                b.reason)
                if res:
                    u = scope.shell.find_member(res.group(1), scope.guild)
                    if u:
                        user = u

                res = re.search("using ban command:(.+)", b.reason)
                if res:
                    reason = res.group(1).strip()

            await stream.send("\n\n**{}#{} by {}#{}**\n{}".format(
                target.name, target.discriminator, user.name,
                user.discriminator, reason))

        await stream.finish()
Exemplo n.º 15
0
    async def display_counters(self, scope, counters, counter_max, title,
                               format):
        stream = praxisbot.MessageStream(scope)
        await stream.send("__**" + title + "**__")

        for counter in counters:
            text = "\nFrom "

            start_date = counter["start_date"]
            start_date = timezone('UTC').localize(start_date)
            start_date = start_date.astimezone(timezone('Europe/Paris'))
            text = text + start_date.strftime(format)

            text = text + " to "

            end_date = counter["end_date"]
            end_date = timezone('UTC').localize(end_date)
            end_date = end_date.astimezone(timezone('Europe/Paris'))
            text = text + end_date.strftime(format)

            text = text + " "

            if counter_max > 0:
                nb_box = int(20.0 * counter["counter"] / counter_max)
                nb_empty = 20 - nb_box
            else:
                nb_box = 0
                nb_empty = 20

            for i in range(0, nb_box):
                text = text + "█"
            for i in range(0, nb_empty):
                text = text + "▁"

            text = text + " " + str(counter["counter"]) + " messages"

            await stream.send_monospace(text)

        await stream.finish()
Exemplo n.º 16
0
    async def execute_commands(self, scope, command, options, lines, **kwargs):
        """
		List all custom commands.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        args = await self.parse_options(scope, parser, options)
        if not args:
            return

        stream = praxisbot.MessageStream(scope)
        await stream.send("__**List of commands**__\n")

        with scope.shell.dbcon:
            c = scope.shell.dbcon.cursor()
            for row in c.execute(
                    "SELECT command FROM " + scope.shell.dbtable("triggers") +
                    " WHERE discord_sid = ? ORDER BY command",
                [int(scope.server.id)]):
                if row[0].find("@") != 0:
                    await stream.send("\n - " + row[0])

        await stream.finish()
Exemplo n.º 17
0
    async def execute_cookies(self, scope, command, options, lines, **kwargs):
        """
		List all cookies.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        args = await self.parse_options(scope, parser, options)
        if not args:
            return

        stream = praxisbot.MessageStream(scope)
        await stream.send("**List of HTTP cookies**\n")

        with scope.shell.dbcon:
            c = scope.shell.dbcon.cursor()
            for row in c.execute(
                    "SELECT nameid, filter FROM " +
                    scope.shell.dbtable("cookies") +
                    " WHERE discord_sid = ? ORDER BY name",
                [int(scope.server.id)]):
                await stream.send("\n - " + row[0] + ": `" + row[1] + "`")

        await stream.finish()
Exemplo n.º 18
0
    async def execute_whois(self, scope, command, options, lines, **kwargs):
        """
		Get all available informations about an user.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        parser.add_argument('user', help='An user')
        parser.add_argument('--channel',
                            '-c',
                            help='Channel where to send the message')
        args = await self.parse_options(scope, parser, options)
        if not args:
            return

        if args.channel:
            chan = scope.shell.find_channel(
                scope.format_text(args.channel).strip(), scope.server)
        else:
            chan = scope.channel

        if not chan:
            await scope.shell.print_error(scope, "Unknown channel.")
            return

        if scope.permission < praxisbot.UserPermission.Script and not chan.permissions_for(
                scope.user).send_messages:
            await scope.shell.print_permission(
                scope, "You don't have write permission in this channel.")
            return

        u = scope.shell.find_member(scope.format_text(args.user), scope.server)
        if not u:
            await scope.shell.print_error(
                scope,
                "User not found. User name must be of the form `@User#1234` or `User#1234`."
            )
            return

        e = discord.Embed()
        e.type = "rich"
        e.set_author(name=u.name + "#" + u.discriminator,
                     icon_url=u.avatar_url.replace(".webp", ".png"))
        e.set_thumbnail(url=u.avatar_url.replace(".webp", ".png"))

        e.add_field(name="Nickname", value=str(u.display_name))
        e.add_field(name="Discord ID", value=str(u.id))
        if u.colour.value != 0:
            e.colour = u.colour

        e.add_field(name="Created since",
                    value=str(datetime.datetime.utcnow() - u.created_at))
        e.add_field(name="Joined since",
                    value=str(datetime.datetime.utcnow() - u.joined_at))

        if u.server_permissions.administrator:
            e.add_field(name="Administrator", value=":crown: Yes")
        if u.server_permissions.manage_server:
            e.add_field(name="Manage server", value=":tools: Yes")
        if u.server_permissions.manage_channels:
            e.add_field(name="Manage channels", value=":tools: Yes")
        if u.server_permissions.manage_messages:
            e.add_field(name="Manage messages", value=":speech_balloon: Yes")
        if u.server_permissions.view_audit_logs:
            e.add_field(name="View audit logs", value=":eye: Yes")
        if u.server_permissions.ban_members:
            e.add_field(name="Ban members", value=":punch: Yes")
        if u.server_permissions.kick_members:
            e.add_field(name="Kick members", value=":punch: Yes")
        if u.server_permissions.mention_everyone:
            e.add_field(name="Mention everyone", value=":loudspeaker: Yes")

        try:
            counter = await scope.shell.client_human.count_messages(
                scope.server, author=u)
            e.add_field(name="Total messages", value=str(counter))
        except:
            pass

        try:
            counter = await scope.shell.client_human.count_messages(
                scope.server,
                author=u,
                after=datetime.datetime.utcnow() - relativedelta(months=1))
            e.add_field(name="Messages last month", value=str(counter))
        except:
            pass

        roles = []
        for r in u.roles:
            if not r.is_everyone:
                roles.append(r.name)
        if len(roles):
            e.add_field(name="Roles", value=", ".join(roles))

        try:
            profile = await scope.shell.client_human.get_user_profile(u.id)

            stream = praxisbot.MessageStream(scope)
            for ca in profile.connected_accounts:
                url = ca.url
                if url:
                    e.add_field(name=ca.provider_name, value=url)
                else:
                    e.add_field(name=ca.provider_name, value=ca.name)
        except:
            pass

        await scope.shell.client.send_message(chan, "", embed=e)
Exemplo n.º 19
0
    async def execute_roles(self, scope, command, options, lines, **kwargs):
        """
		List all roles.
		"""

        parser = argparse.ArgumentParser(description=kwargs["description"],
                                         prog=command)
        args = await self.parse_options(scope, parser, options)
        if not args:
            return

        roles = {}

        for r in scope.server.roles:
            if r.is_everyone:
                continue

            roles[r.id] = {
                "id": r.id,
                "name": r.name,
                "members": 0,
                "position": r.position,
                "type": RoleType.Default,
                "description": "",
                "mentionable": r.mentionable,
                "onlinelist": r.hoist,
                "autosort": 0,
                "autosync": 0,
                "color": r.colour.value
            }

        for m in scope.server.members:
            for r in m.roles:
                if r.id in roles:
                    roles[r.id]["members"] = roles[r.id]["members"] + 1

        with scope.shell.dbcon:
            c = scope.shell.dbcon.cursor()
            for row in c.execute(
                    "SELECT discord_rid, type, description, autosync, autosort FROM "
                    + scope.shell.dbtable("role_options") +
                    " WHERE discord_sid = ?", [int(scope.server.id)]):
                rid = str(row[0])
                if rid in roles:
                    roles[rid]["type"] = row[1]
                    roles[rid]["description"] = row[2]
                    roles[rid]["autosync"] = row[3]
                    roles[rid]["autosort"] = row[4]

        sorted_roles = sorted(roles.values(),
                              key=lambda a: a["position"],
                              reverse=True)

        stream = praxisbot.MessageStream(scope)
        await stream.send("__**List of roles**__\n")
        await stream.send(
            "\n**Properties:** :medal: visible in member list, :label: invisible in member list, :bell: mentionable, :no_bell: not mentionable, :art: colored, :black_circle: default color\n"
        )

        role_above = 0

        for r in sorted_roles:
            if r["type"] == RoleType.Separator:
                text = "\n\n**" + r["name"] + "**"
                if len(r["description"]) > 0:
                    text = text + "\n" + r["description"]
                if r["autosort"] == 1:
                    text = text + "\n:twisted_rightwards_arrows: Roles in this section are automatically sorted"
                if r["autosync"] == 1:
                    text = text + "\n:arrows_counterclockwise: Permissions of roles in this section are automatically synced"
                text = text + "\n"
                await stream.send(text)
            else:
                icon = ""

                if r["onlinelist"]:
                    icon = icon + ":medal:"
                else:
                    icon = icon + ":label:"

                if r["mentionable"]:
                    icon = icon + ":bell:"
                else:
                    icon = icon + ":no_bell:"

                if r["color"] == 0:
                    icon = icon + ":black_circle:"
                else:
                    icon = icon + ":art:"

                description = ""
                if len(r["description"]) > 0:
                    description = ": " + r["description"]
                await stream.send("\n" + icon + " **" + r["name"] + "**, " +
                                  str(r["members"]) + " members" + description)

        await stream.finish()