def _get_rules(room_id, user_ids, store): rules_by_user = yield store.bulk_get_push_rules(user_ids) rules_enabled_by_user = yield store.bulk_get_push_rules_enabled(user_ids) rules_by_user = { uid: baserules.list_with_base_rules([ decode_rule_json(rule_list) for rule_list in rules_by_user.get(uid, []) ]) for uid in user_ids } # We apply the rules-enabled map here: bulk_get_push_rules doesn't # fetch disabled rules, but this won't account for any server default # rules the user has disabled, so we need to do this too. for uid in user_ids: if uid not in rules_enabled_by_user: continue user_enabled_map = rules_enabled_by_user[uid] for i, rule in enumerate(rules_by_user[uid]): rule_id = rule['rule_id'] if rule_id in user_enabled_map: if rule.get('enabled', True) != bool(user_enabled_map[rule_id]): # Rules are cached across users. rule = dict(rule) rule['enabled'] = bool(user_enabled_map[rule_id]) rules_by_user[uid][i] = rule defer.returnValue(rules_by_user)
def __init__(self, user_id, profile_tag, raw_rules, enabled_map, room_id, our_member_event, store): self.user_id = user_id self.profile_tag = profile_tag self.room_id = room_id self.our_member_event = our_member_event self.store = store rules = [] for raw_rule in raw_rules: rule = dict(raw_rule) rule['conditions'] = json.loads(raw_rule['conditions']) rule['actions'] = json.loads(raw_rule['actions']) rules.append(rule) self.rules = baserules.list_with_base_rules(rules) self.enabled_map = enabled_map
def __init__(self, user_name, profile_tag, raw_rules, enabled_map, room_id, our_member_event, store): self.user_name = user_name self.profile_tag = profile_tag self.room_id = room_id self.our_member_event = our_member_event self.store = store rules = [] for raw_rule in raw_rules: rule = dict(raw_rule) rule['conditions'] = json.loads(raw_rule['conditions']) rule['actions'] = json.loads(raw_rule['actions']) rules.append(rule) user = UserID.from_string(self.user_name) self.rules = baserules.list_with_base_rules(rules, user) self.enabled_map = enabled_map
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 to do such things. """ if ev['user_id'] == self.user_name: # let's assume you probably know about messages you sent yourself defer.returnValue(['dont_notify']) rawrules = yield self.store.get_push_rules_for_user(self.user_name) rules = [] for rawrule in rawrules: rule = dict(rawrule) rule['conditions'] = json.loads(rawrule['conditions']) rule['actions'] = json.loads(rawrule['actions']) rules.append(rule) enabled_map = yield self.store.get_push_rules_enabled_for_user(self.user_name) user = UserID.from_string(self.user_name) rules = baserules.list_with_base_rules(rules, user) room_id = ev['room_id'] # get *our* member event for display name matching my_display_name = None our_member_event = yield self.store.get_current_state( room_id=room_id, event_type='m.room.member', state_key=self.user_name, ) if our_member_event: my_display_name = our_member_event[0].content.get("displayname") room_members = yield self.store.get_users_in_room(room_id) room_member_count = len(room_members) for r in rules: if r['rule_id'] in enabled_map: r['enabled'] = enabled_map[r['rule_id']] elif 'enabled' not in r: r['enabled'] = True if not r['enabled']: continue matches = True conditions = r['conditions'] actions = r['actions'] for c in conditions: matches &= self._event_fulfills_condition( ev, c, display_name=my_display_name, room_member_count=room_member_count ) logger.debug( "Rule %s %s", r['rule_id'], "matches" if matches else "doesn't match" ) # 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'], self.user_name ) continue if matches: logger.info( "%s matches for user %s, event %s", r['rule_id'], self.user_name, ev['event_id'] ) defer.returnValue(actions) logger.info( "No rules match for user %s, event %s", self.user_name, ev['event_id'] ) defer.returnValue(Pusher.DEFAULT_ACTIONS)
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 to do such things. """ if ev['user_id'] == self.user_name: # let's assume you probably know about messages you sent yourself defer.returnValue(['dont_notify']) if ev['type'] == 'm.room.member': if ev['state_key'] != self.user_name: defer.returnValue(['dont_notify']) rawrules = yield self.store.get_push_rules_for_user_name(self.user_name) for r in rawrules: r['conditions'] = json.loads(r['conditions']) r['actions'] = json.loads(r['actions']) user = UserID.from_string(self.user_name) 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( room_id=ev['room_id'], event_type='m.room.member', state_key=None ) my_display_name = None room_member_count = 0 for mev in member_events_for_room: if mev.content['membership'] != 'join': continue # This loop does two things: # 1) Find our current display name if mev.state_key == self.user_name and 'displayname' in mev.content: my_display_name = mev.content['displayname'] # and 2) Get the number of people in that room room_member_count += 1 for r in rules: matches = True conditions = r['conditions'] actions = r['actions'] for c in conditions: matches &= self._event_fulfills_condition( ev, c, display_name=my_display_name, room_member_count=room_member_count ) # 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 _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 to do such things. """ if ev['user_id'] == self.user_name: # let's assume you probably know about messages you sent yourself defer.returnValue(['dont_notify']) rawrules = yield self.store.get_push_rules_for_user(self.user_name) for r in rawrules: r['conditions'] = json.loads(r['conditions']) r['actions'] = json.loads(r['actions']) enabled_map = yield self.store.get_push_rules_enabled_for_user(self.user_name) user = UserID.from_string(self.user_name) 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( room_id=ev['room_id'], event_type='m.room.member', state_key=None ) my_display_name = None room_member_count = 0 for mev in member_events_for_room: if mev.content['membership'] != 'join': continue # This loop does two things: # 1) Find our current display name if mev.state_key == self.user_name and 'displayname' in mev.content: my_display_name = mev.content['displayname'] # and 2) Get the number of people in that room room_member_count += 1 for r in rules: if r['rule_id'] in enabled_map: r['enabled'] = enabled_map[r['rule_id']] elif 'enabled' not in r: r['enabled'] = True if not r['enabled']: continue matches = True conditions = r['conditions'] actions = r['actions'] for c in conditions: matches &= self._event_fulfills_condition( ev, c, display_name=my_display_name, room_member_count=room_member_count ) logger.debug( "Rule %s %s", r['rule_id'], "matches" if matches else "doesn't match" ) # 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'], self.user_name ) continue if matches: logger.info( "%s matches for user %s, event %s", r['rule_id'], self.user_name, ev['event_id'] ) defer.returnValue(actions) logger.info( "No rules match for user %s, event %s", self.user_name, ev['event_id'] ) defer.returnValue(Pusher.DEFAULT_ACTIONS)
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 to do such things. """ if ev['user_id'] == self.user_name: # let's assume you probably know about messages you sent yourself defer.returnValue(['dont_notify']) rawrules = yield self.store.get_push_rules_for_user(self.user_name) rules = [] for rawrule in rawrules: rule = dict(rawrule) rule['conditions'] = json.loads(rawrule['conditions']) rule['actions'] = json.loads(rawrule['actions']) rules.append(rule) enabled_map = yield self.store.get_push_rules_enabled_for_user( self.user_name) user = UserID.from_string(self.user_name) rules = baserules.list_with_base_rules(rules, user) room_id = ev['room_id'] # get *our* member event for display name matching my_display_name = None our_member_event = yield self.store.get_current_state( room_id=room_id, event_type='m.room.member', state_key=self.user_name, ) if our_member_event: my_display_name = our_member_event[0].content.get("displayname") room_members = yield self.store.get_users_in_room(room_id) room_member_count = len(room_members) for r in rules: if r['rule_id'] in enabled_map: r['enabled'] = enabled_map[r['rule_id']] elif 'enabled' not in r: r['enabled'] = True if not r['enabled']: continue matches = True conditions = r['conditions'] actions = r['actions'] for c in conditions: matches &= self._event_fulfills_condition( ev, c, display_name=my_display_name, room_member_count=room_member_count) logger.debug("Rule %s %s", r['rule_id'], "matches" if matches else "doesn't match") # 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'], self.user_name) continue if matches: logger.info("%s matches for user %s, event %s", r['rule_id'], self.user_name, ev['event_id']) defer.returnValue(actions) logger.info("No rules match for user %s, event %s", self.user_name, ev['event_id']) defer.returnValue(Pusher.DEFAULT_ACTIONS)