Ejemplo n.º 1
0
    def __init__(self, hawking, bot, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.hawking = hawking
        self.bot = bot

        self.dynamo_db = dynamo_manager.DynamoManager()
Ejemplo n.º 2
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_manager.DynamoManager()
Ejemplo n.º 3
0
    def __init__(self, hawking: Hawking, bot, *args, **kwargs):
        super().__init__(*args, **kwargs)

        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_manager.DynamoManager()
Ejemplo n.º 4
0
    def __init__(self,
                 bot: commands.Bot,
                 channel_timeout_handler=None,
                 *args,
                 **kwargs):
        super().__init__(*args, **kwargs)

        self.bot = bot
        self.server_states = {}
        self.channel_timeout_handler = channel_timeout_handler
        self.dynamo_db = dynamo_manager.DynamoManager()

        ## 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, "")
Ejemplo n.º 5
0
    def __init__(self, hawking, bot, *args, **command_kwargs):
        super().__init__(*args, **command_kwargs)

        self.phrase_file_manager = PhraseFileManager()
        self.dynamo_db = dynamo_manager.DynamoManager()

        self.hawking = hawking
        self.bot = bot
        self.command_kwargs = command_kwargs
        self.command_names: List[str] = []  # All command names
        self.phrase_command_names: List[str] = []
        self.find_command_minimum_similarity = float(
            CONFIG_OPTIONS.get('find_command_minimum_similarity', 0.5))
        self.phrase_groups: Dict[str, PhraseGroup] = {}
        self.phrases_folder_path = self.phrase_file_manager.phrases_folder_path

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

        ## Load and add the phrases
        self.init_phrases()
        self.successful = True
Ejemplo n.º 6
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!")

        ## Set the current working directory to that of the tts executable ASAP, so there's not weird issues arising
        ## from bot init and speech execution potentially being in different working directories.
        speech.TTSController.set_current_working_dir_to_tts_executable()

        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("description",
                                      ["The retro TTS bot for Discord"])
        self.invalid_command_minimum_similarity = float(
            kwargs.get(self.INVALID_COMMAND_MINIMUM_SIMILARITY, 0.66))

        self.dynamo_db = dynamo_manager.DynamoManager()

        ## Init the bot and module manager
        self.bot = commands.Bot(command_prefix=commands.when_mentioned_or(
            self.activation_str),
                                description='\n'.join(self.description))
        self._module_manager = ModuleManager(self, self.bot)

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

        ## Register the modules
        self.module_manager.register_module(privacy_manager.PrivacyManager,
                                            self.bot,
                                            name='Hawking')
        self.module_manager.register_module(
            speech_config_help_command.SpeechConfigHelpCommand, self.bot)
        self.module_manager.register_module(
            social_invite_command.SocialInviteCommand, self, self.bot)
        self.module_manager.register_module(message_parser.MessageParser)
        self.module_manager.register_module(admin.Admin, self, self.bot)
        self.module_manager.register_module(
            speech.Speech, self, dependencies=[message_parser.MessageParser])
        self.module_manager.register_module(
            audio_player.AudioPlayer,
            self.bot,
            None,
            dependencies=[speech.Speech],
            after_successful_init=lambda: self.get_audio_player_cog(
            ).set_channel_timeout_handler(self.get_speech_cog().
                                          play_random_channel_timeout_message))

        ## Find any dynamic modules, and prep them for loading
        self.module_manager.discover_modules()

        ## Load all of the previously registered modules!
        self.module_manager.load_registered_modules()

        ## 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_message_context(ctx, False)

            ## 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.message.channel.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
Ejemplo n.º 7
0
    def __init__(self, bot, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.bot = bot

        # Make sure the bot's name is capitalized, since it's used exclusively when interacting with users textually.
        name = kwargs.get('name', 'bot')
        self.name = name[0].upper() + name[1:]

        self.privacy_policy_url = CONFIG_OPTIONS.get('privacy_policy_url')
        if (self.privacy_policy_url):
            ## Don't add a privacy policy link if there isn't a URL to link to
            command = self.build_privacy_policy_command()
            self.bot.add_command(command)

        ## Build the filepaths for the various tracking files
        delete_request_queue_file_path = CONFIG_OPTIONS.get(
            'delete_request_queue_file_path')
        if (delete_request_queue_file_path):
            self.delete_request_queue_file_path = Path(
                delete_request_queue_file_path)
        else:
            self.delete_request_queue_file_path = Path.joinpath(
                utilities.get_root_path(), 'privacy', 'delete_requests.txt')

        delete_request_meta_file_path = CONFIG_OPTIONS.get(
            'delete_request_meta_file_path')
        if (delete_request_meta_file_path):
            self.delete_request_meta_file_path = Path(
                delete_request_meta_file_path)
        else:
            self.delete_request_meta_file_path = Path.joinpath(
                utilities.get_root_path(), 'privacy', 'meta.json')

        ## Make sure the file containing all delete requests is accessible.
        if (not self.is_file_accessible(self.delete_request_queue_file_path)):
            message = "Unable to access delete request queue file at: '{}'. Make sure that it exists and has r/w permissions applied to it".format(
                self.delete_request_queue_file_path)

            logger.error(message)
            raise RuntimeError(message)

        ## Make sure the file containing the delete request metadata is accessible.
        if (not self.is_file_accessible(self.delete_request_meta_file_path)):
            message = "Unable to access delete request queue file at: '{}'. Make sure that it exists and has r/w permissions applied to it".format(
                self.delete_request_meta_file_path)

            logger.error(message)
            raise RuntimeError(message)

        ## Make sure there's a dynamo manager available for database operations
        self.dynamo_db = dynamo_manager.DynamoManager()

        ## Delete request scheduling
        self.delete_request_scheduled_weekday = int(
            CONFIG_OPTIONS.get('delete_request_weekday_to_process', 0))
        self.delete_request_scheduled_time = dateutil.parser.parse(
            CONFIG_OPTIONS.get('delete_request_time_to_process', "T00:00:00Z"))

        ## Keep a copy of all user ids that should be deleted in memory, so the actual file can't get spammed by repeats.
        self.queued_user_ids = self.get_all_queued_delete_request_ids()

        ## Load the delete request metadata to know when deletion operations last happened
        try:
            self.metadata = utilities.load_json(
                self.delete_request_meta_file_path)
        except json.decoder.JSONDecodeError:
            self.metadata = {}

        ## Perform or prepare the deletion process
        seconds_until_process_delete_request = self.get_seconds_until_process_delete_request_queue_is_due(
        )
        if (seconds_until_process_delete_request <= 0):
            self.bot.loop.create_task(self.process_delete_request_queue())
        else:
            self.bot.loop.create_task(
                self.schedule_process_delete_request_queue(
                    seconds_until_process_delete_request))