async def phfreeze(self, ctx): """ Lock public help system """ await ctx.message.delete() args = parse_arguments(ctx.message.content) await db.lock("public_help") phelp_data = db["public_help"]["current_channels"] if not args.check(0, re=r"(on|off)"): db.unlock("public_help") await self.tmp_msg("No matching argument passed.", ctx.message.channel) return if args[0] == "on": freeze = True elif args[0] == "off": freeze = False db["public_help"] = {"current_channels": phelp_data, "freeze": freeze} db.unlock("public_help") await self.tmp_msg("Successfully applied.", ctx.message.channel, reaction=config.REACT_SUCCESS)
async def deny(self, ctx): """ Ban users due to verification denial """ args = parse_arguments(ctx.message.content) member = await check_for_id(ctx, args) await send_embed_dm(member, config.DENIEDMSG) await member.ban(reason="Verification denied by a moderator.") await log(ctx.message.guild, ctx.message.author, "Reject", f"rejected {member.mention}") await ctx.message.channel.send(f"Successfully denied {member.mention}!" ) # Remove data entry await db.lock("reminds") reminds = db["reminds"]["reminds"] endreminds = [] for reminder in reminds: if reminder["userid"] != member.id: endreminds.append(reminder) db["reminds"] = {"reminds": endreminds} db.unlock("reminds")
async def kick(self, ctx): """ Kick a member """ args = parse_arguments(ctx.message.content) member = await check_for_id(ctx, args) await check_for_role(ctx, member, config.STAFFROLE, "kicked") fullname = get_full_name(ctx.message.author) # Main logic if not args.check(1): await ctx.message.channel.send("Please specify a reason.") return reason = " ".join(args[1:]) await db.lock("logs") now = datetime.utcnow() logs = db["logs"]["logs"] logs.append({ "year": now.year, "month": now.month, "day": now.day, "hour": now.hour, "minute": now.minute, "userid": member.id, "guild": ctx.message.guild.id, "reason": reason, "type": "kick", }) db["logs"] = {"logs": logs} db.unlock("logs") embed = config.KICKMSG embed.add_field( name="Reason", value=reason, ) await send_embed_dm(member, embed) await log(ctx.message.guild, ctx.message.author, "Kick", f"kicked {member.mention}. Reason: {reason}") await member.kick(reason=f"Kicked by {fullname}") await ctx.message.channel.send(f"Successfully kicked {member.mention}!" )
async def phdbflush(self, ctx): await ctx.message.delete() await db.lock("public_help") db["public_help"] = {"current_channels": [], "freeze": False} db.unlock("public_help") await self.tmp_msg("Successfully flushed data.", ctx.message.channel, reaction=config.REACT_SUCCESS)
async def on_member_remove(self, member): """ On member left """ await db.lock("reminds") reminds = db["reminds"]["reminds"] endreminds = [] for reminder in reminds: if reminder["userid"] != member.id: endreminds.append(reminder) db["reminds"] = {"reminds": endreminds} db.unlock("reminds")
async def on_member_join(self, member): """ Send information to user and add set reminder """ # Welcome message channel = self.bot.get_channel(config.WELCOMEMSG_CHANNEL) msg = f"Hello <@{member.id}>!\nCheck out <#690216616163672136> to verify your account and start chatting, <#724238392723767357> to get answers to common questions and <#690219084469895225> to get special roles!" embed = discord.Embed( title="Welcome to Ethical Computing Society!", description=msg, color=config.COLOR, ) await channel.send(embed=embed) # DM await send_embed_dm(member, config.WELCOMEMSG) # Reminder await db.lock("reminds") reminds = db["reminds"]["reminds"] reminder = datetime.utcnow() + timedelta(hours=24) reminds.append({ "year": reminder.year, "month": reminder.month, "day": reminder.day, "hour": reminder.hour, "minute": reminder.minute, "userid": member.id, "guild": member.guild.id, "status": 0, }) db["reminds"] = {"reminds": reminds} db.unlock("reminds") # Add unverified role await member.add_roles(member.guild.get_role(config.UNVERIFIEDROLE), reason="Joined the server.")
async def public_help_tick(self): """ Autodelete inactive channels """ await db.lock("public_help") phelp_data = db["public_help"]["current_channels"] freeze = db["public_help"]["freeze"] for block in phelp_data: channel = self.bot.get_channel(block["channel"]) fetch_message = await channel.history(limit=4).flatten() now = datetime.utcnow() delta = now - fetch_message[0].created_at if delta.days >= config.PHELP_REMEMBER_AFTER_DAY and \ fetch_message[0].author.id != self.bot.user.id: # Warning await channel.send( f"Hey <@{block['user_id']}>, this channel will be automatically deleted in 2 days if not used by then." ) elif delta.days >= config.PHELP_DELETE_AFTER_DAY and \ fetch_message[0].author.id == self.bot.user.id: # Delete Channel # end_data = [] for block in phelp_data: if block["channel"] != fetch_message[0].channel.id: end_data.append(block) await channel.delete() db["public_help"] = { "current_channels": end_data, "freeze": freeze } db.unlock("public_help")
async def clearlog(self, ctx): """ Delete log of a specific user """ args = parse_arguments(ctx.message.content) member = await check_for_id(ctx, args) await db.lock("logs") new_log = [] for log_entry in db["logs"]["logs"]: if log_entry["userid"] != int(args[0]): new_log.append(log_entry) db["logs"] = {"logs": new_log} db.unlock("logs") await ctx.message.channel.send(f"Cleared modlog of {member.mention}.")
async def request_permission(self, db, output_channel, channel, author, client, args): # TODO: Improvised """ Validate selection by asking for message """ if "-y" not in args: req_quest_msg = await output_channel.send( "Please answer with 'YES' if you would like to close and delete your temporary channel." ) for _ in range(4): try: req_msg = await client.wait_for('message', timeout=5) break except TimeoutError: db.unlock("public_help") await self.tmp_msg("Timeout was raised.", output_channel) raise IgnoreException if req_msg.author != author or req_msg.content != "YES" or req_msg.channel.id != channel.id: db.unlock("public_help") await self.tmp_msg( "Message has not been answered with YES.\nYou could try again using the -y argument to bypass this step.", channel, delay=10) raise IgnoreException await req_quest_msg.delete() await req_msg.delete()
async def verify(self, ctx): """ Remove unverified role from user and append member role TODO: Rename user role to member """ args = parse_arguments(ctx.message.content) member = await check_for_id(ctx, args) verifiedrole = ctx.message.guild.get_role(config.VERIFIEDROLE) unverifiedrole = ctx.message.guild.get_role(config.UNVERIFIEDROLE) await member.add_roles(verifiedrole, reason="Verified by a moderator.") await member.remove_roles(unverifiedrole, reason="Verified by a moderator.") await ctx.message.channel.send( f"Successfully verified {member.mention}!") await log(ctx.message.guild, ctx.message.author, "Verification", f"verified {member.mention}") # Remove data entry await db.lock("reminds") reminds = db["reminds"]["reminds"] endreminds = [] for reminder in reminds: if reminder["userid"] != member.id: endreminds.append(reminder) db["reminds"] = {"reminds": endreminds} db.unlock("reminds")
async def mute(self, ctx): """ Mute user for certain amount of time """ # Check stuff args = parse_arguments(ctx.message.content) # Check member = await check_for_id(ctx, args) await check_for_role(ctx, member, config.MODROLE, "muted") fullname = get_full_name(ctx.message.author) await db.lock("punishments") punishments = db["punishments"]["punishments"] strtotimestr = { "5m": "5 minutes", "30m": "30 minutes", "1h": "1 hour", "2h": "2 hours", "1d": "1 day", "2d": "2 days", "3d": "3 days", "5d": "5 days", "7d": "7 days", "perma": "permanently", } strtotimemin = { "5m": 5, "30m": 30, "1h": 60, "2h": 120, "1d": 1440, "2d": 2880, "3d": 4320, "5d": 7200, "7d": 10080, "perma": 999999999, } time_in_minutes, timestr = await get_punishment_reason_length( ctx, args, db, punishments, member, strtotimestr, strtotimemin, ["mute", "ban"], "mute") # Main logic reason = " ".join(args[2:]) embed = config.MUTEMSG embed.add_field( name="Reason", value=reason, ) embed.add_field( name="Duration", value=timestr, ) await send_embed_dm(member, embed) await log(ctx.message.guild, ctx.message.author, "Mute", f"muted {member.mention} for {timestr}. Reason: {reason}") muterole = ctx.message.guild.get_role(config.MUTEDROLE) await member.add_roles(muterole, reason=f"Muted by {fullname}") # Write data endtime = datetime.utcnow() + timedelta(minutes=time_in_minutes) punishments.append({ "year": endtime.year, "month": endtime.month, "day": endtime.day, "hour": endtime.hour, "minute": endtime.minute, "userid": member.id, "guild": ctx.message.guild.id, "type": "mute", }) db["punishments"] = {"punishments": punishments} # Write log now = datetime.utcnow() db.unlock("punishments") await db.lock("logs") logs = db["logs"]["logs"] logs.append({ "year": now.year, "month": now.month, "day": now.day, "hour": now.hour, "minute": now.minute, "userid": member.id, "guild": ctx.message.guild.id, "duration": args[1], "reason": reason, "type": "mute", }) db["logs"] = {"logs": logs} db.unlock("logs") await ctx.message.channel.send(f"Successfully muted {member.mention}!")
async def rename(self, ctx): # TODO: Rework function """ Rename an existing help channel """ args = parse_arguments(ctx.message.content) await ctx.message.delete() category = self.bot.get_channel(config.PHELPCATEGORY) await db.lock("public_help") phelp_data = db["public_help"]["current_channels"] freeze = db["public_help"]["freeze"] # Check for valid request if not args.check(0, re=r"^[0-9]*$"): await self.tmp_msg("Please supply a valid ID.", ctx.message.channel) db.unlock("public_help") return if int(args[0]) not in [data["channel"] for data in phelp_data]: await self.tmp_msg("Please supply a valid ID.", ctx.message.channel) db.unlock("public_help") return if not args.check(1): db.unlock("public_help") await self.tmp_msg("Please supply a title.", ctx.message.channel) return title = " ".join(args[1:]) if len(title) > config.PHELP_MAX_TITLE: db.unlock("public_help") await self.tmp_msg("Please supply a shorter title.", ctx) return channel_id = [ channel["channel"] for channel in phelp_data if channel["channel"] == int(args[0]) ][0] channel = self.bot.get_channel(channel_id) old_name = channel.name await channel.edit(name=title) info_msg = await ctx.message.channel.send( f"Channel successfully renamed from '{old_name}' to '{title}'.") await info_msg.add_reaction(config.REACT_SUCCESS) # Writing Data # date = datetime.utcnow() new_phelp_data = [] for data in phelp_data: if data["channel"] != int(args[0]): new_phelp_data.append(data) phelp_data.append({ "user_id": ctx.author.id, "category": category.id, "channel": channel.id, "title": title, "year": date.year, "month": date.month, "day": date.day, "hour": date.hour, "minute": date.minute, "user_name": ctx.author.name, "guild": ctx.guild.id, }) db["public_help"] = {"current_channels": phelp_data, "freeze": freeze} db.unlock("public_help") await asyc_sleep(10) await info_msg.delete()
async def ban(self, ctx): """ Ban user for specific time and delete messages """ args = parse_arguments(ctx.message.content) member = await check_for_id(ctx, args) await check_for_role(ctx, member, config.MODROLE, "banned") fullname = get_full_name(ctx.message.author) await db.lock("punishments") punishments = db["punishments"]["punishments"] strtotimestr = { "1d": "1 day", "2d": "2 days", "3d": "3 days", "5d": "5 days", "7d": "7 days", "14d": "14 days", "30d": "30 days", "60d": "60 days", "120d": "120 days", "240d": "240 days", "1y": "1 year", "perma": "permanently", } strtotimemin = { "1d": 1440, "2d": 2880, "3d": 4320, "5d": 7200, "7d": 10080, "14d": 20160, "30d": 43200, "60d": 86400, "120d": 172800, "240d": 345600, "1y": 525600, "perma": 999999999, } time_in_minutes, timestr = await get_punishment_reason_length( ctx, args, db, punishments, member, strtotimestr, strtotimemin, ["ban"], "ban") # Main logic reason = " ".join(args[2:]) embed = config.BANMSG embed.add_field( name="Reason", value=reason, ) embed.add_field( name="Duration", value=timestr, ) await send_embed_dm(member, embed) await log(ctx.message.guild, ctx.message.author, "Ban", f"banned {member.mention} for {timestr}. Reason: {reason}") await member.ban( reason=f"Banned by {fullname} for {timestr}. Reason: {reason}", delete_message_days=config.BANDELETEMESSAGES) # Write data endtime = datetime.utcnow() + timedelta(minutes=time_in_minutes) punishments.append({ "year": endtime.year, "month": endtime.month, "day": endtime.day, "hour": endtime.hour, "minute": endtime.minute, "userid": member.id, "guild": ctx.message.guild.id, "type": "ban", }) db["punishments"] = {"punishments": punishments} # Write log now = datetime.utcnow() db.unlock("punishments") await db.lock("logs") logs = db["logs"]["logs"] logs.append({ "year": now.year, "month": now.month, "day": now.day, "hour": now.hour, "minute": now.minute, "userid": member.id, "guild": ctx.message.guild.id, "duration": args[1], "reason": reason, "type": "ban" }) db["logs"] = {"logs": logs} db.unlock("logs") await ctx.message.channel.send(f"Successfully banned {member.mention}!" )
async def close(self, ctx: SlashContext, y_skip=""): # TODO """ Close your public help channel """ # args = parse_arguments(ctx.message.content) # await ctx.message.delete() await db.lock("public_help") phelp_data = db["public_help"]["current_channels"] freeze = db["public_help"]["freeze"] # Check for valid request if freeze: db.unlock("public_help") await self.tmp_msg("This feature is currently locked.", ctx) return list_for_check = [] for data in phelp_data: list_for_check.append(str(data["user_id"])) if str(ctx.author.id) not in list_for_check: db.unlock("public_help") await self.tmp_msg( "You did not create a channel: No channel to delete.", ctx) return # Ask for permission # await self.request_permission(db, ctx, ctx.channel, ctx.author, self.bot, [y_skip]) # Delete Channel # end_data = [] for block in phelp_data: if block["user_id"] == ctx.author.id: delete_channel_id = block["channel"] else: end_data.append(block) delete_channel = self.bot.get_channel(delete_channel_id) db["public_help"] = {"current_channels": end_data, "freeze": freeze} db.unlock("public_help") if delete_channel.topic == str(ctx.author.id): await delete_channel.delete( reason="Help channel deletion requested.") else: db.unlock("public_help") await self.tmp_msg("Fatal Exception author id does not match.", ctx) return await self.tmp_msg("Your channel has been successfully closed.", ctx, reaction=config.REACT_SUCCESS)
async def fclose(self, ctx): """ Force close public help channel """ await ctx.message.delete() args = parse_arguments(ctx.message.content) await db.lock("public_help") phelp_data = db["public_help"]["current_channels"] freeze = db["public_help"]["freeze"] # Check for valid request if not args.check(0, re=r"^[0-9]*$"): db.unlock("public_help") await self.tmp_msg("Please supply a valid ID.", ctx.message.channel) return list_for_check = [] for data in phelp_data: list_for_check.append(str(data["channel"])) if args[0] not in list_for_check: db.unlock("public_help") await self.tmp_msg("Please supply a valid ID.", ctx.message.channel) return # Ask for permission # await self.request_permission(db, ctx.message.channel, ctx.message.channel, ctx.message.author, self.bot, args) # Delete Channel # end_data = [] for block in phelp_data: if str(block["channel"]) != args[0]: end_data.append(block) else: delete_channel_id = str(block["channel"]) db["public_help"] = {"current_channels": end_data, "freeze": freeze} db.unlock("public_help") delete_channel = self.bot.get_channel(int(delete_channel_id)) await delete_channel.delete(reason="Force deletion of help channel.") await self.tmp_msg("The channel has been deleted.", ctx.message.channel, reaction=config.REACT_SUCCESS)
async def unmute(self, ctx): """ Unmute muted member """ args = parse_arguments(ctx.message.content) member = await check_for_id(ctx, args) fullname = get_full_name(ctx.message.author) await db.lock("punishments") punishments = db["punishments"]["punishments"] muted = False for punishment in punishments: if punishment["userid"] == member.id and \ punishment["type"] == "mute": muted = True muterole = ctx.message.guild.get_role(config.MUTEDROLE) muted_role = config.MUTEDROLE in [role.id for role in member.roles] if not muted and muted_role: db.unlock("punishments") await member.remove_roles(muterole, reason="Unmuted by ") await ctx.message.channel.send( f"Successfully unmuted {member.mention}.") return elif not muted: db.unlock("punishments") await ctx.message.channel.send( f"The user {member.mention} is not muted.") return await member.remove_roles(muterole, reason=f"Unmuted by {fullname}") new_punishments = [] for punishment in punishments: if punishment["userid"] != member.id or \ punishment["type"] != "mute": new_punishments.append(punishment) db["punishments"] = {"punishments": new_punishments} db.unlock("punishments") await send_embed_dm(member, config.UNMUTEMSG) await log(ctx.message.guild, ctx.message.author, "Unmuted", f"unmuted {member.mention}") await ctx.message.channel.send( f"Successfully unmuted {member.mention}!")
async def new(self, ctx: SlashContext, title): # TODO """ Create a new help channel """ # args = parse_arguments(ctx.message.content) # await ctx.message.delete() category = self.bot.get_channel(config.PHELPCATEGORY) await db.lock("public_help") phelp_data = db["public_help"]["current_channels"] freeze = db["public_help"]["freeze"] # Check for valid request if freeze: db.unlock("public_help") await self.tmp_msg("This feature is currently locked.", ctx) return if config.PHELP_MUTE_ROLE in [role.id for role in ctx.author.roles]: db.unlock("public_help") await self.tmp_msg( "You don't have permission to use this feature.", ctx) return # if not args.check(0): # db.unlock("public_help") # await self.tmp_msg("Please supply a title.", ctx.message.channel) # return # title = " ".join(args[0:]) if len(title) > config.PHELP_MAX_TITLE: db.unlock("public_help") await self.tmp_msg("Please supply a shorter title.", ctx) return for data in phelp_data: if data["user_id"] == ctx.author.id: db.unlock("public_help") await self.tmp_msg( "You are only allowed to have one public help channel.", ctx) return if len(category.channels) >= config.PHELP_MAX_CHANNELS: db.unlock("public_help") await self.tmp_msg( f"Only {config.PHELP_MAX_CHANNELS} public help channels are allowed.", ctx) return for check_channel in category.channels: if check_channel.topic == str(ctx.author.id): db.unlock("public_help") await self.tmp_msg( "You are only allowed to have one public help channel.", ctx) return # Creating new channel creating_msg = await ctx.send("Creating new channel please wait...") new_channel = await ctx.guild.create_text_channel( title, category=category, topic=str(ctx.author.id), reason="New help channel requested.", ) await new_channel.send( f"This is your new channel: <@{ctx.author.id}>\nPlease explain your problem down below, so other users can help you." ) await creating_msg.edit(content="Your new channel has been created.") await creating_msg.add_reaction(config.REACT_SUCCESS) # Writing Data # date = datetime.utcnow() phelp_data.append({ "user_id": ctx.author.id, "category": category.id, "channel": new_channel.id, "title": title, "year": date.year, "month": date.month, "day": date.day, "hour": date.hour, "minute": date.minute, "user_name": ctx.author.name, "guild": ctx.guild.id, }) db["public_help"] = {"current_channels": phelp_data, "freeze": freeze} db.unlock("public_help") await asyc_sleep(10) await creating_msg.delete()
async def unban(self, ctx): """ Unban banned user """ args = parse_arguments(ctx.message.content) if not args.check(0, re=r"^[0-9]*$"): await ctx.message.channel.send( "Please supply a valid mention or ID.") return banned_users = [ ban.user for ban in await ctx.message.guild.bans() if ban.user.id == int(args[0]) ] if len(banned_users) == 0: await ctx.message.channel.send( "Please supply a valid mention or ID.") return user = banned_users[0] fullname = get_full_name(ctx.message.author) await db.lock("punishments") punishments = db["punishments"]["punishments"] banned = False for punishment in punishments: if punishment["userid"] == user.id and \ punishment["type"] == "ban": banned = True server_banned = user.id in [ ban.user.id for ban in await ctx.message.guild.bans() ] if not banned and server_banned: db.unlock("punishments") await ctx.message.guild.unban(user, reason=f"Unbanned by {fullname}") await ctx.message.channel.send( f"Successfully unbanned {user.mention}.") return elif not banned: db.unlock("punishments") await ctx.message.channel.send( f"The user {user.mention} is not banned.") return await ctx.message.guild.unban(user, reason=f"Unmuted by {fullname}") new_punishments = [] for punishment in punishments: if punishment["userid"] != user.id or \ punishment["type"] != "ban": new_punishments.append(punishment) db["punishments"] = {"punishments": new_punishments} db.unlock("punishments") # await send_embed_dm(user, config.UNBANMSG) await log(ctx.message.guild, ctx.message.author, "Unbanned", f"unbanned {user.mention}") await ctx.message.channel.send(f"Successfully unbanned {user.mention}!" )
async def reminder_tick(self): """ Auto kick inactive users and warn them """ await db.lock("reminds") time_now = datetime.utcnow() reminds = db["reminds"]["reminds"] endreminds = [] for reminder in reminds: guild = self.bot.get_guild(reminder["guild"]) member = guild.get_member(reminder["userid"]) reminder_dt = datetime( reminder["year"], reminder["month"], reminder["day"], reminder["hour"], reminder["minute"], 0, 0, ) if time_now > reminder_dt: if reminder["status"] in [0, 1, 2]: # [0, 1] await send_embed_dm(member, config.REMINDERMSG) newremind = reminder_dt + timedelta(hours=24) endreminds.append({ "year": newremind.year, "month": newremind.month, "day": newremind.day, "hour": newremind.hour, "minute": newremind.minute, "userid": member.id, "guild": guild.id, "status": reminder["status"] + 1, }) else: await log(guild, member, "Kick", "been kicked for not verifying in time.") await send_embed_dm(member, config.REMINDKICKMSG) try: await member.kick(reason="Didn't verify.") except AttributeError: print("[w] Reminder kicking failed") else: endreminds.append(reminder) db["reminds"] = {"reminds": endreminds} db.unlock("reminds")
async def punishment_tick(self): """ Handling of expired punishments """ bancache = {} await db.lock("punishments") now = datetime.utcnow() punishments = db["punishments"]["punishments"] endpunishments = [] for punishment in punishments: if punishment["guild"] not in bancache.keys(): guild = self.bot.get_guild(punishment["guild"]) bancache[punishment["guild"]] = await guild.bans() bans = bancache[punishment["guild"]] member = guild.get_member(punishment["userid"]) ban_member = [ ban.user for ban in bans if ban.user.id == punishment["userid"] ] punishtime = datetime( punishment["year"], punishment["month"], punishment["day"], punishment["hour"], punishment["minute"], 0, 0, ) if now > punishtime: if punishment["type"] == "mute": await send_embed_dm(member, config.UNMUTEMSG) await log(guild, member, "Unmute", "been unmuted due to expiration!") muterole = guild.get_role(config.MUTEDROLE) await member.remove_roles(muterole) elif punishment["type"] == "ban": await log(guild, ban_member[0], "Unban", "been unbanned due to expiration!") await ban_member[0].unban(reason="Ban expired.") else: endpunishments.append(punishment) db["punishments"] = {"punishments": endpunishments} db.unlock("punishments")