示例#1
0
文件: pyborg.py 项目: J0s3f/PyBorg
    def __init__(self):
        """
        Open the dictionary. Resize as required.
        """
        self.settings = Settings({
            'aliases': Setting("A list of similar words", {}),
            'censored': Setting("Words that indicate not to learn the sentences in which they appear", []),
            'ignore_list': Setting("Words to ignore for the answer", ['!.', '?.', "'", ',', ';']),
            'learning': Setting("If True, the bot will learn new words", True),
            'max_words': Setting("Max number of words to learn", 6000),
            'max_word_length': Setting("Max number of characters a word can have to learn it", 13),
            'min_vowel_ratio': Setting("Min ratio of vowels to characters a word can have to learn it", 0.25),
            'protect': Setting("If True, don't overwrite the dictionary and configuration on disk", False),
            'process_with': Setting("Which library to generate replies with ('pyborg' or 'megahal')", "pyborg"),
        })
        self.settings.load('pyborg.cfg')

        self.answers = Settings({
            'sentences': Setting("A list of prepared answers", {}),
        })
        self.answers.load('answers.txt')

        self.unfilterd = {}

        # Read the dictionary
        if self.settings.process_with == "pyborg":
            self.brain = PyborgBrain(self.settings)
        elif self.settings.process_with == "megahal":
            self.brain = MegahalBrain(self.settings)
        else:
            raise ValueError("Unknown 'process_with' value {0}".format(self.settings.process_with))

        self.settings.save()
示例#2
0
    def __init__(self):
        """
        Open the dictionary. Resize as required.
        """
        self.settings = Settings({
            'aliases':
            Setting("A list of similar words", {}),
            'censored':
            Setting(
                "Words that indicate not to learn the sentences in which they appear",
                []),
            'ignore_list':
            Setting("Words to ignore for the answer",
                    ['!.', '?.', "'", ',', ';']),
            'learning':
            Setting("If True, the bot will learn new words", True),
            'max_words':
            Setting("Max number of words to learn", 6000),
            'max_word_length':
            Setting("Max number of characters a word can have to learn it",
                    13),
            'min_vowel_ratio':
            Setting(
                "Min ratio of vowels to characters a word can have to learn it",
                0.25),
            'protect':
            Setting(
                "If True, don't overwrite the dictionary and configuration on disk",
                False),
            'process_with':
            Setting(
                "Which library to generate replies with ('pyborg' or 'megahal')",
                "pyborg"),
        })
        self.settings.load('pyborg.cfg')

        self.answers = Settings({
            'sentences':
            Setting("A list of prepared answers", {}),
        })
        self.answers.load('answers.txt')

        self.unfilterd = {}

        # Read the dictionary
        if self.settings.process_with == "pyborg":
            self.brain = PyborgBrain(self.settings)
        elif self.settings.process_with == "megahal":
            self.brain = MegahalBrain(self.settings)
        else:
            raise ValueError("Unknown 'process_with' value {0}".format(
                self.settings.process_with))

        self.settings.save()
