build.cogs.spotstatscog   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 176
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 28
eloc 142
dl 0
loc 176
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A SpotStatsCog.before_update_spot_stats_loop() 0 4 1
A SpotStatsCog.__init__() 0 7 1
A SpotStatsCog.update_spot_stats_loop() 0 18 1
A SpotStatsCog.get_spotting_stats() 0 30 4
A SpotStatsCog.get_stats_type() 0 27 4
A SpotStatsCog.update_spot_stats() 0 26 3
A SpotStatsCog.get_monster_name() 0 8 5
A SpotStatsCog.create_spots_list() 0 18 4
A SpotStatsCog.get_channel_history() 0 13 4

1 Function

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