async def subCustom(cmd: Union[commands.Context, discord.Interaction], bot: commands.Bot, search: str): """ Subscribes to a VTuber with the channel name provided to the user. Arguments --- ctx: Context from the executed command. bot: The Discord bot. search: The name of the channel to search for. """ db = await botdb.getDB(bot.pool) if isinstance(cmd, commands.Context): message = YagooMessage(bot, cmd.author) message.msg = await cmd.send("Loading channels list...") else: message = YagooMessage(bot, cmd.user) result = await subUtils.channelSearch(cmd, bot, message, search) if result.success: server = await dbTools.serverGrab( bot, str(cmd.guild.id), str(cmd.channel.id), tuple(["subDefault"] + allSubTypes(False)), db) subResult = await subUtils.subOne( cmd, message, server, str(cmd.channel.id), [YouTubeChannel(result.channelID, result.channelName)], db) if subResult.status: await subPrompts.displaySubbed(message, subResult) await removeMessage(cmd=cmd) return await removeMessage(message, cmd)
async def sublistDisplay(cmd: Union[commands.Context, discord.Interaction], bot: commands.Bot): """ Show the user about the current subscriptions for the channel. Arguments --- cmd: Context or interaction from the invoked command. bot: The Discord bot. """ db = await botdb.getDB(bot.pool) server = await dbTools.serverGrab(bot, str(cmd.guild.id), str(cmd.channel.id), tuple(allSubTypes(False)), db) if isinstance(cmd, commands.Context): message = YagooMessage(bot, cmd.author) message.msg = await cmd.send("Loading channel subscriptions...") else: message = YagooMessage(bot, cmd.user) subList = await unsubUtils.parseToSubTypes(server, db) pages = await subPrompts.sublistDisplay.parseToPages(subList) if len(pages) == 0: raise NoSubscriptions(str(cmd.channel.id)) await subPrompts.sublistDisplay.prompt(cmd, message, pages, subList) await removeMessage(cmd=cmd)
async def prompt(cmd: Union[commands.Context, discord.Interaction], message: YagooMessage, buttonText: str = "Subscribe", buttonID: str = "subscribe", subTypes: dict = None, allowNone: bool = False): """ Prompts the user for subscription types. The title and description must be set beforehand. Arguments --- ctx: Context from the executed command. msg: The message that will be used as the prompt. buttonText: The text for the subscribe button. buttonID: The ID for the subscribe button. subTypes: Existing subscription type status as a `dict`. allowNone: To allow the user to select none of the subscription types. Returns --- `SubscriptionData` if the user confirmed the choice. `YagooViewResponse` if cancelled or timed out. """ buttonStates = subTypes if not buttonStates: buttonStates = {} subTypes = allSubTypes(False) for subType in subTypes: buttonStates[subType] = False while True: message.resetComponents() await subPrompts.subTypes.editMsg(subTypes, message, buttonStates, buttonText, buttonID, allowNone) if isinstance(cmd, commands.Context): result = await message.legacyPost(cmd) else: result = await message.post(cmd, True, True) if result.responseType: if result.buttonID not in ["cancel", "all", buttonID]: buttonStates[result.buttonID] = not buttonStates[ result.buttonID] elif result.buttonID == "all": allBool = True for button in buttonStates: if allBool: allBool = buttonStates[button] for button in buttonStates: buttonStates[button] = not allBool else: if result.buttonID == buttonID: return SubscriptionData(buttonStates) return result else: return result
async def defaultSubtype(cmd: Union[commands.Context, discord.Interaction], bot: commands.Bot): """ Prompts the user to either set or change the default subscription types for the channel. Arguments --- cmd: Context or interaction from the invoked command bot: The Discord bot. """ db = await botdb.getDB(bot.pool) server = await dbTools.serverGrab(bot, str(cmd.guild.id), str(cmd.channel.id), ("subDefault", ), db) if isinstance(cmd, commands.Context): message = YagooMessage(bot, cmd.author) message.msg = await cmd.send("Loading channel subscription defaults..." ) else: message = YagooMessage(bot, cmd.user) subTypes = {} for subType in allSubTypes(False): subTypes[subType] = False if not (server["subDefault"] is None or server["subDefault"] == ""): for subType in await botdb.listConvert(server["subDefault"]): subTypes[subType] = True message.embed.title = "Default Channel Subscription Types" message.embed.description = "Pick the subscription types for this channel to subscribe to by default." result = await subPrompts.subTypes.prompt(cmd, message, "Confirm", "confirm", subTypes, True) if isinstance(result, SubscriptionData): subDefault: List[str] = [] for subType in result.subList: if result.subList[subType]: subDefault.append(subType) await botdb.addData( (str(cmd.channel.id), await botdb.listConvert(subDefault)), ("channel", "subDefault"), "servers", db) message.resetEmbed() message.embed.title = "Successfully Set Channel Defaults!" if subDefault == []: message.embed.description = "Subscription commands will now ask for subscription types first." message.embed.color = discord.Color.from_rgb(0, 0, 0) else: defaultSubs = "" for sub in subDefault: defaultSubs += f"{sub.capitalize()}, " message.embed.description = "Subscription commands will now follow the channel's defaults." message.embed.color = discord.Color.green() message.embed.add_field(name="Default Subscriptions", value=defaultSubs.strip(", "), inline=False) await message.msg.edit(content=" ", embed=message.embed, view=None) return await removeMessage(cmd=cmd) await removeMessage(message, cmd)
async def parseToSubTypes(server: dict, db: mysql.connector.MySQLConnection): """ Parses the current channel's subscriptions to subscription indicators. Arguments --- server: The Discord channel's data as a `dict` containing all the subscription types for it. db: A MySQL connection to the database to reduce unnecessary connections. Returns --- A `dict` with: - subbed: A `list` containing the IDs of the subscribed channels. - channels: A `dict` with channels containing `name` and `subTypes` (current subscription types as sub-keys). """ channels = await botdb.getAllData("channels", ("id", "name", "twitter"), db=db) subTypes = allSubTypes(False) subbed = [] channelSubbed = {} channelSubs = ChannelSubscriptionData() for subType in subTypes: temp = await botdb.listConvert(server[subType]) if temp is None: temp = [] if temp != [] and not channelSubs.exists: channelSubs.exists = True channelSubbed[subType] = temp if channelSubs.exists: for channel in channels: if channel["id"] not in subbed: for subType in subTypes: if channel["id"] in channelSubbed[subType] or channel[ "twitter"] in channelSubbed[subType]: if subType != "twitter": channelSubs.addChannel(subType, channel["id"], channel["name"]) else: channelSubs.addChannel(subType, channel["id"], channel["name"], channel["twitter"]) return channelSubs
async def prompt(cmd: Union[commands.Context, discord.Interaction], message: YagooMessage, channelIDs: Optional[List[str]] = None, subData: Optional[ChannelSubscriptionData] = None, allChannels: bool = False): """ Prompts the user for which subscription type to unsubscribe from. Arguments --- ctx: Context from the executed command. msg: The message that will be used as the prompt. channelIDs: IDs of the VTuber channels to be unsubscribed from. subData: The subscription data of the current channel. allChannels: If all channels are to be unsubscribed. Returns --- A `dict` with: - status: `True` if an option was chosen by the user. - unsubbed: A `list` with subscription types to unsubscribe from. """ if not allChannels: channels = await unsubPrompts.removePrompt.parseToChannels( channelIDs, subData) else: channels = subData.allChannels subTypes = {} if allChannels: name = "All Channels" elif len(channelIDs) > 1: name = "Multiple Channels" else: name = channels[0].channelName message.resetEmbed() message.embed.title = f"Unsubscribing from {name}" message.embed.description = "Choose the subscription types to unsubscribe from." if not allChannels: for channel in channels: for subType in subData.findTypes(channel.channelID): if subType not in subTypes: subTypes[subType] = True else: for subType in allSubTypes(False): subTypes[subType] = True while True: await unsubPrompts.removePrompt.editMsg(message, subTypes) if isinstance(cmd, commands.Context): result = await message.legacyPost(cmd) else: result = await message.post(cmd, True, True) if result.responseType: if result.buttonID == "cancel": return UnsubscriptionResponse(False) if result.buttonID == "submit": unsubbed = [] for subType in subTypes: if not subTypes[subType]: unsubbed.append(subType) return UnsubscriptionResponse(True, unsubbed, channels) if result.buttonID == "select": allSubs = True for subType in subTypes: if subTypes[subType]: allSubs = False for subType in subTypes: subTypes[subType] = allSubs else: subTypes[ result.buttonID] = not subTypes[result.buttonID] else: return UnsubscriptionResponse(False)
async def unsubChannel(cmd: Union[commands.Context, discord.Interaction], bot: commands.Bot, channel: str = None): """ Unsubscribes from a VTuber. (bypasses a prompt if a channel is given) Arguments --- ctx: Context or interaction from the invoked command. bot: The Discord bot. channel: The search term for the VTuber. """ db = await botdb.getDB(bot.pool) if isinstance(cmd, commands.Context): message = YagooMessage(bot, cmd.author) message.msg = await cmd.send("Loading channel subscriptions...") else: message = YagooMessage(bot, cmd.user) server = await dbTools.serverGrab(bot, str(cmd.guild.id), str(cmd.channel.id), tuple(allSubTypes(False)), db) subData = await unsubUtils.parseToSubTypes(server, db) if not subData.exists: raise NoSubscriptions(cmd.channel.id) if not channel: message.resetMessage() message.embed.title = "Unsubscribing from VTuber Channels" message.embed.description = "Choose the VTuber(s) to be unsubscribed from." message.embed.add_field( name="Searching for a VTuber?", value="Enter the VTuber's name after the `unsubscribe` command.") message.addSelect(await unsubUtils.parseToPages(subData), "Choose the VTuber(s) here", max_values=25) message.addButton(2, "search", label="Search for a VTuber", disabled=True) message.addButton(2, "all", "Unsubscribe from all VTubers") message.addButton(3, "cancel", "Cancel", style=discord.ButtonStyle.red) if isinstance(cmd, commands.Context): result = await message.legacyPost(cmd) else: result = await message.post(cmd, True, True) else: wikiName = await subUtils.channelSearch(cmd, bot, message, channel, "unsubscribe") if wikiName.success: result = YagooViewResponse() result.responseType = "select" result.selectValues = [wikiName.channelID] else: result = YagooViewResponse() if result.responseType: if result.buttonID == "all": unsubResult = await unsubPrompts.removePrompt.prompt( cmd, message, None, subData, True) if not unsubResult.status: return await removeMessage(message, cmd) await unsubUtils.unsubAll(str(cmd.channel.id), unsubResult, db) elif result.buttonID == "cancel": return await removeMessage(message, cmd) else: unsubResult = await unsubPrompts.removePrompt.prompt( cmd, message, result.selectValues, subData) if not unsubResult.status: return await removeMessage(message, cmd) await unsubUtils.unsubOne(server, str(cmd.channel.id), unsubResult, db) await unsubPrompts.displayResult(message, unsubResult) return await removeMessage(cmd=cmd) await removeMessage(message, cmd)