Passed
Push — master ( 60e754...e420f2 )
by Vinay
03:43
created

cogs.mod.mod.react_error()   A

Complexity

Conditions 2

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 2
nop 3
1
import os
2
import requests
3
import asyncio
4
import datetime
5
import copy
6
import random
7
from collections import Counter
8
from typing import Optional, Union
9
import discord
10
from discord.ext import commands
11
from utils import colors, checks, converters, errors
12
from utils.global_utils import confirm_prompt, send_embedded
13
14
15
class mod(commands.Cog):
16
    """ commands for the mods 👀"""
17
18
    def __init__(self, bot):
19
        self.bot = bot
20
        self._last_result = None
21
22
    def whats_the_reason(self, ctx, reason: str):
23
        if reason:
24
            res = f"{ctx.author.mention}: {reason}"
25
        else:
26
            res = f"Action done by {ctx.author.mention} (ID: {ctx.author.id})"
27
28
        if len(res) > 500:
29
            raise commands.BadArgument("Reason too long bro!")
30
        return res
31
32
    def make_embed(self, ctx, member, action, custom=None):
33
        desc = {
34
            "ban": "has been banned",
35
            "kick": "has been kicked",
36
            "soft": "has been soft banned",
37
            "mute": "has been muted",
38
            "unban": "has been unbanned",
39
        }
40
        what_happen = f"{member} {desc[action]}"
41
42
        embed = discord.Embed(color=random.choice(self.bot.color_list), title="",)
43
        if custom is None:
44
            embed.description = f"{what_happen}"
45
        else:
46
            embed.description = f"Reason: {custom}"
47
        embed.set_author(name=f"{member} {desc[action]}")
48
        if not desc[action] == "has been unbanned":
49
            embed.set_thumbnail(url=member.avatar_url)
50
        embed.set_footer(text=f"Action performed by {ctx.author}")
51
        return embed
52
53
    @commands.command()
54
    @checks.has_permissions(kick_members=True)
55
    async def kick(self, ctx, member: discord.Member = None, *, reason=None):
56
        """kicks a user"""
57
        if member is None:
58
            await ctx.send("You probably haven't entered something correctly\n```!!kick <member> <reason>```")
59
        try:
60
            await ctx.guild.kick(member, reason=self.whats_the_reason(ctx, reason))
61
            await ctx.send(embed=self.make_embed(ctx, member, action="kick", custom=reason))
62
        except discord.HTTPException:
63
            await send_embedded(ctx, "Uh Ho! Something not quite right happened.")
64
65
    @commands.command()
66
    @checks.has_permissions(ban_members=True)
67
    async def ban(
68
        self, ctx, member: discord.Member = None, deleted: Optional[int] = 0, *, reason=None,
69
    ):
70
        """bans an user"""
71
        if member is None:
72
            await ctx.send("You probably haven't entered something correctly\n```!!kick <member> <reason>```")
73
        try:
74
            await ctx.guild.ban(
75
                member, reason=self.whats_the_reason(ctx, reason), delete_message_days=min(deleted, 7),
76
            )
77
            await ctx.send(embed=self.make_embed(ctx, member, action="ban", custom=reason))
78
        except discord.HTTPException:
79
            await send_embedded(ctx, "Uh Ho! Something not quite right happened.")
80
81
    @commands.command()
82
    @checks.has_permissions(ban_members=True)
83
    async def unban(self, ctx, member: converters.BannedMember, *, reason=None):
84
        """unban an user"""
85
        if member is None:
86
            await ctx.send("You probably haven't entered something correctly\n```!!kick <member> <reason>```")
87
        try:
88
            await ctx.guild.unban(member.user, reason=self.whats_the_reason(ctx, reason))
89
            await ctx.send(embed=self.make_embed(ctx, member, action="unban", custom=reason))
90
        except discord.HTTPException:
91
            await send_embedded(ctx, "Uh Ho! Something not quite right happened.")
92
93
    @commands.command()
94
    @checks.has_permissions(ban_members=True)
95
    @checks.has_permissions(kick_members=True)
96
    async def softban(self, ctx, member: converters.MemberID, *, reason=None):
97
        """softbans an user"""
98
        if member is None:
99
            await ctx.send("You probably haven't entered something correctly\n```!!kick <member> <reason>```")
100
        try:
101
            await ctx.guild.ban(member, reason=self.whats_the_reason(ctx, reason))
102
            await ctx.guild.unban(member, reason=self.whats_the_reason(ctx, reason))
103
            await ctx.send(embed=self.make_embed(ctx, member, action="soft", custom=reason))
104
        except discord.HTTPException:
105
            await send_embedded(ctx, "Uh Ho! Something not quite right happened.")
106
107
    @ban.error
108
    @unban.error
109
    @kick.error
110
    @softban.error
111
    async def _error(self, ctx, error):
112
        if isinstance(error, commands.BadArgument):
113
            return await send_embedded(ctx, "Please check the arguments as one of it might be wrong.")
