Esempio n. 1
0
    def __init__(self, hawking, bot):
        self.hawking = hawking
        self.bot = bot
        self.admins = CONFIG_OPTIONS.get(self.ADMINS_KEY, [])
        self.announce_updates = CONFIG_OPTIONS.get(self.ANNOUNCE_UPDATES_KEY, False)

        self.dynamo_db = dynamo_helper.DynamoHelper()
Esempio n. 2
0
    def __init__(self, plane_pal, bot, **kwargs):
        self.plane_pal = plane_pal
        self.bot = bot

        self.plot_command_help = kwargs.get(self.PLOT_COMMAND_HELP_KEY,
                                            self.PLOT_COMMAND_HELP)

        self.path_parser = PathParser()
        self.plotter = plotter.Plotter()
        self.dynamo_db = dynamo_helper.DynamoHelper()
Esempio n. 3
0
    def __init__(self, bot: commands.Bot, channel_timeout_handler, **kwargs):
        self.bot = bot
        self.server_states = {}
        self.channel_timeout_handler = channel_timeout_handler
        self.dynamo_db = dynamo_helper.DynamoHelper()

        ## Clamp between 0.0 and 1.0
        self.skip_percentage = max(
            min(float(CONFIG_OPTIONS.get(self.SKIP_PERCENTAGE_KEY, 0.5)), 1.0),
            0.0)
        self.ffmpeg_parameters = CONFIG_OPTIONS.get(self.FFMPEG_PARAMETERS_KEY,
                                                    "")
        self.ffmpeg_post_parameters = CONFIG_OPTIONS.get(
            self.FFMPEG_POST_PARAMETERS_KEY, "")
Esempio n. 4
0
    def __init__(self,
                 beat_length,
                 duration,
                 note,
                 sharp=False,
                 octave=4,
                 sub_notes=[]):
        self.beat_length = beat_length
        self.duration = duration
        self.note = note
        self.sharp = sharp
        self.octave = octave
        self.sub_notes = sub_notes

        self.dynamo_db = dynamo_helper.DynamoHelper()
Esempio n. 5
0
    def __init__(self, bot, tts_controller=None, **kwargs):
        self.bot = bot
        self.tts_controller = tts_controller or TTSController()
        self.speech_states = {}
        self.save = self.tts_controller.save
        self.delete = self.tts_controller.delete
        self.delete_commands = kwargs.get(self.DELETE_COMMANDS_KEY, self.DELETE_COMMANDS)
        self.skip_votes = int(kwargs.get(self.SKIP_VOTES_KEY, self.SKIP_VOTES))
        self.skip_percentage = int(kwargs.get(self.SKIP_PERCENTAGE_KEY, self.SKIP_PERCENTAGE))
        self.ffmpeg_before_options = kwargs.get(self.FFMPEG_BEFORE_OPTIONS_KEY, self.FFMPEG_BEFORE_OPTIONS)
        self.ffmpeg_options = kwargs.get(self.FFMPEG_OPTIONS_KEY, self.FFMPEG_OPTIONS)
        self.channel_timeout = int(kwargs.get(self.CHANNEL_TIMEOUT_KEY, self.CHANNEL_TIMEOUT))

        ## Beginning config cleanup, hence no extra kwargs.get junk
        self.channel_timeout_phrases = CONFIG_OPTIONS.get(self.CHANNEL_TIMEOUT_PHRASES_KEY, [])

        self.message_parser = message_parser.MessageParser()
        self.dynamo_db = dynamo_helper.DynamoHelper()
Esempio n. 6
0
    def __init__(self, hawking, bot, phrases_folder_path=None, **command_kwargs):
        self.hawking = hawking
        self.bot = bot
        self.phrases_file_extension = self.PHRASES_FILE_EXTENSION
        self.phrases_folder_path = phrases_folder_path or self.PHRASES_FOLDER_PATH
        self.command_kwargs = command_kwargs
        self.command_names = []
        self.find_command_minimum_similarity = float(CONFIG_OPTIONS.get('find_command_minimum_similarity', 0.5))

        self.dynamo_db = dynamo_helper.DynamoHelper()

        ## Make sure context is always passed to the callbacks
        self.command_kwargs["pass_context"] = True

        ## The mapping of phrases into groups 
        self.phrase_groups = {}

        ## Compile a regex for filtering non-letter characters
        self.non_letter_regex = re.compile('\W+')

        ## Load and add the phrases
        self.init_phrases()
