Exemplo n.º 1
0
 def __init__(self, path, user, write, *args, **kwargs):
     HALBot.__init__(self)
     #HALBot.__init__(self, path, user, write, *args, **kwargs)
     
     for file in glob(os.path.join(path, '*.hal')):
         if write:
             print 'Parsing File %s...'%file
         error = self.load(file)
         if error:
             print error.strip()
     
     self.wiki = HALwiki(os.path.join(os.path.split(path)[0], 'clean.chal'))
     self.data_folder = path
     self.debug_write = write
     self.vars = {}
 
     self._init_readable()
     self._init_remove()
Exemplo n.º 2
0
class HALintel(HALBot):
    junks = '!@#$%^()_~`./\\?,'
    regroups = re.compile(r'\\g<([1-9][0-9]*?)>')
    def __init__(self, path, user, write, *args, **kwargs):
        HALBot.__init__(self)
        #HALBot.__init__(self, path, user, write, *args, **kwargs)
        
        for file in glob(os.path.join(path, '*.hal')):
            if write:
                print 'Parsing File %s...'%file
            error = self.load(file)
            if error:
                print error.strip()
        
        self.wiki = HALwiki(os.path.join(os.path.split(path)[0], 'clean.chal'))
        self.data_folder = path
        self.debug_write = write
        self.vars = {}
    
        self._init_readable()
        self._init_remove()
    
    def load(self, file):
        return self.LoadFile(file)
    
    def _init_readable(self):
        self.readable = {}
        readable_subst_path = os.path.join(self.data_folder, 'readable.chal')
        if self.debug_write:
            print 'Reading', readable_subst_path, 'for computer readable substitution...'
        try:
            file = open(readable_subst_path)
        except IOError:
            print 'Failed to read', readable_subst_path, 'for Computer Readable Substitition!!!'
        else:
            for line in file:
                fields = line.strip('\n').split('\t')
                regex = re.compile(re.escape(fields[0]), re.IGNORECASE)
                self.readable[regex] = fields[1]
    
    def _init_remove(self):
        self.remove = []
        word_removal_path = os.path.join(self.data_folder, 'remove.chal')
        if self.debug_write:
            print 'Reading', word_removal_path, 'for word removal...'
        try:
            file = open(word_removal_path)
        except IOError:
            print 'Failed to read', word_removal_path, 'for word removal!!!'
        else:
            for line in file:
                regex = re.compile(r'\b'+re.escape(line.strip())+r'\b', re.IGNORECASE)
                self.remove.append(regex)
    
    def _readable(self, text):
        for regex, replacement in self.readable.iteritems():
            text = regex.sub(replacement, text)
        return text
    
    def _remove(self, text):
        for regex in self.remove:
            text = regex.sub('', text)
        return text
    
    def check(self, input):
        return True
    
    def pick_match(self, ques, array):
        diff = difflib.SequenceMatcher(a=ques.upper(), isjunk=lambda x: x in self.junks)
        sorted = []
        for possible in array:
            diff.set_seq2(possible[0].replace('\\', ''))
            match = diff.ratio()
            sorted.append((match,) + possible)
        best = max(sorted, key=lambda a: a[0])
        return best
    
    def pick_ans(self, ques, best):
        match, pattern, thinkset, answers, groups = best
        answers = [i.replace('^', r'\g<1>').replace('*', r'\g<1>') for i in answers]
        groups = [i.strip() for i in groups]
        filtered = []
        for answer in answers:
            ids = [int(i) for i in self.regroups.findall(answer)]
            is_ok = True
            for id in ids:
                if not (id < len(groups) and groups[id]):
                    is_ok = False
                    break
            if not is_ok:
                continue
            filtered.append(answer)
        answers = filtered
        if not answers:
            raise HALcannotHandle
        answer = random.choice(answers)
        return thinkset, answer, groups
    
    def subst_groups(self, ans, groups):
        # For <sset<>> to work
        groups = [i.replace('<', '').replace('>', '') for i in groups]
        return self.regroups.sub(lambda a: groups[int(a.group(1))], ans)
    
    def answer(self, question, recur=0):
        if recur > 3:
            return question
        #answers = []
        #answers.append(self.Ask(question))
        #answers.append(self.Ask(self._readable(question)))
        #answers.append(self.Ask(self._remove(question)))
        #answers.append(self.Ask(self._readable(self._remove(question))))
        #best, other = zip(*answers)
        #best  = reduce(lambda x, y: x+y, best)
        #other = reduce(lambda x, y: x+y, other)
        best, other = self.Ask(question)
        #print question, best, other
        if best:
            ans = self.pick_match(question, best)
            if ans[0] < 0.3:
                other.append(ans[1:])
            else:
                other = []
        if other:
            ans = self.pick_match(question, other)
        try:
            if not ans:
                raise HALcannotHandle
        except NameError:
            # ans not defined
            raise HALcannotHandle
        thinkset, answer, groups = self.pick_ans(question, ans)
        answer = self.subst_groups(answer, groups)
        if not answer:
            raise HALcannotHandle
        if '|' in answer:
            parts = [part.strip() for part in answer.split('|')]
            for index, part in enumerate(parts):
                #print part
                if part and part[0] == '>':
                    parts[index] = self.answer(answer[1:], recur=recur+1)
            answer = ' '.join(parts)
        if answer[0] == '>':
            answer = self.answer(answer[1:], recur=recur+1)
        if '$HALWIKI$' in answer:
            return self.wiki.getwiki(question)
        return self.clean_answer(answer)
    
    reget = re.compile(r'get\(([A-Za-z_][A-Za-z0-9_]*)\)')
    resset = re.compile(r'sset\((?:\[((?:[A-Za-z_][A-Za-z0-9_]*,?)+)\]|([A-Za-z_][A-Za-z0-9_]*)),(.*?)\)')
    reslient = re.compile(r'<[Ss].*?>')
    def clean_answer(self, answer):
        # <get<>>
        answer = self.reget.sub(string=answer, repl=lambda m: self.vars.get(m.group(1), ''))
        # <sset<><>>
        def sset(m):
            names = m.group(1)
            if names is None:
                names = m.group(2)
            names = [i.strip() for i in names.split(',')]
            value = m.group(3).strip()
            for name in names:
                self.vars[name] = value
            return value
        answer = self.resset.sub(sset, answer)
        answer = self.reslient.sub('', answer)
        return answer