Ejemplo n.º 1
0
 def test_filter_list_constant_scorer(self):
     """Filter a list returning constant scorer."""
     get_scoring_func = mock.MagicMock()
     get_scoring_func.side_effect = [['test-zero'], ['test-two'],
                                     ['test-zero']]
     filtered = scoring.filter_using_score(range(3), get_scoring_func, None)
     self.assertEqual([1], list(filtered))
Ejemplo n.º 2
0
 def list_events(self, project):
     """List all events close to the project's target."""
     today = project.now.strftime('%Y-%m-%d')
     all_events = [
         e for e in self._db.get_collection(project.database)
         if e.start_date >= today
     ]
     return list(
         scoring.filter_using_score(all_events, lambda e: e.filters,
                                    project))
Ejemplo n.º 3
0
def list_all_tips(user,
                  project,
                  piece_of_advice,
                  database,
                  cache=None,
                  filter_tip=None):
    """List all available tips for a piece of advice.

    Args:
        user: the full user info.
        project: the project to give tips for.
        piece_of_advice: the piece of advice to give tips for.
        database: access to the database to get modules and tips.
        cache: an optional dict that is used across calls to this function to
            cache data when scoring tips.
        filter_tip: a function to select which tips to keep, by default (None)
            keeps all of them.
    Returns:
        An iterable of tips for this module.
    """
    if not cache:
        cache = {}

    try:
        module = next(m for m in _advice_modules(database)
                      if m.advice_id == piece_of_advice.advice_id)
    except StopIteration:
        logging.warning('Advice module %s does not exist anymore',
                        piece_of_advice.advice_id)
        return []

    # Get tip templates.
    all_tip_templates = _tip_templates(database)
    tip_templates = filter(None, (all_tip_templates.get(t)
                                  for t in module.tip_template_ids))

    # Additional filter from caller.
    if filter_tip:
        tip_templates = filter(filter_tip, tip_templates)

    # Filter tips.
    scoring_project = cache.get('scoring_project')
    if not scoring_project:
        scoring_project = scoring.ScoringProject(project,
                                                 user.profile,
                                                 user.features_enabled,
                                                 database,
                                                 now=now.get())
        cache['scoring_project'] = scoring_project
    filtered_tips = scoring.filter_using_score(tip_templates,
                                               lambda t: t.filters,
                                               scoring_project)

    return filtered_tips
Ejemplo n.º 4
0
 def test_multiple_filters(self):
     """Filter an item with multiple filters."""
     get_scoring_func = mock.MagicMock()
     get_scoring_func.return_value = ['test-two', 'test-zero']
     filtered = scoring.filter_using_score([42], get_scoring_func, None)
     self.assertEqual([], list(filtered))
Ejemplo n.º 5
0
 def test_unknown_filter(self):
     """Filter an item with an unknown filter."""
     get_scoring_func = mock.MagicMock()
     get_scoring_func.return_value = ['unknown-filter']
     filtered = scoring.filter_using_score([42], get_scoring_func, None)
     self.assertEqual([42], list(filtered))
Ejemplo n.º 6
0
 def test_filter_list_with_no_filters(self):
     """Filter a list with no filters to apply."""
     filtered = scoring.filter_using_score(range(5), lambda a: [], None)
     self.assertEqual([0, 1, 2, 3, 4], list(filtered))
Ejemplo n.º 7
0
def _add_actions_to_project(user_proto,
                            project,
                            num_adds,
                            use_white_chantiers=False):
    if num_adds < 0:
        return False

    all_chantiers = _chantiers()
    if use_white_chantiers:
        activated_chantiers = _white_chantier_ids()
    else:
        activated_chantiers = set(
            chantier_id
            for chantier_id, activated in project.activated_chantiers.items()
            if activated and chantier_id in all_chantiers)
    if not activated_chantiers:
        logging.warning('No activated chantiers')
        return False

    # List all action template IDs for which we already had an action in the
    # near past.
    now_instant = now.get()
    still_hot_action_template_ids = set()
    for hot_action in itertools.chain(project.actions, project.past_actions,
                                      project.sticky_actions):
        if (hot_action.HasField('end_of_cool_down')
                and hot_action.end_of_cool_down.ToDatetime() < now_instant):
            continue
        still_hot_action_template_ids.add(hot_action.action_template_id)

    # List all action templates that are at least in one of the activated
    # chantiers.
    actions_pool = [
        a for action_template_id, a in action.templates(_DB).items()
        # Do not add an action that was already taken.
        if action_template_id not in still_hot_action_template_ids and
        # Only add actions that are meant for these chantiers.
        activated_chantiers & set(a.chantiers)
    ]

    # Filter action templates using the filters field.
    scoring_project = scoring.ScoringProject(project, user_proto.profile,
                                             user_proto.features_enabled, _DB)
    filtered_actions_pool = scoring.filter_using_score(actions_pool,
                                                       lambda a: a.filters,
                                                       scoring_project)

    # Split action templates by priority.
    pools = collections.defaultdict(list)
    for filtered_action in filtered_actions_pool:
        pools[filtered_action.priority_level].append(filtered_action)

    if not pools:
        logging.warning(
            'No action template would match:\n'
            ' - %d activated chantiers\n'
            ' - %d total action templates\n'
            ' - %d action templates still hot\n'
            ' - %d before filtering', len(activated_chantiers),
            len(action.templates(_DB)), len(still_hot_action_template_ids),
            len(actions_pool))
        return False

    added = False

    for priority in sorted(pools.keys(), reverse=True):
        pool = pools[priority]
        # Pick the number of actions to add if enough.
        if num_adds == 0:
            return added
        if len(pool) > num_adds:
            pool = random.sample(pool, num_adds)
            num_adds = 0
        else:
            num_adds -= len(pool)
        random.shuffle(pool)

        for template in pool:
            added = True
            action.instantiate(project.actions.add(), user_proto,
                               project, template, activated_chantiers, _DB,
                               _chantiers())

    return added
Ejemplo n.º 8
0
 def list_jobboards(self, project):
     """List all job boards for this project."""
     all_job_boards = self._db.get_collection(project.database)
     return list(
         scoring.filter_using_score(all_job_boards, lambda j: j.filters,
                                    project))
Ejemplo n.º 9
0
 def list_associations(self, project):
     """List all associations for a project."""
     all_associations = self._db.get_collection(project.database)
     return list(
         scoring.filter_using_score(all_associations, lambda j: j.filters,
                                    project))
Ejemplo n.º 10
0
 def _list_contact_leads(self, project):
     return scoring.filter_using_score(
         self._db.get_collection(project.database), lambda l: l.filters,
         project)