Passed
Push — main ( 55bb28...245da3 )
by Bartosz
02:31 queued 01:14
created

build.cogs.commandscog.CommandsCog._warns()   A

Complexity

Conditions 1

Size

Total Lines 11
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nop 3
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
1
"""
2
Cog with general commands available in the Bot.
3
4
Current commands:
5
/ping -     check Bot latency
6
/clear -    clear x messages on the channel
7
/exit | !exit -     end Bot's runtime and disconnect from the server
8
/warn -     warn @user with reason
9
/warns -    send @user warns to author's DM
10
/nword -    Changes N-Word killed channel name  -   UNSTABLE
11
/updatetotmem - Update #TotalMembers channel
12
/updatecommon - Update common spotting channel with new monster name
13
"""
14
import asyncio
15
import json
16
import discord
17
from discord.utils import get
18
19
import cogs.cogbase as cogbase
20
from discord.ext import commands
21
from discord_slash import cog_ext, SlashContext
22
from cogs.databasecog import DatabaseCog
23
from modules.pull_config.pull_config import get_config
24
25
26
class CommandsCog(cogbase.BaseCog):
27
    def __init__(self, base):
28
        super().__init__(base)
29
30
    # GENERAL FUNCTIONS
31
    # Check latency
32
    @cog_ext.cog_slash(name="ping", guild_ids=cogbase.GUILD_IDS,
33
                       description="Test function for checking latency",
34
                       default_permission=False,
35
                       permissions=cogbase.PERMISSION_MODS)
36
    async def _ping(self, ctx: SlashContext):
37
        await ctx.send(f"Pong! {round(self.bot.latency * 1000)}ms", delete_after=4.0)
38
39
    # Clear messages
40
    @cog_ext.cog_slash(name="clear", guild_ids=cogbase.GUILD_IDS,
41
                       description="Function for clearing messages on channel",
42
                       default_permission=False,
43
                       permissions=cogbase.PERMISSION_MODS)
44
    async def _purge(self, ctx: SlashContext, number):
45
        num_messages = int(number)
46
        await ctx.channel.purge(limit=num_messages)
47
        await ctx.send(f"Cleared {num_messages} messages!", delete_after=4.0)
48
49
    # Disconnect Bot
50
    @cog_ext.cog_slash(name="exit", guild_ids=cogbase.GUILD_IDS,
51
                       description="Turn off the bot",
52
                       default_permission=False,
53
                       permissions=cogbase.PERMISSION_ADMINS)
54
    async def _exit(self, ctx: SlashContext):
55
        await ctx.send(f"Closing Bot", delete_after=1.0)
56
        print(f"[{self.__class__.__name__}]: Exiting Bot")
57
        await asyncio.sleep(3)
58
        await self.bot.close()
59
60
    # WARN FUNCTIONS
61
    # Warn user
62
    @cog_ext.cog_slash(name="warn", guild_ids=cogbase.GUILD_IDS,
63
                       description="Function for warning users",
64
                       default_permission=False,
65
                       permissions=cogbase.PERMISSION_MODS)
66
    async def _warn(self, ctx: SlashContext, user: discord.User, reason: str):
67
68
        await DatabaseCog.db_add_warn(user.id, reason)
69
        await ctx.send(
70
            f"{user.mention} was warned for:\n*\"{reason}\"*\n")  # f"Number of warns: {len(current_user['reasons'])}")
71
72
    # Get list of user's warns
73
    @cog_ext.cog_slash(name="warns", guild_ids=cogbase.GUILD_IDS,
74
                       description="Function for warning users",
75
                       default_permission=False,
76
                       permissions=cogbase.PERMISSION_MODS)
77
    async def _warns(self, ctx: SlashContext, user: discord.User):
78
        warns, nr_of_warns = await DatabaseCog.db_get_warns(user.id)
79
        nl = "\n"
80
        message = f"**{user.name}** has been warned **{nr_of_warns}** times\n\n_Reasons_:\n" \
81
                  f"{nl.join(warns)}\n"
