async def response(self): self.set_selection() if self.selection != self.last_selection: await self._serve() try: reaction, user = await self.menu.bot.wait_for("reaction_add", timeout=self.timeout, check=self.check) except TimeoutError: await self.menu.timeout( chron.long_delta(timedelta(seconds=self.timeout))) else: r = self._resolve_selection(reaction.emoji) if r == "exit": if self.auto_exit: await self.menu.stop() return elif r == "stepback": self.page = 0 elif r == "pageback": self.page -= 1 elif r == "pagenext": self.page += 1 elif r == "stepnext": self.page = self.max_page await self.menu.switch(reaction) return await self.response()
async def response(self): await self._serve() try: reaction, user = await self.menu.bot.wait_for("reaction_add", timeout=self.timeout, check=self.check) except TimeoutError: await self.menu.timeout( chron.long_delta(timedelta(seconds=self.timeout))) else: r = self._resolve_selection(reaction.emoji) if r == "exit" and self.auto_exit: await self.menu.stop() else: return r
async def yt_info_command(self, ctx: commands.Context) -> None: url = f"https://www.googleapis.com/youtube/v3/channels?part=brandingSettings%2Csnippet%2Cstatistics&id={Config.YOUTUBE_CHANNEL_ID}&key={Config.YOUTUBE_API_KEY}" async with ctx.typing(): async with self.bot.session.get(url) as response: if not 200 <= response.status <= 299: return await ctx.send( f"The YouTube API returned {response.status} {response.reason}." ) data = (await response.json())["items"][0] published_at = chron.from_iso(data["snippet"]["publishedAt"][:-1]) await ctx.send(embed=discord.Embed.from_dict({ "title": f"Channel information for {data['brandingSettings']['channel']['title']}", "description": data["brandingSettings"]["channel"]["description"], "color": DEFAULT_EMBED_COLOUR, "thumbnail": { "url": data["snippet"]["thumbnails"]["high"]["url"] }, "image": { "url": data["brandingSettings"]["image"] ["bannerTvImageUrl"] }, "author": { "name": "Information" }, "footer": { "text": f"Requested by {ctx.author.display_name}", "icon_url": f"{ctx.author.avatar_url}", }, "fields": [ { "name": "Trailer", "value": f"Click [here](https://www.youtube.com/watch?v={data['brandingSettings']['channel']['unsubscribedTrailer']}) to watch.", "inline": False, }, { "name": "Country", "value": data["brandingSettings"]["channel"] ["country"], "inline": False, }, { "name": "Published on", "value": f"{chron.long_date_and_time(published_at)} UTC", "inline": False, }, { "name": "Existed for", "value": chron.long_delta(dt.datetime.utcnow() - published_at), "inline": False, }, ], }))
async def on_command_error(self, ctx, exc): if isinstance(exc, commands.CommandNotFound): pass elif isinstance(exc, commands.MissingRequiredArgument): await ctx.send(f"No `{exc.param.name}` argument was passed, despite being required.") elif isinstance(exc, commands.BadArgument): await ctx.send(f"One or more arguments are invalid.") elif isinstance(exc, commands.TooManyArguments): await ctx.send(f"Too many arguments have been passed.",) elif isinstance(exc, commands.MissingPermissions): mp = string.list_of([str(perm.replace("_", " ")).title() for perm in exc.missing_perms], sep="or") await ctx.send(f"You do not have the {mp} permission(s), which are required to use this command.") elif isinstance(exc, commands.BotMissingPermissions): try: mp = string.list_of([str(perm.replace("_", " ")).title() for perm in exc.missing_perms], sep="or") await ctx.send( f"Carberretta does not have the {mp} permission(s), which are required to use this command." ) except discord.Forbidden: # If Carberretta does not have the Send Messages permission # (might redirect this to log channel once it's set up). pass elif isinstance(exc, commands.NotOwner): await ctx.send(f"That command can only be used by Carberretta's owner.") elif isinstance(exc, commands.CommandOnCooldown): # Hooray for discord.py str() logic. cooldown_texts = { "BucketType.user": "******", "BucketType.guild": "The `{}` command can not be used in this server for another {}.", "BucketType.channel": "The `{}` command can not be used in this channel for another {}.", "BucketType.member": "You can not use the `{}` command in this server for another {}.", "BucketType.category": "The `{}` command can not be used in this category for another {}.", } await ctx.message.delete() await ctx.send( cooldown_texts[str(exc.cooldown.type)].format( ctx.command.name, chron.long_delta(dt.timedelta(seconds=exc.retry_after)) ), delete_after=10, ) elif isinstance(exc, commands.InvalidEndOfQuotedStringError): await ctx.send( f"Carberretta expected a space after the closing quote, but found a(n) `{exc.char}` instead." ) elif isinstance(exc, commands.ExpectedClosingQuoteError): await ctx.send(f"Carberretta expected a closing quote character, but did not find one.") # Base errors. elif isinstance(exc, commands.UserInputError): await ctx.send(f"There was an unhandled user input problem (probably argument passing error).") elif isinstance(exc, commands.CheckFailure): await ctx.send(f"There was an unhandled command check error (probably missing privileges).") # Non-command errors. elif (original := getattr(exc, "original", None)) is not None: if isinstance(original, discord.HTTPException): await ctx.send(f"A HTTP exception occurred ({original.status})\n```{original.text}```") else: raise original