Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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)