82
        await ctx.author.send(message)
83
        await ctx.send(f"{user.name} warns has been sent to DM", hidden=True)
84
85
    # Remove all member's warns
86
    @cog_ext.cog_slash(name="removeWarns", guild_ids=cogbase.GUILD_IDS,
87
                       description="Function for removing user's all warns",
88
                       default_permission=False,
89
                       permissions=cogbase.PERMISSION_ADMINS)
90
    async def remove_warns(self, ctx: SlashContext, user: discord.User):
91
        await DatabaseCog.db_remove_warns(user.id)
92
        await ctx.send(f"{user.display_name}'s warns were deleted", hidden=True)
93
94
    # Mute member
95
    @cog_ext.cog_slash(name="mute", guild_ids=cogbase.GUILD_IDS,
96
                       description="Mute member for x minutes",
97
                       default_permission=False,
98
                       permissions=cogbase.PERMISSION_MODS)
99
    async def _mute(self, ctx: SlashContext, user: discord.User, time: int, reason: str):
100
        duration = time * 60
101
        guild = ctx.guild
102
        muted = discord.utils.get(guild.roles, name="Muted")
103
104
        if not muted:
105
            muted = await guild.create_role(name="Muted")
106
            for channel in guild.channels:
107
                await channel.set_permissions(muted, speak=False, send_messages=False, read_message_history=True,
108
                                              read_messages=False)
109
        await user.add_roles(muted, reason=reason)
110
        await ctx.send(f"{user.mention} Was muted by {ctx.author.name} for {time} min\n"
111
                       f"Reason: {reason}", delete_after=10)
112
        await asyncio.sleep(duration)
113
        await user.remove_roles(muted)
114
        await ctx.send(f"{ctx.author.mention} mute is over", delete_after=10)
115
116
    # CHANNEL NAMES UPDATES
117
    # Total member channel name
118
    @cog_ext.cog_slash(name="updateTotalMembers", guild_ids=cogbase.GUILD_IDS,
119
                       description="Update total number of members",
120
                       default_permission=False,
121
                       permissions=cogbase.PERMISSION_MODS)
122
    async def update_member_count_command(self, ctx: SlashContext):
123
        await self.bot.update_member_count(ctx)
124
        await ctx.send(f"Total Members count updated", hidden=True)
125
126
    # Commons channel name
127
    @cog_ext.cog_slash(name="updateCommons", guild_ids=cogbase.GUILD_IDS,
128
                       description="Update common channel name",
129
                       default_permission=False,
130
                       permissions=cogbase.PERMISSION_MODS)
131
    async def update_commons_ch(self, ctx: SlashContext):
132
        with open('./server_files/commons.txt') as f:
133
            try:
134
                commons = f.read().splitlines()
135
            except ValueError:
136
                print(ValueError)
137
138
        new_name = f"common {commons[0]}"
139
        common_ch = self.bot.get_channel(self.bot.ch_common)
140
        await discord.TextChannel.edit(common_ch, name=new_name)
141
        print(f"[{self.__class__.__name__}]: Common channel name updated: {commons[0]}")
142
143
        admin_posting = self.bot.get_channel(self.bot.ch_admin_posting)
144
        await admin_posting.send(f"Common changed: {commons[0]}")
145
        await ctx.send(f"Common changed: {commons[0]}", hidden=True)
146
147
        commons.append(commons.pop(commons.index(commons[0])))
148
        with open('./server_files/commons.txt', 'w') as f:
149
            for item in commons:
150
                f.write("%s\n" % item)
151
152
    # N-Word spotted channel name
153
    # Doesn't work if used too many times in a short period of time
154
    @cog_ext.cog_slash(name="nword", guild_ids=cogbase.GUILD_IDS,
155
                       description="Change N-Word channel name",
156
                       permissions=cogbase.PERMISSION_ADMINS)
157
    async def rename_nword_channel(self, ctx, status: str):
158
        new_status = status
159
        channel = self.bot.get_channel(self.bot.ch_nightmare_killed)
