async def last_online_player(self, ctx, *, player: PlayerConverter): """Get an approximation for the last time a player was online. **Parameters** :key: Player name OR tag **Format** :information_source: `+lastonline player #PLAYER_TAG` :information_source: `+lastonline player Player Name` **Example** :white_check_mark: `+lastonline player #P0LYJC8C` :white_check_mark: `+lastonline player mathsman` """ try: async with self.batch_lock: last_updated = datetime.utcnow() - self.last_updated[player.tag] except KeyError: query = """SELECT player_tag, last_updated - now() AS "since" FROM players WHERE player_tag = $1 AND season_id = $2 ORDER BY since DESC """ fetch = await ctx.db.fetchrow(query, player.tag, await self.bot.seasonconfig.get_season_id()) if not fetch: return await ctx.send( f"{player} ({player.tag}) was not found in the database. Try `+add player {player.tag}`." ) last_updated = fetch['since'] time = readable_time(last_updated.total_seconds()) await ctx.send(f"A good guess for the last time {player} ({player.tag}) was online was: `{time}`.")
async def info_season(self, ctx): """Get Season IDs and start/finish times and info.""" query = "SELECT id, start, finish FROM seasons ORDER BY id DESC" fetch = await ctx.db.fetch(query) table = TabularData() table.set_columns(['ID', 'Start', 'Finish']) for n in fetch: table.add_row([n[0], n[1].strftime('%d-%b-%Y'), n[2].strftime('%d-%b-%Y')]) e = discord.Embed(colour=self.bot.colour, description=f'```\n{table.render()}\n```', title='Season Info', timestamp=datetime.utcnow() ) e.add_field(name='Current Season', value=readable_time((fetch[0][2] - datetime.utcnow()).total_seconds())[:-4] + ' left', inline=False) await ctx.send(embed=e)
async def error_handler(ctx, error): error = getattr(error, 'original', error) if isinstance(error, (checks.NoConfigFailure, paginator.CannotPaginate, commands.CheckFailure)): return await ctx.send(str(error)) if isinstance(error, (commands.BadArgument, commands.BadUnionArgument)): return await ctx.send(str(error)) if isinstance(error, commands.MissingRequiredArgument): return await ctx.send(f'Oops! That didn\'t look right... ' f'please see how to use the command with `+help {ctx.command.qualified_name}`') if isinstance(error, commands.CommandOnCooldown): if await ctx.bot.is_owner(ctx.author): return await ctx.reinvoke() time = formatters.readable_time(error.retry_after) return await ctx.send(f'You\'re on cooldown. Please try again in: {time}') ctx.command.reset_cooldown(ctx) if isinstance(error, (discord.Forbidden, discord.NotFound, paginator.CannotPaginate)): return e = discord.Embed(title='Command Error', colour=0xcc3366) e.add_field(name='Name', value=ctx.command.qualified_name) e.add_field(name='Author', value=f'{ctx.author} (ID: {ctx.author.id})') fmt = f'Channel: {ctx.channel} (ID: {ctx.channel.id})' if ctx.guild: fmt = f'{fmt}\nGuild: {ctx.guild} (ID: {ctx.guild.id})' e.add_field(name='Location', value=fmt, inline=False) e.add_field(name='Content', value=textwrap.shorten(ctx.message.content, width=512)) exc = ''.join( traceback.format_exception(type(error), error, error.__traceback__, chain=False)) e.description = f'```py\n{exc}\n```' e.timestamp = datetime.datetime.utcnow() await ctx.bot.error_webhook.send(embed=e) try: await ctx.send('Uh oh! Something broke. This error has been reported; ' 'the owner is working on it. Please join the support server: ' 'https://discord.gg/ePt8y4V to stay updated!') except discord.Forbidden: pass
def create_row(self, name, player_data): since = player_data[1]['since'].total_seconds() self.table.add_row([player_data[0], name, readable_time(since)[:-3]])
def create_row(self, i, data): self.table.add_row([i, self.emojis.get(data['clan_tag'], ""), readable_time(data['since'].total_seconds())[:-3], data['player_name']])
async def error_handler(ctx, error): error = getattr(error, 'original', error) if isinstance( error, (commands.MissingPermissions, RuntimeError, discord.Forbidden)): log.info( 'command raised no bot permissions: %s, author: %s, error: %s', ctx.invoked_with, ctx.author.id, error) return await ctx.send( str(error) if error else "Please double-check the bot's permissions and try again.") if isinstance(error, (checks.NoConfigFailure, paginator.CannotPaginate, commands.CheckFailure)): log.info('command raised checks failure: %s, author: %s', ctx.invoked_with, ctx.author.id) return await ctx.send(str(error)) if isinstance(error, (commands.BadArgument, commands.BadUnionArgument)): if str(error): return await ctx.send(str(error)) else: return if isinstance(error, commands.MissingRequiredArgument): log.info('command missing required argument: %s, author: %s', ctx.invoked_with, ctx.author.id) return await ctx.send( f'Oops! That didn\'t look right... ' f'please see how to use the command with `+help {ctx.command.qualified_name}`' ) if isinstance(error, commands.CommandOnCooldown): if await ctx.bot.is_owner(ctx.author): return await ctx.reinvoke() time = formatters.readable_time(error.retry_after) log.info('command raised cooldown error: %s', ctx.invoked_with) return await ctx.send( f'You\'re on cooldown. Please try again in: {time}') if isinstance(error, coc.HTTPException): log.info('coc api raised %s for command %s', error, ctx.invoked_with) return await ctx.send( f"The COC API returned {error.message}. " f"If this persists, please join the support server and let us know!" ) ctx.command.reset_cooldown(ctx) if isinstance( error, (discord.Forbidden, discord.NotFound, paginator.CannotPaginate)): return e = discord.Embed(title='Command Error', colour=0xcc3366) e.add_field(name='Name', value=ctx.command.qualified_name) e.add_field(name='Author', value=f'{ctx.author} (ID: {ctx.author.id})') fmt = f'Channel: {ctx.channel} (ID: {ctx.channel.id})' if ctx.guild: fmt = f'{fmt}\nGuild: {ctx.guild} (ID: {ctx.guild.id})' e.add_field(name='Location', value=fmt, inline=False) e.add_field(name='Content', value=textwrap.shorten(ctx.message.content, width=512)) exc = ''.join( traceback.format_exception(type(error), error, error.__traceback__, chain=False)) log.exception('unhandled error occured, command: %s, author: %s', ctx.invoked_with, ctx.author.id, exc_info=error) if len(exc) > 2000: fp = io.BytesIO(exc.encode('utf-8')) e.description = "Traceback was too long." return await ctx.send(embed=e, file=discord.File(fp, 'traceback.txt')) e.description = f'```py\n{exc}\n```' e.timestamp = datetime.datetime.utcnow() if not creds.live: await ctx.send(embed=e) return await ctx.bot.error_webhook.send(embed=e) try: await ctx.send( 'Uh oh! Something broke. This error has been reported; ' 'the owner is working on it. Please join the support server: ' 'https://discord.gg/ePt8y4V to stay updated!') except discord.Forbidden: pass
def readable_time(self): return readable_time((datetime.utcnow() - self.time).total_seconds())