Esempio n. 7
0
    def __init__(self, clipster, bot, clips_folder_path, **command_kwargs):
        self.clipster = clipster
        self.bot = bot
        self.dynamo_db = dynamo_helper.DynamoHelper()

        self.manifest_file_name = self.MANIFEST_FILE_NAME_KEY
        self.clips_folder_path = clips_folder_path
        self.command_kwargs = command_kwargs
        self.command_names = []
        self.command_group_names = []
        self.find_command_minimum_similarity = float(
            CONFIG_OPTIONS.get('find_command_minimum_similarity', 0.5))
        self.channel_timeout_clip_paths = CONFIG_OPTIONS.get(
            'channel_timeout_clip_paths', [])

        ## Make sure context is always passed to the callbacks
        self.command_kwargs["pass_context"] = True

        ## The mapping of clips into groups
        self.clip_groups = {}

        ## Load and add the clips
        self.init_clips()
Esempio n. 8
0
    def __init__(self):
        self.version = CONFIG_OPTIONS.get(self.VERSION_KEY,
                                          'No version information found')
        self.activation_string = CONFIG_OPTIONS.get(self.ACTIVATION_STRING_KEY)
        self.description = CONFIG_OPTIONS.get(self.DESCRIPTION_KEY,
                                              'No bot description found')
        self.clips_folder_path = CONFIG_OPTIONS.get(self.CLIPS_FOLDER_PATH_KEY)
        self.invalid_command_minimum_similarity = float(
            CONFIG_OPTIONS.get("invalid_command_minimum_similarity", 0.25))
        self.dynamo_db = dynamo_helper.DynamoHelper()
        self.token = CONFIG_OPTIONS.get('discord_token')

        ## Make sure we've got the bare minimums to instantiate and run the bot
        if (not self.token):
            raise RuntimeError('Unable to get the token for Discord!')
        if (not self.activation_string):
            raise RuntimeError(
                'Unable to run the bot without an activation string!')

        ## Init the bot and module manager
        self.bot = commands.Bot(command_prefix=commands.when_mentioned_or(
            self.activation_string),
                                description=self.description)
        self.module_manager = module_manager.ModuleManager(self, self.bot)

        ## Apply customized HelpCommand
        self.bot.help_command = help_command.ClipsterHelpCommand()

        ## Register the modules (Order of registration is important, make sure dependancies are loaded first)
        self.module_manager.register(admin.Admin, True, self, self.bot)
        self.module_manager.register(clips.Clips, True, self, self.bot,
                                     self.clips_folder_path)
        self.module_manager.register(
            audio_player.AudioPlayer, True, self.bot,
            self.get_clips_cog().play_random_channel_timeout_clip)

        ## Load any dynamic modules inside the /modules folder
        self.module_manager.discover()

        ## Give some feedback for when the bot is ready to go, and provide some help text via the 'playing' status
        @self.bot.event
        async def on_ready():
            ## todo: Activity instead of Game? Potentially remove "Playing" text below bot
            bot_status = discord.Game(type=0,
                                      name="Use {}help".format(
                                          self.activation_string))
            await self.bot.change_presence(activity=bot_status)

            logger.info("Logged in as '{}' (version: {}), (id: {})".format(
                self.bot.user.name, self.version, self.bot.user.id))

        @self.bot.event
        async def on_command_error(ctx, exception):
            '''Handles command errors. Attempts to find a similar command and suggests it, otherwise directs the user to the help prompt.'''

            logger.exception("Unable to process command.", exc_info=exception)
            self.dynamo_db.put(
                dynamo_helper.DynamoItem(ctx, ctx.message.content,
                                         inspect.currentframe().f_code.co_name,
                                         False, str(exception)))

            ## Attempt to find a command that's similar to the one they wanted. Otherwise just direct them to the help page
            most_similar_command = self.find_most_similar_command(
                ctx.message.content)

            if (most_similar_command[0] == ctx.invoked_with):
                ## Handle issues where the command is valid, but couldn't be completed for whatever reason.
                await ctx.send("I'm sorry <@{}>, I'm afraid I can't do that.\n" \
                    "Discord is having some issues that won't let me speak right now."
                    .format(ctx.message.author.id))
            else:
                help_text_chunks = [
                    "Sorry <@{}>, **{}{}** isn't a valid command.".format(
                        ctx.message.author.id, ctx.prefix, ctx.invoked_with)
                ]

                if (most_similar_command[1] >
                        self.invalid_command_minimum_similarity):
                    help_text_chunks.append("Did you mean **{}{}**?".format(
                        self.activation_string, most_similar_command[0]))
                else:
                    help_text_chunks.append("Try the **{}help** page.".format(
                        self.activation_string))

                ## Dump output to user
                await ctx.send(" ".join(help_text_chunks))
                return
