Example #1
0
    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}`.")
Example #2
0
    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)
Example #3
0
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
Example #4
0
 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]])
Example #5
0
 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
Example #7
0
 def readable_time(self):
     return readable_time((datetime.utcnow() - self.time).total_seconds())