160
        if new_status in channel.name:
161
            await ctx.send(f"{channel.name} has been changed", hidden=True)
162
        else:
163
            await discord.VoiceChannel.edit(channel, name=f"N-Word spotted: {new_status}")
164
            await ctx.send(f"{channel.name} channel name has been changed", hidden=True)
165
166
    # OTHER
167
168
    # Pull config.json from Google Sheets
169
    @cog_ext.cog_slash(name="pullConfig", guild_ids=cogbase.GUILD_IDS,
170
                       description="Pull config from google sheets",
171
                       default_permission=False,
172
                       permissions=cogbase.PERMISSION_ADMINS)
173
    async def pull_config(self, ctx: SlashContext):
174
        get_config()
175
        with open('server_files/config.json', 'r', encoding='utf-8-sig') as fp:
176
            self.bot.config = json.load(fp)
177
            await self.create_roles(ctx, True)
178
            await self.create_roles(ctx, False)
179
            print(f"[{self.__class__.__name__}]: Finished data pull")
180
        await ctx.send(f"Config.json updated", hidden=True)
181
182
    # Create roles if pull_config gets non existent roles
183
    async def create_roles(self, ctx: SlashContext, common: bool):
184
        milestones = "common_milestones" if common else "total_milestones"
185
        for mon_type in self.bot.config[milestones][0]:
186
            if get(ctx.guild.roles, name=mon_type):
187
                continue
188
            else:
189
                await ctx.guild.create_role(name=mon_type)
190
                print(f"[{self.__class__.__name__}]: {mon_type} role created")
191
192
    # Clear temp spots table in database
193
    @cog_ext.cog_slash(name="clearTempSpots", guild_ids=cogbase.GUILD_IDS,
194
                       description="Clear temp spots table in database",
195
                       permissions=cogbase.PERMISSION_ADMINS)
196
    async def clear_temp_spots_table(self, ctx):
197
        await DatabaseCog.db_clear_spots_temp_table()
198
        await ctx.send(f"Temp spots table was cleared", hidden=True)
199
        await self.reload_cog(ctx, "cogs.databasecog")
200
201
    # Reloads cog, very useful because there is no need to exit the bot after updating cog
202
    async def reload_cog(self, ctx: SlashContext, module: str):
203
        """Reloads a module."""
204
        try:
205
            self.bot.load_extension(f"{module}")
206
            await ctx.send(f'[{module}] loaded', hidden=True)
207
            print(f'[{self.__class__.__name__}]: {module} loaded')
208
        except commands.ExtensionAlreadyLoaded:
209
            self.bot.unload_extension(module)
210
            self.bot.load_extension(module)
211
            await ctx.send(f'[{module}] reloaded', hidden=True)
212
            print(f'[{self.__class__.__name__}]: {module} reloaded')
213
        except commands.ExtensionNotFound:
214
            await ctx.send(f'[{module}] not found', hidden=True)
215
            print(f'[{self.__class__.__name__}]: {module} not found')
216
217
    # Command for reloading specific cog
218
    @cog_ext.cog_slash(name="reloadCog", guild_ids=cogbase.GUILD_IDS,
219
                       description="Reload cog",
220
                       permissions=cogbase.PERMISSION_ADMINS)
221
    async def reload_cog_command(self, ctx: SlashContext, module: str):
222
        await self.reload_cog(ctx, module)
223
224
    # Command for reloading all cogs
225
    @cog_ext.cog_slash(name="reloadAllCogs", guild_ids=cogbase.GUILD_IDS,
226
                       description="Reload cog",
227
                       permissions=cogbase.PERMISSION_ADMINS)
228
    async def reload_all_cogs(self, ctx: SlashContext = None):
229
        for cog in list(self.bot.extensions.keys()):
230
            await self.reload_cog(ctx, cog)
231
        await ctx.send(f'All cogs reloaded', hidden=True)
232
233
234
def setup(bot: commands.Bot):
235
    bot.add_cog(CommandsCog(bot))
236