Passed
Push — main ( c507f0...00b29a )
by Bartosz
02:41 queued 01:13
created

build.cogs.spotstatscog.setup()   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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