Use static for const dicts

This commit is contained in:
Erik Johnston 2016-01-18 10:09:14 +00:00
parent 0e39dcd135
commit d1f56f732e
4 changed files with 209 additions and 198 deletions

View file

@ -15,27 +15,25 @@
from synapse.push.rulekinds import PRIORITY_CLASS_MAP, PRIORITY_CLASS_INVERSE_MAP from synapse.push.rulekinds import PRIORITY_CLASS_MAP, PRIORITY_CLASS_INVERSE_MAP
def list_with_base_rules(rawrules, user_id): def list_with_base_rules(rawrules):
ruleslist = [] ruleslist = []
# shove the server default rules for each kind onto the end of each # shove the server default rules for each kind onto the end of each
current_prio_class = PRIORITY_CLASS_INVERSE_MAP.keys()[-1] current_prio_class = PRIORITY_CLASS_INVERSE_MAP.keys()[-1]
ruleslist.extend(make_base_prepend_rules( ruleslist.extend(make_base_prepend_rules(
user_id, PRIORITY_CLASS_INVERSE_MAP[current_prio_class] PRIORITY_CLASS_INVERSE_MAP[current_prio_class]
)) ))
for r in rawrules: for r in rawrules:
if r['priority_class'] < current_prio_class: if r['priority_class'] < current_prio_class:
while r['priority_class'] < current_prio_class: while r['priority_class'] < current_prio_class:
ruleslist.extend(make_base_append_rules( ruleslist.extend(make_base_append_rules(
user_id,
PRIORITY_CLASS_INVERSE_MAP[current_prio_class] PRIORITY_CLASS_INVERSE_MAP[current_prio_class]
)) ))
current_prio_class -= 1 current_prio_class -= 1
if current_prio_class > 0: if current_prio_class > 0:
ruleslist.extend(make_base_prepend_rules( ruleslist.extend(make_base_prepend_rules(
user_id,
PRIORITY_CLASS_INVERSE_MAP[current_prio_class] PRIORITY_CLASS_INVERSE_MAP[current_prio_class]
)) ))
@ -43,28 +41,26 @@ def list_with_base_rules(rawrules, user_id):
while current_prio_class > 0: while current_prio_class > 0:
ruleslist.extend(make_base_append_rules( ruleslist.extend(make_base_append_rules(
user_id,
PRIORITY_CLASS_INVERSE_MAP[current_prio_class] PRIORITY_CLASS_INVERSE_MAP[current_prio_class]
)) ))
current_prio_class -= 1 current_prio_class -= 1
if current_prio_class > 0: if current_prio_class > 0:
ruleslist.extend(make_base_prepend_rules( ruleslist.extend(make_base_prepend_rules(
user_id,
PRIORITY_CLASS_INVERSE_MAP[current_prio_class] PRIORITY_CLASS_INVERSE_MAP[current_prio_class]
)) ))
return ruleslist return ruleslist
def make_base_append_rules(user, kind): def make_base_append_rules(kind):
rules = [] rules = []
if kind == 'override': if kind == 'override':
rules = make_base_append_override_rules() rules = BASE_APPEND_OVRRIDE_RULES
elif kind == 'underride': elif kind == 'underride':
rules = make_base_append_underride_rules(user) rules = BASE_APPEND_UNDERRIDE_RULES
elif kind == 'content': elif kind == 'content':
rules = make_base_append_content_rules(user) rules = BASE_APPEND_CONTENT_RULES
for r in rules: for r in rules:
r['priority_class'] = PRIORITY_CLASS_MAP[kind] r['priority_class'] = PRIORITY_CLASS_MAP[kind]
@ -73,11 +69,11 @@ def make_base_append_rules(user, kind):
return rules return rules
def make_base_prepend_rules(user, kind): def make_base_prepend_rules(kind):
rules = [] rules = []
if kind == 'override': if kind == 'override':
rules = make_base_prepend_override_rules() rules = BASE_PREPEND_OVERRIDE_RULES
for r in rules: for r in rules:
r['priority_class'] = PRIORITY_CLASS_MAP[kind] r['priority_class'] = PRIORITY_CLASS_MAP[kind]
@ -86,180 +82,182 @@ def make_base_prepend_rules(user, kind):
return rules return rules
def make_base_append_content_rules(user): BASE_APPEND_CONTENT_RULES = [
return [ {
{ 'rule_id': 'global/content/.m.rule.contains_user_name',
'rule_id': 'global/content/.m.rule.contains_user_name', 'conditions': [
'conditions': [ {
{ 'kind': 'event_match',
'kind': 'event_match', 'key': 'content.body',
'key': 'content.body', 'pattern_type': 'user_localpart'
'pattern': user.localpart, # Matrix ID match }
} ],
], 'actions': [
'actions': [ 'notify',
'notify', {
{ 'set_tweak': 'sound',
'set_tweak': 'sound', 'value': 'default',
'value': 'default', }, {
}, { 'set_tweak': 'highlight'
'set_tweak': 'highlight' }
} ]
] },
}, ]
]
def make_base_prepend_override_rules(): BASE_PREPEND_OVERRIDE_RULES = [
return [ {
{ 'rule_id': 'global/override/.m.rule.master',
'rule_id': 'global/override/.m.rule.master', 'enabled': False,
'enabled': False, 'conditions': [],
'conditions': [], 'actions': [
'actions': [ "dont_notify"
"dont_notify" ]
] }
} ]
]
def make_base_append_override_rules(): BASE_APPEND_OVRRIDE_RULES = [
return [ {
{ 'rule_id': 'global/override/.m.rule.suppress_notices',
'rule_id': 'global/override/.m.rule.suppress_notices', 'conditions': [
'conditions': [ {
{ 'kind': 'event_match',
'kind': 'event_match', 'key': 'content.msgtype',
'key': 'content.msgtype', 'pattern': 'm.notice',
'pattern': 'm.notice', '_id': '_suppress_notices',
} }
], ],
'actions': [ 'actions': [
'dont_notify', 'dont_notify',
] ]
} }
] ]
def make_base_append_underride_rules(user): BASE_APPEND_UNDERRIDE_RULES = [
return [ {
{ 'rule_id': 'global/underride/.m.rule.call',
'rule_id': 'global/underride/.m.rule.call', 'conditions': [
'conditions': [ {
{ 'kind': 'event_match',
'kind': 'event_match', 'key': 'type',
'key': 'type', 'pattern': 'm.call.invite',
'pattern': 'm.call.invite', '_id': '_call',
} }
], ],
'actions': [ 'actions': [
'notify', 'notify',
{ {
'set_tweak': 'sound', 'set_tweak': 'sound',
'value': 'ring' 'value': 'ring'
}, { }, {
'set_tweak': 'highlight', 'set_tweak': 'highlight',
'value': False 'value': False
} }
] ]
}, },
{ {
'rule_id': 'global/underride/.m.rule.contains_display_name', 'rule_id': 'global/underride/.m.rule.contains_display_name',
'conditions': [ 'conditions': [
{ {
'kind': 'contains_display_name' 'kind': 'contains_display_name'
} }
], ],
'actions': [ 'actions': [
'notify', 'notify',
{ {
'set_tweak': 'sound', 'set_tweak': 'sound',
'value': 'default' 'value': 'default'
}, { }, {
'set_tweak': 'highlight' 'set_tweak': 'highlight'
} }
] ]
}, },
{ {
'rule_id': 'global/underride/.m.rule.room_one_to_one', 'rule_id': 'global/underride/.m.rule.room_one_to_one',
'conditions': [ 'conditions': [
{ {
'kind': 'room_member_count', 'kind': 'room_member_count',
'is': '2' 'is': '2'
} }
], ],
'actions': [ 'actions': [
'notify', 'notify',
{ {
'set_tweak': 'sound', 'set_tweak': 'sound',
'value': 'default' 'value': 'default'
}, { }, {
'set_tweak': 'highlight', 'set_tweak': 'highlight',
'value': False 'value': False
} }
] ]
}, },
{ {
'rule_id': 'global/underride/.m.rule.invite_for_me', 'rule_id': 'global/underride/.m.rule.invite_for_me',
'conditions': [ 'conditions': [
{ {
'kind': 'event_match', 'kind': 'event_match',
'key': 'type', 'key': 'type',
'pattern': 'm.room.member', 'pattern': 'm.room.member',
}, '_id': '_invite_type',
{ },
'kind': 'event_match', {
'key': 'content.membership', 'kind': 'event_match',
'pattern': 'invite', 'key': 'content.membership',
}, 'pattern': 'invite',
{ '_id': '_invite_member',
'kind': 'event_match', },
'key': 'state_key', {
'pattern': user.to_string(), 'kind': 'event_match',
}, 'key': 'state_key',
], 'pattern_type': 'user_id'
'actions': [ },
'notify', ],
{ 'actions': [
'set_tweak': 'sound', 'notify',
'value': 'default' {
}, { 'set_tweak': 'sound',
'set_tweak': 'highlight', 'value': 'default'
'value': False }, {
} 'set_tweak': 'highlight',
] 'value': False
}, }
{ ]
'rule_id': 'global/underride/.m.rule.member_event', },
'conditions': [ {
{ 'rule_id': 'global/underride/.m.rule.member_event',
'kind': 'event_match', 'conditions': [
'key': 'type', {
'pattern': 'm.room.member', 'kind': 'event_match',
} 'key': 'type',
], 'pattern': 'm.room.member',
'actions': [ '_id': '_member',
'notify', { }
'set_tweak': 'highlight', ],
'value': False 'actions': [
} 'notify', {
] 'set_tweak': 'highlight',
}, 'value': False
{ }
'rule_id': 'global/underride/.m.rule.message', ]
'enabled': False, },
'conditions': [ {
{ 'rule_id': 'global/underride/.m.rule.message',
'kind': 'event_match', 'enabled': False,
'key': 'type', 'conditions': [
'pattern': 'm.room.message', {
} 'kind': 'event_match',
], 'key': 'type',
'actions': [ 'pattern': 'm.room.message',
'notify', { '_id': '_message',
'set_tweak': 'highlight', }
'value': False ],
} 'actions': [
] 'notify', {
} 'set_tweak': 'highlight',
] 'value': False
}
]
}
]

View file

@ -22,7 +22,6 @@ import baserules
from push_rule_evaluator import PushRuleEvaluatorForEvent from push_rule_evaluator import PushRuleEvaluatorForEvent
from synapse.api.constants import EventTypes from synapse.api.constants import EventTypes
from synapse.types import UserID
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -38,10 +37,10 @@ def decode_rule_json(rule):
def _get_rules(room_id, user_ids, store): def _get_rules(room_id, user_ids, store):
rules_by_user = yield store.bulk_get_push_rules(user_ids) rules_by_user = yield store.bulk_get_push_rules(user_ids)
rules_by_user = { rules_by_user = {
uid: baserules.list_with_base_rules( uid: baserules.list_with_base_rules([
[decode_rule_json(rule_list) for rule_list in rules_by_user.get(uid, [])], decode_rule_json(rule_list)
UserID.from_string(uid), for rule_list in rules_by_user.get(uid, [])
) ])
for uid in user_ids for uid in user_ids
} }
defer.returnValue(rules_by_user) defer.returnValue(rules_by_user)
@ -108,7 +107,7 @@ class BulkPushRuleEvaluator:
continue continue
matches = _condition_checker( matches = _condition_checker(
evaluator, rule['conditions'], display_name, condition_cache evaluator, rule['conditions'], uid, display_name, condition_cache
) )
if matches: if matches:
actions = [x for x in rule['actions'] if x != 'dont_notify'] actions = [x for x in rule['actions'] if x != 'dont_notify']
@ -118,7 +117,7 @@ class BulkPushRuleEvaluator:
defer.returnValue(actions_by_user) defer.returnValue(actions_by_user)
def _condition_checker(evaluator, conditions, display_name, cache): def _condition_checker(evaluator, conditions, uid, display_name, cache):
for cond in conditions: for cond in conditions:
_id = cond.get("_id", None) _id = cond.get("_id", None)
if _id: if _id:
@ -128,7 +127,7 @@ def _condition_checker(evaluator, conditions, display_name, cache):
elif res is True: elif res is True:
continue continue
res = evaluator.matches(cond, display_name, None) res = evaluator.matches(cond, uid, display_name, None)
if _id: if _id:
cache[_id] = res cache[_id] = res

View file

@ -91,8 +91,7 @@ class PushRuleEvaluator:
rule['actions'] = json.loads(raw_rule['actions']) rule['actions'] = json.loads(raw_rule['actions'])
rules.append(rule) rules.append(rule)
user = UserID.from_string(self.user_id) self.rules = baserules.list_with_base_rules(rules)
self.rules = baserules.list_with_base_rules(rules, user)
self.enabled_map = enabled_map self.enabled_map = enabled_map
@ -150,7 +149,9 @@ class PushRuleEvaluator:
matches = True matches = True
for c in conditions: for c in conditions:
matches = evaluator.matches(c, my_display_name, self.profile_tag) matches = evaluator.matches(
c, self.user_id, my_display_name, self.profile_tag
)
if not matches: if not matches:
break break
@ -201,9 +202,9 @@ class PushRuleEvaluatorForEvent(object):
return PushRuleEvaluatorForEvent(event, body_parts, room_member_count) return PushRuleEvaluatorForEvent(event, body_parts, room_member_count)
def matches(self, condition, display_name, profile_tag): def matches(self, condition, user_id, display_name, profile_tag):
if condition['kind'] == 'event_match': if condition['kind'] == 'event_match':
return self._event_match(condition) return self._event_match(condition, user_id)
elif condition['kind'] == 'device': elif condition['kind'] == 'device':
if 'profile_tag' not in condition: if 'profile_tag' not in condition:
return True return True
@ -217,9 +218,16 @@ class PushRuleEvaluatorForEvent(object):
else: else:
return True return True
def _event_match(self, condition): def _event_match(self, condition, user_id):
pattern = condition.get('pattern', None) pattern = condition.get('pattern', None)
if not pattern:
pattern_type = condition.get('pattern_type', None)
if pattern_type == "user_id":
pattern = user_id
elif pattern_type == "user_localpart":
pattern = UserID.from_string(user_id).localpart
if not pattern: if not pattern:
logger.warn("event_match condition with no pattern") logger.warn("event_match condition with no pattern")
return False return False

View file

@ -126,7 +126,7 @@ class PushRuleRestServlet(ClientV1RestServlet):
rule["actions"] = json.loads(rawrule["actions"]) rule["actions"] = json.loads(rawrule["actions"])
ruleslist.append(rule) ruleslist.append(rule)
ruleslist = baserules.list_with_base_rules(ruleslist, user) ruleslist = baserules.list_with_base_rules(ruleslist)
rules = {'global': {}, 'device': {}} rules = {'global': {}, 'device': {}}
@ -144,6 +144,12 @@ class PushRuleRestServlet(ClientV1RestServlet):
for c in r["conditions"]: for c in r["conditions"]:
c.pop("_id", None) c.pop("_id", None)
pattern_type = c.pop("pattern_type", None)
if pattern_type == "user_id":
c["pattern"] = user.to_string()
elif pattern_type == "user_localpart":
c["pattern"] = user.localpart
if r['priority_class'] > PRIORITY_CLASS_MAP['override']: if r['priority_class'] > PRIORITY_CLASS_MAP['override']:
# per-device rule # per-device rule
profile_tag = _profile_tag_from_conditions(r["conditions"]) profile_tag = _profile_tag_from_conditions(r["conditions"])