async def reboot(self, ctx=None): msg = await components.send( ctx, f"再起動しますか?\n現在のVC: {len(self.bot.voice_clients)}", components=[ components.Button( "する", "reboot_yes", style=components.ButtonType.danger, ), components.Button( "しない", "reboot_no", style=components.ButtonType.secondary, ), ], ) com = await self.bot.wait_for("button_click", check=lambda c: c.message == msg) await self.bot.change_presence( status=discord.Status.dnd, activity=discord.Game(name="Rebooting..." + "⠀" * 20)) if com.custom_id == "reboot_yes": with open("./reboot", "w"): pass await com.send("再起動します...") else: await com.send("キャンセルされました。")
async def shutdown(self, ctx=None): msg = await components.send( ctx, "シャットダウンしますか?", components=[ components.Button( "する", "shutdown_yes", style=components.ButtonType.danger, ), components.Button( "しない", "shutdown_no", style=components.ButtonType.secondary, ), ], ) com = await self.bot.wait_for("button_click", check=lambda c: c.message == msg) if com.custom_id == "shutdown_yes": with open("./shutdown", "w"): pass await com.send("シャットダウンします...") else: await com.send("キャンセルされました。")
async def auth_web(self, ctx, role: discord.Role = 0): if self.bot.guild_settings[ ctx.guild.id]["auth_role"] == 0 and role == 0: e = discord.Embed( title="ロールが登録されていません", description="初回はロールを登録する必要があります", color=Error, ) await ctx.reply(embed=e) return elif role.position > ctx.author.top_role.position and not ctx.guild.owner_id == ctx.author.id: e = discord.Embed( title=get_txt(ctx.guild.id, "no_role_perm").format(role.name), color=Error, ) await ctx.reply(embed=e) return if role != 0: self.bot.guild_settings[ctx.guild.id]["auth_role"] = role.id role_mention = ctx.guild.get_role( self.bot.guild_settings[ctx.guild.id]["auth_role"]).mention e = discord.Embed( title="認証ボタン - Web認証", description=f"下のボタンを押して認証\n" f"ロール: {role_mention}", color=Widget, ) await components.send(ctx, embed=e, components=[components.Button("認証", "auth")]) try: await ctx.message.delete() except discord.Forbidden: pass
async def ticket( self, ctx, subject, description, cooldown: convert_timedelta = datetime.timedelta(hours=1)): if self.bot.guild_settings[ctx.guild.id]["ticket_category"] == 0: overwrites = { ctx.guild.default_role: discord.PermissionOverwrite(read_messages=False), ctx.guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True), } cat = await ctx.guild.create_category("チケット", overwrites=overwrites) self.bot.guild_settings[ctx.guild.id]["ticket_category"] = cat.id else: cat = self.bot.get_channel( self.bot.guild_settings[ctx.guild.id]["ticket_category"]) e = discord.Embed(title="チケット作成", description=subject, color=Widget) e.set_footer(text=f"{delta_to_text(cooldown, ctx)}に1回") m = await components.send( ctx, embed=e, components=[ components.Button( label="作成", style=components.ButtonType.secondary, custom_id="ticket_create", ), ], ) await self.bot.db.tickets.insert_one({ "message": m.id, "subject": subject, "description": description, "count": 0, "cooldown": cooldown.total_seconds(), })
class TicketCog(commands.Cog): def __init__(self, bot): global Texts global get_txt self.bot: commands.Bot = bot Texts = bot.texts get_txt = bot.get_txt @commands.Cog.listener("on_raw_reaction_add") async def on_raw_reaction_add(self, pl: discord.RawReactionActionEvent): if pl.user_id == self.bot.user.id: return channel = self.bot.get_channel(pl.channel_id) try: message = await channel.fetch_message(pl.message_id) except (discord.errors.NotFound, discord.errors.Forbidden): return guild = self.bot.get_guild(pl.guild_id) user = guild.get_member(pl.user_id) if message.embeds == []: return if message.author.id != self.bot.user.id: return m0 = message.embeds[0] if m0.footer.text == "下の南京錠ボタンを押して終了": if await self.bot.db.tickets.find_one({"message": message.id}) is not None: await message.remove_reaction(pl.emoji, user) if pl.emoji.name == "lock": await self.close_ticket(message, user, guild) if message.embeds[0].title == "チケット作成": await message.remove_reaction(pl.emoji, user) if pl.emoji.name == "add": success, status, data = await self.create_ticket( message, user, guild) if not success: if status == "in_cooldown": await message.channel.send( user.mention, embed=SEmbed( color=Error, description= f"作成の上限を超えています。<t:{int(data)}:R>に再度お試しください。", footer="このメッセージは5秒後に削除されます。", ), delete_after=5, ) @commands.Cog.listener("on_button_click") async def on_button_click(self, com: components.ButtonResponse): if com.custom_id == "ticket_lock": await com.defer_update() await self.close_ticket(com.message, com.guild) elif com.custom_id == "ticket_create": success, status, data = await self.create_ticket( com.message, com.fired_by, com.guild) if not success: if status == "in_cooldown": await com.send( com.fired_by.mention, embed=SEmbed( color=Error, description= f"作成の上限を超えています。<t:{int(data)}:R>に再度お試しください。"), hidden=True, ) @commands.command(name="ticket") @commands.has_guild_permissions(manage_guild=True, manage_channels=True) async def ticket( self, ctx, subject, description, cooldown: convert_timedelta = datetime.timedelta(hours=1)): if self.bot.guild_settings[ctx.guild.id]["ticket_category"] == 0: overwrites = { ctx.guild.default_role: discord.PermissionOverwrite(read_messages=False), ctx.guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True), } cat = await ctx.guild.create_category("チケット", overwrites=overwrites) self.bot.guild_settings[ctx.guild.id]["ticket_category"] = cat.id else: cat = self.bot.get_channel( self.bot.guild_settings[ctx.guild.id]["ticket_category"]) e = discord.Embed(title="チケット作成", description=subject, color=Widget) e.set_footer(text=f"{delta_to_text(cooldown, ctx)}に1回") m = await components.send( ctx, embed=e, components=[ components.Button( label="作成", style=components.ButtonType.secondary, custom_id="ticket_create", ), ], ) await self.bot.db.tickets.insert_one({ "message": m.id, "subject": subject, "description": description, "count": 0, "cooldown": cooldown.total_seconds(), }) async def create_ticket(self, message: discord.Message, user: discord.User, guild: discord.Guild): ticket_data = await self.bot.db.tickets.find_one( {"message": message.id}) if ticket_time := self.bot.consts["ticket_time"].get( f"{guild.id}-{user.id}"): if time.time() - ticket_time < ticket_data["cooldown"]: return ( False, "in_cooldown", self.bot.consts["ticket_time"][f"{guild.id}-{user.id}"] + ticket_data["cooldown"], ) self.bot.consts["ticket_time"][f"{guild.id}-{user.id}"] = time.time() cat = self.bot.get_channel( self.bot.guild_settings[guild.id]["ticket_category"]) if cat is None: ow = { guild.default_role: discord.PermissionOverwrite(read_messages=False), guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True), } cat = await guild.create_category_channel(name="チケット", overwrites=ow) self.bot.guild_settings[guild.id]["ticket_category"] = cat.id ow = cat.overwrites ow[user] = discord.PermissionOverwrite(read_messages=True, send_messages=True) await self.bot.db.tickets.update_one( {"message": message.id}, {"$inc": { "count": 1 }}, ) tc = await guild.create_text_channel( category=cat, name=f"チケット#{str(ticket_data['count']+1).zfill(4)}-アクティブ", overwrites=ow, ) e = discord.Embed(title=ticket_data["subject"], description=ticket_data["description"], color=Widget) e.set_footer(text="下のボタンを押して終了") message = await components.send( tc, user.mention, embed=e, components=[ components.Button("終了", "ticket_lock", components.ButtonType.danger) ], ) return True, message, tc
async def tr_list(self, ctx): g = ctx.guild.id if g not in self.bot.guild_settings: await self.reset(ctx) gs = self.bot.guild_settings[g] if gs["timed_role"] == {}: e = discord.Embed( title=get_txt(ctx.guild.id, "tr_list_no"), description=get_txt(ctx.guild.id, "tr_list_desc"), color=Error, ) return await ctx.reply(embed=e) else: def make_new(): table = Texttable(max_width=80) table.set_deco(Texttable.HEADER) table.set_cols_width( [ max([chrsize_len(str(c)) for c in gs["timed_role"].keys()]), max([chrsize_len(str(to_lts(c))) for c in gs["timed_role"].values()]), ] ) table.set_cols_dtype(["t", "t"]) table.set_cols_align(["l", "l"]) table.add_row(get_txt(ctx.guild.id, "tr_list_row")) return table table = make_new() res = [] for k, v in gs["timed_role"].items(): b = table.draw() if ctx.guild.get_role(k): rn = ctx.guild.get_role(k).name else: continue table.add_row([f"@{remove_emoji(rn)}", to_lts(v)]) if len(table.draw()) > 2000: res.append(b) table = make_new() table.add_row( [ k, v[0].replace("\n", get_txt(ctx.guild.id, "tr_list_br")), v[1].replace("\n", get_txt(ctx.guild.id, "tr_list_br")), ] ) res.append(table.draw()) e = discord.Embed( title=get_txt(ctx.guild.id, "tr_list") + f" - {1}/{len(res)}", description=f"```asciidoc\n{res[0]}```", color=Info, ) buttons = [ components.Button("前のページ", "left", style=2), components.Button("次のページ", "right", style=2), components.Button("終了", "exit", style=4), ] msg = await components.reply(ctx, embed=e, components=buttons) page = 0 while True: try: com = await self.bot.wait_for( "button_click", check=lambda com: com.message == msg and com.member == ctx.author, timeout=60, ) await com.defer_update() if com.custom_id == "left": if page > 0: page -= 1 buttons[0].enabled = page != 0 elif com.custom_id == "right": if page < (len(res) - 1): page += 1 buttons[1].enabled = page != (len(res) - 1) elif com.custom_id == "exit": break e = discord.Embed( title=get_txt(ctx.guild.id, "tr_list") + f" - {page+1}/{len(res)}", description=f"```asciidoc\n{res[page]}```", color=Info, ) await msg.edit(embed=e) except asyncio.TimeoutError: break for c in buttons: c.enabled = False await components.edit(msg, components=buttons)