Passed
Branch BonHowi (3885db)
by Bartosz
01:36
created

SpotStatsCog.get_spotting_stats()   B

Complexity

Conditions 6

Size

Total Lines 54
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 45
dl 0
loc 54
rs 7.8666
c 0
b 0
f 0
cc 6
nop 2

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
import discord
2
from cogs.databasecog import DatabaseCog
3
from discord.ext import commands, tasks
4
from discord.utils import get
5
from cogs import cogbase
6
from discord_slash import cog_ext
7
8
9
class SpotStatsCog(cogbase.BaseCog):
10
    def __init__(self, base):
11
        super().__init__(base)
12
        self.hex_to_int = "%02x%02x%02x"
13
        self.lege_total = 0
14
        self.rare_total = 0
15
        self.common_total = 0
16
        self.update_spot_stats_loop.start()
17
18
    @cog_ext.cog_slash(name="updatedbwitholdstats", guild_ids=cogbase.GUILD_IDS,
19
                       description=" ",
20
                       default_permission=True,
21
                       permissions=cogbase.PERMISSION_MODS
22
                       )
23
    async def get_old_stats(self, ctx):
24
        await ctx.send("Generating spots stats", delete_after=5)
25
        guild = self.bot.get_guild(self.bot.guild[0])
26
        channel = self.bot.get_channel(self.bot.ch_logs)
27
        async for message in channel.history(limit=None, oldest_first=True):
28
            for member in guild.members:
29
                if message.content.startswith("[PingLog]") and str(member.id) in message.content:
30
                    for monster in self.bot.config["commands"]:
31
                        if monster["name"] in message.content:
32
                            monster_type = "legendary" if monster["type"] == 1 else "rare"
33
                            DatabaseCog.db_count_monster_spot(member.id, monster_type, monster["name"])
34
                            break
35
        self.create_log_msg("Finished updating database")
36
37
    async def get_channel_history(self, channel_id, channel_type) -> list:
38
        guild = self.bot.get_guild(self.bot.guild[0])
39
        channel = self.bot.get_channel(channel_id)
40
        roles_list = []
41
        async for message in channel.history(limit=None, oldest_first=True):
42
            if message.content.startswith("<@&8"):  # If message is a ping for a role
43
                seq_type = type(message.content)
44
                role_id = int(seq_type().join(filter(seq_type.isdigit, message.content)))
45
                role = get(guild.roles, id=role_id)
46
                if role:
47
                    roles_list.append(self.get_monster_name(role, channel_type))
48
        roles_list = list(filter(None, roles_list))
49
        return roles_list
50
51
    def get_monster_name(self, role, channel_type):
52
        monster_found = None
53
        for monster in self.bot.config["commands"]:
54
            if monster["name"].lower() == role.name.lower() or role.name.lower() in monster["triggers"]:
55
                monster_found = monster
56
                break
57
        if monster_found["type"] == channel_type:
58
            return role.name
59
60
    async def create_spots_list(self, channel_type: int):
61
        spots_df = await DatabaseCog.db_get_total_spots_df(self.bot.user.id, channel_type)
62
        spots_df = spots_df.to_dict(orient='records')
63
        spots_df = spots_df[0]
64
        del spots_df['member_id']
65
        top_print = []
66
        total = 0
67
        for key, value in spots_df.items():
68
            spotting_stats = [f"{key}:  **{value}**"]
69
            top_print.append(spotting_stats)
70
            total += value
71
        return top_print, total
72
73
    async def update_spot_stats(self, channel_id: int, channel_type: int):
74
        spot_stats_ch = self.bot.get_channel(self.bot.ch_spotting_stats)
75
        top_print, total = await self.create_spots_list(channel_type)
76
        top_print = ['\n'.join([elem for elem in sublist]) for sublist in top_print]
77
        top_print = "\n".join(top_print)
78
79
        if channel_type == 1:
80
            embed_title = "LEGENDARY"
81
            embed_color = int(self.hex_to_int % (163, 140, 21), 16)
82
            self.lege_total = total
83
        elif channel_type == 0:
84
            embed_title = "RARE"
85
            embed_color = int(self.hex_to_int % (17, 93, 178), 16)
86
            self.rare_total = total
87
        else:
88
            embed_title = "OTHER"
89
            embed_color = int(self.hex_to_int % (1, 1, 1), 16)
