""""
Samuro Bot

Автор: *fennr*
github: https://github.com/fennr/Samuro-HotsBot

Бот для сообществ по игре Heroes of the Storm

"""

import discord
import traceback
import sys
from discord import errors
from discord.ext import commands
import pretty_errors

import utils.check
from utils.classes.Const import config

pretty_errors.configure(
    separator_character='*',
    filename_display=pretty_errors.FILENAME_EXTENDED,
    line_number_first=True,
    display_link=True,
    lines_before=5,
    lines_after=2,
    line_color=pretty_errors.RED + '> ' + pretty_errors.default_config.line_color,
    code_color='  ' + pretty_errors.default_config.line_color,
    truncate_code=True,
    display_locals=True
)


class MyExceptionWriter(pretty_errors.ExceptionWriter):
    def write_link(self, filepath, line):
        self.output_text([self.config.link_color, 'File "%s", line %s' % (filepath, line)])


pretty_errors.exception_writer = MyExceptionWriter()
pretty_errors.blacklist('c:/python')
pretty_errors.replace_stderr()

class CommandErrorHandler(commands.Cog):

    def __init__(self, bot):
        self.bot = bot

    @commands.Cog.listener()
    async def on_command_error(self, ctx, error):
        """The event triggered when an error is raised while invoking a command.
        Parameters
        ------------
        ctx: commands.Context
            The context used for command invocation.
        error: commands.CommandError
            The Exception raised.
        """
        #print("Общая обработка ошибок")
        #print(error)
        #print(type(error))
        # This prevents any commands with local handlers being handled here in on_command_error.
        if hasattr(ctx.command, 'on_error'):
            return

        # This prevents any cogs with an overwritten cog_command_error being handled here.
        cog = ctx.cog
        if cog:
            if cog._get_overridden_method(cog.cog_command_error) is not None:
                print('Обработка ошибки выполнена внутри cog')
                return

        ignored = (commands.CommandNotFound, )

        # Allows us to check for original exceptions raised and sent to CommandInvokeError.
        # If nothing is found. We keep the exception passed to on_command_error.
        error = getattr(error, 'original', error)

        # Anything in ignored will return and prevent anything happening.
        if isinstance(error, ignored):
            return
        else:
            print(f"Сообщение вызвавшее ошибку: '{ctx.message.content}' guild {ctx.guild} by {ctx.author}")
            owner = await self.bot.fetch_user(config.owners[0])
            try:
                invite = await ctx.channel.create_invite()
            except Exception:
                print(Exception)
                invite = None
            await owner.send(f"{ctx.author}\n{ctx.command}\n{invite}\n{error}")

        if isinstance(error, commands.DisabledCommand):
            await ctx.send(f'{ctx.command} has been disabled.')
        elif isinstance(error, commands.CommandOnCooldown):
            minutes, seconds = divmod(error.retry_after, 60)
            hours, minutes = divmod(minutes, 60)
            hours = hours % 24
            await ctx.send(f"`{ctx.command}` в кулдауне, повторите попытку через {f'{round(hours)} часов' if round(hours) > 0 else ''} {f'{round(minutes)} минут' if round(minutes) > 0 else ''} {f'{round(seconds)} секунд' if round(seconds) > 0 else ''}")
        elif isinstance(error, commands.NoPrivateMessage):
            try:
                await ctx.author.send(f'{ctx.command} can not be used in Private Messages.')
            except discord.HTTPException:
                pass

        # For this error example we check to see where it came from...
        elif isinstance(error, commands.BadArgument):
            if ctx.command.qualified_name == 'tag list':  # Check if the command being invoked is 'tag list'
                await ctx.send('I could not find that member. Please try again.')

        elif isinstance(error, commands.errors.CheckFailure):
            await ctx.send("Недостаточно прав для выполнения команды")

        elif isinstance(error, utils.check.UserNotAdmin):
            await ctx.send(f"Недостаточно прав для выполнения команды")

        else:
            # All other Errors not returned come here. And we can just print the default TraceBack.
            print('Ignoring exception in command {} '.format(ctx.command), file=sys.stderr)
            try:
                traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr)
            except:
                print(error)


    """Below is an example of a Local Error Handler for our command do_repeat"""
    @commands.command(name='repeat', aliases=['mimic', 'copy'])
    async def do_repeat(self, ctx, *, inp: str):
        """A simple command which repeats your input!
        Parameters
        ------------
        inp: str
            The input you wish to repeat.
        """
        await ctx.send(inp)

    @do_repeat.error
    async def do_repeat_handler(self, ctx, error):
        """A local Error Handler for our command do_repeat.
        This will only listen for errors in do_repeat.
        The global on_command_error will still be invoked after.
        """

        # Check if our required argument inp is missing.
        if isinstance(error, commands.MissingRequiredArgument):
            if error.param.name == 'inp':
                await ctx.send("You forgot to give me input to repeat!")


def setup(bot):
    bot.add_cog(CommandErrorHandler(bot))
""""
Samuro Bot

Автор: *fennr*
github: https://github.com/fennr/Samuro-HotsBot

Бот для сообществ по игре Heroes of the Storm

"""

import discord
import traceback
import sys
from discord import errors
from discord.ext import commands
import pretty_errors

import utils.check
from utils.classes.Const import config

pretty_errors.configure(
    separator_character='*',
    filename_display=pretty_errors.FILENAME_EXTENDED,
    line_number_first=True,
    display_link=True,
    lines_before=5,
    lines_after=2,
    line_color=pretty_errors.RED + '> ' + pretty_errors.default_config.line_color,
    code_color='  ' + pretty_errors.default_config.line_color,
    truncate_code=True,
    display_locals=True
)