示例#3
0
class Pyborg(object):

    ver_string = "I am a version 1.1.2 PyBorg"

    # Main command list
    commandlist = "Pyborg commands:\n!checkdict, !contexts, !help, !known, !learning, !rebuilddict, \
!replace, !unlearn, !purge, !version, !words, !limit, !alias, !save, !censor, !uncensor, !owner"

    commanddict = {
        "help":
        "Owner command. Usage: !help [command]\nPrints information about using a command, or a list of commands if no command is given",
        "version":
        "Usage: !version\nDisplay what version of Pyborg we are running",
        "words": "Usage: !words\nDisplay how many words are known",
        "known":
        "Usage: !known word1 [word2 [...]]\nDisplays if one or more words are known, and how many contexts are known",
        "contexts":
        "Owner command. Usage: !contexts <phrase>\nPrint contexts containing <phrase>",
        "unlearn":
        "Owner command. Usage: !unlearn <expression>\nRemove all occurances of a word or expression from the dictionary. For example '!unlearn of of' would remove all contexts containing double 'of's",
        "purge":
        "Owner command. Usage: !purge [number]\nRemove all occurances of the words that appears in less than <number> contexts",
        "replace":
        "Owner command. Usage: !replace <old> <new>\nReplace all occurances of word <old> in the dictionary with <new>",
        "learning":
        "Owner command. Usage: !learning [on|off]\nToggle bot learning. Without arguments shows the current setting",
        "checkdict":
        "Owner command. Usage: !checkdict\nChecks the dictionary for broken links. Shouldn't happen, but worth trying if you get KeyError crashes",
        "rebuilddict":
        "Owner command. Usage: !rebuilddict\nRebuilds dictionary links from the lines of known text. Takes a while. You probably don't need to do it unless your dictionary is very screwed",
        "censor":
        "Owner command. Usage: !censor [word1 [...]]\nPrevent the bot using one or more words. Without arguments lists the currently censored words",
        "uncensor":
        "Owner command. Usage: !uncensor word1 [word2 [...]]\nRemove censorship on one or more words",
        "limit":
        "Owner command. Usage: !limit [number]\nSet the number of words that pyBorg can learn",
        "alias":
        "Owner command. Usage: !alias : Show the differents aliases\n!alias <alias> : show the words attached to this alias\n!alias <alias> <word> : link the word to the alias",
        "owner": "Usage : !owner password\nAdd the user in the owner list"
    }

    log = logging.getLogger('Pyborg')

    def __init__(self):
        """
        Open the dictionary. Resize as required.
        """
        self.settings = Settings({
            'aliases':
            Setting("A list of similar words", {}),
            'censored':
            Setting(
                "Words that indicate not to learn the sentences in which they appear",
                []),
            'ignore_list':
            Setting("Words to ignore for the answer",
                    ['!.', '?.', "'", ',', ';']),
            'learning':
            Setting("If True, the bot will learn new words", True),
            'max_words':
            Setting("Max number of words to learn", 6000),
            'max_word_length':
            Setting("Max number of characters a word can have to learn it",
                    13),
            'min_vowel_ratio':
            Setting(
                "Min ratio of vowels to characters a word can have to learn it",
                0.25),
            'protect':
            Setting(
                "If True, don't overwrite the dictionary and configuration on disk",
                False),
            'process_with':
            Setting(
                "Which library to generate replies with ('pyborg' or 'megahal')",
                "pyborg"),
        })
        self.settings.load('pyborg.cfg')

        self.answers = Settings({
            'sentences':
            Setting("A list of prepared answers", {}),
        })
        self.answers.load('answers.txt')

        self.unfilterd = {}

        # Read the dictionary
        if self.settings.process_with == "pyborg":
            self.brain = PyborgBrain(self.settings)
        elif self.settings.process_with == "megahal":
            self.brain = MegahalBrain(self.settings)
        else:
            raise ValueError("Unknown 'process_with' value {0}".format(
                self.settings.process_with))

        self.settings.save()

    def save_all(self):
        if self.settings.protect:
            return

        self.brain.save()

        sentence_list = sorted(
            (sentence for sentence in self.unfilterd.iteritems()),
            key=lambda s: s[1])
        with open('sentences.txt', 'w') as sentence_file:
            for word, count in sentence_list:
                sentence_file.write(word)
                sentence_file.write('\n')

        self.settings.save()

    def process_msg(self,
                    io_module,
                    body,
                    replyrate,
                    learn,
                    args,
                    owner=False):
        """
        Process message 'body' and pass back to IO module with args.
        If owner, allow owner commands.
        """
        # add trailing space so sentences are broken up correctly
        body = body + " "

        # Parse commands
        if body.startswith('!'):
            self.do_commands(io_module, body, args, owner)
            return

        # Filter out garbage and do some formatting
        body = self.brain.filter_message(body)

        # Learn from input
        if learn == 1 and self.settings.learning:
            self.brain.learn(body)

        # Make a reply if desired
        if random.randint(0, 99) < replyrate:
            message = ""

            #Look if we can find a prepared answer
            for sentence in self.answers.sentences.keys():
                pattern = "^%s$" % sentence
                if re.search(pattern, body):
                    message = self.answers.sentences[sentence][random.randint(
                        0,
                        len(self.answers.sentences[sentence]) - 1)]
                    break
                else:
                    if body in self.unfilterd:
                        self.unfilterd[body] = self.unfilterd[body] + 1
                    else:
                        self.unfilterd[body] = 0

            if message == "":
                message = self.brain.reply(body)

            # single word reply: always output
            if len(message.split()) == 1:
                io_module.output(message, args)
                return
            # empty. do not output
            if message == "":
                return
            # else output
            if not owner:
                time.sleep(.2 * len(message))
            io_module.output(message, args)

    def do_commands(self, io_module, body, args, owner):
        """
        Respond to user comands.
        """
        command_list = body.split()
        command = command_list.pop(0).lstrip('!').lower()

        command_method = getattr(self, command, None)
        self.log.debug("What is command %r?", command)
        if command_method is None:
            self.log.debug(
                "No such pyborg command %r. Is there a brain command %r?",
                command, command)
            command_method = getattr(self.brain, command, None)
        if command_method is None:
            self.log.debug(
                "No such pyborg or brain command %r, doing nothing :(")
            return
        if not getattr(command_method, 'is_command', False):
            self.log.debug(
                "Found requested method %r for command %r, but it's not a command, doing nothing :(",
                command_method, command)
            return
        if getattr(command_method, 'is_owner_command', False) and not owner:
            self.log.debug(
                "Command %r is an owner command but requestor is not the owner, doing nothing :(",
                command)
            return

        self.log.debug("Yay, running command %r!", command)
        try:
            message = command_method(io_module, command_list, args)
        except Exception, exc:
            message = 'Oops, internal error :('
            self.log.exception('Internal error dispatching command %r', body)
        if message:
            io_module.output(message, args)
