mirror of
https://github.com/element-hq/synapse
synced 2024-08-18 20:20:52 +00:00
Implement new experimental push rules with a database hack to enable them
This commit is contained in:
parent
923c995023
commit
9725c59247
3 changed files with 259 additions and 14 deletions
|
@ -19,7 +19,7 @@ import copy
|
||||||
from synapse.push.rulekinds import PRIORITY_CLASS_INVERSE_MAP, PRIORITY_CLASS_MAP
|
from synapse.push.rulekinds import PRIORITY_CLASS_INVERSE_MAP, PRIORITY_CLASS_MAP
|
||||||
|
|
||||||
|
|
||||||
def list_with_base_rules(rawrules):
|
def list_with_base_rules(rawrules, use_new_defaults=False):
|
||||||
"""Combine the list of rules set by the user with the default push rules
|
"""Combine the list of rules set by the user with the default push rules
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -43,7 +43,9 @@ def list_with_base_rules(rawrules):
|
||||||
|
|
||||||
ruleslist.extend(
|
ruleslist.extend(
|
||||||
make_base_prepend_rules(
|
make_base_prepend_rules(
|
||||||
PRIORITY_CLASS_INVERSE_MAP[current_prio_class], modified_base_rules
|
PRIORITY_CLASS_INVERSE_MAP[current_prio_class],
|
||||||
|
modified_base_rules,
|
||||||
|
use_new_defaults,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -54,6 +56,7 @@ def list_with_base_rules(rawrules):
|
||||||
make_base_append_rules(
|
make_base_append_rules(
|
||||||
PRIORITY_CLASS_INVERSE_MAP[current_prio_class],
|
PRIORITY_CLASS_INVERSE_MAP[current_prio_class],
|
||||||
modified_base_rules,
|
modified_base_rules,
|
||||||
|
use_new_defaults,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
current_prio_class -= 1
|
current_prio_class -= 1
|
||||||
|
@ -62,6 +65,7 @@ def list_with_base_rules(rawrules):
|
||||||
make_base_prepend_rules(
|
make_base_prepend_rules(
|
||||||
PRIORITY_CLASS_INVERSE_MAP[current_prio_class],
|
PRIORITY_CLASS_INVERSE_MAP[current_prio_class],
|
||||||
modified_base_rules,
|
modified_base_rules,
|
||||||
|
use_new_defaults,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -70,27 +74,31 @@ def list_with_base_rules(rawrules):
|
||||||
while current_prio_class > 0:
|
while current_prio_class > 0:
|
||||||
ruleslist.extend(
|
ruleslist.extend(
|
||||||
make_base_append_rules(
|
make_base_append_rules(
|
||||||
PRIORITY_CLASS_INVERSE_MAP[current_prio_class], modified_base_rules
|
PRIORITY_CLASS_INVERSE_MAP[current_prio_class],
|
||||||
|
modified_base_rules,
|
||||||
|
use_new_defaults,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
current_prio_class -= 1
|
current_prio_class -= 1
|
||||||
if current_prio_class > 0:
|
if current_prio_class > 0:
|
||||||
ruleslist.extend(
|
ruleslist.extend(
|
||||||
make_base_prepend_rules(
|
make_base_prepend_rules(
|
||||||
PRIORITY_CLASS_INVERSE_MAP[current_prio_class], modified_base_rules
|
PRIORITY_CLASS_INVERSE_MAP[current_prio_class],
|
||||||
|
modified_base_rules,
|
||||||
|
use_new_defaults,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return ruleslist
|
return ruleslist
|
||||||
|
|
||||||
|
|
||||||
def make_base_append_rules(kind, modified_base_rules):
|
def make_base_append_rules(kind, modified_base_rules, use_new_defaults=False):
|
||||||
rules = []
|
rules = []
|
||||||
|
|
||||||
if kind == "override":
|
if kind == "override":
|
||||||
rules = BASE_APPEND_OVERRIDE_RULES
|
rules = NEW_APPEND_OVERRIDE_RULES if use_new_defaults else BASE_APPEND_OVERRIDE_RULES
|
||||||
elif kind == "underride":
|
elif kind == "underride":
|
||||||
rules = BASE_APPEND_UNDERRIDE_RULES
|
rules = NEW_APPEND_UNDERRIDE_RULES if use_new_defaults else BASE_APPEND_UNDERRIDE_RULES
|
||||||
elif kind == "content":
|
elif kind == "content":
|
||||||
rules = BASE_APPEND_CONTENT_RULES
|
rules = BASE_APPEND_CONTENT_RULES
|
||||||
|
|
||||||
|
@ -105,11 +113,11 @@ def make_base_append_rules(kind, modified_base_rules):
|
||||||
return rules
|
return rules
|
||||||
|
|
||||||
|
|
||||||
def make_base_prepend_rules(kind, modified_base_rules):
|
def make_base_prepend_rules(kind, modified_base_rules, use_new_defaults=False):
|
||||||
rules = []
|
rules = []
|
||||||
|
|
||||||
if kind == "override":
|
if kind == "override":
|
||||||
rules = BASE_PREPEND_OVERRIDE_RULES
|
rules = NEW_PREPEND_OVERRIDE_RULES if use_new_defaults else BASE_PREPEND_OVERRIDE_RULES
|
||||||
|
|
||||||
# Copy the rules before modifying them
|
# Copy the rules before modifying them
|
||||||
rules = copy.deepcopy(rules)
|
rules = copy.deepcopy(rules)
|
||||||
|
@ -151,6 +159,16 @@ BASE_PREPEND_OVERRIDE_RULES = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
NEW_PREPEND_OVERRIDE_RULES = [
|
||||||
|
{
|
||||||
|
"rule_id": "global/override/.m.rule.master",
|
||||||
|
"enabled": False,
|
||||||
|
"conditions": [],
|
||||||
|
"actions": [],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
BASE_APPEND_OVERRIDE_RULES = [
|
BASE_APPEND_OVERRIDE_RULES = [
|
||||||
{
|
{
|
||||||
"rule_id": "global/override/.m.rule.suppress_notices",
|
"rule_id": "global/override/.m.rule.suppress_notices",
|
||||||
|
@ -270,6 +288,141 @@ BASE_APPEND_OVERRIDE_RULES = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
NEW_APPEND_OVERRIDE_RULES = [
|
||||||
|
{
|
||||||
|
"rule_id": "global/override/.m.rule.encrypted",
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"kind": "event_match",
|
||||||
|
"key": "type",
|
||||||
|
"pattern": "m.room.encrypted",
|
||||||
|
"_id": "_encrypted",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actions": ["notify"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "global/override/.m.rule.suppress_notices",
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"kind": "event_match",
|
||||||
|
"key": "type",
|
||||||
|
"pattern": "m.room.message",
|
||||||
|
"_id": "_suppress_notices_type",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "event_match",
|
||||||
|
"key": "content.msgtype",
|
||||||
|
"pattern": "m.notice",
|
||||||
|
"_id": "_suppress_notices",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actions": [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "global/underride/.m.rule.suppress_edits",
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"kind": "event_match",
|
||||||
|
"key": "m.relates_to.m.rel_type",
|
||||||
|
"pattern": "m.replace",
|
||||||
|
"_id": "_suppress_edits",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actions": [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "global/override/.m.rule.invite_for_me",
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"kind": "event_match",
|
||||||
|
"key": "type",
|
||||||
|
"pattern": "m.room.member",
|
||||||
|
"_id": "_member",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "event_match",
|
||||||
|
"key": "content.membership",
|
||||||
|
"pattern": "invite",
|
||||||
|
"_id": "_invite_member",
|
||||||
|
},
|
||||||
|
{"kind": "event_match", "key": "state_key", "pattern_type": "user_id"},
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "sound", "value": "default"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "global/override/.m.rule.contains_display_name",
|
||||||
|
"conditions": [{"kind": "contains_display_name"}],
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "sound", "value": "default"},
|
||||||
|
{"set_tweak": "highlight"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "global/override/.m.rule.tombstone",
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"kind": "event_match",
|
||||||
|
"key": "type",
|
||||||
|
"pattern": "m.room.tombstone",
|
||||||
|
"_id": "_tombstone",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "event_match",
|
||||||
|
"key": "state_key",
|
||||||
|
"pattern": "",
|
||||||
|
"_id": "_tombstone_statekey",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "sound", "value": "default"},
|
||||||
|
{"set_tweak": "highlight"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "global/override/.m.rule.roomnotif",
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"kind": "event_match",
|
||||||
|
"key": "content.body",
|
||||||
|
"pattern": "@room",
|
||||||
|
"_id": "_roomnotif_content",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "sender_notification_permission",
|
||||||
|
"key": "room",
|
||||||
|
"_id": "_roomnotif_pl",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "highlight"},
|
||||||
|
{"set_tweak": "sound", "value": "default"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "global/override/.m.rule.call",
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"kind": "event_match",
|
||||||
|
"key": "type",
|
||||||
|
"pattern": "m.call.invite",
|
||||||
|
"_id": "_call",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "sound", "value": "ring"},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
BASE_APPEND_UNDERRIDE_RULES = [
|
BASE_APPEND_UNDERRIDE_RULES = [
|
||||||
{
|
{
|
||||||
"rule_id": "global/underride/.m.rule.call",
|
"rule_id": "global/underride/.m.rule.call",
|
||||||
|
@ -354,6 +507,29 @@ BASE_APPEND_UNDERRIDE_RULES = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
NEW_APPEND_UNDERRIDE_RULES = [
|
||||||
|
{
|
||||||
|
"rule_id": "global/underride/.m.rule.room_one_to_one",
|
||||||
|
"conditions": [
|
||||||
|
{"kind": "room_member_count", "is": "2", "_id": "member_count"},
|
||||||
|
{"kind": "event_match", "key": "content.body", "pattern": "*", "_id": "body"},
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"notify",
|
||||||
|
{"set_tweak": "sound", "value": "default"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rule_id": "global/underride/.m.rule.message",
|
||||||
|
"conditions": [
|
||||||
|
{"kind": "event_match", "key": "content.body", "pattern": "*", "_id": "body"},
|
||||||
|
],
|
||||||
|
"actions": ["notify"],
|
||||||
|
"enabled": False,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
BASE_RULE_IDS = set()
|
BASE_RULE_IDS = set()
|
||||||
|
|
||||||
for r in BASE_APPEND_CONTENT_RULES:
|
for r in BASE_APPEND_CONTENT_RULES:
|
||||||
|
@ -375,3 +551,26 @@ for r in BASE_APPEND_UNDERRIDE_RULES:
|
||||||
r["priority_class"] = PRIORITY_CLASS_MAP["underride"]
|
r["priority_class"] = PRIORITY_CLASS_MAP["underride"]
|
||||||
r["default"] = True
|
r["default"] = True
|
||||||
BASE_RULE_IDS.add(r["rule_id"])
|
BASE_RULE_IDS.add(r["rule_id"])
|
||||||
|
|
||||||
|
|
||||||
|
NEW_RULE_IDS = set()
|
||||||
|
|
||||||
|
for r in BASE_APPEND_CONTENT_RULES:
|
||||||
|
r["priority_class"] = PRIORITY_CLASS_MAP["content"]
|
||||||
|
r["default"] = True
|
||||||
|
NEW_RULE_IDS.add(r["rule_id"])
|
||||||
|
|
||||||
|
for r in NEW_PREPEND_OVERRIDE_RULES:
|
||||||
|
r["priority_class"] = PRIORITY_CLASS_MAP["override"]
|
||||||
|
r["default"] = True
|
||||||
|
NEW_RULE_IDS.add(r["rule_id"])
|
||||||
|
|
||||||
|
for r in NEW_APPEND_OVERRIDE_RULES:
|
||||||
|
r["priority_class"] = PRIORITY_CLASS_MAP["override"]
|
||||||
|
r["default"] = True
|
||||||
|
NEW_RULE_IDS.add(r["rule_id"])
|
||||||
|
|
||||||
|
for r in NEW_APPEND_UNDERRIDE_RULES:
|
||||||
|
r["priority_class"] = PRIORITY_CLASS_MAP["underride"]
|
||||||
|
r["default"] = True
|
||||||
|
NEW_RULE_IDS.add(r["rule_id"])
|
||||||
|
|
|
@ -39,7 +39,7 @@ from synapse.util.caches.stream_change_cache import StreamChangeCache
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _load_rules(rawrules, enabled_map):
|
def _load_rules(rawrules, enabled_map, use_new_defaults=False):
|
||||||
ruleslist = []
|
ruleslist = []
|
||||||
for rawrule in rawrules:
|
for rawrule in rawrules:
|
||||||
rule = dict(rawrule)
|
rule = dict(rawrule)
|
||||||
|
@ -49,7 +49,7 @@ def _load_rules(rawrules, enabled_map):
|
||||||
ruleslist.append(rule)
|
ruleslist.append(rule)
|
||||||
|
|
||||||
# We're going to be mutating this a lot, so do a deep copy
|
# We're going to be mutating this a lot, so do a deep copy
|
||||||
rules = list(list_with_base_rules(ruleslist))
|
rules = list(list_with_base_rules(ruleslist, use_new_defaults))
|
||||||
|
|
||||||
for i, rule in enumerate(rules):
|
for i, rule in enumerate(rules):
|
||||||
rule_id = rule["rule_id"]
|
rule_id = rule["rule_id"]
|
||||||
|
@ -115,7 +115,7 @@ class PushRulesWorkerStore(
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
@cachedInlineCallbacks(max_entries=5000)
|
@cachedInlineCallbacks(max_entries=5000)
|
||||||
def get_push_rules_for_user(self, user_id):
|
def _get_push_rules_for_user(self, user_id, use_new_defaults=False):
|
||||||
rows = yield self.db.simple_select_list(
|
rows = yield self.db.simple_select_list(
|
||||||
table="push_rules",
|
table="push_rules",
|
||||||
keyvalues={"user_name": user_id},
|
keyvalues={"user_name": user_id},
|
||||||
|
@ -134,10 +134,24 @@ class PushRulesWorkerStore(
|
||||||
|
|
||||||
enabled_map = yield self.get_push_rules_enabled_for_user(user_id)
|
enabled_map = yield self.get_push_rules_enabled_for_user(user_id)
|
||||||
|
|
||||||
rules = _load_rules(rows, enabled_map)
|
rules = _load_rules(rows, enabled_map, use_new_defaults)
|
||||||
|
|
||||||
return rules
|
return rules
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def get_push_rules_for_user(self, user_id):
|
||||||
|
# Temporary hack so we can use the new experimental default push rules to some
|
||||||
|
# users without impacting others.
|
||||||
|
use_new_defaults = yield self.db.simple_select_list(
|
||||||
|
table="new_push_rules_users_tmp",
|
||||||
|
keyvalues={"user_id": user_id},
|
||||||
|
retcols=("user_id",),
|
||||||
|
desc="get_user_new_default_push_rules",
|
||||||
|
)
|
||||||
|
|
||||||
|
rules = yield self._get_push_rules_for_user(user_id, bool(use_new_defaults))
|
||||||
|
return rules
|
||||||
|
|
||||||
@cachedInlineCallbacks(max_entries=5000)
|
@cachedInlineCallbacks(max_entries=5000)
|
||||||
def get_push_rules_enabled_for_user(self, user_id):
|
def get_push_rules_enabled_for_user(self, user_id):
|
||||||
results = yield self.db.simple_select_list(
|
results = yield self.db.simple_select_list(
|
||||||
|
@ -194,7 +208,18 @@ class PushRulesWorkerStore(
|
||||||
enabled_map_by_user = yield self.bulk_get_push_rules_enabled(user_ids)
|
enabled_map_by_user = yield self.bulk_get_push_rules_enabled(user_ids)
|
||||||
|
|
||||||
for user_id, rules in results.items():
|
for user_id, rules in results.items():
|
||||||
results[user_id] = _load_rules(rules, enabled_map_by_user.get(user_id, {}))
|
# Temporary hack so we can use the new experimental default push rules to some
|
||||||
|
# users without impacting others.
|
||||||
|
use_new_defaults = yield self.db.simple_select_list(
|
||||||
|
table="new_push_rules_users_tmp",
|
||||||
|
keyvalues={"user_id": user_id},
|
||||||
|
retcols=("user_id",),
|
||||||
|
desc="get_user_new_default_push_rules",
|
||||||
|
)
|
||||||
|
|
||||||
|
results[user_id] = _load_rules(
|
||||||
|
rules, enabled_map_by_user.get(user_id, {}), bool(use_new_defaults),
|
||||||
|
)
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* Copyright 2020 The Matrix.org Foundation C.I.C
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-- This is a temporary table in which we store the IDs of the users for which we need to
|
||||||
|
-- serve the new experimental default push rules. The purpose of this table is to help
|
||||||
|
-- test these new defaults, so it shall be dropped when the experimentation is done.
|
||||||
|
CREATE TABLE IF NOT EXISTS new_push_rules_users_tmp (
|
||||||
|
user_id TEXT PRIMARY KEY
|
||||||
|
);
|
Loading…
Reference in a new issue