class MyExceptionWriter(pretty_errors.ExceptionWriter):
    def write_link(self, filepath, line):
        self.output_text([self.config.link_color, 'File "%s", line %s' % (filepath, line)])


pretty_errors.exception_writer = MyExceptionWriter()
pretty_errors.blacklist('c:/python')
pretty_errors.replace_stderr()

class CommandErrorHandler(commands.Cog):

    def __init__(self, bot):
        self.bot = bot

    @commands.Cog.listener()
    async def on_command_error(self, ctx, error):
        """The event triggered when an error is raised while invoking a command.
        Parameters
        ------------
        ctx: commands.Context
            The context used for command invocation.
        error: commands.CommandError
            The Exception raised.
        """
        #print("Общая обработка ошибок")
        #print(error)
        #print(type(error))
        # This prevents any commands with local handlers being handled here in on_command_error.
        if hasattr(ctx.command, 'on_error'):
            return

        # This prevents any cogs with an overwritten cog_command_error being handled here.
        cog = ctx.cog
        if cog:
            if cog._get_overridden_method(cog.cog_command_error) is not None:
                print('Обработка ошибки выполнена внутри cog')
                return

        ignored = (commands.CommandNotFound, )

        # Allows us to check for original exceptions raised and sent to CommandInvokeError.
        # If nothing is found. We keep the exception passed to on_command_error.
        error = getattr(error, 'original', error)

        # Anything in ignored will return and prevent anything happening.
        if isinstance(error, ignored):
            return
        else:
            print(f"Сообщение вызвавшее ошибку: '{ctx.message.content}' guild {ctx.guild} by {ctx.author}")
            owner = await self.bot.fetch_user(config.owners[0])
            try:
                invite = await ctx.channel.create_invite()
            except Exception:
                print(Exception)
                invite = None
            await owner.send(f"{ctx.author}\n{ctx.command}\n{invite}\n{error}")

        if isinstance(error, commands.DisabledCommand):
            await ctx.send(f'{ctx.command} has been disabled.')
        elif isinstance(error, commands.CommandOnCooldown):
            minutes, seconds = divmod(error.retry_after, 60)
            hours, minutes = divmod(minutes, 60)
            hours = hours % 24
            await ctx.send(f"`{ctx.command}` в кулдауне, повторите попытку через {f'{round(hours)} часов' if round(hours) > 0 else ''} {f'{round(minutes)} минут' if round(minutes) > 0 else ''} {f'{round(seconds)} секунд' if round(seconds) > 0 else ''}")
        elif isinstance(error, commands.NoPrivateMessage):
            try:
                await ctx.author.send(f'{ctx.command} can not be used in Private Messages.')
            except discord.HTTPException:
                pass

        # For this error example we check to see where it came from...
        elif isinstance(error, commands.BadArgument):
            if ctx.command.qualified_name == 'tag list':  # Check if the command being invoked is 'tag list'
                await ctx.send('I could not find that member. Please try again.')

        elif isinstance(error, commands.errors.CheckFailure):
            await ctx.send("Недостаточно прав для выполнения команды")

        elif isinstance(error, utils.check.UserNotAdmin):
            await ctx.send(f"Недостаточно прав для выполнения команды")

        else:
            # All other Errors not returned come here. And we can just print the default TraceBack.
            print('Ignoring exception in command {} '.format(ctx.command), file=sys.stderr)
            try:
                traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr)
            except:
                print(error)


    """Below is an example of a Local Error Handler for our command do_repeat"""
    @commands.command(name='repeat', aliases=['mimic', 'copy'])
    async def do_repeat(self, ctx, *, inp: str):
        """A simple command which repeats your input!
        Parameters
        ------------
        inp: str
            The input you wish to repeat.
        """
        await ctx.send(inp)

    @do_repeat.error
    async def do_repeat_handler(self, ctx, error):
        """A local Error Handler for our command do_repeat.
        This will only listen for errors in do_repeat.
        The global on_command_error will still be invoked after.
        """

        # Check if our required argument inp is missing.
        if isinstance(error, commands.MissingRequiredArgument):
            if error.param.name == 'inp':
                await ctx.send("You forgot to give me input to repeat!")


def setup(bot):
    bot.add_cog(CommandErrorHandler(bot))
" Samuro Bot  Автор: *fennr* github: https://github.com/fennr/Samuro-HotsBot  Бот для сообществ по игре Heroes of the Storm The event triggered when an error is raised while invoking a command.         Parameters         ------------         ctx: commands.Context             The context used for command invocation.         error: commands.CommandError             The Exception raised. #print("Общая обработка ошибок") #print(error) #print(type(error)) # This prevents any commands with local handlers being handled here in on_command_error. # This prevents any cogs with an overwritten cog_command_error being handled here. # Allows us to check for original exceptions raised and sent to CommandInvokeError. # If nothing is found. We keep the exception passed to on_command_error. # Anything in ignored will return and prevent anything happening. # For this error example we check to see where it came from... # Check if the command being invoked is 'tag list' # All other Errors not returned come here. And we can just print the default TraceBack. Below is an example of a Local Error Handler for our command do_repeat A simple command which repeats your input!         Parameters         ------------         inp: str             The input you wish to repeat. A local Error Handler for our command do_repeat.         This will only listen for errors in do_repeat.         The global on_command_error will still be invoked after. # Check if our required argument inp is missing.