示例#4
0
文件: pyborg.py 项目: J0s3f/PyBorg
class Pyborg(object):

    ver_string = "I am a version 1.1.2 PyBorg"

    # Main command list
    commandlist = "Pyborg commands:\n!checkdict, !contexts, !help, !known, !learning, !rebuilddict, \
!replace, !unlearn, !purge, !version, !words, !limit, !alias, !save, !censor, !uncensor, !owner"
    commanddict = {
        "help": "Owner command. Usage: !help [command]\nPrints information about using a command, or a list of commands if no command is given",
        "version": "Usage: !version\nDisplay what version of Pyborg we are running",
        "words": "Usage: !words\nDisplay how many words are known",
        "known": "Usage: !known word1 [word2 [...]]\nDisplays if one or more words are known, and how many contexts are known",
        "contexts": "Owner command. Usage: !contexts <phrase>\nPrint contexts containing <phrase>",
        "unlearn": "Owner command. Usage: !unlearn <expression>\nRemove all occurances of a word or expression from the dictionary. For example '!unlearn of of' would remove all contexts containing double 'of's",
        "purge": "Owner command. Usage: !purge [number]\nRemove all occurances of the words that appears in less than <number> contexts",
        "replace": "Owner command. Usage: !replace <old> <new>\nReplace all occurances of word <old> in the dictionary with <new>",
        "learning": "Owner command. Usage: !learning [on|off]\nToggle bot learning. Without arguments shows the current setting",
        "checkdict": "Owner command. Usage: !checkdict\nChecks the dictionary for broken links. Shouldn't happen, but worth trying if you get KeyError crashes",
        "rebuilddict": "Owner command. Usage: !rebuilddict\nRebuilds dictionary links from the lines of known text. Takes a while. You probably don't need to do it unless your dictionary is very screwed",
        "censor": "Owner command. Usage: !censor [word1 [...]]\nPrevent the bot using one or more words. Without arguments lists the currently censored words",
        "uncensor": "Owner command. Usage: !uncensor word1 [word2 [...]]\nRemove censorship on one or more words",
        "limit": "Owner command. Usage: !limit [number]\nSet the number of words that pyBorg can learn",
        "alias": "Owner command. Usage: !alias : Show the differents aliases\n!alias <alias> : show the words attached to this alias\n!alias <alias> <word> : link the word to the alias",
        "owner": "Usage : !owner password\nAdd the user in the owner list"
    }

    log = logging.getLogger('Pyborg')

    def __init__(self):
        """
        Open the dictionary. Resize as required.
        """
        self.settings = Settings({
            'aliases': Setting("A list of similar words", {}),
            'censored': Setting("Words that indicate not to learn the sentences in which they appear", []),
            'ignore_list': Setting("Words to ignore for the answer", ['!.', '?.', "'", ',', ';']),
            'learning': Setting("If True, the bot will learn new words", True),
            'max_words': Setting("Max number of words to learn", 6000),
            'max_word_length': Setting("Max number of characters a word can have to learn it", 13),
            'min_vowel_ratio': Setting("Min ratio of vowels to characters a word can have to learn it", 0.25),
            'protect': Setting("If True, don't overwrite the dictionary and configuration on disk", False),
            'process_with': Setting("Which library to generate replies with ('pyborg' or 'megahal')", "pyborg"),
        })
        self.settings.load('pyborg.cfg')

        self.answers = Settings({
            'sentences': Setting("A list of prepared answers", {}),
        })
        self.answers.load('answers.txt')

        self.unfilterd = {}

        # Read the dictionary
        if self.settings.process_with == "pyborg":
            self.brain = PyborgBrain(self.settings)
        elif self.settings.process_with == "megahal":
            self.brain = MegahalBrain(self.settings)
        else:
            raise ValueError("Unknown 'process_with' value {0}".format(self.settings.process_with))

        self.settings.save()

    def save_all(self):
        if self.settings.protect:
            return

        self.brain.save()

        sentence_list = sorted((sentence for sentence in self.unfilterd.iteritems()), key=lambda s: s[1])
        with open('sentences.txt', 'w') as sentence_file:
            for word, count in sentence_list:
                sentence_file.write(word)
                sentence_file.write('\n')

        self.settings.save()

    def process_msg(self, io_module, body, replyrate, learn, args, owner=False):
        """
        Process message 'body' and pass back to IO module with args.
        If owner, allow owner commands.
        """
        # add trailing space so sentences are broken up correctly
        body = body + " "

        # Parse commands
        if body.startswith('!'):
            self.do_commands(io_module, body, args, owner)
            return

        # Filter out garbage and do some formatting
        body = self.brain.filter_message(body)

        # Learn from input
        if learn == 1 and self.settings.learning:
            self.brain.learn(body)

        # Make a reply if desired
        if random.randint(0, 99) < replyrate:
            message = ""

            #Look if we can find a prepared answer
            for sentence in self.answers.sentences.keys():
                pattern = "^%s$" % sentence
                if re.search(pattern, body):
                    message = self.answers.sentences[sentence][random.randint(0, len(self.answers.sentences[sentence]) - 1)]
                    break
                else:
                    if body in self.unfilterd:
                        self.unfilterd[body] = self.unfilterd[body] + 1
                    else:
                        self.unfilterd[body] = 0

            if message == "":
                message = self.brain.reply(body)

            # single word reply: always output
            if len(message.split()) == 1:
                io_module.output(message, args)
                return
            # empty. do not output
            if message == "":
                return
            # else output
            if not owner:
                time.sleep(.2 * len(message))
            io_module.output(message, args)

    def do_commands(self, io_module, body, args, owner):
        """
        Respond to user comands.
        """
        command_list = body.split()
        command = command_list.pop(0).lstrip('!').lower()

        command_method = getattr(self, command, None)
        self.log.debug("What is command %r?", command)
        if command_method is None:
            self.log.debug("No such pyborg command %r. Is there a brain command %r?", command, command)
            command_method = getattr(self.brain, command, None)
        if command_method is None:
            self.log.debug("No such pyborg or brain command %r, doing nothing :(")
            return
        if not getattr(command_method, 'is_command', False):
            self.log.debug("Found requested method %r for command %r, but it's not a command, doing nothing :(",
                command_method, command)
            return
        if getattr(command_method, 'is_owner_command', False) and not owner:
            self.log.debug("Command %r is an owner command but requestor is not the owner, doing nothing :(", command)
            return

        self.log.debug("Yay, running command %r!", command)
        try:
            message = command_method(io_module, command_list, args)
        except Exception, exc:
            message = 'Oops, internal error :('
            self.log.exception('Internal error dispatching command %r', body)
        if message:
            io_module.output(message, args)