async def ban(ctx, user: User, reason: str, days: int = None): if user.id == ctx.guild.owner_id: raise InvalidAction("Guild owner cannot be banned.") db_ban = BanMixin() prepare_outlaw(db_ban, escaped(reason), user, ctx, days=days) graph.create(db_ban) if days is not None: for_days = ctx.translate("for [days] days").format(days) else: for_days = "" conf_msg = ctx.translate("user banned").format(for_days) member: discord.Member = ctx.guild.get_member(user.id) try: await member.send( ctx.translate("[user] just banned you").format( str(ctx.author), ctx.guild.name, for_days, escaped(reason))) except discord.Forbidden: warning_note = ctx.translate("but user doesn't allow direct messages") conf_msg = f"{conf_msg}\n{warning_note}" await member.ban(reason=reason, delete_message_days=1) UnbanTimer(ctx, days, member, reason=ctx.translate("ban time expired")) await ctx.send(conf_msg) await ctx.db_guild.log( ctx.translate( "[user] banned [user][for days] because of [reason]").format( str(ctx.author), str(member), for_days, db_ban.reason))
async def kick(ctx, user: User, reason: str): if user.id == ctx.guild.owner_id: raise InvalidAction("Guild owner cannot be kicked.") db_kick = KickMixin() prepare_outlaw(db_kick, escaped(reason), user, ctx) graph.create(db_kick) conf_msg = ctx.translate("user kicked") member: discord.Member = ctx.guild.get_member(user.id) try: await member.send( ctx.translate("[user] just kicked you").format( str(ctx.author), ctx.guild.name, escaped(reason))) except discord.Forbidden: warning_note = ctx.translate("but user doesn't allow direct messages") conf_msg = f"{conf_msg}\n{warning_note}" await member.kick(reason=reason) await ctx.send(conf_msg) await ctx.db_guild.log( ctx.translate("[user] kicked [user] because of [reason]").format( str(ctx.author), str(member), db_kick.reason))
async def _create(ctx, t: Ticket, content: str): """ This is to create new responses/to answer tickets. """ if t.scope_enum == enums.Scope.CHANNEL and ctx.channel != t.channel and not ctx.may_fully_access( t): await ctx.send(ctx.translate("the related ticket is channel scope")) return None elif t.scope_enum == enums.Scope.PRIVATE and not ctx.may_fully_access(t): await ctx.send(ctx.translate("this is a private ticket")) return None elif t.state_enum == enums.State.CLOSED: await ctx.send(ctx.translate("this ticket is closed")) return None if t.scope_enum == enums.Scope.PRIVATE: try: await ctx.message.delete() except discord.Forbidden: pass utc = time.time() resp = Response() author = User.from_discord_user(ctx.author) resp.created_by.add(author, properties={'UTC': utc}) resp.located_on.add(ctx.db_guild) resp.refers_to.add(t) resp.content = escaped(content) resp.deleted = False resp.updated = utc highest_id = graph.run( "MATCH (r:Response)-[:REFERS_TO]->(t:Ticket {uuid: '%s'}) RETURN max(r.id)" % t.uuid).evaluate() if highest_id is None: highest_id = 0 resp.id = highest_id + 1 resp.uuid = uuid.uuid4().hex graph.create(resp) await ctx.send(ctx.translate("response created").format(resp.full_id)) resp_msg = ctx.translate( "[user] just responded to your ticket [ticket]").format( ctx.author.name, ctx.author.discriminator, t.id) await notify_author(ctx, resp_msg, t, embed=response_embed(ctx, resp)) await resp.guild.log( ctx.translate("[user] created response [response]").format( ctx.author, f"{resp.ticket.id}-{resp.id}"))
async def report(ctx, user: User, reason: str): db_author: User = ctx.db_author if user in [r.affected_user for r in db_author.issued_reports]: await ctx.send(ctx.translate("you already reported this user")) elif db_author.id == user.id: await ctx.send(ctx.translate("you cannot report yourself")) return else: db_guild = ctx.db_guild report_node = ReportMixin() report_node.reason = escaped(reason) report_node.utc = time.time() report_node.uuid = uuid.uuid4().hex report_node.issued_on.add(db_guild) report_node.issued_by.add(db_author) report_node.applies_to.add(user) graph.create(report_node) await ctx.send(ctx.translate("user reported")) if len(user.reports) == 3: msg_addition = ctx.translate("user has been reported three times now") else: msg_addition = "" await notify_supporters( ctx.bot, ctx.translate("[user] reported [user] because of [reason]" ).format(ctx.author, user.discord, escaped(reason) ) + msg_addition, db_guild ) await db_guild.log( ctx.translate("[user] has been reported because of [reason]").format(user.discord, escaped(reason)) ) try: await ctx.message.delete() except discord.Forbidden: pass
async def warn(ctx, user: User, reason: str): db_warning = WarningMixin() prepare_outlaw(db_warning, escaped(reason), user, ctx) graph.create(db_warning) conf_msg = ctx.translate("user warned") member = ctx.guild.get_member(user.id) try: await member.send( ctx.translate("[user] just warned you").format( str(ctx.author), ctx.guild.name, escaped(reason))) except discord.Forbidden: warning_note = ctx.translate("but user doesn't allow direct messages") conf_msg = f"{conf_msg}\n{warning_note}" await ctx.send(conf_msg) await ctx.db_guild.log( ctx.translate("[user] warned [user] because of [reason]").format( str(ctx.author), str(member), db_warning.reason))
async def _create(ctx, title: str, description: str="", scope: Scope=None): """ This is to create a support ticket. """ guild = ctx.db_guild t = Ticket(ctx=ctx) if len(title) > enums.TitleLength.MAX: await ctx.send(ctx.translate("title too long").format(enums.TitleLength.MAX.value, len(title))) elif len(title) < enums.TitleLength.MIN: await ctx.send(ctx.translate("title too short").format(enums.TitleLength.MIN.value, len(title))) else: utc = time.time() t.title = escaped(title) t.description = escaped(description) t.state = enums.State.OPEN.value t.updated = utc author = User.from_discord_user(ctx.author) t.created_by.add(author, properties={'UTC': utc}) t.located_on.add(guild) if scope is None: scope = t.guild.default_scope t.scope = scope highest_id = graph.run( "MATCH (t:Ticket)-[:TICKET_LOCATED_ON]->(g:Guild {id: %i}) RETURN max(t.id)" % guild.id ).evaluate() if highest_id is None: highest_id = 0 t.id = highest_id + 1 t.uuid = uuid.uuid4().hex responsible_user = None if t.guild.auto_assigning: support_role: discord.Role = t.guild.discord.get_role(t.guild.support_role) if support_role is not None: responsible_user = random.choice(support_role.members) responsible_user = User.from_discord_user(responsible_user, ctx=ctx) t.assigned_to.add(responsible_user) graph.create(t) send_invokation_channel = False # create text channel (and category if not exist yet) for channel ticket if t.scope_enum == enums.Scope.CHANNEL: supporter = discord.utils.get(guild.discord.roles, id=guild.support_role) if supporter is None: supporter = guild.discord.owner overwrites = { guild.discord.default_role: discord.PermissionOverwrite(read_messages=False), guild.discord.me: discord.PermissionOverwrite(read_messages=True, send_messages=True, manage_messages=True, add_reactions=True, manage_channels=True), supporter: discord.PermissionOverwrite(read_messages=True, send_messages=True) } if guild.ticket_category is None: category = await guild.discord.create_category( ctx.translate("support tickets"), overwrites=overwrites, reason=ctx.translate("first channel-ticket has been created") ) guild.ticket_category = category.id guild.push() else: category = guild.discord.get_channel(guild.ticket_category) overwrites[author.discord] = discord.PermissionOverwrite(read_messages=True, send_messages=True) channel = await guild.discord.create_text_channel( str(t.id), overwrites=overwrites, category=category, reason=ctx.translate("new channel-ticket has been created") ) await channel.edit( topic=t.title ) await channel.send(embed=ticket_embed(ctx, t)) format_id = channel.mention elif t.scope_enum == enums.Scope.PRIVATE: try: await ctx.message.delete() except discord.Forbidden: pass format_id = t.id else: send_invokation_channel = True format_id = t.id msg = ctx.translate("ticket created").format(format_id) try: await ctx.author.send(ctx.translate("your ticket has been created").format(t.id, guild.discord.name)) dm_allowed = True except commands.BotMissingPermissions: dm_allowed = False if not dm_allowed: msg += '\n' + ctx.translate("please allow receiving dms") if responsible_user is not None: msg += '\n\n' + ctx.translate("ticket auto-assigned to [user]").format(responsible_user.discord) await ctx.send(msg) if t.guild.channel != ctx.channel.id: new_ticket_msg = ctx.translate("new ticket") if send_invokation_channel: new_ticket_msg += ctx.translate("created in [channel]").format(ctx.channel.mention) await notify_ticket_authority(ctx, t, new_ticket_msg, send_embed=True) await t.guild.log(ctx.translate("[user] created ticket [ticket]").format(ctx.author, t.id))