async def whoarewe(self, ctx: commands.context): """ List members of system belonging to user who executes command :param ctx: Discord Context """ log.debug(f"Listing members for {ctx.author.display_name}...") c.execute( "SELECT * FROM members WHERE discord_account_id == ?", [ctx.author.id], ) member_list = c.fetchall() embed = discord.Embed(title=f"Members of System") embed.set_author(name=f"{ctx.author}", icon_url=ctx.author.avatar_url) if member_list is None: embed.add_field(name="No members where found", value="Ask a mod to add some!") for member in member_list: member_user = ctx.guild.get_member_named( f"p.{member['member_name']}") tags = [] for tag in json.loads(member["pk_proxy_tags"]): tags.append("`" + (tag.get("prefix") or "") + "text" + (tag.get("suffix") or "") + "`") embed.add_field( name=dict(member).get("display_name", member["member_name"]), value= f"""**User:** {member_user.mention}\n**PluralKit Member ID:** `{member['pk_member_id']}`\n**Tags:** {' or '.join(tags)}\n**Enabled:** `{'Yes' if member['member_enabled'] else 'No'}`""", inline=True, ) await ctx.send(embed=embed)
async def tokens(self, ctx: commands.context, *tokens: str): """ Add tokens to queue :param ctx: Discord Context :param tokens: List of tokens """ async def session(self, author: discord.Member): self.token_session.append(author) await asyncio.sleep(300) self.token_session.remove(author) if (ctx.channel.type is discord.ChannelType.private and ctx.message.author in self.token_session): await ctx.send("Adding tokens...") log.debug(tokens) for index, token in enumerate(tokens): logger = LogMessage(ctx, title=f"Adding token #{index+1}...") await logger.init() # Check token await logger.log(f"Checking token #{index+1}...") check_result, client_id = await check_token(token) if not check_result: logger.title = f"Token #{index+1} Invalid" logger.color = discord.Color.red() await logger.log("Bot token is invalid") else: await logger.log("Token valid") if get_token(token) is None: log.info("Adding new token to database") insert_token(token, False) logger.title = f"Bot token #{index+1} added" logger.color = discord.Color.green() c.execute("SELECT * FROM tokens WHERE used = 0") slots = c.fetchall() from polyphony.bot import bot await logger.send( f"[Invite to Server]({discord.utils.oauth_url(client_id, permissions=discord.Permissions(DEFAULT_INSTANCE_PERMS), guild=bot.get_guild(GUILD_ID))})\n\n**Client ID:** {client_id}\nThere are now {len(slots)} slot(s) available" ) else: logger.title = f"Token #{index+1} already in database" logger.color = discord.Color.orange() await logger.log("Bot token already in database") elif ctx.channel.type is not discord.ChannelType.private: await ctx.message.delete() if any(role.name in MODERATOR_ROLES for role in ctx.message.author.roles): await ctx.message.author.send( f"Token mode enabled for 5 minutes. Add tokens with `{self.bot.command_prefix}tokens [token] (more tokens...)` right here.\n\n*Don't paste a bot token in a server*" ) await session(self, ctx.message.author) elif any(role.name in MODERATOR_ROLES for role in ctx.message.author.roles): ctx.message.delete() await ctx.channel.send( f"To add tokens, execute `{self.bot.command_prefix}tokens` as a moderator on a server **WITHOUT A BOT TOKEN**. Then in DMs, use `{self.bot.command_prefix}tokens [token] (more tokens...)`\n\n*Seriously don't paste a bot token in a server*" )
async def system(self, ctx: commands.context, member: discord.Member): log.debug(f"Listing members for {member.display_name}...") c.execute( "SELECT * FROM members WHERE discord_account_id == ?", [member.id], ) member_list = c.fetchall() embed = discord.Embed(title=f"Members of System") embed.set_author(name=f"{member} ({member.id})", icon_url=member.avatar_url) await self.send_member_list(ctx, embed, member_list)
async def list(self, ctx: commands.context): """ list: Shows all active Polyphony members sorted by main account :param ctx: Discord Context """ if ctx.invoked_subcommand is not None: return log.debug("Listing active members...") c.execute("SELECT * FROM members WHERE member_enabled == 1") member_list = c.fetchall() embed = discord.Embed(title="Active Members") await send_member_list(ctx, embed, member_list)
async def whoarewe(self, ctx: commands.context): """ List members of system belonging to user who executes command :param ctx: Discord Context """ log.debug(f"Listing members for {ctx.author.display_name}...") c.execute( "SELECT * FROM members WHERE main_account_id == ?", [ctx.author.id], ) member_list = c.fetchall() embed = discord.Embed(title=f"Members of System") embed.set_author(name=f"{ctx.author}", icon_url=ctx.author.avatar_url) await send_member_list(ctx, embed, member_list, whoarewe=True)
async def edit( self, ctx: commands.context, message: Optional[discord.Message] = None, *, content: str, ): """ edit (message id) [message]: Edits the last message or message with ID :param ctx: Discord Context :param message: (optional) ID of message :param content: Message Content """ await ctx.message.delete() if message is not None: log.debug( f"Editing message {message.id} by {message.author} for {ctx.author}" ) c.execute( "SELECT * FROM members WHERE discord_account_id == ? AND member_account_id == ?", [ctx.author.id, message.author.id], ) if c.fetchone(): for instance in instances: if instance.user.id == message.author.id: message = await instance.get_channel( message.channel.id).fetch_message(message.id) await message.edit(content=content) break else: log.debug(f"Editing last Polyphony message for {ctx.author}") c.execute( "SELECT * FROM members WHERE discord_account_id == ?", [ctx.author.id], ) member_ids = [ member["member_account_id"] for member in c.fetchall() ] async for message in ctx.channel.history(): if message.author.id in member_ids: for instance in instances: if instance.user.id == message.author.id: message = await instance.get_channel( message.channel.id).fetch_message(message.id) await message.edit(content=content) break break
async def delete( self, ctx: commands.context, message: Optional[discord.Message] = None, ): """ del (id): Deletes the last message unless a message ID parameter is provided. Can be run multiple times. n max limited by config. :param ctx: Discord Context :param message: ID of message to delete """ await ctx.message.delete() if message is not None: log.debug( f"Deleting message {message.id} by {message.author} for {ctx.author}" ) c.execute( "SELECT * FROM members WHERE discord_account_id == ? AND member_account_id == ?", [ctx.author.id, message.author.id], ) if c.fetchone(): for instance in instances: if instance.user.id == message.author.id: message = await instance.get_channel( message.channel.id).fetch_message(message.id) await message.delete() break else: log.debug(f"Deleting last Polyphony message for {ctx.author}") c.execute( "SELECT * FROM members WHERE discord_account_id == ?", [ctx.author.id], ) member_ids = [ member["member_account_id"] for member in c.fetchall() ] async for message in ctx.channel.history(): if message.author.id in member_ids: for instance in instances: if instance.user.id == message.author.id: message = await instance.get_channel( message.channel.id).fetch_message(message.id) await message.delete() break break
async def slots(self, ctx: commands.context): """ Show number of slots available :param ctx: Discord Context """ await ctx.message.delete() c.execute("SELECT * FROM tokens WHERE used = 0") slots = c.fetchall() if 2 > len(slots) >= 1: embed = discord.Embed(title=f"There is 1 slot available.", color=discord.Color.green()) elif len(slots) > 1: embed = discord.Embed( title=f"There are {len(slots)} slots available", color=discord.Color.green(), ) else: embed = discord.Embed( title=f"Sorry, there are currently no slots available", description="Contact a moderator", ) await ctx.channel.send(embed=embed)
async def suspended(self, ctx: commands.context): log.debug("Listing suspended members...") c.execute("SELECT * FROM members WHERE member_enabled == 0") member_list = c.fetchall() embed = discord.Embed(title="Suspended Members") await self.send_member_list(ctx, embed, member_list)
async def all(self, ctx: commands.context): log.debug("Listing all members...") c.execute("SELECT * FROM members") member_list = c.fetchall() embed = discord.Embed(title="All Members") await self.send_member_list(ctx, embed, member_list)
async def register( self, ctx: commands.context, pluralkit_member_id: str, account: discord.Member, ): """ Creates a new Polyphony member instance :param ctx: Discord Context :param pluralkit_member_id: PluralKit system or member id :param account: Main Account to be extended from """ log.debug("Registering new member...") logger = LogMessage(ctx, title="Registering...") await logger.init() instance = None async with ctx.channel.typing(): await logger.log("Fetching member from PluralKit...") member = await pk_get_member(pluralkit_member_id) # Member exists if member is not None: system_names = [f"{member['name']} (`{member['id']}`)"] await logger.log( f"Fetched member -> {member['name']} (`{member['id']}`)") tokens = get_unused_tokens() # Fail: No Slots Available if len(tokens) == 0: logger.title = "Error Registering: No Slots Available" logger.color = discord.Color.red() await logger.log( f"No tokens in queue. Run `{self.bot.command_prefix}tokens` for information on how to add more." ) return # Confirm add confirmation = BotConfirmation(ctx, discord.Color.blue()) await confirmation.confirm( f"Create member for {account} with member {', '.join(system_names)}?" ) if confirmation.confirmed: await confirmation.message.delete() await logger.log("Adding to database...") else: await confirmation.message.delete() logger.title = "Extend Cancelled" logger.color = discord.Color.red() await logger.log("Registration cancelled by user") return # Get a token and update as used bot_token = tokens[0] update_token_as_used(bot_token["token"]) # Insert new user into users database if get_user(account.id) is None: await logger.log( f"{account.mention} is a new user! Registering them with Polyphony" ) insert_user(account.id) # Insert member unless already registered if get_member(pluralkit_member_id) is None: insert_member( bot_token["token"], member["id"], account.id, 0, member["name"], member["display_name"], member["avatar_url"], member["proxy_tags"][0], member["keep_proxy"], member_enabled=True, ) # Fail: Member Already Registered else: logger.title = "Member Already Registered with Polyphony" logger.color = discord.Color.light_grey() await logger.log( f"Member ID `{pluralkit_member_id}` was already registered with Polyphony" ) return await logger.log("Creating member instance...") instance = create_member_instance(get_member(member["id"])) # Fail: Invalid ID else: logger.title = "Error Registering: Member ID invalid" logger.color = discord.Color.red() await logger.log( f"Member ID `{pluralkit_member_id}` was not found") return # Success State logger.title = f"Registration of {member['name']} Successful" logger.color = discord.Color.green() c.execute("SELECT * FROM tokens WHERE used = 0") slots = c.fetchall() await logger.log(f"There are now {len(slots)} slots available") await logger.log(f"\nUser is {instance.user.mention}") log.info("New member instance extended and activated")
async def tokens(self, ctx: commands.context, *tokens: str): """ Add tokens to queue :param ctx: Discord Context :param tokens: List of tokens """ async def session(self, author: discord.Member): self.token_session.append(author) await asyncio.sleep(300) self.token_session.remove(author) if (ctx.channel.type is discord.ChannelType.private and ctx.message.author in self.token_session): await ctx.send("Adding tokens...") for index, token in enumerate(tokens): logger = LogMessage(ctx, title=f"Adding token #{index+1}...") await logger.init() # Check token await logger.log(f"Checking token #{index+1}...") all_tokens = conn.execute("SELECT * FROM tokens").fetchall() chk = False token_client = decode_token(token) for chk_token in all_tokens: if decode_token(str(chk_token["token"])) == token_client: chk = True check_result, client_id = await check_token(token) if chk: logger.title = f"Token #{index + 1} Client ID already in database" logger.color = discord.Color.red() await logger.log("Client ID already exists in database") elif not check_result: logger.title = f"Token #{index+1} Invalid" logger.color = discord.Color.red() await logger.log("Bot token is invalid") else: await logger.log("Token valid") if (conn.execute("SELECT * FROM tokens WHERE token = ?", [token]).fetchone() is None): conn.execute("INSERT INTO tokens VALUES(?, ?)", [token, False]) conn.commit() logger.title = f"Bot token #{index+1} added" logger.color = discord.Color.green() c.execute("SELECT * FROM tokens WHERE used = 0") slots = c.fetchall() from polyphony.bot import bot await logger.send( f"[Invite to Server]({discord.utils.oauth_url(client_id, permissions=discord.Permissions(DEFAULT_INSTANCE_PERMS), guild=bot.get_guild(GUILD_ID))})\n\n**Client ID:** {client_id}\nThere are now {len(slots)} slot(s) available" ) log.info( f"New token added by {ctx.author} (There are now {len(slots)} slots)" ) else: logger.title = f"Token #{index+1} already in database" logger.color = discord.Color.orange() await logger.log("Bot token already in database") elif ctx.channel.type is not discord.ChannelType.private: await ctx.message.delete() if any(role.name in MODERATOR_ROLES for role in ctx.message.author.roles) or ctx.bot.is_owner( ctx.author): try: await ctx.message.author.send( f"Token mode enabled for 5 minutes. Add tokens with `{self.bot.command_prefix}tokens [token] (more tokens...)` right here.\n\n*Don't paste a bot token in a server*" ) except discord.errors.Forbidden: await ctx.send("Enable server DMs to use token command", delete_after=10.0) await session(self, ctx.message.author) elif any(role.name in MODERATOR_ROLES for role in ctx.message.author.roles) or ctx.bot.is_owner( ctx.author): await ctx.channel.send( f"To add tokens, execute `{self.bot.command_prefix}tokens` as a moderator on a server **WITHOUT A BOT TOKEN**. Then in DMs, use `{self.bot.command_prefix}tokens [token] (more tokens...)`\n\n*Seriously don't paste a bot token in a server*", delete_after=10.0, )