Passed
Branch BonHowi (176536)
by Bartosz
01:15
created

CommandsCog.update_member_count_command()   A

Complexity

Conditions 1

Size

Total Lines 7
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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