114
        elif isinstance(error, commands.MissingPermissions):
115
            return await send_embedded(ctx, "You don't have the permission to pull this one off broh!!")
116
117
    @commands.command()
118
    @checks.has_permissions(manage_emojis=True)
119
    async def react(self, ctx, emoji, messageID: int):
120
        msg = await ctx.fetch_message(messageID)
121
        await msg.add_reaction(emoji)
122
        await ctx.message.delete(delay=5)
123
124
    @react.error
125
    async def react_error(self, ctx, error):
126
        if isinstance(error, commands.CheckFailure):
127
            return await send_embedded(ctx, "Can't do that!")
128
129
    @commands.command()
130
    @commands.guild_only()
131
    @checks.has_permissions(ban_members=True)
132
    async def lockdown(self, ctx, action):
133
        """LOCKDOWN"""
134
        if action.lower() == "on":
135
            msg = await ctx.send("Locking down the channel...")
136
            await ctx.channel.set_permissions(discord.utils.get(ctx.guild.roles, id=ctx.guild.id), send_messages=False)
137
            return await msg.edit(content="The channel has been successfully locked down. :lock: ")
138
        elif action.lower() == "off":
139
            msg = await ctx.send("Unlocking the channel...")
140
            await ctx.channel.set_permissions(discord.utils.get(ctx.guild.roles, id=ctx.guild.id), send_messages=True)
141
            return await msg.edit(content="The channel has been successfully unlocked. :unlock: ")
142
        else:
143
            return await send_embedded(ctx, "Lockdown command:\n!!lockdown [on/off]")
144
145
    @lockdown.error
146
    async def lockdown_error(self, ctx, error):
147
        if isinstance(error, commands.BadArgument):
148
            return await send_embedded(ctx, "Please check the arguments as one of it might be wrong.")
149
        elif isinstance(error, commands.MissingPermissions):
150
            return await send_embedded(ctx, "You don't have the permission to pull this one off broh!!")
151
152
    # Purge commands --------------------------------------------------------------------------------------------
153
    async def to_purge(self, ctx, limit, check, *, before=None, after=None):
154
        if limit > 150:
155
            return await send_embedded(ctx, "limit of messages that can be deleted is 150!")
156
157
        try:
158
            purged = await ctx.channel.purge(limit=limit, before=ctx.message, check=check)
159
        except discord.Forbidden:
160
            return await ctx.send("I do not have permissions to carry out this command")
161
        except discord.HTTPException as e:
162
            return await ctx.send(f"**Error:** {e}")
163
164
        authors = Counter(str(msg.author) for msg in purged)
165
        purged = len(purged)
166
        desc = [f"Deleted {purged} message(s)"]
167
168
        if purged:
169
            desc.append("")
170
            spammers = sorted(authors.items(), key=lambda t: t[1], reverse=True)
171
            desc.extend(f"**{name}**: {count}" for name, count in spammers)
172
173
        embed = discord.Embed(color=random.choice(self.bot.color_list), description="\n".join(desc))
174
        await ctx.send(embed=embed, delete_after=15)
175
176
    @commands.group(case_insensitive=True, invoke_without_command=False)
177
    @checks.is_mod()
178
    @checks.is_admin()
179
    @checks.has_permissions(manage_messages=True)
180
    async def purge(self, ctx):
181
        """purges messages on the basis of subcommands"""
182
        if ctx.invoked_subcommand is None:
183
            await ctx.send_help(ctx.command)
184
185
    @purge.error
186
    async def purge_error(self, ctx, error):
187
        if isinstance(error, commands.MissingRequiredArgument):
188
            return await send_embedded(ctx, "An argument is missing!")
189
        elif isinstance(error, commands.MissingPermissions):
190
            return await send_embedded(ctx, "You don't have the permission to pull it off broh!!")
191
192
    @purge.command(name="user")
193
    async def _user(self, ctx, member: discord.Member, search: int = 10):
194
        """purge message by certain user"""
195
        await self.to_purge(ctx, search, lambda m: m.author == member)
196
        await ctx.message.add_reaction("\U00002705")
197
198
    @purge.command(name="all")
199
    async def _all(self, ctx, search: int = 20):
200
        """deletes given ammount of messages"""
201
        if not await confirm_prompt(ctx, f"Delete {search} messages?"):
202
            return
203
        await self.to_purge(ctx, search, lambda m: True)
204
        await ctx.message.add_reaction("\U00002705")
205
206
    @purge.command(name="clean")
207
    @commands.is_owner()
208
    async def _clean(self, ctx, search: int = 149):
209
        """deletes last 150 messages"""
210
        if not await confirm_prompt(ctx, f"Delete **all** messages?"):
211
            return
212
        await self.to_purge(ctx, search, lambda m: True)
213
        await ctx.message.add_reaction("\U00002705")
214
215
    @purge.command(name="content")
216
    async def _equals(self, ctx, *, substr):
217
        """deletes messages equal to a given string"""
