From 8a850573c9cf50dd83ba47c033b28fe2bbbaf9d4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 22 Jan 2015 19:32:17 +0000 Subject: As yet fairly untested GET API for push rules --- synapse/rest/client/v1/push_rule.py | 138 +++++++++++++++++++++++++++++++++--- 1 file changed, 128 insertions(+), 10 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index b5e74479cf..2803c1f071 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -15,7 +15,7 @@ from twisted.internet import defer -from synapse.api.errors import SynapseError, Codes, UnrecognizedRequestError +from synapse.api.errors import SynapseError, Codes, UnrecognizedRequestError, NotFoundError from base import RestServlet, client_path_pattern from synapse.storage.push_rule import InconsistentRuleException, RuleNotFoundException @@ -24,6 +24,14 @@ import json class PushRuleRestServlet(RestServlet): PATTERN = client_path_pattern("/pushrules/.*$") + PRIORITY_CLASS_MAP = { + 'underride': 0, + 'sender': 1, + 'room': 2, + 'content': 3, + 'override': 4 + } + PRIORITY_CLASS_INVERSE_MAP = {v: k for k,v in PRIORITY_CLASS_MAP.items()} def rule_spec_from_path(self, path): if len(path) < 2: @@ -109,15 +117,7 @@ class PushRuleRestServlet(RestServlet): return (conditions, actions) def priority_class_from_spec(self, spec): - map = { - 'underride': 0, - 'sender': 1, - 'room': 2, - 'content': 3, - 'override': 4 - } - - if spec['template'] not in map.keys(): + if spec['template'] not in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): raise InvalidRuleException("Unknown template: %s" % (spec['kind'])) pc = map[spec['template']] @@ -171,10 +171,128 @@ class PushRuleRestServlet(RestServlet): defer.returnValue((200, {})) + @defer.inlineCallbacks + def on_GET(self, request): + user = yield self.auth.get_user_by_req(request) + + # we build up the full structure and then decide which bits of it + # to send which means doing unnecessary work sometimes but is + # is probably not going to make a whole lot of difference + rawrules = yield self.hs.get_datastore().get_push_rules_for_user_name(user.to_string()) + + rules = {'global': {}, 'device': {}} + + rules['global'] = _add_empty_priority_class_arrays(rules['global']) + + for r in rawrules: + rulearray = None + + r["conditions"] = json.loads(r["conditions"]) + r["actions"] = json.loads(r["actions"]) + + template_name = _priority_class_to_template_name(r['priority_class']) + + if r['priority_class'] > PushRuleRestServlet.PRIORITY_CLASS_MAP['override']: + # per-device rule + instance_handle = _instance_handle_from_conditions(r["conditions"]) + if not instance_handle: + continue + if instance_handle not in rules['device']: + rules['device'][instance_handle] = [] + rules['device'][instance_handle] = \ + _add_empty_priority_class_arrays(rules['device'][instance_handle]) + + rulearray = rules['device'][instance_handle] + else: + rulearray = rules['global'][template_name] + + template_rule = _rule_to_template(r) + if template_rule: + rulearray.append(template_rule) + + path = request.postpath[1:] + if path == []: + defer.returnValue((200, rules)) + + if path[0] == 'global': + path = path[1:] + result = _filter_ruleset_with_path(rules['global'], path) + defer.returnValue((200, result)) + elif path[0] == 'device': + path = path[1:] + if path == []: + raise UnrecognizedRequestError + instance_handle = path[0] + if instance_handle not in rules['device']: + ret = {} + ret = _add_empty_priority_class_arrays(ret) + defer.returnValue((200, ret)) + ruleset = rules['device'][instance_handle] + result = _filter_ruleset_with_path(ruleset, path) + defer.returnValue((200, result)) + else: + raise UnrecognizedRequestError() + + def on_OPTIONS(self, _): return 200, {} +def _add_empty_priority_class_arrays(d): + for pc in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): + d[pc] = [] + return d + +def _instance_handle_from_conditions(conditions): + """ + Given a list of conditions, return the instance handle of the + device rule if there is one + """ + for c in conditions: + if c['kind'] == 'device': + return c['instance_handle'] + return None + +def _filter_ruleset_with_path(ruleset, path): + if path == []: + return ruleset + template_kind = path[0] + if template_kind not in ruleset: + raise UnrecognizedRequestError() + path = path[1:] + if path == []: + return ruleset[template_kind] + rule_id = path[0] + for r in ruleset[template_kind]: + if r['rule_id'] == rule_id: + return r + raise NotFoundError + +def _priority_class_to_template_name(pc): + if pc > PushRuleRestServlet.PRIORITY_CLASS_MAP['override']: + # per-device + prio_class_index = pc - PushRuleRestServlet.PRIORITY_CLASS_MAP['override'] + return PushRuleRestServlet.PRIORITY_CLASS_INVERSE_MAP[prio_class_index] + else: + return PushRuleRestServlet.PRIORITY_CLASS_INVERSE_MAP[pc] + +def _rule_to_template(rule): + template_name = _priority_class_to_template_name(rule['priority_class']) + if template_name in ['override', 'underride']: + return {k:rule[k] for k in ["rule_id", "conditions", "actions"]} + elif template_name in ["sender", "room"]: + return {k:rule[k] for k in ["rule_id", "actions"]} + elif template_name == 'content': + if len(rule["conditions"]) != 1: + return None + thecond = rule["conditions"][0] + if "pattern" not in thecond: + return None + ret = {k:rule[k] for k in ["rule_id", "actions"]} + ret["pattern"] = thecond["pattern"] + return ret + + class InvalidRuleException(Exception): pass -- cgit 1.5.1 From 6927b6b19783d7134eba3461c4fafe4efdec40f1 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Jan 2015 10:21:47 +0000 Subject: This really serves me right for ever making a map called 'map'. --- synapse/rest/client/v1/push_rule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 2803c1f071..7df3fc7f09 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -119,7 +119,7 @@ class PushRuleRestServlet(RestServlet): def priority_class_from_spec(self, spec): if spec['template'] not in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): raise InvalidRuleException("Unknown template: %s" % (spec['kind'])) - pc = map[spec['template']] + pc = PushRuleRestServlet.PRIORITY_CLASS_MAP[spec['template']] if spec['scope'] == 'device': pc += 5 -- cgit 1.5.1 From bcd48b9636071543fa64e7fb066275d1c9c1e363 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Jan 2015 10:28:25 +0000 Subject: Fix adding rules without before/after & add the rule that we couldn't find to the error --- synapse/rest/client/v1/push_rule.py | 4 ++-- synapse/storage/push_rule.py | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 7df3fc7f09..77a0772479 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -166,8 +166,8 @@ class PushRuleRestServlet(RestServlet): ) except InconsistentRuleException as e: raise SynapseError(400, e.message) - except RuleNotFoundException: - raise SynapseError(400, "before/after rule not found") + except RuleNotFoundException as e: + raise SynapseError(400, e.message) defer.returnValue((200, {})) diff --git a/synapse/storage/push_rule.py b/synapse/storage/push_rule.py index d087257ffc..2366090e09 100644 --- a/synapse/storage/push_rule.py +++ b/synapse/storage/push_rule.py @@ -46,7 +46,7 @@ class PushRuleStore(SQLBaseStore): defer.returnValue(dicts) @defer.inlineCallbacks - def add_push_rule(self, **kwargs): + def add_push_rule(self, before, after, **kwargs): vals = copy.copy(kwargs) if 'conditions' in vals: vals['conditions'] = json.dumps(vals['conditions']) @@ -57,10 +57,12 @@ class PushRuleStore(SQLBaseStore): if 'id' in vals: del vals['id'] - if 'after' in kwargs or 'before' in kwargs: + if before or after: ret = yield self.runInteraction( "_add_push_rule_relative_txn", self._add_push_rule_relative_txn, + before=before, + after=after, **vals ) defer.returnValue(ret) @@ -89,7 +91,7 @@ class PushRuleStore(SQLBaseStore): txn.execute(sql, (user_name, relative_to_rule)) res = txn.fetchall() if not res: - raise RuleNotFoundException() + raise RuleNotFoundException("before/after rule not found: %s" % (relative_to_rule)) (priority_class, base_rule_priority) = res[0] if 'priority_class' in kwargs and kwargs['priority_class'] != priority_class: -- cgit 1.5.1 From 49fe31792bc0cf709248e592baefb8f34606236a Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Jan 2015 11:19:02 +0000 Subject: Add slightly pedantic trailing slash error. --- synapse/api/errors.py | 7 ++++++- synapse/rest/client/v1/push_rule.py | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/api/errors.py b/synapse/api/errors.py index 4f59e1742c..5872e82d0f 100644 --- a/synapse/api/errors.py +++ b/synapse/api/errors.py @@ -88,9 +88,14 @@ class UnrecognizedRequestError(SynapseError): def __init__(self, *args, **kwargs): if "errcode" not in kwargs: kwargs["errcode"] = Codes.UNRECOGNIZED + message = None + if len(args) == 0: + message = "Unrecognized request" + else: + message = args[0] super(UnrecognizedRequestError, self).__init__( 400, - "Unrecognized request", + message, **kwargs ) diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 77a0772479..6f108431b2 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -32,6 +32,8 @@ class PushRuleRestServlet(RestServlet): 'override': 4 } PRIORITY_CLASS_INVERSE_MAP = {v: k for k,v in PRIORITY_CLASS_MAP.items()} + SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR =\ + "Unrecognised request: You probably wanted a trailing slash" def rule_spec_from_path(self, path): if len(path) < 2: @@ -211,10 +213,14 @@ class PushRuleRestServlet(RestServlet): rulearray.append(template_rule) path = request.postpath[1:] + if path == []: - defer.returnValue((200, rules)) + # we're a reference impl: pedantry is our job. + raise UnrecognizedRequestError(PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR) - if path[0] == 'global': + if path[0] == '': + defer.returnValue((200, rules)) + elif path[0] == 'global': path = path[1:] result = _filter_ruleset_with_path(rules['global'], path) defer.returnValue((200, result)) @@ -255,12 +261,17 @@ def _instance_handle_from_conditions(conditions): def _filter_ruleset_with_path(ruleset, path): if path == []: + raise UnrecognizedRequestError(PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR) + + if path[0] == '': return ruleset template_kind = path[0] if template_kind not in ruleset: raise UnrecognizedRequestError() path = path[1:] if path == []: + raise UnrecognizedRequestError(PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR) + if path[0] == '': return ruleset[template_kind] rule_id = path[0] for r in ruleset[template_kind]: -- cgit 1.5.1 From 6188c4f69c2f902410b43bc50c0ae8d488b4d93c Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Jan 2015 13:23:10 +0000 Subject: make per-device rules work --- synapse/rest/client/v1/push_rule.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 6f108431b2..417fd368d7 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -73,7 +73,7 @@ class PushRuleRestServlet(RestServlet): spec['device'] = device return spec - def rule_tuple_from_request_object(self, rule_template, rule_id, req_obj): + def rule_tuple_from_request_object(self, rule_template, rule_id, req_obj, device=None): if rule_template in ['override', 'underride']: if 'conditions' not in req_obj: raise InvalidRuleException("Missing 'conditions'") @@ -104,6 +104,12 @@ class PushRuleRestServlet(RestServlet): else: raise InvalidRuleException("Unknown rule template: %s" % (rule_template)) + if device: + conditions.append({ + 'kind': 'device', + 'instance_handle': device + }) + if 'actions' not in req_obj: raise InvalidRuleException("No actions found") actions = req_obj['actions'] @@ -144,7 +150,8 @@ class PushRuleRestServlet(RestServlet): (conditions, actions) = self.rule_tuple_from_request_object( spec['template'], spec['rule_id'], - content + content, + device=spec['device'] if 'device' in spec else None ) except InvalidRuleException as e: raise SynapseError(400, e.message) @@ -200,11 +207,11 @@ class PushRuleRestServlet(RestServlet): if not instance_handle: continue if instance_handle not in rules['device']: - rules['device'][instance_handle] = [] + rules['device'][instance_handle] = {} rules['device'][instance_handle] = \ _add_empty_priority_class_arrays(rules['device'][instance_handle]) - rulearray = rules['device'][instance_handle] + rulearray = rules['device'][instance_handle][template_name] else: rulearray = rules['global'][template_name] @@ -227,7 +234,10 @@ class PushRuleRestServlet(RestServlet): elif path[0] == 'device': path = path[1:] if path == []: - raise UnrecognizedRequestError + raise UnrecognizedRequestError(PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR) + if path[0] == '': + defer.returnValue((200, rules['device'])) + instance_handle = path[0] if instance_handle not in rules['device']: ret = {} -- cgit 1.5.1 From 54c689c8199336b819c632a3e996120cb13007db Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Jan 2015 13:25:14 +0000 Subject: stray space --- synapse/rest/client/v1/push_rule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 417fd368d7..9cb2494035 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -65,7 +65,7 @@ class PushRuleRestServlet(RestServlet): rule_id = path[0] spec = { - 'scope' : scope, + 'scope': scope, 'template': template, 'rule_id': rule_id } -- cgit 1.5.1 From 98e1080555965c650e09ed09bdac3b52daeda123 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Jan 2015 13:25:36 +0000 Subject: redundant parens --- synapse/rest/client/v1/push_rule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 9cb2494035..46b8c3f625 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -122,7 +122,7 @@ class PushRuleRestServlet(RestServlet): else: raise InvalidRuleException("Unrecognised action") - return (conditions, actions) + return conditions, actions def priority_class_from_spec(self, spec): if spec['template'] not in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): -- cgit 1.5.1 From d3e72b4d8788e64cd4b1d9668382639476730b4d Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Jan 2015 13:25:58 +0000 Subject: Make string format tuple an actual tuple --- synapse/rest/client/v1/push_rule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 46b8c3f625..35ffcba3df 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -102,7 +102,7 @@ class PushRuleRestServlet(RestServlet): 'pattern': req_obj['pattern'] }] else: - raise InvalidRuleException("Unknown rule template: %s" % (rule_template)) + raise InvalidRuleException("Unknown rule template: %s" % (rule_template,)) if device: conditions.append({ -- cgit 1.5.1 From b3f66ea6fb5871d7eeb71b466740adb61a89c0d2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Jan 2015 13:28:00 +0000 Subject: more pep8 --- synapse/rest/client/v1/push_rule.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 35ffcba3df..ce2f0febf4 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -249,7 +249,6 @@ class PushRuleRestServlet(RestServlet): else: raise UnrecognizedRequestError() - def on_OPTIONS(self, _): return 200, {} @@ -259,6 +258,7 @@ def _add_empty_priority_class_arrays(d): d[pc] = [] return d + def _instance_handle_from_conditions(conditions): """ Given a list of conditions, return the instance handle of the @@ -289,6 +289,7 @@ def _filter_ruleset_with_path(ruleset, path): return r raise NotFoundError + def _priority_class_to_template_name(pc): if pc > PushRuleRestServlet.PRIORITY_CLASS_MAP['override']: # per-device @@ -297,12 +298,13 @@ def _priority_class_to_template_name(pc): else: return PushRuleRestServlet.PRIORITY_CLASS_INVERSE_MAP[pc] + def _rule_to_template(rule): template_name = _priority_class_to_template_name(rule['priority_class']) if template_name in ['override', 'underride']: return {k:rule[k] for k in ["rule_id", "conditions", "actions"]} elif template_name in ["sender", "room"]: - return {k:rule[k] for k in ["rule_id", "actions"]} + return {k: rule[k] for k in ["rule_id", "actions"]} elif template_name == 'content': if len(rule["conditions"]) != 1: return None -- cgit 1.5.1 From f21f9fa3c51db49212c42adfe6972025e1d27a15 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Jan 2015 17:07:06 +0000 Subject: Use push settings! --- synapse/push/__init__.py | 91 +++++++++++++++++++++++++++++++++---- synapse/push/httppusher.py | 9 ++-- synapse/rest/client/v1/push_rule.py | 43 ++++++++++++------ 3 files changed, 117 insertions(+), 26 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/push/__init__.py b/synapse/push/__init__.py index 47da31e500..53d3319699 100644 --- a/synapse/push/__init__.py +++ b/synapse/push/__init__.py @@ -21,6 +21,8 @@ from synapse.types import StreamToken import synapse.util.async import logging +import fnmatch +import json logger = logging.getLogger(__name__) @@ -29,6 +31,7 @@ class Pusher(object): INITIAL_BACKOFF = 1000 MAX_BACKOFF = 60 * 60 * 1000 GIVE_UP_AFTER = 24 * 60 * 60 * 1000 + DEFAULT_ACTIONS = ['notify'] def __init__(self, _hs, instance_handle, user_name, app_id, app_display_name, device_display_name, pushkey, pushkey_ts, @@ -37,7 +40,7 @@ class Pusher(object): self.evStreamHandler = self.hs.get_handlers().event_stream_handler self.store = self.hs.get_datastore() self.clock = self.hs.get_clock() - self.instance_handle = instance_handle, + self.instance_handle = instance_handle self.user_name = user_name self.app_id = app_id self.app_display_name = app_display_name @@ -51,7 +54,8 @@ class Pusher(object): self.failing_since = failing_since self.alive = True - def _should_notify_for_event(self, ev): + @defer.inlineCallbacks + def _actions_for_event(self, ev): """ This should take into account notification settings that the user has configured both globally and per-room when we have the ability @@ -59,8 +63,47 @@ class Pusher(object): """ if ev['user_id'] == self.user_name: # let's assume you probably know about messages you sent yourself + defer.returnValue(['dont_notify']) + + rules = yield self.store.get_push_rules_for_user_name(self.user_name) + + for r in rules: + matches = True + + conditions = json.loads(r['conditions']) + actions = json.loads(r['actions']) + + for c in conditions: + matches &= self._event_fulfills_condition(ev, c) + # ignore rules with no actions (we have an explict 'dont_notify' + if len(actions) == 0: + logger.warn( + "Ignoring rule id %s with no actions for user %s" % + (r['rule_id'], r['user_name']) + ) + continue + if matches: + defer.returnValue(actions) + + defer.returnValue(Pusher.DEFAULT_ACTIONS) + + def _event_fulfills_condition(self, ev, condition): + if condition['kind'] == 'event_match': + if 'pattern' not in condition: + logger.warn("event_match condition with no pattern") + return False + pat = condition['pattern'] + + val = _value_for_dotted_key(condition['key'], ev) + if fnmatch.fnmatch(val, pat): + return True return False - return True + elif condition['kind'] == 'device': + if 'instance_handle' not in condition: + return True + return condition['instance_handle'] == self.instance_handle + else: + return True @defer.inlineCallbacks def get_context_for_event(self, ev): @@ -113,8 +156,23 @@ class Pusher(object): continue processed = False - if self._should_notify_for_event(single_event): - rejected = yield self.dispatch_push(single_event) + actions = yield self._actions_for_event(single_event) + tweaks = _tweaks_for_actions(actions) + + if len(actions) == 0: + logger.warn("Empty actions! Using default action.") + actions = Pusher.DEFAULT_ACTIONS + if 'notify' not in actions and 'dont_notify' not in actions: + logger.warn("Neither notify nor dont_notify in actions: adding default") + actions.extend(Pusher.DEFAULT_ACTIONS) + if 'dont_notify' in actions: + logger.debug( + "%s for %s: dont_notify", + single_event['event_id'], self.user_name + ) + processed = True + else: + rejected = yield self.dispatch_push(single_event, tweaks) if not rejected is False: processed = True for pk in rejected: @@ -133,8 +191,6 @@ class Pusher(object): yield self.hs.get_pusherpool().remove_pusher( self.app_id, pk ) - else: - processed = True if not self.alive: continue @@ -202,7 +258,7 @@ class Pusher(object): def stop(self): self.alive = False - def dispatch_push(self, p): + def dispatch_push(self, p, tweaks): """ Overridden by implementing classes to actually deliver the notification :param p: The event to notify for as a single event from the event stream @@ -214,6 +270,25 @@ class Pusher(object): pass +def _value_for_dotted_key(dotted_key, event): + parts = dotted_key.split(".") + val = event + while len(parts) > 0: + if parts[0] not in val: + return None + val = val[parts[0]] + parts = parts[1:] + return val + +def _tweaks_for_actions(actions): + tweaks = {} + for a in actions: + if not isinstance(a, dict): + continue + if 'set_sound' in a: + tweaks['sound'] = a['set_sound'] + return tweaks + class PusherConfigException(Exception): def __init__(self, msg): super(PusherConfigException, self).__init__(msg) \ No newline at end of file diff --git a/synapse/push/httppusher.py b/synapse/push/httppusher.py index 46433ad4a9..25db1dded5 100644 --- a/synapse/push/httppusher.py +++ b/synapse/push/httppusher.py @@ -52,7 +52,7 @@ class HttpPusher(Pusher): del self.data_minus_url['url'] @defer.inlineCallbacks - def _build_notification_dict(self, event): + def _build_notification_dict(self, event, tweaks): # we probably do not want to push for every presence update # (we may want to be able to set up notifications when specific # people sign in, but we'd want to only deliver the pertinent ones) @@ -83,7 +83,8 @@ class HttpPusher(Pusher): 'app_id': self.app_id, 'pushkey': self.pushkey, 'pushkey_ts': long(self.pushkey_ts / 1000), - 'data': self.data_minus_url + 'data': self.data_minus_url, + 'tweaks': tweaks } ] } @@ -97,8 +98,8 @@ class HttpPusher(Pusher): defer.returnValue(d) @defer.inlineCallbacks - def dispatch_push(self, event): - notification_dict = yield self._build_notification_dict(event) + def dispatch_push(self, event, tweaks): + notification_dict = yield self._build_notification_dict(event, tweaks) if not notification_dict: defer.returnValue([]) try: diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index ce2f0febf4..9dc2c0e11e 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -96,10 +96,15 @@ class PushRuleRestServlet(RestServlet): elif rule_template == 'content': if 'pattern' not in req_obj: raise InvalidRuleException("Content rule missing 'pattern'") + pat = req_obj['pattern'] + if pat.strip("*?[]") == pat: + # no special glob characters so we assume the user means + # 'contains this string' rather than 'is this string' + pat = "*%s*" % (pat) conditions = [{ 'kind': 'event_match', 'key': 'content.body', - 'pattern': req_obj['pattern'] + 'pattern': pat }] else: raise InvalidRuleException("Unknown rule template: %s" % (rule_template,)) @@ -115,7 +120,7 @@ class PushRuleRestServlet(RestServlet): actions = req_obj['actions'] for a in actions: - if a in ['notify', 'dont-notify', 'coalesce']: + if a in ['notify', 'dont_notify', 'coalesce']: pass elif isinstance(a, dict) and 'set_sound' in a: pass @@ -124,21 +129,11 @@ class PushRuleRestServlet(RestServlet): return conditions, actions - def priority_class_from_spec(self, spec): - if spec['template'] not in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): - raise InvalidRuleException("Unknown template: %s" % (spec['kind'])) - pc = PushRuleRestServlet.PRIORITY_CLASS_MAP[spec['template']] - - if spec['scope'] == 'device': - pc += 5 - - return pc - @defer.inlineCallbacks def on_PUT(self, request): spec = self.rule_spec_from_path(request.postpath) try: - priority_class = self.priority_class_from_spec(spec) + priority_class = _priority_class_from_spec(spec) except InvalidRuleException as e: raise SynapseError(400, e.message) @@ -204,6 +199,7 @@ class PushRuleRestServlet(RestServlet): if r['priority_class'] > PushRuleRestServlet.PRIORITY_CLASS_MAP['override']: # per-device rule instance_handle = _instance_handle_from_conditions(r["conditions"]) + r = _strip_device_condition(r) if not instance_handle: continue if instance_handle not in rules['device']: @@ -239,6 +235,7 @@ class PushRuleRestServlet(RestServlet): defer.returnValue((200, rules['device'])) instance_handle = path[0] + path = path[1:] if instance_handle not in rules['device']: ret = {} ret = _add_empty_priority_class_arrays(ret) @@ -290,10 +287,21 @@ def _filter_ruleset_with_path(ruleset, path): raise NotFoundError +def _priority_class_from_spec(spec): + if spec['template'] not in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): + raise InvalidRuleException("Unknown template: %s" % (spec['kind'])) + pc = PushRuleRestServlet.PRIORITY_CLASS_MAP[spec['template']] + + if spec['scope'] == 'device': + pc += len(PushRuleRestServlet.PRIORITY_CLASS_MAP) + + return pc + + def _priority_class_to_template_name(pc): if pc > PushRuleRestServlet.PRIORITY_CLASS_MAP['override']: # per-device - prio_class_index = pc - PushRuleRestServlet.PRIORITY_CLASS_MAP['override'] + prio_class_index = pc - len(PushRuleRestServlet.PRIORITY_CLASS_MAP) return PushRuleRestServlet.PRIORITY_CLASS_INVERSE_MAP[prio_class_index] else: return PushRuleRestServlet.PRIORITY_CLASS_INVERSE_MAP[pc] @@ -316,6 +324,13 @@ def _rule_to_template(rule): return ret +def _strip_device_condition(rule): + for i,c in enumerate(rule['conditions']): + if c['kind'] == 'device': + del rule['conditions'][i] + return rule + + class InvalidRuleException(Exception): pass -- cgit 1.5.1 From 5f84ba8ea1991dff279f0135f474d9debfd1419a Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Jan 2015 17:49:37 +0000 Subject: Add API to delete push rules. --- synapse/rest/client/v1/push_rule.py | 41 ++++++++++++++++++++++++++++++++++++- synapse/storage/push_rule.py | 9 ++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 9dc2c0e11e..50bf5b9008 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -15,7 +15,8 @@ from twisted.internet import defer -from synapse.api.errors import SynapseError, Codes, UnrecognizedRequestError, NotFoundError +from synapse.api.errors import SynapseError, Codes, UnrecognizedRequestError, NotFoundError, \ + StoreError from base import RestServlet, client_path_pattern from synapse.storage.push_rule import InconsistentRuleException, RuleNotFoundException @@ -175,6 +176,44 @@ class PushRuleRestServlet(RestServlet): defer.returnValue((200, {})) + @defer.inlineCallbacks + def on_DELETE(self, request): + spec = self.rule_spec_from_path(request.postpath) + try: + priority_class = _priority_class_from_spec(spec) + except InvalidRuleException as e: + raise SynapseError(400, e.message) + + user = yield self.auth.get_user_by_req(request) + + if 'device' in spec: + rules = yield self.hs.get_datastore().get_push_rules_for_user_name( + user.to_string() + ) + + for r in rules: + conditions = json.loads(r['conditions']) + ih = _instance_handle_from_conditions(conditions) + if ih == spec['device'] and r['priority_class'] == priority_class: + yield self.hs.get_datastore().delete_push_rule( + user.to_string(), spec['rule_id'] + ) + defer.returnValue((200, {})) + raise NotFoundError() + else: + try: + yield self.hs.get_datastore().delete_push_rule( + user.to_string(), spec['rule_id'], + priority_class=priority_class + ) + defer.returnValue((200, {})) + except StoreError as e: + if e.code == 404: + raise NotFoundError() + else: + raise + + @defer.inlineCallbacks def on_GET(self, request): user = yield self.auth.get_user_by_req(request) diff --git a/synapse/storage/push_rule.py b/synapse/storage/push_rule.py index 2366090e09..ca04f2ccee 100644 --- a/synapse/storage/push_rule.py +++ b/synapse/storage/push_rule.py @@ -174,6 +174,15 @@ class PushRuleStore(SQLBaseStore): txn.execute(sql, new_rule.values()) + @defer.inlineCallbacks + def delete_push_rule(self, user_name, rule_id): + yield self._simple_delete_one( + PushRuleTable.table_name, + { + 'user_name': user_name, + 'rule_id': rule_id + } + ) class RuleNotFoundException(Exception): pass -- cgit 1.5.1 From 20c47383dca7d68608c903fe1f856756fd3da057 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 28 Jan 2015 14:10:46 +0000 Subject: Oops, bad merge: needed to change the base class of the rest servlets too. --- synapse/push/__init__.py | 5 +++-- synapse/rest/client/v1/push_rule.py | 4 ++-- synapse/rest/client/v1/pusher.py | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/push/__init__.py b/synapse/push/__init__.py index b79f2d4b27..1cac5fff4e 100644 --- a/synapse/push/__init__.py +++ b/synapse/push/__init__.py @@ -269,8 +269,9 @@ class Pusher(object): def dispatch_push(self, p, tweaks): """ Overridden by implementing classes to actually deliver the notification - :param p: The event to notify for as a single event from the event stream - :return: If the notification was delivered, an array containing any + Args: + p The event to notify for as a single event from the event stream + Returns: If the notification was delivered, an array containing any pushkeys that were rejected by the push gateway. False if the notification could not be delivered (ie. should be retried). diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 50bf5b9008..00fed42f44 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -17,13 +17,13 @@ from twisted.internet import defer from synapse.api.errors import SynapseError, Codes, UnrecognizedRequestError, NotFoundError, \ StoreError -from base import RestServlet, client_path_pattern +from .base import ClientV1RestServlet, client_path_pattern from synapse.storage.push_rule import InconsistentRuleException, RuleNotFoundException import json -class PushRuleRestServlet(RestServlet): +class PushRuleRestServlet(ClientV1RestServlet): PATTERN = client_path_pattern("/pushrules/.*$") PRIORITY_CLASS_MAP = { 'underride': 0, diff --git a/synapse/rest/client/v1/pusher.py b/synapse/rest/client/v1/pusher.py index 4659c9b1d9..80a11890a3 100644 --- a/synapse/rest/client/v1/pusher.py +++ b/synapse/rest/client/v1/pusher.py @@ -17,12 +17,12 @@ from twisted.internet import defer from synapse.api.errors import SynapseError, Codes from synapse.push import PusherConfigException -from base import RestServlet, client_path_pattern +from .base import ClientV1RestServlet, client_path_pattern import json -class PusherRestServlet(RestServlet): +class PusherRestServlet(ClientV1RestServlet): PATTERN = client_path_pattern("/pushers/set$") @defer.inlineCallbacks -- cgit 1.5.1 From 6741c3dbd90b6406d7eba8445868cdd8fd2ec6a5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 28 Jan 2015 14:26:03 +0000 Subject: Brackets are nicer --- synapse/rest/client/v1/push_rule.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 00fed42f44..b03d804d82 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -33,8 +33,8 @@ class PushRuleRestServlet(ClientV1RestServlet): 'override': 4 } PRIORITY_CLASS_INVERSE_MAP = {v: k for k,v in PRIORITY_CLASS_MAP.items()} - SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR =\ - "Unrecognised request: You probably wanted a trailing slash" + SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR = ( + "Unrecognised request: You probably wanted a trailing slash") def rule_spec_from_path(self, path): if len(path) < 2: -- cgit 1.5.1 From d93ce29a86b79478bfb2011c9b8d3c8ec7d0bdd0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 28 Jan 2015 14:27:01 +0000 Subject: Ah, the comma of doom. --- synapse/rest/client/v1/push_rule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index b03d804d82..c6085370a4 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -101,7 +101,7 @@ class PushRuleRestServlet(ClientV1RestServlet): if pat.strip("*?[]") == pat: # no special glob characters so we assume the user means # 'contains this string' rather than 'is this string' - pat = "*%s*" % (pat) + pat = "*%s*" % (pat,) conditions = [{ 'kind': 'event_match', 'key': 'content.body', -- cgit 1.5.1 From 032f8d4ed3a5b4015087b7a97295da9b580a95b3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 28 Jan 2015 14:33:15 +0000 Subject: Another superfluous newline --- synapse/rest/client/v1/push_rule.py | 1 - 1 file changed, 1 deletion(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index c6085370a4..3a08bdd9af 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -213,7 +213,6 @@ class PushRuleRestServlet(ClientV1RestServlet): else: raise - @defer.inlineCallbacks def on_GET(self, request): user = yield self.auth.get_user_by_req(request) -- cgit 1.5.1 From 8807f4170eaf2515407b656b7eb6fe7e8fc93796 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 28 Jan 2015 14:35:00 +0000 Subject: Better style --- synapse/rest/client/v1/push_rule.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 3a08bdd9af..52f2b19bbe 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -242,8 +242,11 @@ class PushRuleRestServlet(ClientV1RestServlet): continue if instance_handle not in rules['device']: rules['device'][instance_handle] = {} - rules['device'][instance_handle] = \ - _add_empty_priority_class_arrays(rules['device'][instance_handle]) + rules['device'][instance_handle] = ( + _add_empty_priority_class_arrays( + rules['device'][instance_handle] + ) + ) rulearray = rules['device'][instance_handle][template_name] else: -- cgit 1.5.1 From 3cb5b73c0dd10ba9020547a81864846c70d4e709 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 28 Jan 2015 14:37:55 +0000 Subject: Unnecessary newline. --- synapse/rest/client/v1/push_rule.py | 1 - 1 file changed, 1 deletion(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 52f2b19bbe..550554c18c 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -290,7 +290,6 @@ class PushRuleRestServlet(ClientV1RestServlet): def on_OPTIONS(self, _): return 200, {} - def _add_empty_priority_class_arrays(d): for pc in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): d[pc] = [] -- cgit 1.5.1 From 289a2498743caae7e0c3366a1c1f7855d48d9a8e Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 28 Jan 2015 14:39:03 +0000 Subject: Unnecessary newlines. --- synapse/rest/client/v1/push_rule.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 550554c18c..dbcac3d4e1 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -295,7 +295,6 @@ def _add_empty_priority_class_arrays(d): d[pc] = [] return d - def _instance_handle_from_conditions(conditions): """ Given a list of conditions, return the instance handle of the @@ -326,7 +325,6 @@ def _filter_ruleset_with_path(ruleset, path): return r raise NotFoundError - def _priority_class_from_spec(spec): if spec['template'] not in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): raise InvalidRuleException("Unknown template: %s" % (spec['kind'])) @@ -337,7 +335,6 @@ def _priority_class_from_spec(spec): return pc - def _priority_class_to_template_name(pc): if pc > PushRuleRestServlet.PRIORITY_CLASS_MAP['override']: # per-device @@ -346,7 +343,6 @@ def _priority_class_to_template_name(pc): else: return PushRuleRestServlet.PRIORITY_CLASS_INVERSE_MAP[pc] - def _rule_to_template(rule): template_name = _priority_class_to_template_name(rule['priority_class']) if template_name in ['override', 'underride']: @@ -363,7 +359,6 @@ def _rule_to_template(rule): ret["pattern"] = thecond["pattern"] return ret - def _strip_device_condition(rule): for i,c in enumerate(rule['conditions']): if c['kind'] == 'device': -- cgit 1.5.1 From 2cfdfee572dc037b65571ab72efcb3223c7d8d11 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 28 Jan 2015 14:41:51 +0000 Subject: spaces --- synapse/rest/client/v1/push_rule.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index dbcac3d4e1..2b33bdac08 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -346,7 +346,7 @@ def _priority_class_to_template_name(pc): def _rule_to_template(rule): template_name = _priority_class_to_template_name(rule['priority_class']) if template_name in ['override', 'underride']: - return {k:rule[k] for k in ["rule_id", "conditions", "actions"]} + return {k: rule[k] for k in ["rule_id", "conditions", "actions"]} elif template_name in ["sender", "room"]: return {k: rule[k] for k in ["rule_id", "actions"]} elif template_name == 'content': @@ -355,7 +355,7 @@ def _rule_to_template(rule): thecond = rule["conditions"][0] if "pattern" not in thecond: return None - ret = {k:rule[k] for k in ["rule_id", "actions"]} + ret = {k: rule[k] for k in ["rule_id", "actions"]} ret["pattern"] = thecond["pattern"] return ret -- cgit 1.5.1 From 8552ed8df2990d79b0015e0e84dd98de25fd0a9d Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 28 Jan 2015 18:04:40 +0000 Subject: Change uses of get_user_by_req because it returns a tuple now. --- synapse/rest/client/v1/push_rule.py | 6 +++--- synapse/rest/client/v1/pusher.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 2b33bdac08..64743a2f46 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -138,7 +138,7 @@ class PushRuleRestServlet(ClientV1RestServlet): except InvalidRuleException as e: raise SynapseError(400, e.message) - user = yield self.auth.get_user_by_req(request) + user, _ = yield self.auth.get_user_by_req(request) content = _parse_json(request) @@ -184,7 +184,7 @@ class PushRuleRestServlet(ClientV1RestServlet): except InvalidRuleException as e: raise SynapseError(400, e.message) - user = yield self.auth.get_user_by_req(request) + user, _ = yield self.auth.get_user_by_req(request) if 'device' in spec: rules = yield self.hs.get_datastore().get_push_rules_for_user_name( @@ -215,7 +215,7 @@ class PushRuleRestServlet(ClientV1RestServlet): @defer.inlineCallbacks def on_GET(self, request): - user = yield self.auth.get_user_by_req(request) + user, _ = yield self.auth.get_user_by_req(request) # we build up the full structure and then decide which bits of it # to send which means doing unnecessary work sometimes but is diff --git a/synapse/rest/client/v1/pusher.py b/synapse/rest/client/v1/pusher.py index 80a11890a3..72d5e9e476 100644 --- a/synapse/rest/client/v1/pusher.py +++ b/synapse/rest/client/v1/pusher.py @@ -27,7 +27,7 @@ class PusherRestServlet(ClientV1RestServlet): @defer.inlineCallbacks def on_POST(self, request): - user = yield self.auth.get_user_by_req(request) + user, _ = yield self.auth.get_user_by_req(request) content = _parse_json(request) -- cgit 1.5.1 From acb68a39e02f405c116135400e33a3b1940a07f8 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 29 Jan 2015 16:10:35 +0000 Subject: Code style fixes. --- synapse/api/errors.py | 1 + synapse/push/__init__.py | 15 +++++++-------- synapse/push/httppusher.py | 8 ++++---- synapse/push/pusherpool.py | 2 +- synapse/rest/__init__.py | 2 +- synapse/rest/client/v1/push_rule.py | 29 ++++++++++++++++++++++------- synapse/storage/push_rule.py | 9 +++++---- synapse/storage/pusher.py | 2 +- 8 files changed, 42 insertions(+), 26 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/api/errors.py b/synapse/api/errors.py index 5872e82d0f..ad478aa6b7 100644 --- a/synapse/api/errors.py +++ b/synapse/api/errors.py @@ -111,6 +111,7 @@ class NotFoundError(SynapseError): **kwargs ) + class AuthError(SynapseError): """An error raised when there was a problem authorising an event.""" diff --git a/synapse/push/__init__.py b/synapse/push/__init__.py index fa967c5a5d..472ede5480 100644 --- a/synapse/push/__init__.py +++ b/synapse/push/__init__.py @@ -189,8 +189,8 @@ class Pusher(object): # for sanity, we only remove the pushkey if it # was the one we actually sent... logger.warn( - ("Ignoring rejected pushkey %s because we " - "didn't send it"), pk + ("Ignoring rejected pushkey %s because we" + " didn't send it"), pk ) else: logger.info( @@ -236,8 +236,7 @@ class Pusher(object): # of old notifications. logger.warn("Giving up on a notification to user %s, " "pushkey %s", - self.user_name, self.pushkey - ) + self.user_name, self.pushkey) self.backoff_delay = Pusher.INITIAL_BACKOFF self.last_token = chunk['end'] self.store.update_pusher_last_token( @@ -258,8 +257,7 @@ class Pusher(object): "Trying again in %dms", self.user_name, self.clock.time_msec() - self.failing_since, - self.backoff_delay - ) + self.backoff_delay) yield synapse.util.async.sleep(self.backoff_delay / 1000.0) self.backoff_delay *= 2 if self.backoff_delay > Pusher.MAX_BACKOFF: @@ -299,7 +297,6 @@ class Pusher(object): self.has_unread = False - def _value_for_dotted_key(dotted_key, event): parts = dotted_key.split(".") val = event @@ -310,6 +307,7 @@ def _value_for_dotted_key(dotted_key, event): parts = parts[1:] return val + def _tweaks_for_actions(actions): tweaks = {} for a in actions: @@ -319,6 +317,7 @@ def _tweaks_for_actions(actions): tweaks['sound'] = a['set_sound'] return tweaks + class PusherConfigException(Exception): def __init__(self, msg): - super(PusherConfigException, self).__init__(msg) \ No newline at end of file + super(PusherConfigException, self).__init__(msg) diff --git a/synapse/push/httppusher.py b/synapse/push/httppusher.py index e12b946727..ab128e31e5 100644 --- a/synapse/push/httppusher.py +++ b/synapse/push/httppusher.py @@ -71,11 +71,11 @@ class HttpPusher(Pusher): # we may have to fetch this over federation and we # can't trust it anyway: is it worth it? #'from_display_name': 'Steve Stevington' - 'counts': { #-- we don't mark messages as read yet so - # we have no way of knowing + 'counts': { # -- we don't mark messages as read yet so + # we have no way of knowing # Just set the badge to 1 until we have read receipts 'unread': 1, - # 'missed_calls': 2 + # 'missed_calls': 2 }, 'devices': [ { @@ -142,4 +142,4 @@ class HttpPusher(Pusher): rejected = [] if 'rejected' in resp: rejected = resp['rejected'] - defer.returnValue(rejected) \ No newline at end of file + defer.returnValue(rejected) diff --git a/synapse/push/pusherpool.py b/synapse/push/pusherpool.py index 856defedac..4892c21e7b 100644 --- a/synapse/push/pusherpool.py +++ b/synapse/push/pusherpool.py @@ -149,4 +149,4 @@ class PusherPool: logger.info("Stopping pusher %s", fullid) self.pushers[fullid].stop() del self.pushers[fullid] - yield self.store.delete_pusher_by_app_id_pushkey(app_id, pushkey) \ No newline at end of file + yield self.store.delete_pusher_by_app_id_pushkey(app_id, pushkey) diff --git a/synapse/rest/__init__.py b/synapse/rest/__init__.py index 90afd93333..1a84d94cd9 100644 --- a/synapse/rest/__init__.py +++ b/synapse/rest/__init__.py @@ -11,4 +11,4 @@ # 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. \ No newline at end of file +# limitations under the License. diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 64743a2f46..2b1e930326 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -30,9 +30,9 @@ class PushRuleRestServlet(ClientV1RestServlet): 'sender': 1, 'room': 2, 'content': 3, - 'override': 4 + 'override': 4, } - PRIORITY_CLASS_INVERSE_MAP = {v: k for k,v in PRIORITY_CLASS_MAP.items()} + PRIORITY_CLASS_INVERSE_MAP = {v: k for k, v in PRIORITY_CLASS_MAP.items()} SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR = ( "Unrecognised request: You probably wanted a trailing slash") @@ -260,7 +260,9 @@ class PushRuleRestServlet(ClientV1RestServlet): if path == []: # we're a reference impl: pedantry is our job. - raise UnrecognizedRequestError(PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR) + raise UnrecognizedRequestError( + PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR + ) if path[0] == '': defer.returnValue((200, rules)) @@ -271,7 +273,9 @@ class PushRuleRestServlet(ClientV1RestServlet): elif path[0] == 'device': path = path[1:] if path == []: - raise UnrecognizedRequestError(PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR) + raise UnrecognizedRequestError( + PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR + ) if path[0] == '': defer.returnValue((200, rules['device'])) @@ -290,11 +294,13 @@ class PushRuleRestServlet(ClientV1RestServlet): def on_OPTIONS(self, _): return 200, {} + def _add_empty_priority_class_arrays(d): for pc in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): d[pc] = [] return d + def _instance_handle_from_conditions(conditions): """ Given a list of conditions, return the instance handle of the @@ -305,9 +311,12 @@ def _instance_handle_from_conditions(conditions): return c['instance_handle'] return None + def _filter_ruleset_with_path(ruleset, path): if path == []: - raise UnrecognizedRequestError(PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR) + raise UnrecognizedRequestError( + PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR + ) if path[0] == '': return ruleset @@ -316,7 +325,9 @@ def _filter_ruleset_with_path(ruleset, path): raise UnrecognizedRequestError() path = path[1:] if path == []: - raise UnrecognizedRequestError(PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR) + raise UnrecognizedRequestError( + PushRuleRestServlet.SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR + ) if path[0] == '': return ruleset[template_kind] rule_id = path[0] @@ -325,6 +336,7 @@ def _filter_ruleset_with_path(ruleset, path): return r raise NotFoundError + def _priority_class_from_spec(spec): if spec['template'] not in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): raise InvalidRuleException("Unknown template: %s" % (spec['kind'])) @@ -335,6 +347,7 @@ def _priority_class_from_spec(spec): return pc + def _priority_class_to_template_name(pc): if pc > PushRuleRestServlet.PRIORITY_CLASS_MAP['override']: # per-device @@ -343,6 +356,7 @@ def _priority_class_to_template_name(pc): else: return PushRuleRestServlet.PRIORITY_CLASS_INVERSE_MAP[pc] + def _rule_to_template(rule): template_name = _priority_class_to_template_name(rule['priority_class']) if template_name in ['override', 'underride']: @@ -359,8 +373,9 @@ def _rule_to_template(rule): ret["pattern"] = thecond["pattern"] return ret + def _strip_device_condition(rule): - for i,c in enumerate(rule['conditions']): + for i, c in enumerate(rule['conditions']): if c['kind'] == 'device': del rule['conditions'][i] return rule diff --git a/synapse/storage/push_rule.py b/synapse/storage/push_rule.py index c7b553292e..27502d2399 100644 --- a/synapse/storage/push_rule.py +++ b/synapse/storage/push_rule.py @@ -117,7 +117,7 @@ class PushRuleStore(SQLBaseStore): new_rule['priority'] = new_rule_priority sql = ( - "SELECT COUNT(*) FROM "+PushRuleTable.table_name+ + "SELECT COUNT(*) FROM " + PushRuleTable.table_name + " WHERE user_name = ? AND priority_class = ? AND priority = ?" ) txn.execute(sql, (user_name, priority_class, new_rule_priority)) @@ -146,10 +146,11 @@ class PushRuleStore(SQLBaseStore): txn.execute(sql, new_rule.values()) - def _add_push_rule_highest_priority_txn(self, txn, user_name, priority_class, **kwargs): + def _add_push_rule_highest_priority_txn(self, txn, user_name, + priority_class, **kwargs): # find the highest priority rule in that class sql = ( - "SELECT COUNT(*), MAX(priority) FROM "+PushRuleTable.table_name+ + "SELECT COUNT(*), MAX(priority) FROM " + PushRuleTable.table_name + " WHERE user_name = ? and priority_class = ?" ) txn.execute(sql, (user_name, priority_class)) @@ -209,4 +210,4 @@ class PushRuleTable(Table): "actions", ] - EntryType = collections.namedtuple("PushRuleEntry", fields) \ No newline at end of file + EntryType = collections.namedtuple("PushRuleEntry", fields) diff --git a/synapse/storage/pusher.py b/synapse/storage/pusher.py index 113cdc8a8e..f253c9e2c3 100644 --- a/synapse/storage/pusher.py +++ b/synapse/storage/pusher.py @@ -170,4 +170,4 @@ class PushersTable(Table): "failing_since" ] - EntryType = collections.namedtuple("PusherEntry", fields) \ No newline at end of file + EntryType = collections.namedtuple("PusherEntry", fields) -- cgit 1.5.1 From 4bdfce30d70dddaa7c6de551fe3c9eed4a899d49 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 29 Jan 2015 17:12:11 +0000 Subject: Renumber priority classes so we can use 0 for defaults. --- synapse/rest/client/v1/push_rule.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 2b1e930326..0f78fa667c 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -26,11 +26,11 @@ import json class PushRuleRestServlet(ClientV1RestServlet): PATTERN = client_path_pattern("/pushrules/.*$") PRIORITY_CLASS_MAP = { - 'underride': 0, - 'sender': 1, - 'room': 2, - 'content': 3, - 'override': 4, + 'underride': 1, + 'sender': 2, + 'room': 3, + 'content': 4, + 'override': 5, } PRIORITY_CLASS_INVERSE_MAP = {v: k for k, v in PRIORITY_CLASS_MAP.items()} SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR = ( -- cgit 1.5.1 From 4ffac34a646fa2e763ba9214199d7803d1174959 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 30 Jan 2015 15:02:21 +0000 Subject: Add glob asterisks when running rules. Means that now you can't do exact matches even in override rules, but I think we can live with that. Advantage is that you'll now always get back what was put in to the API. --- synapse/push/__init__.py | 5 +++++ synapse/rest/client/v1/push_rule.py | 5 +---- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/push/__init__.py b/synapse/push/__init__.py index cc05278c8c..6a302305fb 100644 --- a/synapse/push/__init__.py +++ b/synapse/push/__init__.py @@ -137,6 +137,11 @@ class Pusher(object): return False pat = condition['pattern'] + if pat.strip("*?[]") == pat: + # no special glob characters so we assume the user means + # 'contains this string' rather than 'is this string' + pat = "*%s*" % (pat,) + val = _value_for_dotted_key(condition['key'], ev) if val is None: return False diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 0f78fa667c..61e3bc8236 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -98,10 +98,7 @@ class PushRuleRestServlet(ClientV1RestServlet): if 'pattern' not in req_obj: raise InvalidRuleException("Content rule missing 'pattern'") pat = req_obj['pattern'] - if pat.strip("*?[]") == pat: - # no special glob characters so we assume the user means - # 'contains this string' rather than 'is this string' - pat = "*%s*" % (pat,) + conditions = [{ 'kind': 'event_match', 'key': 'content.body', -- cgit 1.5.1 From b4b892f4a3f9194289f57ed2d166eca26da41594 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 30 Jan 2015 15:54:29 +0000 Subject: Spit out server default rules too. --- synapse/push/baserules.py | 11 +++++------ synapse/rest/client/v1/push_rule.py | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 10 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/push/baserules.py b/synapse/push/baserules.py index bd162baade..382de118e0 100644 --- a/synapse/push/baserules.py +++ b/synapse/push/baserules.py @@ -1,9 +1,5 @@ def make_base_rules(user_name): - """ - Nominally we reserve priority class 0 for these rules, although - in practice we just append them to the end so we don't actually need it. - """ - return [ + rules = [ { 'conditions': [ { @@ -46,4 +42,7 @@ def make_base_rules(user_name): } ] } - ] \ No newline at end of file + ] + for r in rules: + r['priority_class'] = 0 + return rules \ No newline at end of file diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 61e3bc8236..faa7919fbb 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -19,6 +19,7 @@ from synapse.api.errors import SynapseError, Codes, UnrecognizedRequestError, No StoreError from .base import ClientV1RestServlet, client_path_pattern from synapse.storage.push_rule import InconsistentRuleException, RuleNotFoundException +import synapse.push.baserules as baserules import json @@ -26,6 +27,7 @@ import json class PushRuleRestServlet(ClientV1RestServlet): PATTERN = client_path_pattern("/pushrules/.*$") PRIORITY_CLASS_MAP = { + 'default': 0, 'underride': 1, 'sender': 2, 'room': 3, @@ -137,6 +139,9 @@ class PushRuleRestServlet(ClientV1RestServlet): user, _ = yield self.auth.get_user_by_req(request) + if spec['template'] == 'default': + raise SynapseError(403, "The default rules are immutable.") + content = _parse_json(request) try: @@ -218,6 +223,10 @@ class PushRuleRestServlet(ClientV1RestServlet): # to send which means doing unnecessary work sometimes but is # is probably not going to make a whole lot of difference rawrules = yield self.hs.get_datastore().get_push_rules_for_user_name(user.to_string()) + for r in rawrules: + r["conditions"] = json.loads(r["conditions"]) + r["actions"] = json.loads(r["actions"]) + rawrules.extend(baserules.make_base_rules(user.to_string())) rules = {'global': {}, 'device': {}} @@ -226,9 +235,6 @@ class PushRuleRestServlet(ClientV1RestServlet): for r in rawrules: rulearray = None - r["conditions"] = json.loads(r["conditions"]) - r["actions"] = json.loads(r["actions"]) - template_name = _priority_class_to_template_name(r['priority_class']) if r['priority_class'] > PushRuleRestServlet.PRIORITY_CLASS_MAP['override']: @@ -356,7 +362,9 @@ def _priority_class_to_template_name(pc): def _rule_to_template(rule): template_name = _priority_class_to_template_name(rule['priority_class']) - if template_name in ['override', 'underride']: + if template_name in ['default']: + return {k: rule[k] for k in ["conditions", "actions"]} + elif template_name in ['override', 'underride']: return {k: rule[k] for k in ["rule_id", "conditions", "actions"]} elif template_name in ["sender", "room"]: return {k: rule[k] for k in ["rule_id", "actions"]} -- cgit 1.5.1 From dc7bb70f22edf8ef0631c961f2c77a82de7c76d5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 3 Feb 2015 16:51:07 +0000 Subject: s/instance_handle/profile_tag/ --- synapse/push/__init__.py | 8 ++++---- synapse/push/httppusher.py | 4 ++-- synapse/push/pusherpool.py | 12 ++++++------ synapse/rest/client/v1/push_rule.py | 28 ++++++++++++++-------------- synapse/rest/client/v1/pusher.py | 4 ++-- synapse/storage/pusher.py | 14 +++++++------- synapse/storage/schema/delta/v12.sql | 2 +- synapse/storage/schema/pusher.sql | 2 +- 8 files changed, 37 insertions(+), 37 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/push/__init__.py b/synapse/push/__init__.py index 00f3513c23..8c6f0a6571 100644 --- a/synapse/push/__init__.py +++ b/synapse/push/__init__.py @@ -37,14 +37,14 @@ class Pusher(object): INEQUALITY_EXPR = re.compile("^([=<>]*)([0-9]*)$") - def __init__(self, _hs, instance_handle, user_name, app_id, + def __init__(self, _hs, profile_tag, user_name, app_id, app_display_name, device_display_name, pushkey, pushkey_ts, data, last_token, last_success, failing_since): self.hs = _hs self.evStreamHandler = self.hs.get_handlers().event_stream_handler self.store = self.hs.get_datastore() self.clock = self.hs.get_clock() - self.instance_handle = instance_handle + self.profile_tag = profile_tag self.user_name = user_name self.app_id = app_id self.app_display_name = app_display_name @@ -147,9 +147,9 @@ class Pusher(object): return False return fnmatch.fnmatch(val.upper(), pat.upper()) elif condition['kind'] == 'device': - if 'instance_handle' not in condition: + if 'profile_tag' not in condition: return True - return condition['instance_handle'] == self.instance_handle + return condition['profile_tag'] == self.profile_tag elif condition['kind'] == 'contains_display_name': # This is special because display names can be different # between rooms and so you can't really hard code it in a rule. diff --git a/synapse/push/httppusher.py b/synapse/push/httppusher.py index 7c6953c989..5788db4eba 100644 --- a/synapse/push/httppusher.py +++ b/synapse/push/httppusher.py @@ -24,12 +24,12 @@ logger = logging.getLogger(__name__) class HttpPusher(Pusher): - def __init__(self, _hs, instance_handle, user_name, app_id, + def __init__(self, _hs, profile_tag, user_name, app_id, app_display_name, device_display_name, pushkey, pushkey_ts, data, last_token, last_success, failing_since): super(HttpPusher, self).__init__( _hs, - instance_handle, + profile_tag, user_name, app_id, app_display_name, diff --git a/synapse/push/pusherpool.py b/synapse/push/pusherpool.py index 4892c21e7b..5a525befd7 100644 --- a/synapse/push/pusherpool.py +++ b/synapse/push/pusherpool.py @@ -55,7 +55,7 @@ class PusherPool: self._start_pushers(pushers) @defer.inlineCallbacks - def add_pusher(self, user_name, instance_handle, kind, app_id, + def add_pusher(self, user_name, profile_tag, kind, app_id, app_display_name, device_display_name, pushkey, lang, data): # we try to create the pusher just to validate the config: it # will then get pulled out of the database, @@ -64,7 +64,7 @@ class PusherPool: self._create_pusher({ "user_name": user_name, "kind": kind, - "instance_handle": instance_handle, + "profile_tag": profile_tag, "app_id": app_id, "app_display_name": app_display_name, "device_display_name": device_display_name, @@ -77,18 +77,18 @@ class PusherPool: "failing_since": None }) yield self._add_pusher_to_store( - user_name, instance_handle, kind, app_id, + user_name, profile_tag, kind, app_id, app_display_name, device_display_name, pushkey, lang, data ) @defer.inlineCallbacks - def _add_pusher_to_store(self, user_name, instance_handle, kind, app_id, + def _add_pusher_to_store(self, user_name, profile_tag, kind, app_id, app_display_name, device_display_name, pushkey, lang, data): yield self.store.add_pusher( user_name=user_name, - instance_handle=instance_handle, + profile_tag=profile_tag, kind=kind, app_id=app_id, app_display_name=app_display_name, @@ -104,7 +104,7 @@ class PusherPool: if pusherdict['kind'] == 'http': return HttpPusher( self.hs, - instance_handle=pusherdict['instance_handle'], + profile_tag=pusherdict['profile_tag'], user_name=pusherdict['user_name'], app_id=pusherdict['app_id'], app_display_name=pusherdict['app_display_name'], diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index faa7919fbb..348adb9c0d 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -112,7 +112,7 @@ class PushRuleRestServlet(ClientV1RestServlet): if device: conditions.append({ 'kind': 'device', - 'instance_handle': device + 'profile_tag': device }) if 'actions' not in req_obj: @@ -195,7 +195,7 @@ class PushRuleRestServlet(ClientV1RestServlet): for r in rules: conditions = json.loads(r['conditions']) - ih = _instance_handle_from_conditions(conditions) + ih = _profile_tag_from_conditions(conditions) if ih == spec['device'] and r['priority_class'] == priority_class: yield self.hs.get_datastore().delete_push_rule( user.to_string(), spec['rule_id'] @@ -239,19 +239,19 @@ class PushRuleRestServlet(ClientV1RestServlet): if r['priority_class'] > PushRuleRestServlet.PRIORITY_CLASS_MAP['override']: # per-device rule - instance_handle = _instance_handle_from_conditions(r["conditions"]) + profile_tag = _profile_tag_from_conditions(r["conditions"]) r = _strip_device_condition(r) - if not instance_handle: + if not profile_tag: continue - if instance_handle not in rules['device']: - rules['device'][instance_handle] = {} - rules['device'][instance_handle] = ( + if profile_tag not in rules['device']: + rules['device'][profile_tag] = {} + rules['device'][profile_tag] = ( _add_empty_priority_class_arrays( - rules['device'][instance_handle] + rules['device'][profile_tag] ) ) - rulearray = rules['device'][instance_handle][template_name] + rulearray = rules['device'][profile_tag][template_name] else: rulearray = rules['global'][template_name] @@ -282,13 +282,13 @@ class PushRuleRestServlet(ClientV1RestServlet): if path[0] == '': defer.returnValue((200, rules['device'])) - instance_handle = path[0] + profile_tag = path[0] path = path[1:] - if instance_handle not in rules['device']: + if profile_tag not in rules['device']: ret = {} ret = _add_empty_priority_class_arrays(ret) defer.returnValue((200, ret)) - ruleset = rules['device'][instance_handle] + ruleset = rules['device'][profile_tag] result = _filter_ruleset_with_path(ruleset, path) defer.returnValue((200, result)) else: @@ -304,14 +304,14 @@ def _add_empty_priority_class_arrays(d): return d -def _instance_handle_from_conditions(conditions): +def _profile_tag_from_conditions(conditions): """ Given a list of conditions, return the instance handle of the device rule if there is one """ for c in conditions: if c['kind'] == 'device': - return c['instance_handle'] + return c['profile_tag'] return None diff --git a/synapse/rest/client/v1/pusher.py b/synapse/rest/client/v1/pusher.py index 353a4a6589..e10d2576d2 100644 --- a/synapse/rest/client/v1/pusher.py +++ b/synapse/rest/client/v1/pusher.py @@ -41,7 +41,7 @@ class PusherRestServlet(ClientV1RestServlet): ) defer.returnValue((200, {})) - reqd = ['instance_handle', 'kind', 'app_id', 'app_display_name', + reqd = ['profile_tag', 'kind', 'app_id', 'app_display_name', 'device_display_name', 'pushkey', 'lang', 'data'] missing = [] for i in reqd: @@ -54,7 +54,7 @@ class PusherRestServlet(ClientV1RestServlet): try: yield pusher_pool.add_pusher( user_name=user.to_string(), - instance_handle=content['instance_handle'], + profile_tag=content['profile_tag'], kind=content['kind'], app_id=content['app_id'], app_display_name=content['app_display_name'], diff --git a/synapse/storage/pusher.py b/synapse/storage/pusher.py index f253c9e2c3..e2a662a6c7 100644 --- a/synapse/storage/pusher.py +++ b/synapse/storage/pusher.py @@ -29,7 +29,7 @@ class PusherStore(SQLBaseStore): @defer.inlineCallbacks def get_pushers_by_app_id_and_pushkey(self, app_id_and_pushkey): sql = ( - "SELECT id, user_name, kind, instance_handle, app_id," + "SELECT id, user_name, kind, profile_tag, app_id," "app_display_name, device_display_name, pushkey, ts, data, " "last_token, last_success, failing_since " "FROM pushers " @@ -45,7 +45,7 @@ class PusherStore(SQLBaseStore): "id": r[0], "user_name": r[1], "kind": r[2], - "instance_handle": r[3], + "profile_tag": r[3], "app_id": r[4], "app_display_name": r[5], "device_display_name": r[6], @@ -64,7 +64,7 @@ class PusherStore(SQLBaseStore): @defer.inlineCallbacks def get_all_pushers(self): sql = ( - "SELECT id, user_name, kind, instance_handle, app_id," + "SELECT id, user_name, kind, profile_tag, app_id," "app_display_name, device_display_name, pushkey, ts, data, " "last_token, last_success, failing_since " "FROM pushers" @@ -77,7 +77,7 @@ class PusherStore(SQLBaseStore): "id": r[0], "user_name": r[1], "kind": r[2], - "instance_handle": r[3], + "profile_tag": r[3], "app_id": r[4], "app_display_name": r[5], "device_display_name": r[6], @@ -94,7 +94,7 @@ class PusherStore(SQLBaseStore): defer.returnValue(ret) @defer.inlineCallbacks - def add_pusher(self, user_name, instance_handle, kind, app_id, + def add_pusher(self, user_name, profile_tag, kind, app_id, app_display_name, device_display_name, pushkey, pushkey_ts, lang, data): try: @@ -107,7 +107,7 @@ class PusherStore(SQLBaseStore): dict( user_name=user_name, kind=kind, - instance_handle=instance_handle, + profile_tag=profile_tag, app_display_name=app_display_name, device_display_name=device_display_name, ts=pushkey_ts, @@ -158,7 +158,7 @@ class PushersTable(Table): "id", "user_name", "kind", - "instance_handle", + "profile_tag", "app_id", "app_display_name", "device_display_name", diff --git a/synapse/storage/schema/delta/v12.sql b/synapse/storage/schema/delta/v12.sql index a6867cba62..16c2258ca4 100644 --- a/synapse/storage/schema/delta/v12.sql +++ b/synapse/storage/schema/delta/v12.sql @@ -24,7 +24,7 @@ CREATE TABLE IF NOT EXISTS rejections( CREATE TABLE IF NOT EXISTS pushers ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_name TEXT NOT NULL, - instance_handle varchar(32) NOT NULL, + profile_tag varchar(32) NOT NULL, kind varchar(8) NOT NULL, app_id varchar(64) NOT NULL, app_display_name varchar(64) NOT NULL, diff --git a/synapse/storage/schema/pusher.sql b/synapse/storage/schema/pusher.sql index 8c4dfd5c1b..3735b11547 100644 --- a/synapse/storage/schema/pusher.sql +++ b/synapse/storage/schema/pusher.sql @@ -16,7 +16,7 @@ CREATE TABLE IF NOT EXISTS pushers ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_name TEXT NOT NULL, - instance_handle varchar(32) NOT NULL, + profile_tag varchar(32) NOT NULL, kind varchar(8) NOT NULL, app_id varchar(64) NOT NULL, app_display_name varchar(64) NOT NULL, -- cgit 1.5.1 From 2e77ba637a75adcf0681e04c281f4fea74ebec6b Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 4 Feb 2015 16:24:15 +0000 Subject: More s/instance_handle/profile_tag/ --- synapse/rest/client/v1/push_rule.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 348adb9c0d..5582f33c8e 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -73,7 +73,7 @@ class PushRuleRestServlet(ClientV1RestServlet): 'rule_id': rule_id } if device: - spec['device'] = device + spec['profile_tag'] = device return spec def rule_tuple_from_request_object(self, rule_template, rule_id, req_obj, device=None): @@ -188,15 +188,15 @@ class PushRuleRestServlet(ClientV1RestServlet): user, _ = yield self.auth.get_user_by_req(request) - if 'device' in spec: + if 'profile_tag' in spec: rules = yield self.hs.get_datastore().get_push_rules_for_user_name( user.to_string() ) for r in rules: conditions = json.loads(r['conditions']) - ih = _profile_tag_from_conditions(conditions) - if ih == spec['device'] and r['priority_class'] == priority_class: + pt = _profile_tag_from_conditions(conditions) + if pt == spec['profile_tag'] and r['priority_class'] == priority_class: yield self.hs.get_datastore().delete_push_rule( user.to_string(), spec['rule_id'] ) @@ -306,7 +306,7 @@ def _add_empty_priority_class_arrays(d): def _profile_tag_from_conditions(conditions): """ - Given a list of conditions, return the instance handle of the + Given a list of conditions, return the profile tag of the device rule if there is one """ for c in conditions: -- cgit 1.5.1 From f90782a6589ee567d6dc9ead19451cc8a0aabdd3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 5 Feb 2015 09:35:21 +0000 Subject: namespace rule IDs to be unique within their scope and rule type. --- synapse/rest/client/v1/push_rule.py | 252 ++++++++++++++++++------------------ 1 file changed, 129 insertions(+), 123 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 5582f33c8e..eaef55cc1e 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -38,100 +38,9 @@ class PushRuleRestServlet(ClientV1RestServlet): SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR = ( "Unrecognised request: You probably wanted a trailing slash") - def rule_spec_from_path(self, path): - if len(path) < 2: - raise UnrecognizedRequestError() - if path[0] != 'pushrules': - raise UnrecognizedRequestError() - - scope = path[1] - path = path[2:] - if scope not in ['global', 'device']: - raise UnrecognizedRequestError() - - device = None - if scope == 'device': - if len(path) == 0: - raise UnrecognizedRequestError() - device = path[0] - path = path[1:] - - if len(path) == 0: - raise UnrecognizedRequestError() - - template = path[0] - path = path[1:] - - if len(path) == 0: - raise UnrecognizedRequestError() - - rule_id = path[0] - - spec = { - 'scope': scope, - 'template': template, - 'rule_id': rule_id - } - if device: - spec['profile_tag'] = device - return spec - - def rule_tuple_from_request_object(self, rule_template, rule_id, req_obj, device=None): - if rule_template in ['override', 'underride']: - if 'conditions' not in req_obj: - raise InvalidRuleException("Missing 'conditions'") - conditions = req_obj['conditions'] - for c in conditions: - if 'kind' not in c: - raise InvalidRuleException("Condition without 'kind'") - elif rule_template == 'room': - conditions = [{ - 'kind': 'event_match', - 'key': 'room_id', - 'pattern': rule_id - }] - elif rule_template == 'sender': - conditions = [{ - 'kind': 'event_match', - 'key': 'user_id', - 'pattern': rule_id - }] - elif rule_template == 'content': - if 'pattern' not in req_obj: - raise InvalidRuleException("Content rule missing 'pattern'") - pat = req_obj['pattern'] - - conditions = [{ - 'kind': 'event_match', - 'key': 'content.body', - 'pattern': pat - }] - else: - raise InvalidRuleException("Unknown rule template: %s" % (rule_template,)) - - if device: - conditions.append({ - 'kind': 'device', - 'profile_tag': device - }) - - if 'actions' not in req_obj: - raise InvalidRuleException("No actions found") - actions = req_obj['actions'] - - for a in actions: - if a in ['notify', 'dont_notify', 'coalesce']: - pass - elif isinstance(a, dict) and 'set_sound' in a: - pass - else: - raise InvalidRuleException("Unrecognised action") - - return conditions, actions - @defer.inlineCallbacks def on_PUT(self, request): - spec = self.rule_spec_from_path(request.postpath) + spec = _rule_spec_from_path(request.postpath) try: priority_class = _priority_class_from_spec(spec) except InvalidRuleException as e: @@ -142,10 +51,13 @@ class PushRuleRestServlet(ClientV1RestServlet): if spec['template'] == 'default': raise SynapseError(403, "The default rules are immutable.") + if not spec['rule_id'].isalnum(): + raise SynapseError(400, "rule_id may only contain alphanumeric characters") + content = _parse_json(request) try: - (conditions, actions) = self.rule_tuple_from_request_object( + (conditions, actions) = _rule_tuple_from_request_object( spec['template'], spec['rule_id'], content, @@ -164,7 +76,7 @@ class PushRuleRestServlet(ClientV1RestServlet): try: yield self.hs.get_datastore().add_push_rule( user_name=user.to_string(), - rule_id=spec['rule_id'], + rule_id=_namespaced_rule_id_from_spec(spec), priority_class=priority_class, conditions=conditions, actions=actions, @@ -180,7 +92,7 @@ class PushRuleRestServlet(ClientV1RestServlet): @defer.inlineCallbacks def on_DELETE(self, request): - spec = self.rule_spec_from_path(request.postpath) + spec = _rule_spec_from_path(request.postpath) try: priority_class = _priority_class_from_spec(spec) except InvalidRuleException as e: @@ -188,32 +100,18 @@ class PushRuleRestServlet(ClientV1RestServlet): user, _ = yield self.auth.get_user_by_req(request) - if 'profile_tag' in spec: - rules = yield self.hs.get_datastore().get_push_rules_for_user_name( - user.to_string() - ) + namespaced_rule_id = _namespaced_rule_id_from_spec(spec) - for r in rules: - conditions = json.loads(r['conditions']) - pt = _profile_tag_from_conditions(conditions) - if pt == spec['profile_tag'] and r['priority_class'] == priority_class: - yield self.hs.get_datastore().delete_push_rule( - user.to_string(), spec['rule_id'] - ) - defer.returnValue((200, {})) - raise NotFoundError() - else: - try: - yield self.hs.get_datastore().delete_push_rule( - user.to_string(), spec['rule_id'], - priority_class=priority_class - ) - defer.returnValue((200, {})) - except StoreError as e: - if e.code == 404: - raise NotFoundError() - else: - raise + try: + yield self.hs.get_datastore().delete_push_rule( + user.to_string(), namespaced_rule_id + ) + defer.returnValue((200, {})) + except StoreError as e: + if e.code == 404: + raise NotFoundError() + else: + raise @defer.inlineCallbacks def on_GET(self, request): @@ -298,6 +196,99 @@ class PushRuleRestServlet(ClientV1RestServlet): return 200, {} +def _rule_spec_from_path(path): + if len(path) < 2: + raise UnrecognizedRequestError() + if path[0] != 'pushrules': + raise UnrecognizedRequestError() + + scope = path[1] + path = path[2:] + if scope not in ['global', 'device']: + raise UnrecognizedRequestError() + + device = None + if scope == 'device': + if len(path) == 0: + raise UnrecognizedRequestError() + device = path[0] + path = path[1:] + + if len(path) == 0: + raise UnrecognizedRequestError() + + template = path[0] + path = path[1:] + + if len(path) == 0: + raise UnrecognizedRequestError() + + rule_id = path[0] + + spec = { + 'scope': scope, + 'template': template, + 'rule_id': rule_id + } + if device: + spec['profile_tag'] = device + return spec + + +def _rule_tuple_from_request_object(rule_template, rule_id, req_obj, device=None): + if rule_template in ['override', 'underride']: + if 'conditions' not in req_obj: + raise InvalidRuleException("Missing 'conditions'") + conditions = req_obj['conditions'] + for c in conditions: + if 'kind' not in c: + raise InvalidRuleException("Condition without 'kind'") + elif rule_template == 'room': + conditions = [{ + 'kind': 'event_match', + 'key': 'room_id', + 'pattern': rule_id + }] + elif rule_template == 'sender': + conditions = [{ + 'kind': 'event_match', + 'key': 'user_id', + 'pattern': rule_id + }] + elif rule_template == 'content': + if 'pattern' not in req_obj: + raise InvalidRuleException("Content rule missing 'pattern'") + pat = req_obj['pattern'] + + conditions = [{ + 'kind': 'event_match', + 'key': 'content.body', + 'pattern': pat + }] + else: + raise InvalidRuleException("Unknown rule template: %s" % (rule_template,)) + + if device: + conditions.append({ + 'kind': 'device', + 'profile_tag': device + }) + + if 'actions' not in req_obj: + raise InvalidRuleException("No actions found") + actions = req_obj['actions'] + + for a in actions: + if a in ['notify', 'dont_notify', 'coalesce']: + pass + elif isinstance(a, dict) and 'set_sound' in a: + pass + else: + raise InvalidRuleException("Unrecognised action") + + return conditions, actions + + def _add_empty_priority_class_arrays(d): for pc in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): d[pc] = [] @@ -361,20 +352,24 @@ def _priority_class_to_template_name(pc): def _rule_to_template(rule): + unscoped_rule_id = _rule_id_from_namespaced(rule['rule_id']) + template_name = _priority_class_to_template_name(rule['priority_class']) if template_name in ['default']: return {k: rule[k] for k in ["conditions", "actions"]} elif template_name in ['override', 'underride']: - return {k: rule[k] for k in ["rule_id", "conditions", "actions"]} + ret = {k: rule[k] for k in ["conditions", "actions"]} + ret['rule_id'] = unscoped_rule_id + return ret elif template_name in ["sender", "room"]: - return {k: rule[k] for k in ["rule_id", "actions"]} + return {'rule_id': unscoped_rule_id, 'actions': rule['actions']} elif template_name == 'content': if len(rule["conditions"]) != 1: return None thecond = rule["conditions"][0] if "pattern" not in thecond: return None - ret = {k: rule[k] for k in ["rule_id", "actions"]} + ret = {'rule_id': unscoped_rule_id, 'actions': rule['actions']} ret["pattern"] = thecond["pattern"] return ret @@ -386,6 +381,17 @@ def _strip_device_condition(rule): return rule +def _namespaced_rule_id_from_spec(spec): + if spec['scope'] == 'global': + scope = 'global' + else: + scope = 'device.%s' % (spec['profile_tag']) + return "%s.%s.%s" % (scope, spec['template'], spec['rule_id']) + + +def _rule_id_from_namespaced(in_rule_id, spec): + return in_rule_id.split('.')[-1] + class InvalidRuleException(Exception): pass -- cgit 1.5.1 From 2df41aa1386545f4237c0141c19db1fef85e7161 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 5 Feb 2015 14:46:06 +0000 Subject: Server default rules now of all kinds rather than all being at lowest prio. --- synapse/push/__init__.py | 8 ++--- synapse/push/baserules.py | 62 +++++++++++++++++++++++++++----- synapse/push/rulekinds.py | 8 +++++ synapse/rest/client/v1/push_rule.py | 71 +++++++++++++++++-------------------- 4 files changed, 98 insertions(+), 51 deletions(-) create mode 100644 synapse/push/rulekinds.py (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/push/__init__.py b/synapse/push/__init__.py index 8c6f0a6571..7293715293 100644 --- a/synapse/push/__init__.py +++ b/synapse/push/__init__.py @@ -77,15 +77,15 @@ class Pusher(object): if ev['state_key'] != self.user_name: defer.returnValue(['dont_notify']) - rules = yield self.store.get_push_rules_for_user_name(self.user_name) + rawrules = yield self.store.get_push_rules_for_user_name(self.user_name) - for r in rules: + for r in rawrules: r['conditions'] = json.loads(r['conditions']) r['actions'] = json.loads(r['actions']) - user_name_localpart = UserID.from_string(self.user_name).localpart + user = UserID.from_string(self.user_name) - rules.extend(baserules.make_base_rules(user_name_localpart)) + rules = baserules.list_with_base_rules(rawrules, user) # get *our* member event for display name matching member_events_for_room = yield self.store.get_current_state( diff --git a/synapse/push/baserules.py b/synapse/push/baserules.py index 376d1d4d33..191909ad4d 100644 --- a/synapse/push/baserules.py +++ b/synapse/push/baserules.py @@ -1,20 +1,68 @@ -def make_base_rules(user_name): - rules = [ +from synapse.push.rulekinds import PRIORITY_CLASS_MAP, PRIORITY_CLASS_INVERSE_MAP + +def list_with_base_rules(rawrules, user_name): + ruleslist = [] + + # shove the server default rules for each kind onto the end of each + current_prio_class = 1 + for r in rawrules: + if r['priority_class'] > current_prio_class: + while current_prio_class < r['priority_class']: + ruleslist.extend(make_base_rules( + user_name, + PRIORITY_CLASS_INVERSE_MAP[current_prio_class]) + ) + current_prio_class += 1 + + ruleslist.append(r) + + while current_prio_class <= PRIORITY_CLASS_INVERSE_MAP.keys()[-1]: + ruleslist.extend(make_base_rules( + user_name, + PRIORITY_CLASS_INVERSE_MAP[current_prio_class]) + ) + current_prio_class += 1 + + return ruleslist + + +def make_base_rules(user, kind): + rules = [] + + if kind == 'override': + rules = make_base_override_rules() + elif kind == 'content': + rules = make_base_content_rules(user) + + for r in rules: + r['priority_class'] = PRIORITY_CLASS_MAP[kind] + + return rules + + +def make_base_content_rules(user): + return [ { 'conditions': [ { 'kind': 'event_match', 'key': 'content.body', - 'pattern': '*%s*' % (user_name,), # Matrix ID match + 'pattern': user.localpart, # Matrix ID match } ], 'actions': [ 'notify', { - 'set_sound': 'default' + 'set_tweak': 'sound', + 'value': 'default', } ] }, + ] + + +def make_base_override_rules(): + return [ { 'conditions': [ { @@ -24,7 +72,8 @@ def make_base_rules(user_name): 'actions': [ 'notify', { - 'set_sound': 'default' + 'set_tweak': 'sound', + 'value': 'default' } ] }, @@ -44,6 +93,3 @@ def make_base_rules(user_name): ] } ] - for r in rules: - r['priority_class'] = 0 - return rules \ No newline at end of file diff --git a/synapse/push/rulekinds.py b/synapse/push/rulekinds.py new file mode 100644 index 0000000000..763bdee58e --- /dev/null +++ b/synapse/push/rulekinds.py @@ -0,0 +1,8 @@ +PRIORITY_CLASS_MAP = { + 'underride': 1, + 'sender': 2, + 'room': 3, + 'content': 4, + 'override': 5, + } +PRIORITY_CLASS_INVERSE_MAP = {v: k for k, v in PRIORITY_CLASS_MAP.items()} diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index eaef55cc1e..7ab167ce03 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -20,21 +20,13 @@ from synapse.api.errors import SynapseError, Codes, UnrecognizedRequestError, No from .base import ClientV1RestServlet, client_path_pattern from synapse.storage.push_rule import InconsistentRuleException, RuleNotFoundException import synapse.push.baserules as baserules +from synapse.push.rulekinds import PRIORITY_CLASS_MAP, PRIORITY_CLASS_INVERSE_MAP import json class PushRuleRestServlet(ClientV1RestServlet): PATTERN = client_path_pattern("/pushrules/.*$") - PRIORITY_CLASS_MAP = { - 'default': 0, - 'underride': 1, - 'sender': 2, - 'room': 3, - 'content': 4, - 'override': 5, - } - PRIORITY_CLASS_INVERSE_MAP = {v: k for k, v in PRIORITY_CLASS_MAP.items()} SLIGHTLY_PEDANTIC_TRAILING_SLASH_ERROR = ( "Unrecognised request: You probably wanted a trailing slash") @@ -48,11 +40,8 @@ class PushRuleRestServlet(ClientV1RestServlet): user, _ = yield self.auth.get_user_by_req(request) - if spec['template'] == 'default': - raise SynapseError(403, "The default rules are immutable.") - - if not spec['rule_id'].isalnum(): - raise SynapseError(400, "rule_id may only contain alphanumeric characters") + if '/' in spec['rule_id'] or '\\' in spec['rule_id']: + raise SynapseError(400, "rule_id may not contain slashes") content = _parse_json(request) @@ -121,21 +110,23 @@ class PushRuleRestServlet(ClientV1RestServlet): # to send which means doing unnecessary work sometimes but is # is probably not going to make a whole lot of difference rawrules = yield self.hs.get_datastore().get_push_rules_for_user_name(user.to_string()) + for r in rawrules: r["conditions"] = json.loads(r["conditions"]) r["actions"] = json.loads(r["actions"]) - rawrules.extend(baserules.make_base_rules(user.to_string())) + + ruleslist = baserules.list_with_base_rules(rawrules, user) rules = {'global': {}, 'device': {}} rules['global'] = _add_empty_priority_class_arrays(rules['global']) - for r in rawrules: + for r in ruleslist: rulearray = None template_name = _priority_class_to_template_name(r['priority_class']) - if r['priority_class'] > PushRuleRestServlet.PRIORITY_CLASS_MAP['override']: + if r['priority_class'] > PRIORITY_CLASS_MAP['override']: # per-device rule profile_tag = _profile_tag_from_conditions(r["conditions"]) r = _strip_device_condition(r) @@ -290,7 +281,7 @@ def _rule_tuple_from_request_object(rule_template, rule_id, req_obj, device=None def _add_empty_priority_class_arrays(d): - for pc in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): + for pc in PRIORITY_CLASS_MAP.keys(): d[pc] = [] return d @@ -332,46 +323,48 @@ def _filter_ruleset_with_path(ruleset, path): def _priority_class_from_spec(spec): - if spec['template'] not in PushRuleRestServlet.PRIORITY_CLASS_MAP.keys(): + if spec['template'] not in PRIORITY_CLASS_MAP.keys(): raise InvalidRuleException("Unknown template: %s" % (spec['kind'])) - pc = PushRuleRestServlet.PRIORITY_CLASS_MAP[spec['template']] + pc = PRIORITY_CLASS_MAP[spec['template']] if spec['scope'] == 'device': - pc += len(PushRuleRestServlet.PRIORITY_CLASS_MAP) + pc += len(PRIORITY_CLASS_MAP) return pc def _priority_class_to_template_name(pc): - if pc > PushRuleRestServlet.PRIORITY_CLASS_MAP['override']: + if pc > PRIORITY_CLASS_MAP['override']: # per-device prio_class_index = pc - len(PushRuleRestServlet.PRIORITY_CLASS_MAP) - return PushRuleRestServlet.PRIORITY_CLASS_INVERSE_MAP[prio_class_index] + return PRIORITY_CLASS_INVERSE_MAP[prio_class_index] else: - return PushRuleRestServlet.PRIORITY_CLASS_INVERSE_MAP[pc] + return PRIORITY_CLASS_INVERSE_MAP[pc] def _rule_to_template(rule): - unscoped_rule_id = _rule_id_from_namespaced(rule['rule_id']) + unscoped_rule_id = None + if 'rule_id' in rule: + _rule_id_from_namespaced(rule['rule_id']) template_name = _priority_class_to_template_name(rule['priority_class']) - if template_name in ['default']: - return {k: rule[k] for k in ["conditions", "actions"]} - elif template_name in ['override', 'underride']: - ret = {k: rule[k] for k in ["conditions", "actions"]} - ret['rule_id'] = unscoped_rule_id - return ret + if template_name in ['override', 'underride']: + templaterule = {k: rule[k] for k in ["conditions", "actions"]} elif template_name in ["sender", "room"]: - return {'rule_id': unscoped_rule_id, 'actions': rule['actions']} + templaterule = {'actions': rule['actions']} + unscoped_rule_id = rule['conditions'][0]['pattern'] elif template_name == 'content': if len(rule["conditions"]) != 1: return None thecond = rule["conditions"][0] if "pattern" not in thecond: return None - ret = {'rule_id': unscoped_rule_id, 'actions': rule['actions']} - ret["pattern"] = thecond["pattern"] - return ret + templaterule = {'actions': rule['actions']} + templaterule["pattern"] = thecond["pattern"] + + if unscoped_rule_id: + templaterule['rule_id'] = unscoped_rule_id + return templaterule def _strip_device_condition(rule): @@ -385,12 +378,12 @@ def _namespaced_rule_id_from_spec(spec): if spec['scope'] == 'global': scope = 'global' else: - scope = 'device.%s' % (spec['profile_tag']) - return "%s.%s.%s" % (scope, spec['template'], spec['rule_id']) + scope = 'device/%s' % (spec['profile_tag']) + return "%s/%s/%s" % (scope, spec['template'], spec['rule_id']) -def _rule_id_from_namespaced(in_rule_id, spec): - return in_rule_id.split('.')[-1] +def _rule_id_from_namespaced(in_rule_id): + return in_rule_id.split('/')[-1] class InvalidRuleException(Exception): pass -- cgit 1.5.1 From aaf50bf6f3d6adee92fa4d5cb55dbf3c5a13dbe3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 5 Feb 2015 15:11:38 +0000 Subject: Give server default rules the 'default' attribute and fix various brokenness. --- synapse/push/baserules.py | 1 + synapse/rest/client/v1/push_rule.py | 4 +++- synapse/storage/push_rule.py | 7 +++++-- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/push/baserules.py b/synapse/push/baserules.py index 191909ad4d..8d4b806da6 100644 --- a/synapse/push/baserules.py +++ b/synapse/push/baserules.py @@ -36,6 +36,7 @@ def make_base_rules(user, kind): for r in rules: r['priority_class'] = PRIORITY_CLASS_MAP[kind] + r['default'] = True return rules diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 7ab167ce03..80f116b1ed 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -345,7 +345,7 @@ def _priority_class_to_template_name(pc): def _rule_to_template(rule): unscoped_rule_id = None if 'rule_id' in rule: - _rule_id_from_namespaced(rule['rule_id']) + unscoped_rule_id = _rule_id_from_namespaced(rule['rule_id']) template_name = _priority_class_to_template_name(rule['priority_class']) if template_name in ['override', 'underride']: @@ -364,6 +364,8 @@ def _rule_to_template(rule): if unscoped_rule_id: templaterule['rule_id'] = unscoped_rule_id + if 'default' in rule: + templaterule['default'] = rule['default'] return templaterule diff --git a/synapse/storage/push_rule.py b/synapse/storage/push_rule.py index 27502d2399..30e23445d9 100644 --- a/synapse/storage/push_rule.py +++ b/synapse/storage/push_rule.py @@ -176,7 +176,7 @@ class PushRuleStore(SQLBaseStore): txn.execute(sql, new_rule.values()) @defer.inlineCallbacks - def delete_push_rule(self, user_name, rule_id, **kwargs): + def delete_push_rule(self, user_name, rule_id): """ Delete a push rule. Args specify the row to be deleted and can be any of the columns in the push_rule table, but below are the @@ -186,7 +186,10 @@ class PushRuleStore(SQLBaseStore): user_name (str): The matrix ID of the push rule owner rule_id (str): The rule_id of the rule to be deleted """ - yield self._simple_delete_one(PushRuleTable.table_name, kwargs) + yield self._simple_delete_one( + PushRuleTable.table_name, + {'user_name': user_name, 'rule_id': rule_id} + ) class RuleNotFoundException(Exception): -- cgit 1.5.1 From a93fa42bcef97b1e5f938a3a96f5afcbaeaef376 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 5 Feb 2015 15:45:16 +0000 Subject: priority class now dealt with in namespaced rule_id --- synapse/rest/client/v1/push_rule.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index 80f116b1ed..d43ade39dd 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -82,10 +82,6 @@ class PushRuleRestServlet(ClientV1RestServlet): @defer.inlineCallbacks def on_DELETE(self, request): spec = _rule_spec_from_path(request.postpath) - try: - priority_class = _priority_class_from_spec(spec) - except InvalidRuleException as e: - raise SynapseError(400, e.message) user, _ = yield self.auth.get_user_by_req(request) -- cgit 1.5.1 From b085fac7353e1cd395b89f9334c8273a8e996f48 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Tue, 10 Feb 2015 16:30:48 +0000 Subject: Code-style fixes --- synapse/handlers/presence.py | 4 +++- synapse/handlers/register.py | 13 ++++++++----- synapse/push/__init__.py | 8 +++++--- synapse/push/baserules.py | 11 ++++++----- synapse/push/rulekinds.py | 12 ++++++------ synapse/python_dependencies.py | 6 ++++-- synapse/rest/client/v1/push_rule.py | 18 +++++++++++++----- synapse/rest/client/v1/pusher.py | 4 ++-- synapse/rest/media/v1/upload_resource.py | 7 ++++--- synapse/storage/_base.py | 6 +++--- synapse/storage/push_rule.py | 4 +++- 11 files changed, 57 insertions(+), 36 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/handlers/presence.py b/synapse/handlers/presence.py index cd0798c2b0..6a266ee0fe 100644 --- a/synapse/handlers/presence.py +++ b/synapse/handlers/presence.py @@ -658,7 +658,9 @@ class PresenceHandler(BaseHandler): observers = set(self._remote_recvmap.get(user, set())) if observers: - logger.debug(" | %d interested local observers %r", len(observers), observers) + logger.debug( + " | %d interested local observers %r", len(observers), observers + ) rm_handler = self.homeserver.get_handlers().room_member_handler room_ids = yield rm_handler.get_rooms_for_user(user) diff --git a/synapse/handlers/register.py b/synapse/handlers/register.py index 4f06c487b1..0247327eb9 100644 --- a/synapse/handlers/register.py +++ b/synapse/handlers/register.py @@ -105,17 +105,20 @@ class RegistrationHandler(BaseHandler): # do it here. try: auth_user = UserID.from_string(user_id) - identicon_resource = self.hs.get_resource_for_media_repository().getChildWithDefault("identicon", None) - upload_resource = self.hs.get_resource_for_media_repository().getChildWithDefault("upload", None) + media_repository = self.hs.get_resource_for_media_repository() + identicon_resource = media_repository.getChildWithDefault("identicon", None) + upload_resource = media_repository.getChildWithDefault("upload", None) identicon_bytes = identicon_resource.generate_identicon(user_id, 320, 320) content_uri = yield upload_resource.create_content( "image/png", None, identicon_bytes, len(identicon_bytes), auth_user ) profile_handler = self.hs.get_handlers().profile_handler - profile_handler.set_avatar_url(auth_user, auth_user, ("%s#auto" % content_uri)) + profile_handler.set_avatar_url( + auth_user, auth_user, ("%s#auto" % (content_uri,)) + ) except NotImplementedError: - pass # make tests pass without messing around creating default avatars - + pass # make tests pass without messing around creating default avatars + defer.returnValue((user_id, token)) @defer.inlineCallbacks diff --git a/synapse/push/__init__.py b/synapse/push/__init__.py index 6f143a5df9..418a348a58 100644 --- a/synapse/push/__init__.py +++ b/synapse/push/__init__.py @@ -140,7 +140,7 @@ class Pusher(object): lambda x: ('[%s%s]' % (x.group(1) and '^' or '', re.sub(r'\\\-', '-', x.group(2)))), r) return r - + def _event_fulfills_condition(self, ev, condition, display_name, room_member_count): if condition['kind'] == 'event_match': if 'pattern' not in condition: @@ -170,8 +170,10 @@ class Pusher(object): return False if not display_name: return False - return re.search("\b%s\b" % re.escape(display_name), - ev['content']['body'], flags=re.IGNORECASE) is not None + return re.search( + "\b%s\b" % re.escape(display_name), ev['content']['body'], + flags=re.IGNORECASE + ) is not None elif condition['kind'] == 'room_member_count': if 'is' not in condition: diff --git a/synapse/push/baserules.py b/synapse/push/baserules.py index 37878f1e0b..162d265f66 100644 --- a/synapse/push/baserules.py +++ b/synapse/push/baserules.py @@ -1,5 +1,6 @@ from synapse.push.rulekinds import PRIORITY_CLASS_MAP, PRIORITY_CLASS_INVERSE_MAP + def list_with_base_rules(rawrules, user_name): ruleslist = [] @@ -9,9 +10,9 @@ def list_with_base_rules(rawrules, user_name): if r['priority_class'] < current_prio_class: while r['priority_class'] < current_prio_class: ruleslist.extend(make_base_rules( - user_name, - PRIORITY_CLASS_INVERSE_MAP[current_prio_class]) - ) + user_name, + PRIORITY_CLASS_INVERSE_MAP[current_prio_class] + )) current_prio_class -= 1 ruleslist.append(r) @@ -19,8 +20,8 @@ def list_with_base_rules(rawrules, user_name): while current_prio_class > 0: ruleslist.extend(make_base_rules( user_name, - PRIORITY_CLASS_INVERSE_MAP[current_prio_class]) - ) + PRIORITY_CLASS_INVERSE_MAP[current_prio_class] + )) current_prio_class -= 1 return ruleslist diff --git a/synapse/push/rulekinds.py b/synapse/push/rulekinds.py index 763bdee58e..660aa4e10e 100644 --- a/synapse/push/rulekinds.py +++ b/synapse/push/rulekinds.py @@ -1,8 +1,8 @@ PRIORITY_CLASS_MAP = { - 'underride': 1, - 'sender': 2, - 'room': 3, - 'content': 4, - 'override': 5, - } + 'underride': 1, + 'sender': 2, + 'room': 3, + 'content': 4, + 'override': 5, +} PRIORITY_CLASS_INVERSE_MAP = {v: k for k, v in PRIORITY_CLASS_MAP.items()} diff --git a/synapse/python_dependencies.py b/synapse/python_dependencies.py index a89d618606..fd68da9dfb 100644 --- a/synapse/python_dependencies.py +++ b/synapse/python_dependencies.py @@ -19,10 +19,11 @@ REQUIREMENTS = { "pydenticon": ["pydenticon"], } + def github_link(project, version, egg): return "https://github.com/%s/tarball/%s/#egg=%s" % (project, version, egg) -DEPENDENCY_LINKS=[ +DEPENDENCY_LINKS = [ github_link( project="matrix-org/syutil", version="v0.0.2", @@ -101,6 +102,7 @@ def check_requirements(): % (dependency, file_path, version, required_version) ) + def list_requirements(): result = [] linked = [] @@ -111,7 +113,7 @@ def list_requirements(): for requirement in REQUIREMENTS: is_linked = False for link in linked: - if requirement.replace('-','_').startswith(link): + if requirement.replace('-', '_').startswith(link): is_linked = True if not is_linked: result.append(requirement) diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index d43ade39dd..c4e7dfcf0e 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -15,12 +15,17 @@ from twisted.internet import defer -from synapse.api.errors import SynapseError, Codes, UnrecognizedRequestError, NotFoundError, \ - StoreError +from synapse.api.errors import ( + SynapseError, Codes, UnrecognizedRequestError, NotFoundError, StoreError +) from .base import ClientV1RestServlet, client_path_pattern -from synapse.storage.push_rule import InconsistentRuleException, RuleNotFoundException +from synapse.storage.push_rule import ( + InconsistentRuleException, RuleNotFoundException +) import synapse.push.baserules as baserules -from synapse.push.rulekinds import PRIORITY_CLASS_MAP, PRIORITY_CLASS_INVERSE_MAP +from synapse.push.rulekinds import ( + PRIORITY_CLASS_MAP, PRIORITY_CLASS_INVERSE_MAP +) import json @@ -105,7 +110,9 @@ class PushRuleRestServlet(ClientV1RestServlet): # we build up the full structure and then decide which bits of it # to send which means doing unnecessary work sometimes but is # is probably not going to make a whole lot of difference - rawrules = yield self.hs.get_datastore().get_push_rules_for_user_name(user.to_string()) + rawrules = yield self.hs.get_datastore().get_push_rules_for_user_name( + user.to_string() + ) for r in rawrules: r["conditions"] = json.loads(r["conditions"]) @@ -383,6 +390,7 @@ def _namespaced_rule_id_from_spec(spec): def _rule_id_from_namespaced(in_rule_id): return in_rule_id.split('/')[-1] + class InvalidRuleException(Exception): pass diff --git a/synapse/rest/client/v1/pusher.py b/synapse/rest/client/v1/pusher.py index e10d2576d2..80e9939b79 100644 --- a/synapse/rest/client/v1/pusher.py +++ b/synapse/rest/client/v1/pusher.py @@ -34,8 +34,8 @@ class PusherRestServlet(ClientV1RestServlet): pusher_pool = self.hs.get_pusherpool() if ('pushkey' in content and 'app_id' in content - and 'kind' in content and - content['kind'] is None): + and 'kind' in content and + content['kind'] is None): yield pusher_pool.remove_pusher( content['app_id'], content['pushkey'] ) diff --git a/synapse/rest/media/v1/upload_resource.py b/synapse/rest/media/v1/upload_resource.py index 5b42782331..6df52ca434 100644 --- a/synapse/rest/media/v1/upload_resource.py +++ b/synapse/rest/media/v1/upload_resource.py @@ -38,9 +38,10 @@ class UploadResource(BaseMediaResource): def render_OPTIONS(self, request): respond_with_json(request, 200, {}, send_cors=True) return NOT_DONE_YET - + @defer.inlineCallbacks - def create_content(self, media_type, upload_name, content, content_length, auth_user): + def create_content(self, media_type, upload_name, content, content_length, + auth_user): media_id = random_string(24) fname = self.filepaths.local_media_filepath(media_id) @@ -65,7 +66,7 @@ class UploadResource(BaseMediaResource): } yield self._generate_local_thumbnails(media_id, media_info) - + defer.returnValue("mxc://%s/%s" % (self.server_name, media_id)) @defer.inlineCallbacks diff --git a/synapse/storage/_base.py b/synapse/storage/_base.py index 36455ef93c..3e1ab0a159 100644 --- a/synapse/storage/_base.py +++ b/synapse/storage/_base.py @@ -84,7 +84,7 @@ class PerformanceCounters(object): def update(self, key, start_time, end_time=None): if end_time is None: - end_time = time.time() * 1000; + end_time = time.time() * 1000 duration = end_time - start_time count, cum_time = self.current_counters.get(key, (0, 0)) count += 1 @@ -588,7 +588,7 @@ class SQLBaseStore(object): "LIMIT 1 " ) - start_time = time.time() * 1000; + start_time = time.time() * 1000 txn.execute(sql, (event_id,)) @@ -613,7 +613,7 @@ class SQLBaseStore(object): def _get_event_from_row_txn(self, txn, internal_metadata, js, redacted, check_redacted=True, get_prev_content=False): - start_time = time.time() * 1000; + start_time = time.time() * 1000 update_counter = self._get_event_counters.update d = json.loads(js) diff --git a/synapse/storage/push_rule.py b/synapse/storage/push_rule.py index 30e23445d9..620de71398 100644 --- a/synapse/storage/push_rule.py +++ b/synapse/storage/push_rule.py @@ -91,7 +91,9 @@ class PushRuleStore(SQLBaseStore): txn.execute(sql, (user_name, relative_to_rule)) res = txn.fetchall() if not res: - raise RuleNotFoundException("before/after rule not found: %s" % (relative_to_rule)) + raise RuleNotFoundException( + "before/after rule not found: %s" % (relative_to_rule,) + ) priority_class, base_rule_priority = res[0] if 'priority_class' in kwargs and kwargs['priority_class'] != priority_class: -- cgit 1.5.1 From 4ebbaf0d4382813ba896f3e8101de12e112cbed5 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Wed, 11 Feb 2015 14:23:10 +0000 Subject: Blunty replace json with simplejson --- synapse/crypto/keyclient.py | 2 +- synapse/federation/persistence.py | 2 +- synapse/federation/transport/server.py | 2 +- synapse/http/client.py | 2 +- synapse/http/matrixfederationclient.py | 2 +- synapse/push/__init__.py | 2 +- synapse/push/pusherpool.py | 2 +- synapse/rest/client/v1/directory.py | 2 +- synapse/rest/client/v1/login.py | 2 +- synapse/rest/client/v1/presence.py | 2 +- synapse/rest/client/v1/profile.py | 2 +- synapse/rest/client/v1/push_rule.py | 2 +- synapse/rest/client/v1/pusher.py | 2 +- synapse/rest/client/v1/register.py | 2 +- synapse/rest/client/v1/room.py | 2 +- synapse/rest/client/v2_alpha/filter.py | 2 +- synapse/rest/media/v0/content_repository.py | 2 +- synapse/storage/__init__.py | 2 +- synapse/storage/_base.py | 2 +- synapse/storage/filtering.py | 2 +- synapse/storage/push_rule.py | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) (limited to 'synapse/rest/client/v1/push_rule.py') diff --git a/synapse/crypto/keyclient.py b/synapse/crypto/keyclient.py index cd12349f67..74008347c3 100644 --- a/synapse/crypto/keyclient.py +++ b/synapse/crypto/keyclient.py @@ -19,7 +19,7 @@ from twisted.internet.protocol import Factory from twisted.internet import defer, reactor from synapse.http.endpoint import matrix_federation_endpoint from synapse.util.logcontext import PreserveLoggingContext -import json +import simplejson as json import logging diff --git a/synapse/federation/persistence.py b/synapse/federation/persistence.py index 85c82a4623..8a1afc0ca5 100644 --- a/synapse/federation/persistence.py +++ b/synapse/federation/persistence.py @@ -23,7 +23,7 @@ from twisted.internet import defer from synapse.util.logutils import log_function -import json +import simplejson as json import logging diff --git a/synapse/federation/transport/server.py b/synapse/federation/transport/server.py index 9c9f8d525b..2ffb37aa18 100644 --- a/synapse/federation/transport/server.py +++ b/synapse/federation/transport/server.py @@ -20,7 +20,7 @@ from synapse.api.errors import Codes, SynapseError from synapse.util.logutils import log_function import logging -import json +import simplejson as json import re diff --git a/synapse/http/client.py b/synapse/http/client.py index 198f575cfa..d500e19c81 100644 --- a/synapse/http/client.py +++ b/synapse/http/client.py @@ -23,7 +23,7 @@ from twisted.web.http_headers import Headers from StringIO import StringIO -import json +import simplejson as json import logging import urllib diff --git a/synapse/http/matrixfederationclient.py b/synapse/http/matrixfederationclient.py index 056d446e42..406203acf2 100644 --- a/synapse/http/matrixfederationclient.py +++ b/synapse/http/matrixfederationclient.py @@ -33,7 +33,7 @@ from synapse.api.errors import ( from syutil.crypto.jsonsign import sign_json -import json +import simplejson as json import logging import urllib import urlparse diff --git a/synapse/push/__init__.py b/synapse/push/__init__.py index 418a348a58..0659a1cb9b 100644 --- a/synapse/push/__init__.py +++ b/synapse/push/__init__.py @@ -22,7 +22,7 @@ import synapse.util.async import baserules import logging -import json +import simplejson as json import re logger = logging.getLogger(__name__) diff --git a/synapse/push/pusherpool.py b/synapse/push/pusherpool.py index 5a525befd7..7483d257bf 100644 --- a/synapse/push/pusherpool.py +++ b/synapse/push/pusherpool.py @@ -20,7 +20,7 @@ from httppusher import HttpPusher from synapse.push import PusherConfigException import logging -import json +import simplejson as json logger = logging.getLogger(__name__) diff --git a/synapse/rest/client/v1/directory.py b/synapse/rest/client/v1/directory.py index 8ed7e2d669..420aa89f38 100644 --- a/synapse/rest/client/v1/directory.py +++ b/synapse/rest/client/v1/directory.py @@ -20,7 +20,7 @@ from synapse.api.errors import AuthError, SynapseError, Codes from synapse.types import RoomAlias from .base import ClientV1RestServlet, client_path_pattern -import json +import simplejson as json import logging diff --git a/synapse/rest/client/v1/login.py b/synapse/rest/client/v1/login.py index 7116ac98e8..b2257b749d 100644 --- a/synapse/rest/client/v1/login.py +++ b/synapse/rest/client/v1/login.py @@ -19,7 +19,7 @@ from synapse.api.errors import SynapseError from synapse.types import UserID from base import ClientV1RestServlet, client_path_pattern -import json +import simplejson as json class LoginRestServlet(ClientV1RestServlet): diff --git a/synapse/rest/client/v1/presence.py b/synapse/rest/client/v1/presence.py index 7feb4aadb1..78d4f2b128 100644 --- a/synapse/rest/client/v1/presence.py +++ b/synapse/rest/client/v1/presence.py @@ -21,7 +21,7 @@ from synapse.api.errors import SynapseError from synapse.types import UserID from .base import ClientV1RestServlet, client_path_pattern -import json +import simplejson as json import logging logger = logging.getLogger(__name__) diff --git a/synapse/rest/client/v1/profile.py b/synapse/rest/client/v1/profile.py index 15d6f3fc6c..1e77eb49cf 100644 --- a/synapse/rest/client/v1/profile.py +++ b/synapse/rest/client/v1/profile.py @@ -19,7 +19,7 @@ from twisted.internet import defer from .base import ClientV1RestServlet, client_path_pattern from synapse.types import UserID -import json +import simplejson as json class ProfileDisplaynameRestServlet(ClientV1RestServlet): diff --git a/synapse/rest/client/v1/push_rule.py b/synapse/rest/client/v1/push_rule.py index c4e7dfcf0e..b012f31084 100644 --- a/synapse/rest/client/v1/push_rule.py +++ b/synapse/rest/client/v1/push_rule.py @@ -27,7 +27,7 @@ from synapse.push.rulekinds import ( PRIORITY_CLASS_MAP, PRIORITY_CLASS_INVERSE_MAP ) -import json +import simplejson as json class PushRuleRestServlet(ClientV1RestServlet): diff --git a/synapse/rest/client/v1/pusher.py b/synapse/rest/client/v1/pusher.py index 80e9939b79..6045e86f34 100644 --- a/synapse/rest/client/v1/pusher.py +++ b/synapse/rest/client/v1/pusher.py @@ -19,7 +19,7 @@ from synapse.api.errors import SynapseError, Codes from synapse.push import PusherConfigException from .base import ClientV1RestServlet, client_path_pattern -import json +import simplejson as json class PusherRestServlet(ClientV1RestServlet): diff --git a/synapse/rest/client/v1/register.py b/synapse/rest/client/v1/register.py index c0423c2d45..d3399c446b 100644 --- a/synapse/rest/client/v1/register.py +++ b/synapse/rest/client/v1/register.py @@ -25,7 +25,7 @@ from synapse.util.async import run_on_reactor from hashlib import sha1 import hmac -import json +import simplejson as json import logging import urllib diff --git a/synapse/rest/client/v1/room.py b/synapse/rest/client/v1/room.py index 410f19ccf6..0346afb1b4 100644 --- a/synapse/rest/client/v1/room.py +++ b/synapse/rest/client/v1/room.py @@ -23,7 +23,7 @@ from synapse.api.constants import EventTypes, Membership from synapse.types import UserID, RoomID, RoomAlias from synapse.events.utils import serialize_event -import json +import simplejson as json import logging import urllib diff --git a/synapse/rest/client/v2_alpha/filter.py b/synapse/rest/client/v2_alpha/filter.py index 6ddc495d23..703250cea8 100644 --- a/synapse/rest/client/v2_alpha/filter.py +++ b/synapse/rest/client/v2_alpha/filter.py @@ -21,7 +21,7 @@ from synapse.types import UserID from ._base import client_v2_pattern -import json +import simplejson as json import logging diff --git a/synapse/rest/media/v0/content_repository.py b/synapse/rest/media/v0/content_repository.py index 22e26e3cd5..e77a20fb2e 100644 --- a/synapse/rest/media/v0/content_repository.py +++ b/synapse/rest/media/v0/content_repository.py @@ -25,7 +25,7 @@ from twisted.web import server, resource from twisted.internet import defer import base64 -import json +import simplejson as json import logging import os import re diff --git a/synapse/storage/__init__.py b/synapse/storage/__init__.py index a63c59a8a2..924ea89035 100644 --- a/synapse/storage/__init__.py +++ b/synapse/storage/__init__.py @@ -44,7 +44,7 @@ from syutil.jsonutil import encode_canonical_json from synapse.crypto.event_signing import compute_event_reference_hash -import json +import simplejson as json import logging import os diff --git a/synapse/storage/_base.py b/synapse/storage/_base.py index 3e1ab0a159..b74e74ac91 100644 --- a/synapse/storage/_base.py +++ b/synapse/storage/_base.py @@ -23,7 +23,7 @@ from synapse.util.logcontext import PreserveLoggingContext, LoggingContext from twisted.internet import defer import collections -import json +import simplejson as json import sys import time diff --git a/synapse/storage/filtering.py b/synapse/storage/filtering.py index e86eeced45..457a11fd02 100644 --- a/synapse/storage/filtering.py +++ b/synapse/storage/filtering.py @@ -17,7 +17,7 @@ from twisted.internet import defer from ._base import SQLBaseStore -import json +import simplejson as json class FilteringStore(SQLBaseStore): diff --git a/synapse/storage/push_rule.py b/synapse/storage/push_rule.py index 620de71398..ae46b39cc1 100644 --- a/synapse/storage/push_rule.py +++ b/synapse/storage/push_rule.py @@ -20,7 +20,7 @@ from twisted.internet import defer import logging import copy -import json +import simplejson as json logger = logging.getLogger(__name__) -- cgit 1.5.1