forked from MirrorHub/synapse
Add room member count condition and default rule to make a noise on rooms of only 2 people.
This commit is contained in:
parent
1251d017c1
commit
322a047502
3 changed files with 63 additions and 6 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,18 @@ def make_base_rules(user_name):
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'conditions': [
|
||||||
|
{
|
||||||
|
'kind': 'room_member_count',
|
||||||
|
'is': '2'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'actions': [
|
||||||
|
'notify',
|
||||||
|
{
|
||||||
|
'set_sound': 'default'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
|
@ -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, )
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue