aichaos / rivescript-python

A RiveScript interpreter for Python. RiveScript is a scripting language for chatterbots.
https://www.rivescript.com
MIT License
158 stars 72 forks source link

trigger_info dosen't work. please help me. #120

Closed sucream closed 4 years ago

sucream commented 6 years ago

I used example code in ex3.py i use ver.1.14.9

#!/usr/bin/python3

# Python 3 example

from rivescript import RiveScript

rs = RiveScript()
rs.load_directory("./eg/brain")
rs.sort_replies()

while True:
    msg = input("You> ")
    if msg == '/quit':
        quit()
    reply = rs.reply("localuser", msg)
    trigger = rs.last_match("localuser")
    info = rs.trigger_info(trigger)
    print(trigger)
    print(info)
    print("Bot>", reply)

and this works like this.

You> hi
(hello|hi|hey|howdy|hola|hai|yo) [*]
None
Bot> How do you do. Please state your problem.
You>

So, My question is why trigger_info doen't work properly? Please answer me thanks.

kirsle commented 6 years ago

It seems this feature stopped working 2 years ago when I refactored the codebase.

I used to keep a self._syntax dict that kept track of the file names and line numbers of everything the parser parsed. When I refactored the code, I didn't put these lines back in.

trigger_info() searches through the _syntax object, but it's an empty dict() nowadays.

If you wanna fix it and send a pull request: put the lines back in to parser.py that update the self._syntax object, like the line I linked to above.

sucream commented 6 years ago

sorry, I don't know where should i change codes in parser.py. Can you explain to me more?

snoopyjc commented 4 years ago

I just ran into this same issue - grepping to no avail where self._syntax is set (and it isn't!)

snoopyjc commented 4 years ago

Here is my workaround (in my code, not in the rivescript code), which is probably faster because it uses a dict instead of a loop:

trigger_source = {}     # map from trigger to (filename, lineno)

def load_directory(directory, ext=None):  #"borrowed" from rivescript.py
    """Load RiveScript documents from a directory.

    :param str directory: The directory of RiveScript documents to load
    replies from.
    :param []str ext: List of file extensions to consider as RiveScript
    documents. The default is ``[".rive", ".rs"]``.
    """
    #self._say("Loading from directory: " + directory)

    if ext is None:
    # Use the default extensions - .rive is preferable.
    ext = ['.rive', '.rs']
    elif type(ext) == str:
    # Backwards compatibility for ext being a string value.
    ext = [ext]

    if not os.path.isdir(directory):
    #self._warn("Error: " + directory + " is not a directory.")
    return

    for root, subdirs, files in os.walk(directory):
    for file in files:
        for extension in ext:
        if file.lower().endswith(extension):
            # Load this file.
            #self.load_file(os.path.join(root, file))
            load_file(os.path.join(root, file))
            break

def load_file(filename):        
    global trigger_source
    with open(filename, 'r', encoding="utf-8") as f:
    lines = f.readlines()

    for lno, line in enumerate(lines, start=1):
    if line.startswith('+'):
        trigger = line.strip()[2:]
        if trigger not in trigger_source:       # First one wins
        trigger_source[trigger] = (filename, lno)

Then I call my own load_directory after called the rs one, then I use it like:

    if LOG_LAST_MATCH:      
        trigger = rs.last_match(attuid)
        #print(trigger)
        group = '_GRP' if from_group else ''
        u_type = 'SME' if attuid in SMEs else 'USR'
        # Issue: trigger_info doesn't work!!  https://github.com/aichaos/rivescript-python/issues/120
        #triggers = rs.trigger_info(trigger=trigger)
        #if triggers:
            #for trigger in triggers:
                #print(trigger)
                #logger.info(f'{u_type} {attuid}{group}:{trigger}')
        #else:
        fn_lno = ''
        if trigger in trigger_source:
            fn, lno = trigger_source[trigger]
            fn_lno = f' | {fn}:{lno}'
        logger.info(f'{u_type} {attuid}{group}:+ {trigger}{fn_lno}')
bicmane commented 4 years ago

In version 2.0.0 the trigger_info from the documentation doesn't work yet (it always returns null). And the example mentioned by the other user I don't understand how to apply it, the same with parser.py I can't understand it.

However, in the play.rivescript.com if I set the debug mode I can read the path of the trigger. How do I achieve that in my application in Python?

kirsle commented 4 years ago

Fixed in #144.