Passed
Push — master ( f7d90b...d79004 )
by Cyb3r
01:30
created

utils.messages   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 138
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 61
dl 0
loc 138
rs 10
c 0
b 0
f 0
wmc 19

4 Functions

Rating   Name   Duplication   Size   Complexity  
C list_message() 0 51 9
A admin_log() 0 30 4
A make_embed() 0 30 5
A error_message() 0 11 1
1
"""Deals with long message sending"""
2
import logging
3
import random
4
import discord
5
from .datahandler import select
6
7
log = logging.getLogger("bot")
8
9
10
async def list_message(ctx, message: list, title: str, **kwargs):
11
    """list_message
12
    ---
13
    Asynchronous Function
14
15
    Breaks up messages that contain a list and sends the parts of them. Shared function between
16
    multiple commands.
17
18
19
    I'm sorry for everyone dealing with this function. It is not clean and I have commented to
20
    the best that I can.
21
22
    Arguments:
23
    ---
24
        ctx {discord.ext.commands.Context} -- Context of the command.
25
        message {list} -- list of items to send.
26
        title {str} -- First line of the message to send.
27
    """
28
    joined_message = len("".join(message))
29
    list_of_embeds = []
30
    part = 1
31
    item = 0
32
    amount_of_embeds = len(range(0, joined_message, 1500))
33
    for _ in range(amount_of_embeds):
34
        # Each embed can only be 6000 characters so if the length is over that more are created
35
        embed = await make_embed(ctx, title=title, send=False, **kwargs)
36
        for _ in range(2):
37
            temp_msg = ""
38
            while len(temp_msg) < 1024:
39
                # Each field can only be 1024 characters
40
                try:
41
                    if len(temp_msg + "- {}\n".format(message[item])) > 1024:
42
                        # If the new item is going to make it over the 1024 limit then skip it.
43
                        break
44
                    temp_msg += "- {}\n".format(message[item])
45
                    item += 1
46
                except IndexError:
47
                    # Error happens when there the length of temp_msg is still under 1000 but
48
                    # no items left.
49
                    break
50
            if len(temp_msg) > 0:
51
                # Blank messages can occur and this filters them out
52
                embed.add_field(name="Part: {}".format(part), value=temp_msg, inline=True)
53
                part += 1
54
        list_of_embeds.append(embed)
55
56
    for item in list_of_embeds:
57
        if len(item.fields) > 0:
58
            await ctx.send(embed=item)
59
        else:
60
            log.warning("Empty embed")
61
62
63
async def admin_log(bot, message: str, log_status: bool = True):
64
    """admin_log
65
    ---
66
    Asynchronous Function
67
68
    Log the :refs:`message` to the admin channels.
69
70
    Arguments:
71
    ---
72
        bot {discord.commands.Bot} -- The bot
73
        log_status {bool} -- If the log will be sent to logging channels or non logging channels
74
    """
75
    if len(message) > 2000:
76
        message = "Log message length too long, it will not be sent. Length: {}".format(
77
            len(message)
78
        )
79
        log.warning(message)
80
81
    channels = await select("admin_channels", "id", "log", log_status)
82
    for channel in channels:
83
        to_send = bot.get_channel(channel)
84
        if to_send is None:
85
            log.warning("No channel found for id {}".format(channel))
86
        else:
87
            embed = discord.Embed(
88
                title="Log Update:",
89
                description=message,
90
                color=discord.Color(int("FF0000", 16)),
91
            )
92
            await to_send.send(embed=embed)
93
94
95
async def error_message(ctx, message: str, title: str = "Error:", **kwargs):
96
    """
97
    Generate an error embed
98
99
    Args:
100
        title: Title of the embed
101
        ctx: Discord context
102
        message: The message to send
103
104
    """
105
    await make_embed(ctx, "FF0000", True, description=message, title=title, **kwargs)
106
107
108
async def make_embed(
109
    ctx, color: [str, int] = None, send: (bool, str) = True, **kwargs
110
) -> discord.Embed():
111
    """make_embed
112
    ---
113
114
    Asynchronous Function
115
116
    Makes and sends a discord embed
117
118
    Arguments:
119
    ---
120
        ctx {discord.ext.commands.Context} -- Context of the command.
121
        color {str} -- Hex code for color. If empty random one will be added (default: {None})
122
        send {bool} -- If make_embed sends the embed. Only false is the function adds items to the
123
                        embed such as fields.
124
    """
125
    if not color:
126
        kwargs["color"] = int("0x%06x" % random.randint(0, 0xFFFFFF), 16)  # nosec
127
    elif isinstance(color, str):
128
        kwargs["color"] = discord.Color(int(color, 16))
129
130
    embed = discord.Embed(timestamp=ctx.message.created_at, **kwargs)
131
132
    if "footer" in kwargs:
133
        embed.set_footer(text=kwargs["footer"])
134
    if send:
135
        await ctx.send(embed=embed)
136
    else:
137
        return embed
138