Esempio n. 9
0
    def __init__(self, **kwargs):
        ## Make sure there's a Discord token before doing anything else
        self.token = CONFIG_OPTIONS.get("discord_token")
        if (not self.token):
            raise RuntimeError("Unable to get Discord token!")

        self.version = kwargs.get(self.VERSION_KEY, self.VERSION)
        self.activation_str = kwargs.get(self.ACTIVATION_STR_KEY,
                                         self.ACTIVATION_STR)
        self.description = kwargs.get(self.DESCRIPTION_KEY, self.DESCRIPTION)
        self.invalid_command_minimum_similarity = float(
            kwargs.get(self.INVALID_COMMAND_MINIMUM_SIMILARITY, 0.66))

        self.dynamo_db = dynamo_helper.DynamoHelper()

        ## Init the bot and module manager
        self.bot = commands.Bot(command_prefix=commands.when_mentioned_or(
            self.activation_str),
                                description=self.description)
        self.module_manager = ModuleManager(self, self.bot)

        ## Apply customized HelpCommand
        self.bot.help_command = help_command.HawkingHelpCommand()

        ## Register the modules (Order of registration is important, make sure dependancies are loaded first)
        self.module_manager.register(message_parser.MessageParser, False)
        self.module_manager.register(admin.Admin, True, self, self.bot)
        self.module_manager.register(speech.Speech, True, self)
        self.module_manager.register(
            audio_player.AudioPlayer, True, self.bot,
            self.get_speech_cog().play_random_channel_timeout_message)

        ## Load any dynamic modules inside the /modules folder
        self.module_manager.discover()

        ## Give some feedback for when the bot is ready to go, and provide some help text via the 'playing' status
        @self.bot.event
        async def on_ready():
            ## todo: Activity instead of Game? Potentially remove "Playing" text below bot
            bot_status = discord.Game(type=0,
                                      name="Use {}help".format(
                                          self.activation_str))
            await self.bot.change_presence(activity=bot_status)

            logger.info("Logged in as '{}' (version: {}), (id: {})".format(
                self.bot.user.name, self.version, self.bot.user.id))

        ## Give some feedback to users when their command doesn't execute.
        @self.bot.event
        async def on_command_error(ctx, exception):
            '''Handles command errors. Attempts to find a similar command and suggests it, otherwise directs the user to the help prompt.'''

            self.dynamo_db.put(
                dynamo_helper.DynamoItem(ctx, ctx.message.content,
                                         inspect.currentframe().f_code.co_name,
                                         False, str(exception)))

            ## Attempt to find a command that's similar to the one they wanted. Otherwise just direct them to the help page
            most_similar_command = self.find_most_similar_command(
                ctx.message.content)

            if (most_similar_command[0] == ctx.invoked_with):
                logger.exception(
                    "Unable to complete command, with content: {}, for author: {}, in channel {}, in server: {}"
                    .format(ctx.message.content, ctx.message.author.name,
                            ctx.guild.name),
                    exc_info=exception)
                ## Handle issues where the command is valid, but couldn't be completed for whatever reason.
                await ctx.send(
                    "I'm sorry <@{}>, I'm afraid I can't do that.\nSomething went wrong, and I couldn't complete the command."
                    .format(ctx.message.author.id))
            else:
                logger.exception(
                    "Received invalid command: '{0}{1}', suggested: '{0}{2}', for author: {3}, in server: {4}"
                    .format(self.activation_str, ctx.invoked_with,
                            most_similar_command[0], ctx.message.author.name,
                            ctx.guild.name),
                    exc_info=exception)

                help_text_chunks = [
                    "Sorry <@{}>, **{}{}** isn't a valid command.".format(
                        ctx.message.author.id, ctx.prefix, ctx.invoked_with)
                ]

                if (most_similar_command[1] >
                        self.invalid_command_minimum_similarity):
                    help_text_chunks.append("Did you mean **{}{}**?".format(
                        self.activation_str, most_similar_command[0]))
                else:
                    help_text_chunks.append("Try the **{}help** page.".format(
                        self.activation_str))

                ## Dump output to user
                await ctx.send(" ".join(help_text_chunks))
                return
