async def play(self, ctx: Context, *, query): player: Player = ctx.voice_client if not player or not player.is_connected(): player = await self.get_guild_player(ctx) async with ctx.typing(): tracks, query_type = await self.get_tracks(ctx, query) if query_type is QueryType.CANCELLED: return await ctx.reply('Cancelled', mention_author=False) if not tracks: msg = 'Sorry no tracks found with that query.' if query_type is QueryType.SOUNDCLOUD: msg += '\nNote: SoundCloud can sometimes be unreliable and just not work. Consider using Youtube or Spotify' elif query_type is QueryType.YOUTUBETRACK: msg += '\nNote: If this is happening consistently, blame YouTube and try again later.' return await ctx.reply(msg) if isinstance(tracks, wavelink.YouTubePlaylist): for track in tracks.tracks: await player.add_track(track) await ctx.reply( f'Added {len(tracks.tracks)} songs from `{tracks.name}` to the queue' ) elif isinstance(tracks, list): for track in tracks: await player.add_track(track) await ctx.reply(f'Added {len(tracks)} songs to the queue') else: await player.add_track(tracks) if player.is_empty: await ctx.reply(f'Playing `{tracks.title}`') else: await ctx.reply(f'Added `{tracks.title}` to the queue') await player.invoke_controller(force_delete=True)
async def danbooru(self, ctx: Context, *, params: str) -> None: """Danbooru command. Access danbooru commands. This command uses a flag style syntax. The following options are valid. `*` denotes it is a mandatory argument. `+t | ++tags`: The tags to search Gelbooru for. `*` (uses logical AND per tag) `+l | ++limit`: The maximum amount of posts to show. Cannot be higher than 30. Examples: ``` !gelbooru ++tags lemon - search for the 'lemon' tag. - NOTE: if your tag has a space in it, replace it with '_' !danbooru ++tags melon -rating:explicit - search for the 'melon' tag, removing posts marked as 'explicit` !danbooru ++tags apple orange rating:safe - Search for the 'apple' AND 'orange' tags, with only 'safe' results. ``` """ aiohttp_params = {} parser = argparse.ArgumentParser(add_help=False, allow_abbrev=False, prefix_chars="+") parser.add_argument("+t", "++tags", nargs="+", required=True) parser.add_argument("+l", "++limit", type=int, default=40) try: real_args = parser.parse_args(shlex.split(params)) except SystemExit as f**k: raise commands.BadArgument( "Your flags could not be parsed.") from f**k except Exception as err: await ctx.send(f"Parsing your args failed: {err}.") return current_config = await self.get_booru_config( getattr(ctx.guild, "id", -1)) if real_args.limit: limit = real_args.limit if not 1 < real_args.limit <= 30: limit = 30 aiohttp_params.update({"limit": limit}) lowered_tags = [tag.lower() for tag in real_args.tags] tags = set(lowered_tags) common_elems = tags & current_config.blacklist if common_elems: raise BlacklistedBooru(common_elems) aiohttp_params.update({"tags": " ".join(lowered_tags)}) async with ctx.typing(): async with self.bot.session.get( self.danbooru_config.endpoint, params=aiohttp_params, auth=self.danbooru_config.auth, ) as resp: data = await resp.text() if not data: ctx.command.reset_cooldown(ctx) raise commands.BadArgument( "Got an empty response... bad search?") json_data = json.loads(data) if not json_data: ctx.command.reset_cooldown(ctx) raise commands.BadArgument( "The specified query returned no results.") embeds = self._gen_danbooru_embeds(json_data, current_config) if not embeds: fmt = "Your search had results but all of them contained blacklisted tags" if "loli" in lowered_tags: fmt += "\nPlease note that Danbooru does not support 'loli'." raise commands.BadArgument(fmt) pages = RoboPages(source=SimpleListSource(embeds[:30]), ctx=ctx) await pages.start()
async def serverinfo(self, ctx: Context): """Shows the server's info.""" guild: discord.Guild = ctx.guild if not guild.chunked: async with ctx.typing(): await guild.chunk(cache=True) description = f'**ID:** {guild.id}' if guild.id != DSCN_GUILD: description += f' | **Owner:** {guild.owner}' embed = discord.Embed(title=str(guild), description=description, colour=ctx.bot.colour, timestamp=guild.created_at) embed.set_footer(text='Created') if guild.icon: embed.set_thumbnail(url=guild.icon.url) key_to_emoji = { "text": "<:text:824903975626997771>", "voice": "<:voice:824903975098777601>" } text = len(guild.text_channels) voice = len(guild.voice_channels) embed.add_field(name='Members', value=guild.member_count) embed.add_field(name='Voice Region', value=str(guild.region).title()) embed.add_field( name='Channels', value= f'{key_to_emoji["text"]} {text} {key_to_emoji["voice"]} {voice}') embed.add_field(name='Roles', value=f'{len(guild.roles)} roles') s = 0 a = 0 for e in guild.emojis: if e.animated: a += 1 else: s += 1 embed.add_field( name = f'Emojis ({len(guild.emojis)})', value = f'Static: {s}\n'\ f'Animated: {a}' ) embed.add_field( name='Boosts', value= f'{guild.premium_subscription_count} boosts (Level {guild.premium_tier})' ) if guild.features: embed.add_field(name='Features', value=', '.join(f"{f}".replace('_', ' ').title() for f in guild.features), inline=False) if guild.banner: embed.set_image(url=guild.banner.url) await ctx.send(embed=embed)
async def gelbooru(self, ctx: Context, *, params: str): """This command uses a flag style syntax. The following options are valid. `*` denotes it is a mandatory argument. `+t | ++tags`: The tags to search Gelbooru for. `*` (uses logical AND per tag) `+l | ++limit`: The maximum amount of posts to show. Cannot be higher than 30. `+p | ++pid`: Page ID to search. Handy when posts begin to repeat. `+c | ++cid`: Change ID of the post to search for(?) Examples: ``` !gelbooru ++tags lemon - search for the 'lemon' tag. - NOTE: if your tag has a space in it, replace it with '_' !gelbooru ++tags melon -rating:explicit - search for the 'melon' tag, removing posts marked as 'explicit` !gelbooru ++tags apple orange rating:safe ++pid 2 - Search for the 'apple' AND 'orange' tags, with only 'safe' results, but on Page 2. - NOTE: if not enough searches are returned, page 2 will cause an empty response. ``` """ aiohttp_params = {} aiohttp_params.update({"json": 1}) parser = argparse.ArgumentParser(add_help=False, allow_abbrev=False, prefix_chars="+") parser.add_argument("+l", "++limit", type=int, default=40) parser.add_argument("+p", "++pid", type=int) parser.add_argument("+t", "++tags", nargs="+", required=True) parser.add_argument("+c", "++cid", type=int) try: real_args = parser.parse_args(shlex.split(params)) except SystemExit as f**k: raise commands.BadArgument( "Your flags could not be parsed.") from f**k except Exception as err: await ctx.send(f"Parsing your args failed: {err}") return current_config = await self.get_booru_config( getattr(ctx.guild, "id", -1)) if real_args.limit: aiohttp_params.update({"limit": int(real_args.limit)}) if real_args.pid: aiohttp_params.update({"pid": real_args.pid}) if real_args.cid: aiohttp_params.update({"cid", real_args.cid}) lowered_tags = [tag.lower() for tag in real_args.tags] tags_set = set(lowered_tags) common_elems = tags_set & current_config.blacklist if common_elems: raise BlacklistedBooru(common_elems) aiohttp_params.update({"tags": " ".join(lowered_tags)}) async with ctx.typing(): async with self.bot.session.get( self.gelbooru_config.endpoint, params=aiohttp_params, auth=self.gelbooru_config.auth, ) as resp: data = await resp.text() if not data: ctx.command.reset_cooldown(ctx) raise commands.BadArgument( "Got an empty response... bad search?") json_data = json.loads(data) if not json_data: ctx.command.reset_cooldown(ctx) raise commands.BadArgument( "The specified query returned no results.") embeds = self._gen_gelbooru_embeds(json_data, current_config) if not embeds: raise commands.BadArgument( "Your search had results but all of them contain blacklisted tags." ) pages = RoboPages( source=LewdPageSource(embeds[:30]), delete_message_after=False, clear_reactions_after=True, ) await pages.start(ctx)