summary refs log tree commit diff
path: root/synapse/push/__init__.py
diff options
context:
space:
mode:
authorDavid Baker <dave@matrix.org>2015-01-30 14:46:03 +0000
committerDavid Baker <dave@matrix.org>2015-01-30 14:46:45 +0000
commit322a047502c938bfe9a6acab47e370e69fefc522 (patch)
tree24f42d86ad2d47707a2417e7cfaabcf8482c0fc4 /synapse/push/__init__.py
parentMerge pull request #38 from matrix-org/new_state_resolution (diff)
downloadsynapse-322a047502c938bfe9a6acab47e370e69fefc522.tar.xz
Add room member count condition and default rule to make a noise on rooms of only 2 people.
Diffstat (limited to 'synapse/push/__init__.py')
-rw-r--r--synapse/push/__init__.py50
1 files changed, 45 insertions, 5 deletions
diff --git a/synapse/push/__init__.py b/synapse/push/__init__.py
index 19478c72a2..cc05278c8c 100644
--- a/synapse/push/__init__.py
+++ b/synapse/push/__init__.py
@@ -24,6 +24,7 @@ import baserules
 import logging
 import fnmatch
 import json
+import re
 
 logger = logging.getLogger(__name__)
 
@@ -34,6 +35,8 @@ class Pusher(object):
     GIVE_UP_AFTER = 24 * 60 * 60 * 1000
     DEFAULT_ACTIONS = ['notify']
 
+    INEQUALITY_EXPR = re.compile("^([=<>]*)([0-9]*)$")
+
     def __init__(self, _hs, instance_handle, user_name, app_id,
                  app_display_name, device_display_name, pushkey, pushkey_ts,
                  data, last_token, last_success, failing_since):
@@ -88,11 +91,21 @@ class Pusher(object):
         member_events_for_room = yield self.store.get_current_state(
             room_id=ev['room_id'],
             event_type='m.room.member',
-            state_key=self.user_name
+            state_key=None
         )
         my_display_name = None
-        if len(member_events_for_room) > 0:
-            my_display_name = member_events_for_room[0].content['displayname']
+        room_member_count = 0
+        for mev in member_events_for_room:
+            if mev.content['membership'] != 'join':
+                continue
+
+            # This loop does two things:
+            # 1) Find our current display name
+            if mev.state_key == self.user_name:
+                my_display_name = mev.content['displayname']
+
+            # and 2) Get the number of people in that room
+            room_member_count += 1
 
         for r in rules:
             matches = True
@@ -102,7 +115,8 @@ class Pusher(object):
 
             for c in conditions:
                 matches &= self._event_fulfills_condition(
-                    ev, c, display_name=my_display_name
+                    ev, c, display_name=my_display_name,
+                    room_member_count=room_member_count
                 )
             # ignore rules with no actions (we have an explict 'dont_notify'
             if len(actions) == 0:
@@ -116,7 +130,7 @@ class Pusher(object):
 
         defer.returnValue(Pusher.DEFAULT_ACTIONS)
 
-    def _event_fulfills_condition(self, ev, condition, display_name):
+    def _event_fulfills_condition(self, ev, condition, display_name, room_member_count):
         if condition['kind'] == 'event_match':
             if 'pattern' not in condition:
                 logger.warn("event_match condition with no pattern")
@@ -138,9 +152,35 @@ class Pusher(object):
             # the event stream.
             if 'content' not in ev or 'body' not in ev['content']:
                 return False
+            if not display_name:
+                return False
             return fnmatch.fnmatch(
                 ev['content']['body'].upper(), "*%s*" % (display_name.upper(),)
             )
+        elif condition['kind'] == 'room_member_count':
+            if 'is' not in condition:
+                return False
+            m = Pusher.INEQUALITY_EXPR.match(condition['is'])
+            if not m:
+                return False
+            ineq = m.group(1)
+            rhs = m.group(2)
+            if not rhs.isdigit():
+                return False
+            rhs = int(rhs)
+
+            if ineq == '' or ineq == '==':
+                return room_member_count == rhs
+            elif ineq == '<':
+                return room_member_count < rhs
+            elif ineq == '>':
+                return room_member_count > rhs
+            elif ineq == '>=':
+                return room_member_count >= rhs
+            elif ineq == '<=':
+                return room_member_count <= rhs
+            else:
+                return False
         else:
             return True