SpotCog.before_update_leaderboards_loop()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
"""
2
Cog with role related commands available in the Bot.
3
4
Current commands:
5
/remove_spot
6
7
"""
8
from datetime import datetime
9
import discord
10
from discord.ext import commands, tasks
11
from discord.utils import get
12
13
import cogs.cogbase as cogbase
14
from cogs.databasecog import DatabaseCog
15
16
monster_type_dict = {0: "rare", 1: "legendary", 2: "event1", 3: "event2", 4: "common"}
17
18
prefix = "/"
19
cords_beginning = ["-", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
20
21
22
class SpotCog(cogbase.BaseCog):
23
    def __init__(self, base):
24
        super().__init__(base)
25
        self.peepo_ban_emote: str = ":peepoban:872502800146382898"
26
        self.spotting_channels: list = [self.bot.ch_legendary_spot, self.bot.ch_rare_spot,
27
                                        self.bot.ch_legendary_nemeton, self.bot.ch_rare_nemeton]
28
29
        self.clear_nemeton_channels_loop.start()
30
31
    # Ping monster role
32
    @commands.Cog.listener()
33
    async def on_message(self, ctx) -> None:
34
        if ctx.author.id == self.bot.user.id or isinstance(ctx.channel, discord.channel.DMChannel):
35
            return
36
        # If common spotted
37
        try:
38
            if ctx.channel.id == self.bot.ch_common:
39
                await self.handle_spotted_common(ctx)
40
                return
41
            elif ctx.channel.category and ctx.channel.category.id == self.bot.cat_spotting:
42
                await self.handle_spotted_monster(ctx)
43
                return
44
            # elif ctx.channel.id != self.bot.ch_role_request:
45
            #     await self.handle_wrong_ping(ctx)
46
        except AttributeError:
47
            pass
48
49
        # If monster pinged by member without using bot
50
        channels_dont_check = [self.bot.ch_role_request, self.bot.ch_leaderboards, self.bot.ch_leaderboards_common,
51
                               self.bot.ch_leaderboards_event, self.bot.ch_logs, self.bot.ch_spotting_stats]
52
        if ctx.channel.id not in channels_dont_check:
53
            await self.handle_wrong_ping(ctx)
54
55
    async def handle_wrong_ping(self, ctx):
56
        guild = self.bot.get_guild(self.bot.guild[0])
57
        guild_roles: list = [role.id for role in ctx.guild.roles]
58
        tagged_roles: list = ([role for role in guild_roles if (str(role) in ctx.content)])
59
        tagged_roles_names = [get(guild.roles, id=role).name for role in tagged_roles]
60
        for monster in self.bot.config["commands"]:
61
            if monster["name"] in tagged_roles_names:
62
                await ctx.channel.send(f"{ctx.author.mention} you have tagged monster without using a bot! "
63
                                       f"Please read <#876116496651280424> and consider it a warning! "
64
                                       f"<{self.peepo_ban_emote}>\n"
65
                                       f"*If you think this message was sent incorrectly please let "
66
                                       f"<@&872189602281193522> know*")
67
68
    @staticmethod
69
    async def handle_spotted_common(ctx) -> None:
70
        if ctx.content[0] in cords_beginning:
71
            await DatabaseCog.db_count_spot(ctx.author.id, "common", "")
72
            await DatabaseCog.db_save_coords(ctx.content, "common")
73
        else:
74
            await ctx.delete()
75
76
    # TODO: Reduce code complexity
77
    async def handle_spotted_monster(self, ctx) -> None:
78
        if ctx.content.startswith(prefix):
79
            spotted_monster = self.get_monster(ctx, ctx.content.replace(prefix, ""))
80
            if spotted_monster:
81
                monster_type_str = monster_type_dict[spotted_monster["type"]]
82
                if await self.wrong_channel(ctx, spotted_monster, monster_type_str):
83
                    return
84
                role = get(ctx.guild.roles, name=spotted_monster["name"])
85
                try:
86
                    await ctx.delete()
87
                except discord.errors.NotFound:
88
                    pass
89
                await ctx.channel.send(f"{role.mention}")
90
                await DatabaseCog.db_count_spot(ctx.author.id,
91
                                                monster_type_str, spotted_monster["name"])
92
                logs_ch = self.bot.get_channel(self.bot.ch_logs)
93
                await logs_ch.send(f"[PingLog] {ctx.author} ({ctx.author.id})"
94
                                   f" ping for **{spotted_monster['name']}** on {ctx.channel}")
95
            else:
96
                await ctx.delete()
97
                await ctx.channel.send(
98
                    f"{ctx.author.mention} monster not found - are you sure that the name is correct?", delete_after=5)
99
        elif len(ctx.content) > 0 and ctx.content[0] in cords_beginning:
100
            await DatabaseCog.db_save_coords(ctx.content, ctx.channel.name)
101
        elif ctx.channel.id in self.spotting_channels:
102
            try:
103
                await ctx.add_reaction(f"a{self.peepo_ban_emote}")
104
            except discord.errors.NotFound:
105
                pass
106
107
    async def wrong_channel(self, ctx, spotted_monster, monster_type_str: str) -> bool:
108
        if ctx.channel.id in self.spotting_channels:
109
            if monster_type_str not in ctx.channel.name:
110
                channel_wild = discord.utils.get(ctx.guild.channels, name=monster_type_str)
111
                correct_channel_wild = channel_wild.id
112
                channel_nemeton = discord.utils.get(ctx.guild.channels, name=f"{monster_type_str}-nemeton")
113
                correct_channel_nemeton = channel_nemeton.id
114
                await ctx.delete()
115
                await ctx.channel.send(
116
                    f"{ctx.author.mention} you posted {spotted_monster['name']} on wrong channel! "
117
                    f"Use <#{correct_channel_wild}> or <#{correct_channel_nemeton}> instead! <{self.peepo_ban_emote}>",
118
                    delete_after=8)
119
                return True
120
            return False
121
122
    async def clear_channel_messages(self, channel) -> None:
123
        messages = []
124
        # Can't use datetime.utcnow().date() beacuse discord
125
        today = datetime.utcnow()
126
        today = today.replace(hour=0, minute=0, second=0, microsecond=0)
127
        async for message in channel.history(before=today):
128
            messages.append(message)
129
        await channel.delete_messages(messages)
130
        self.create_log_msg(f"Wiped - {channel.name} history")
131
132
    @tasks.loop(hours=3)
133
    async def clear_nemeton_channels_loop(self) -> None:
134
        lege_nemeton = self.bot.get_channel(self.bot.ch_legendary_nemeton)
135
        rare_nemeton = self.bot.get_channel(self.bot.ch_rare_nemeton)
136
        await self.clear_channel_messages(lege_nemeton)
137
        await self.clear_channel_messages(rare_nemeton)
138
139
    @clear_nemeton_channels_loop.before_loop
140
    async def before_update_leaderboards_loop(self) -> None:
141
        self.create_log_msg("Waiting until Bot is ready")
142
        await self.bot.wait_until_ready()
143
144
145
def setup(bot: commands.Bot) -> None:
146
    bot.add_cog(SpotCog(bot))
147