Esempio n. 10
0
    def __init__(self, hawking, bot):
        self.hawking = hawking
        self.bot = bot
        self.admins = CONFIG_OPTIONS.get(self.ADMINS_KEY, [])

        self.dynamo_db = dynamo_helper.DynamoHelper()
Esempio n. 11
0
    def __init__(self, **kwargs):
        self.activation_str = kwargs.get(self.ACTIVATION_STR_KEY, self.ACTIVATION_STR)
        self.description = kwargs.get(self.DESCRIPTION_KEY, self.DESCRIPTION)
        self.token_file_path = kwargs.get(self.TOKEN_FILE_PATH_KEY, self.TOKEN_FILE_PATH)
        self.invalid_command_minimum_similarity = float(kwargs.get(self.INVALID_COMMAND_MINIMUM_SIMILARITY, 0.66))
        self.dynamo_db = dynamo_helper.DynamoHelper()
        ## Todo: pass kwargs to the their modules

        ## Init the bot and module manager
        self.bot = commands.Bot(
            command_prefix=commands.when_mentioned_or(self.activation_str),
            formatter=help_formatter.HawkingHelpFormatter(),
            description=self.description
        )
        self.module_manager = ModuleManager(self, self.bot)

        ## Register the modules (Order of registration is important, make sure dependancies are loaded first)
        self.module_manager.register(message_parser.MessageParser, False)
        self.module_manager.register(speech.Speech, True, self.bot)
        self.module_manager.register(admin.Admin, True, self, self.bot)

        ## Load any dynamic modules inside the /modules folder
        self.module_manager.discover()

        ## Give some feedback for when the bot is ready to go, and provide some help text via the 'playing' status
        @self.bot.event
        async def on_ready():
            bot_status = discord.Game(type=0, name="Use {}help".format(self.activation_str))
            await self.bot.change_presence(game=bot_status)
            print("Logged in as '{}' (version: {}), (id: {})".format(self.bot.user.name, self.VERSION, self.bot.user.id))

        ## Give some feedback to users when their command doesn't execute.
        @self.bot.event
        async def on_command_error(exception, ctx):
            # discord.py uses reflection to set the destination chat channel for whatever reason (sans command ctx)
            _internal_channel = ctx.message.channel

            utilities.debug_print(exception, debug_level=2)

            self.dynamo_db.put(dynamo_helper.DynamoItem(
                ctx, ctx.message.content, inspect.currentframe().f_code.co_name, False, str(exception)))

            ## Handy for debugging
            # import traceback
            # print('Ignoring exception in command {}:'.format(ctx.command), file=sys.stderr)
            # traceback.print_exception(type(exception), exception, exception.__traceback__, file=sys.stderr)

            ## Permissions error?
            if (isinstance(exception, CommandInvokeError) and isinstance(exception.original, TimeoutError)):
                await self.bot.say("Sorry <@{}>, I'm not able to join the voice channel right now. Discord might be having issues, or I might not have permission to join."
                    .format(ctx.message.author.id))
                return

            ## Poorly handled (for now, until I can get more concrete examples in my database) error messages for users
            if ("code =" in str(exception)):
                await self.bot.say("Sorry <@{}>, Discord is having some issues that won't let me speak right now."
                    .format(ctx.message.author.id))
                return

            ## Attempt to find a command that's similar to the one they wanted. Otherwise just direct them to the help page
            else:
                most_similar_command = self.find_most_similar_command(ctx.message.content)

                if (most_similar_command[0] == ctx.invoked_with):
                    ## Handle issues where the command is valid, but couldn't be completed for whatever reason.
                    await self.bot.say("Sorry <@{}>, I can't talk right now. Try again in a little bit.".format(ctx.message.author.id))
                else:
                    ## Otherwise, handle other issues involving invalid commands
                    help_text_chunks = [
                        "Sorry <@{}>, **{}{}** isn't a valid command.".format(ctx.message.author.id, ctx.prefix, ctx.invoked_with)
                    ]

                    ## Build the output to give to the user
                    if (most_similar_command[1] > self.invalid_command_minimum_similarity):
                        help_text_chunks.append("Did you mean **{}{}**?".format(self.activation_str, most_similar_command[0]))
                    else:
                        help_text_chunks.append("Try the **{}help** page.".format(self.activation_str))

                    await self.bot.say(" ".join(help_text_chunks))