218
        await self.to_purge(ctx, 50, lambda m: m.content == substr)
219
        await ctx.message.add_reaction("\U00002705")
220
221
    @purge.command(name="contains")
222
    async def _contains(self, ctx, *, substr):
223
        """deletes message with a specific string in it"""
224
        await self.to_purge(ctx, 50, lambda m: substr in m.content)
225
        await ctx.message.add_reaction("\U00002705")
226
227
    ### Purge commans end ------------------------------------------------------------------------------------
228
229
    @commands.command()
230
    @checks.has_permissions(administrator=True)
231
    async def dm(self, ctx, member: discord.Member, *, msg: str):
232
        try:
233
            await member.send(msg)
234
            await ctx.message.delete()
235
            await send_embedded(ctx, f"DM to {member} has been sent!")
236
        except commands.MissingPermissions:
237
            await send_embedded(ctx, f"You dont have the permissions mah dude!")
238
239
    ### Presence tools -------------------------------------
240
241
    @commands.group(name="presence", invoke_without_command=True, case_insensitive=True)
242
    @checks.is_admin()
243
    async def change_presence(self, ctx):
244
        """change rich presence of the bot"""
245
        await ctx.send_help(ctx.command)
246
247 View Code Duplication
    @change_presence.command(aliases=["l"])
248
    async def listen(self, ctx, *, name):
249
        if ctx.guild is None:
250
            botmember = self.bot.guilds[0].me
251
        else:
252
            botmember = ctx.me
253
        status = botmember.status
254
        await self.bot.change_presence(
255
            activity=discord.Activity(name=name, type=discord.ActivityType.listening), status=status,
256
        )
257
        await ctx.message.add_reaction("\u2705")
258
        await ctx.message.delete(delay=15.0)
259
260
    @change_presence.command(aliases=["p"])
261
    async def playing(self, ctx, *, name):
262
        if ctx.guild is None:
263
            botmember = self.bot.guilds[0].me
264
        else:
265
            botmember = ctx.me
266
        status = botmember.status
267
        await self.bot.change_presence(activity=discord.Game(name=name), status=status)
268
        await ctx.message.add_reaction("\u2705")
269
        await ctx.message.delete(delay=15.0)
270
271
    @change_presence.command(aliases=["s"])
272
    async def streaming(self, ctx, name, url=None):
273
        if ctx.guild is None:
274
            botmember = self.bot.guilds[0].me
275
        else:
276
            botmember = ctx.me
277
        status = botmember.status
278
        # url = url or 'https://www.twitch.tv/directory'
279
        if name and (url == None):
280
            url = f"https://www.twitch.tv/{name}"
281
        await self.bot.change_presence(
282
            activity=discord.Streaming(name=name, url=url, twitch_name=name), status=status,
283
        )
284
        await ctx.message.add_reaction("\u2705")
285
        await ctx.message.delete(delay=15.0)
286
287 View Code Duplication
    @change_presence.command(aliases=["w"])
288
    async def watching(self, ctx, *, name):
289
        if ctx.guild is None:
290
            botmember = self.bot.guilds[0].me
291
        else:
292
            botmember = ctx.me
293
        status = botmember.status
294
        await self.bot.change_presence(
295
            activity=discord.Activity(name=name, type=discord.ActivityType.watching), status=status,
296
        )
297
        await ctx.message.add_reaction("\u2705")
298
        await ctx.message.delete(delay=15.0)
299
300
    @change_presence.command()
301
    async def status(self, ctx, status):
302
        """change status of the bot"""
303
        stata = {
304
            "online": discord.Status.online,
305
            "offline": discord.Status.invisible,
306
            "invis": discord.Status.invisible,
307
            "invisible": discord.Status.invisible,
308
            "idle": discord.Status.idle,
309
            "dnd": discord.Status.dnd,
310
        }
311
        status = status.lower()
312
        if status not in stata:
313
            return await ctx.send(f'Not a valid status! Choose: [{", ".join(stata.keys())}]')
314
        if ctx.guild is None:
315
            botmember = self.bot.guilds[0].me
316
        else:
317
            botmember = ctx.me
318
        activity = botmember.activity
319
        await self.bot.change_presence(status=stata[status], activity=activity)
320
        await ctx.message.add_reaction("\u2705")
321
        await ctx.message.delete(delay=15.0)
322
323
    @change_presence.command()
324
    async def clear(self, ctx):
325
        """clears rich presence"""
326
        await self.bot.change_presence()
327
        await ctx.message.add_reaction("\u2705")
328
        await ctx.message.delete(delay=15.0)
329
330
    @change_presence.command()
331
    async def reset(self, ctx):
332
        """sets a generic rich presence"""
333
        await self.bot.change_presence(
334
            activity=discord.Activity(type=discord.ActivityType.listening, name="you for feedback :)")
335
        )
336
        await ctx.message.add_reaction("\u2705")
337
        await ctx.message.delete(delay=15.0)
338
339
340
def setup(bot):
341
    bot.add_cog(mod(bot))
342