Passed
Push — master ( dcd1eb...4f7f97 )
by Cyb3r
02:51 queued 01:44
created

bot.utils.messages.list_message()   C

Complexity

Conditions 9

Size

Total Lines 56
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 26
nop 4
dl 0
loc 56
rs 6.6666
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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