-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32 from aichaos/feature/session-handler
Session Handler and Developer Friendly Parser
- Loading branch information
Showing
27 changed files
with
1,756 additions
and
947 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
__pycache__ | ||
*.pyc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,5 +16,5 @@ | |
|
||
> object shutdown python | ||
# Shut down | ||
exit(0) | ||
quit() | ||
< object |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
# RiveScript Parser Example | ||
|
||
The RiveScript parser was broken out into its own stand-alone module usable by | ||
third party developers, and this is an example of how to use it. | ||
|
||
The bare minimum code to use the RiveScript parser are as follows: | ||
|
||
```python | ||
from rivescript.parser import Parser | ||
|
||
# Instantiate it. | ||
p = Parser() | ||
|
||
# And parse some RiveScript code! | ||
ast = p.parse("any-file-name.rive", [ | ||
"+ hello bot", | ||
"- Hello human!", | ||
]) | ||
``` | ||
|
||
The `Parser.parse()` function requires a file name (used only for syntax | ||
reporting purposes) and an array of lines of source code to parse. | ||
|
||
## Running the Example | ||
|
||
```bash | ||
# Simply run it! It will parse and dump ../brain/clients.rive by default. | ||
% python parse.py | ||
|
||
# Or give it the name of a different RiveScript file. | ||
% python parse.py ../brain/eliza.rive | ||
|
||
# Or enable debug logging. | ||
% env PARSER_DEBUG=1 python parse.py ../brain/begin.rive | ||
|
||
# (For the Windows/Command Prompt users) | ||
> set PARSER_DEBUG=1 | ||
> python parse.py ../brain/myself.rive | ||
``` | ||
|
||
The parse script will parse the RiveScript file given on the command line, | ||
and dump its "abstract syntax tree" as JSON to the standard output so you can | ||
see what the data structure looks like. | ||
|
||
Check the source code of `parse.py` for the details. The environment variable | ||
`PARSER_DEBUG` is something the example script uses, not the underlying | ||
`rivescript.parser` module; debugging is made possible by using the `on_debug` | ||
and `on_warn` arguments to the Parser constructor. | ||
|
||
## Example Output | ||
|
||
`python parse.py ../brain/admin.rive` | ||
|
||
```json | ||
{ | ||
"begin": { | ||
"array": {}, | ||
"global": {}, | ||
"person": {}, | ||
"sub": {}, | ||
"var": {} | ||
}, | ||
"objects": [ | ||
{ | ||
"code": [ | ||
"\tmy ($rs) = @_;\n", | ||
"\t# Shut down.\n", | ||
"\texit(0);\n" | ||
], | ||
"language": "perl", | ||
"name": "shutdown" | ||
}, | ||
{ | ||
"code": [ | ||
"\t# Shut down\n", | ||
"\tquit()\n" | ||
], | ||
"language": "python", | ||
"name": "shutdown" | ||
} | ||
], | ||
"topics": { | ||
"random": { | ||
"includes": {}, | ||
"inherits": {}, | ||
"triggers": [ | ||
{ | ||
"condition": [ | ||
"<id> eq <bot master> => Shutting down... <call>shutdown</call>" | ||
], | ||
"previous": null, | ||
"redirect": null, | ||
"reply": [ | ||
"{@botmaster only}" | ||
], | ||
"trigger": "shutdown{weight=10000}" | ||
}, | ||
{ | ||
"condition": [], | ||
"previous": null, | ||
"redirect": null, | ||
"reply": [ | ||
"This command can only be used by my botmaster. <id> != <bot master>" | ||
], | ||
"trigger": "botmaster only" | ||
} | ||
] | ||
} | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#!/usr/bin/env python | ||
|
||
from __future__ import print_function | ||
import codecs | ||
import os | ||
import json | ||
import sys | ||
from rivescript.parser import Parser | ||
|
||
"""Example use of the RiveScript Parser module. | ||
Usage: python parse.py [path/to/file.rive] | ||
By default it will parse ../brain/clients.rive but you can pass it any | ||
RiveScript file you want. | ||
""" | ||
|
||
def main(): | ||
# Get the command line argument. | ||
filename = "../brain/clients.rive" | ||
if len(sys.argv) > 1: | ||
filename = sys.argv[1] | ||
|
||
# Make sure it's really a file. | ||
if not os.path.isfile(filename): | ||
print("{}: Not a file.".format(filename)) | ||
sys.exit(1) | ||
|
||
# Make sure it looks like a RiveScript file. | ||
if not filename.lower().endswith(".rive"): | ||
print("{}: Doesn't look like a RiveScript file (no .rive extension)") | ||
sys.exit(1) | ||
|
||
# Create a parser instance. | ||
if os.environ.get("PARSER_DEBUG"): | ||
parser = Parser( | ||
on_debug=on_debug, | ||
on_warn=on_warn, | ||
) | ||
else: | ||
parser = Parser() | ||
|
||
# Read the file's contents. | ||
with codecs.open(filename, "r", "utf-8") as fh: | ||
source = fh.readlines() | ||
|
||
# Create a parser and parse it. | ||
ast = parser.parse(filename, source) | ||
|
||
# Dump the "Abstract Syntax Tree" to the console as JSON. | ||
print(json.dumps(ast, indent=2, sort_keys=True)) | ||
|
||
def on_debug(message): | ||
print("[DEBUG]", message) | ||
|
||
def on_warn(message, filename=None, lineno=None): | ||
if filename is not None and lineno is not None: | ||
print("[WARN]", message, "at", filename, "line", lineno) | ||
else: | ||
print("[WARN]", message) | ||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# Session Storage Example | ||
|
||
By default RiveScript stores all user variables and state in memory, with no | ||
automatic persistence to disk when the bot exits and restarts. RiveScript does | ||
provide functions to export and import user variables in bulk so that you can | ||
manually store and reload data, but an alternative is to use a third party | ||
session storage driver. | ||
|
||
The example bot at `redis-bot.py` uses a [Redis cache](http://redis.io/) to | ||
store user variables. To run the example you'll need to install and start a | ||
Redis server. | ||
|
||
## Setup | ||
|
||
```bash | ||
### | ||
# 1. Install Redis | ||
### | ||
|
||
# Fedora users: | ||
sudo dnf install redis | ||
|
||
# RHEL and CentOS <= 7 | ||
sudo yum install redis | ||
|
||
# Debian/Ubuntu | ||
sudo apt-get install redis-server | ||
|
||
### | ||
# 2. Start the Redis server | ||
### | ||
|
||
# Either do this to start it in a terminal window: | ||
redis-server | ||
|
||
# Or enable/start it with systemd. | ||
sudo systemctl enable redis.service | ||
sudo systemctl start redis.service | ||
|
||
### | ||
# 3. Run this example bot. | ||
### | ||
|
||
pip install -r requirements.txt | ||
python redis_bot.py | ||
``` | ||
|
||
## Example Output | ||
|
||
``` | ||
% python redis_bot.py | ||
RiveScript Redis Session Storage Example | ||
This example uses a Redis server to store user variables. For the sake of the | ||
example, choose a username to store your variables under. You can re-run this | ||
script with the same username (or a different one!) and verify that your | ||
variables are kept around! | ||
Type '/quit' to quit. | ||
What is your username? kirsle | ||
You> Hello bot. | ||
Bot> How do you do. Please state your problem. | ||
You> My name is Noah. | ||
Bot> Noah, nice to meet you. | ||
You> Who am I? | ||
Bot> You told me your name is Noah. | ||
You> /quit | ||
% python redis_bot.py | ||
RiveScript Redis Session Storage Example | ||
This example uses a Redis server to store user variables. For the sake of the | ||
example, choose a username to store your variables under. You can re-run this | ||
script with the same username (or a different one!) and verify that your | ||
variables are kept around! | ||
Type '/quit' to quit. | ||
What is your username? kirsle | ||
You> What's my name? | ||
Bot> Your name is Noah. | ||
You> /quit | ||
``` | ||
|
||
And the Redis cache can be verified via the `redis-cli` command: | ||
|
||
``` | ||
% redis-cli | ||
127.0.0.1:6379> keys * | ||
1) "rs-users/kirsle" | ||
127.0.0.1:6379> get rs-users/kirsle | ||
...redacted large JSON blob... | ||
``` |
Oops, something went wrong.