aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStavros Korokithakis <hi@stavros.io>2018-12-11 19:00:07 +0200
committerStavros Korokithakis <hi@stavros.io>2018-12-11 19:00:07 +0200
commit36560c9c3b414d24ecaff901dc766ade28fad228 (patch)
treeaf6338b30095272f5b02e54efd24ee924c235a72
parente4255041219e364e5ae7aa4d95085008f823e9fe (diff)
downloadpysignald-36560c9c3b414d24ecaff901dc766ade28fad228.tar.gz
pysignald-36560c9c3b414d24ecaff901dc766ade28fad228.zip
Add `order` argument and match continuation
-rw-r--r--README.md24
-rw-r--r--signald/main.py18
2 files changed, 37 insertions, 5 deletions
diff --git a/README.md b/README.md
index 4999174..3843409 100644
--- a/README.md
+++ b/README.md
@@ -46,9 +46,23 @@ from signald import Signal
s = Signal("+1234567890")
-@s.chat_handler("hello") # This is case-insensitive.
+@s.chat_handler("hello there", order=10) # This is case-insensitive.
+def hello_there(message, match):
+ # Returning `False` as the first argument will cause matching to continue
+ # after this handler runs.
+ stop = False
+ reply = "Hello there!"
+ return stop, reply
+
+
+# Matching is case-insensitive. The `order` argument signifies when
+# the handler will try to match (default is 100), and functions get sorted
+# by order of declaration secondly.
+@s.chat_handler("hello", order=10)
def hello(message, match):
- return "Hello there!"
+ # This will match on "hello there" as well because of the "stop" return code in
+ # the function above. Both replies will be sent.
+ return "Hello!"
@s.chat_handler(re.compile("my name is (.*)")) # This is case-sensitive.
@@ -56,6 +70,12 @@ def name(message, match):
return "Hello %s." % match.group(1)
+@s.chat_handler("")
+def catch_all(message, match):
+ # This will only be sent if nothing else matches, because matching
+ # stops by default on the first function that matches.
+ return "I don't know what you said."
+
s.run_chat()
```
diff --git a/signald/main.py b/signald/main.py
index da90d40..30231c7 100644
--- a/signald/main.py
+++ b/signald/main.py
@@ -141,7 +141,7 @@ class Signal:
payload = {"type": "send", "username": self.username, "recipientNumber": recipient, "messageBody": text}
self._send_command(payload, block)
- def chat_handler(self, regex):
+ def chat_handler(self, regex, order=100):
"""
A decorator that registers a chat handler function with a regex.
"""
@@ -149,7 +149,9 @@ class Signal:
regex = re.compile(regex, re.I)
def decorator(func):
- self._chat_handlers.append((regex, func))
+ self._chat_handlers.append((order, regex, func))
+ # Use only the first value to sort so that declaration order doesn't change.
+ self._chat_handlers.sort(key=lambda x: x[0])
return func
return decorator
@@ -162,7 +164,7 @@ class Signal:
if not message.text:
continue
- for regex, func in self._chat_handlers:
+ for _, regex, func in self._chat_handlers:
match = re.search(regex, message.text)
if not match:
continue
@@ -171,4 +173,14 @@ class Signal:
reply = func(message, match)
except: # noqa - We don't care why this failed.
continue
+
+ if isinstance(reply, tuple):
+ stop, reply = reply
+ else:
+ stop = True
+
self.send_message(recipient=message.source, text=reply)
+
+ if stop:
+ # We don't want to continue matching things.
+ break