Passed
Branch BonHowi (8c970b)
by Bartosz
01:28
created

build.cogs.spotstatscog   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 31
eloc 158
dl 0
loc 182
rs 9.92
c 0
b 0
f 0

7 Methods

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