From 36560c9c3b414d24ecaff901dc766ade28fad228 Mon Sep 17 00:00:00 2001 From: Stavros Korokithakis Date: Tue, 11 Dec 2018 19:00:07 +0200 Subject: Add `order` argument and match continuation --- README.md | 24 ++++++++++++++++++++++-- signald/main.py | 18 +++++++++++++++--- 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 -- cgit v1.2.3-54-g00ecf