90
91
        embed_command = discord.Embed(title=f"{embed_title}", description=top_print, color=embed_color)
92
        embed_command.add_field(name="Total", value=f"**{total}**", inline=False)
93
        dt_string = self.bot.get_current_time()
94
        embed_command.set_footer(text=f"{dt_string}")
95
        await spot_stats_ch.send(embed=embed_command)
96
97
        channel = self.bot.get_channel(channel_id)
98
        self.create_log_msg(f"Spotting stats updated - {channel.name}")
99
100
    @tasks.loop(hours=12)
101
    async def update_spot_stats_loop(self):
102
        spot_stats_ch = self.bot.get_channel(self.bot.ch_spotting_stats)
103
        await spot_stats_ch.purge()
104
        await self.update_spot_stats(self.bot.ch_legendary_spot, 1)
105
        await self.update_spot_stats(self.bot.ch_rare_spot, 0)
106
        self.create_log_msg(f"All spotting stats updated")
107
108
    @update_spot_stats_loop.before_loop
109
    async def before_update_spot_stats_loop(self):
110
        self.create_log_msg(f"Waiting until Bot is ready")
111
        await self.bot.wait_until_ready()
112
113
    # TODO: code refactoring
114
    # Member own stats
115
    @cog_ext.cog_slash(name="mySpottingStats", guild_ids=cogbase.GUILD_IDS,
116
                       description=" ",
117
                       default_permission=True,
118
                       permissions=cogbase.PERMISSION_MODS
119
                       )
120
    async def get_spotting_stats(self, ctx):
121
        await ctx.send("Generating spots stats", delete_after=5)
122
123
        # Legendary
124
        leges_list, leges_total = await self.create_spots_list(1)
125
        leges_print = ['\n'.join([elem for elem in sublist]) for sublist in leges_list]
126
        leges_print = "\n".join(leges_print)
127
128
        leges_color = int(self.hex_to_int % (163, 140, 21), 16)
129
        embed_command = discord.Embed(title=f"Legendary", description=leges_print, color=leges_color)
130
        embed_command.add_field(name="Total", value=f"**{leges_total}**", inline=False)
131
        if self.lege_total != 0:
132
            percentage_leges = round(leges_total / self.lege_total * 100, 2)
133
            embed_command.add_field(name="Server %", value=f"**{percentage_leges}%**", inline=False)
134
        dt_string = self.bot.get_current_time()
135
        embed_command.set_footer(text=f"{dt_string}")
136
        await ctx.author.send(embed=embed_command)
137
138
        # Rare
139
        rares_list, rares_total = await self.create_spots_list(0)
140
        rares_print = ['\n'.join([elem for elem in sublist]) for sublist in rares_list]
141
        rares_print = "\n".join(rares_print)
142
143
        rares_color = int(self.hex_to_int % (17, 93, 178), 16)
144
        embed_command = discord.Embed(title=f"Rare", description=rares_print, color=rares_color)
145
        embed_command.add_field(name="Total", value=f"**{rares_total}**", inline=False)
146
        if self.rare_total != 0:
147
            percentage_rares = round(rares_total / self.rare_total * 100, 2)
148
            embed_command.add_field(name="Server %", value=f"**{percentage_rares}%**", inline=False)
149
        dt_string = self.bot.get_current_time()
150
        embed_command.set_footer(text=f"{dt_string}")
151
        await ctx.author.send(embed=embed_command)
152
153
        # Common
154
        common_ch = self.bot.get_channel(self.bot.ch_common)
155
        common_total = 0
156
        async for message in common_ch.history(limit=None, oldest_first=True):
157
            self.common_total += 1
158
            if ctx.author == message.author:
159
                common_total += 1
160
        embed_command = discord.Embed(title=f"Common")
161
        embed_command.add_field(name="Total", value=f"**{common_total}**", inline=False)
162
        if self.common_total != 0:
163
            percentage_common = round(common_total / self.common_total * 100, 2)
164
            embed_command.add_field(name="Server %", value=f"**{percentage_common}%**", inline=False)
165
        dt_string = self.bot.get_current_time()
166
        embed_command.set_footer(text=f"{dt_string}")
167
        await ctx.author.send(embed=embed_command)
168
        self.create_log_msg(f"Spotting stats created for {ctx.author}")
169
170
171
def setup(bot: commands.Bot):
172
    bot.add_cog(SpotStatsCog(bot))
173