Add room member count condition and default rule to make a noise on rooms of only 2 people.

This commit is contained in:
David Baker 2015-01-30 14:46:03 +00:00
parent 1251d017c1
commit 322a047502
3 changed files with 63 additions and 6 deletions

View File

@ -24,6 +24,7 @@ import baserules
import logging import logging
import fnmatch import fnmatch
import json import json
import re
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -34,6 +35,8 @@ class Pusher(object):
GIVE_UP_AFTER = 24 * 60 * 60 * 1000 GIVE_UP_AFTER = 24 * 60 * 60 * 1000
DEFAULT_ACTIONS = ['notify'] DEFAULT_ACTIONS = ['notify']
INEQUALITY_EXPR = re.compile("^([=<>]*)([0-9]*)$")
def __init__(self, _hs, instance_handle, user_name, app_id, def __init__(self, _hs, instance_handle, user_name, app_id,
app_display_name, device_display_name, pushkey, pushkey_ts, app_display_name, device_display_name, pushkey, pushkey_ts,
data, last_token, last_success, failing_since): data, last_token, last_success, failing_since):
@ -88,11 +91,21 @@ class Pusher(object):
member_events_for_room = yield self.store.get_current_state( member_events_for_room = yield self.store.get_current_state(
room_id=ev['room_id'], room_id=ev['room_id'],
event_type='m.room.member', event_type='m.room.member',
state_key=self.user_name state_key=None
) )
my_display_name = None my_display_name = None
if len(member_events_for_room) > 0: room_member_count = 0
my_display_name = member_events_for_room[0].content['displayname'] 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: for r in rules:
matches = True matches = True
@ -102,7 +115,8 @@ class Pusher(object):
for c in conditions: for c in conditions:
matches &= self._event_fulfills_condition( 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' # ignore rules with no actions (we have an explict 'dont_notify'
if len(actions) == 0: if len(actions) == 0:
@ -116,7 +130,7 @@ class Pusher(object):
defer.returnValue(Pusher.DEFAULT_ACTIONS) 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 condition['kind'] == 'event_match':
if 'pattern' not in condition: if 'pattern' not in condition:
logger.warn("event_match condition with no pattern") logger.warn("event_match condition with no pattern")
@ -138,9 +152,35 @@ class Pusher(object):
# the event stream. # the event stream.
if 'content' not in ev or 'body' not in ev['content']: if 'content' not in ev or 'body' not in ev['content']:
return False return False
if not display_name:
return False
return fnmatch.fnmatch( return fnmatch.fnmatch(
ev['content']['body'].upper(), "*%s*" % (display_name.upper(),) 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: else:
return True return True

View File

@ -32,4 +32,18 @@ def make_base_rules(user_name):
} }
] ]
}, },
{
'conditions': [
{
'kind': 'room_member_count',
'is': '2'
}
],
'actions': [
'notify',
{
'set_sound': 'default'
}
]
}
] ]

View File

@ -375,9 +375,12 @@ class DataStore(RoomMemberStore, RoomStore,
"redacted": del_sql, "redacted": del_sql,
} }
if event_type: if event_type and state_key is not None:
sql += " AND s.type = ? AND s.state_key = ? " sql += " AND s.type = ? AND s.state_key = ? "
args = (room_id, event_type, state_key) args = (room_id, event_type, state_key)
elif event_type:
sql += " AND s.type = ?"
args = (room_id, event_type)
else: else:
args = (room_id, ) args = (room_id, )