Beispiel #1
0
    def test_reindex_users_that_contributed_yesterday(self):
        yesterday = datetime.now() - timedelta(days=1)

        # Verify for answers.
        u = user(username='******', save=True)
        profile(user=u)
        answer(creator=u, created=yesterday, save=True)

        reindex_users_that_contributed_yesterday()
        self.refresh()

        data = UserMappingType.search().query(username__match='answerer')[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())

        # Verify for edits.
        u = user(username='******', save=True)
        profile(user=u)
        revision(creator=u, created=yesterday, save=True)

        reindex_users_that_contributed_yesterday()
        self.refresh()

        data = UserMappingType.search().query(username__match='editor')[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())

        # Verify for reviews.
        u = user(username='******', save=True)
        profile(user=u)
        revision(reviewer=u, reviewed=yesterday, save=True)

        reindex_users_that_contributed_yesterday()
        self.refresh()

        data = UserMappingType.search().query(username__match='reviewer')[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())
Beispiel #2
0
    def test_reindex_users_that_contributed_yesterday(self):
        yesterday = datetime.now() - timedelta(days=1)

        # Verify for answers.
        u = UserFactory(username='******')
        AnswerFactory(creator=u, created=yesterday)

        call_command('reindex_users_that_contributed_yesterday')
        self.refresh()

        data = UserMappingType.search().query(username__match='answerer')[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())

        # Verify for edits.
        u = UserFactory(username='******')
        RevisionFactory(creator=u, created=yesterday)

        call_command('reindex_users_that_contributed_yesterday')
        self.refresh()

        data = UserMappingType.search().query(username__match='editor')[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())

        # Verify for reviews.
        u = UserFactory(username='******')
        RevisionFactory(reviewer=u, reviewed=yesterday)

        call_command('reindex_users_that_contributed_yesterday')
        self.refresh()

        data = UserMappingType.search().query(username__match='reviewer')[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())
Beispiel #3
0
    def test_query_display_name_with_whitespace(self):
        UserFactory(username='******', profile__name=u'Elite Mike')
        UserFactory(username='******', profile__name=u'NotElite Mike')

        self.refresh()

        eq_(UserMappingType.search().count(), 2)
        eq_(UserMappingType.search().query(
            idisplay_name__match_whitespace='elite').count(), 1)
Beispiel #4
0
    def test_query_username_with_numbers(self):
        u = UserFactory(username='******', profile__name=u'Elite Mike')
        UserFactory(username='******', profile__name=u'NotElite Mike')

        self.refresh()

        eq_(UserMappingType.search().query(iusername__match='1337mike').count(), 1)
        data = UserMappingType.search().query(iusername__match='1337mike')[0]
        eq_(data['username'], u.username)
        eq_(data['display_name'], u.profile.name)
Beispiel #5
0
    def test_query_display_name_with_whitespace(self):
        u1 = user(username="******", save=True)
        p = profile(user=u1, name=u"Elite Mike")
        u2 = user(username="******", save=True)
        profile(user=u2, name=u"NotElite Mike")

        self.refresh()

        eq_(UserMappingType.search().count(), 2)
        eq_(UserMappingType.search().query(idisplay_name__match_whitespace="elite").count(), 1)
Beispiel #6
0
    def test_suggest_completions_numbers(self):
        u1 = UserFactory(username='******', profile__name=u'Elite Mike')
        UserFactory(username='******', profile__name=u'Crazy Pants')

        self.refresh()
        eq_(UserMappingType.search().count(), 2)

        results = UserMappingType.suggest_completions('13')
        eq_(1, len(results))
        eq_('Elite Mike (1337mike)', results[0]['text'])
        eq_(u1.id, results[0]['payload']['user_id'])
Beispiel #7
0
    def test_last_contribution_date(self):
        """Verify the last_contribution_date field works properly."""
        u = user(username='******', save=True)
        p = profile(user=u)

        self.refresh()

        data = UserMappingType.search().query(
            username__match='satdav').values_dict()[0]
        assert not data['last_contribution_date']

        # Add a AoA reply. It should be the last contribution.
        d = datetime(2014, 1, 1)
        reply(user=u, created=d, save=True)

        p.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(
            username__match='satdav').values_dict()[0]
        eq_(data['last_contribution_date'], d)

        # Add a Support Forum answer. It should be the last contribution.
        d = datetime(2014, 1, 2)
        answer(creator=u, created=d, save=True)

        p.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(
            username__match='satdav').values_dict()[0]
        eq_(data['last_contribution_date'], d)

        # Add a Revision edit. It should be the last contribution.
        d = datetime(2014, 1, 3)
        revision(creator=u, created=d, save=True)

        p.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(
            username__match='satdav').values_dict()[0]
        eq_(data['last_contribution_date'], d)

        # Add a Revision review. It should be the last contribution.
        d = datetime(2014, 1, 4)
        revision(reviewer=u, reviewed=d, save=True)

        p.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(
            username__match='satdav').values_dict()[0]
        eq_(data['last_contribution_date'], d)
Beispiel #8
0
    def test_query_display_name_with_whitespace(self):
        u1 = user(username='******', save=True)
        profile(user=u1, name=u'Elite Mike')
        u2 = user(username='******', save=True)
        profile(user=u2, name=u'NotElite Mike')

        self.refresh()

        eq_(UserMappingType.search().count(), 2)
        eq_(UserMappingType.search().query(
            idisplay_name__match_whitespace='elite').count(), 1)
Beispiel #9
0
    def test_query_username_with_numbers(self):
        u1 = user(username="******", save=True)
        p = profile(user=u1, name=u"Elite Mike")
        u2 = user(username="******", save=True)
        profile(user=u2, name=u"NotElite Mike")

        self.refresh()

        eq_(UserMappingType.search().query(iusername__match="1337mike").count(), 1)
        data = UserMappingType.search().query(iusername__match="1337mike").values_dict()[0]
        eq_(data["username"], p.user.username)
        eq_(data["display_name"], p.name)
Beispiel #10
0
    def test_add_and_delete(self):
        """Adding a user with a profile should add it to the index.

        Deleting should delete it.
        """
        p = profile()
        self.refresh()
        eq_(UserMappingType.search().count(), 1)

        p.user.delete()
        self.refresh()
        eq_(UserMappingType.search().count(), 0)
Beispiel #11
0
    def test_suggest_completions_numbers(self):
        u1 = user(username="******", save=True)
        profile(user=u1, name=u"Elite Mike")
        u2 = user(username="******", save=True)
        profile(user=u2, name=u"Crazy Pants")

        self.refresh()
        eq_(UserMappingType.search().count(), 2)

        results = UserMappingType.suggest_completions("13")
        eq_(1, len(results))
        eq_("Elite Mike (1337mike)", results[0]["text"])
        eq_(u1.id, results[0]["payload"]["user_id"])
Beispiel #12
0
    def test_query_username_with_numbers(self):
        u1 = user(username='******', save=True)
        p = profile(user=u1, name=u'Elite Mike')
        u2 = user(username='******', save=True)
        profile(user=u2, name=u'NotElite Mike')

        self.refresh()

        eq_(UserMappingType.search().query(
            iusername__match='1337mike').count(), 1)
        data = UserMappingType.search().query(iusername__match='1337mike')[0]
        eq_(data['username'], p.user.username)
        eq_(data['display_name'], p.name)
Beispiel #13
0
    def test_query_twitter_usernames(self):
        u1 = UserFactory(username='******', profile__name=u'Elite Mike')
        u2 = UserFactory(username='******', profile__name=u'NotElite Mike')
        r1 = ReplyFactory(user=u1, twitter_username='******')
        ReplyFactory(user=u2, twitter_username='******')

        self.refresh()

        eq_(UserMappingType.search().query(itwitter_usernames__match='l33tmike').count(), 1)
        data = UserMappingType.search().query(itwitter_usernames__match='l33tmike')[0]
        eq_(data['username'], u1.username)
        eq_(data['display_name'], u1.profile.name)
        assert r1.twitter_username in data['twitter_usernames']
Beispiel #14
0
    def test_suggest_completions_numbers(self):
        u1 = user(username='******', save=True)
        profile(user=u1, name=u'Elite Mike')
        u2 = user(username='******', save=True)
        profile(user=u2, name=u'Crazy Pants')

        self.refresh()
        eq_(UserMappingType.search().count(), 2)

        results = UserMappingType.suggest_completions('13')
        eq_(1, len(results))
        eq_('Elite Mike (1337mike)', results[0]['text'])
        eq_(u1.id, results[0]['payload']['user_id'])
Beispiel #15
0
def search(request):
    """Find users by username and displayname.

    Uses the ES user's index.
    """
    results = []
    search_errored = False
    q = request.GET.get("q")

    if q:
        lowerq = q.lower()
        try:
            results = (UserMappingType.search().query(
                iusername__match=lowerq,
                idisplay_name__match_whitespace=lowerq,
                itwitter_usernames__match=lowerq,
                should=True,
            ).values_dict(
                "id",
                "username",
                "display_name",
                "avatar",
                "twitter_usernames",
                "last_contribution_date",
            ))
            results = UserMappingType.reshape(results)

        except ES_EXCEPTIONS:
            search_errored = True
            log.exception("User search failed.")

    # For now, we're just truncating results at 30 and not doing any
    # pagination. If somebody complains, we can add pagination or something.
    results = list(results[:30])

    # Calculate days since last activity.
    for r in results:
        lcd = r.get("last_contribution_date", None)
        if lcd:
            delta = datetime.now() - lcd
            r["days_since_last_activity"] = delta.days
        else:
            r["days_since_last_activity"] = None

    data = {
        "q": q,
        "results": results,
        "search_errored": search_errored,
    }

    return render(request, "community/search.html", data)
Beispiel #16
0
    def test_query_username_with_numbers(self):
        u1 = user(username='******', save=True)
        p = profile(user=u1, name=u'Elite Mike')
        u2 = user(username='******', save=True)
        profile(user=u2, name=u'NotElite Mike')

        self.refresh()

        eq_(
            UserMappingType.search().query(
                iusername__match='1337mike').count(), 1)
        data = UserMappingType.search().query(iusername__match='1337mike')[0]
        eq_(data['username'], p.user.username)
        eq_(data['display_name'], p.name)
Beispiel #17
0
    def test_last_contribution_date(self):
        """Verify the last_contribution_date field works properly."""
        u = user(username='******', save=True)
        p = profile(user=u)

        self.refresh()

        data = UserMappingType.search().query(username__match='satdav')[0]
        assert not data['last_contribution_date']

        # Add a AoA reply. It should be the last contribution.
        d = datetime(2014, 1, 1)
        reply(user=u, created=d, save=True)

        self.refresh()

        data = UserMappingType.search().query(username__match='satdav')[0]
        eq_(data['last_contribution_date'], d)

        # Add a Support Forum answer. It should be the last contribution.
        d = datetime(2014, 1, 2)
        answer(creator=u, created=d, save=True)

        p.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(username__match='satdav')[0]
        eq_(data['last_contribution_date'], d)

        # Add a Revision edit. It should be the last contribution.
        d = datetime(2014, 1, 3)
        revision(creator=u, created=d, save=True)

        p.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(username__match='satdav')[0]
        eq_(data['last_contribution_date'], d)

        # Add a Revision review. It should be the last contribution.
        d = datetime(2014, 1, 4)
        revision(reviewer=u, reviewed=d, save=True)

        p.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(username__match='satdav')[0]
        eq_(data['last_contribution_date'], d)
Beispiel #18
0
    def test_query_twitter_usernames(self):
        u1 = UserFactory(username='******', profile__name=u'Elite Mike')
        u2 = UserFactory(username='******', profile__name=u'NotElite Mike')
        r1 = ReplyFactory(user=u1, twitter_username='******')
        ReplyFactory(user=u2, twitter_username='******')

        self.refresh()

        eq_(
            UserMappingType.search().query(
                itwitter_usernames__match='l33tmike').count(), 1)
        data = UserMappingType.search().query(
            itwitter_usernames__match='l33tmike')[0]
        eq_(data['username'], u1.username)
        eq_(data['display_name'], u1.profile.name)
        assert r1.twitter_username in data['twitter_usernames']
Beispiel #19
0
    def test_data_in_index(self):
        """Verify the data we are indexing."""
        u = user(username='******', email='*****@*****.**', save=True)
        p = profile(user=u, name=u'Rick Róss')

        self.refresh()

        eq_(UserMappingType.search().count(), 1)
        data = UserMappingType.search().values_dict()[0]
        eq_(data['username'], p.user.username)
        eq_(data['display_name'], p.name)

        u = user(username='******', email='*****@*****.**', save=True)
        p = profile(user=u, name=u'Will Cage')
        self.refresh()
        eq_(UserMappingType.search().count(), 2)
Beispiel #20
0
def _get_creator_counts(query, count):
    """Get the list of top contributors with the contribution count."""
    creator_counts = query.facet_counts()['creator_id']['terms']

    # Grab all the users from the user index in ES.
    user_ids = [x['term'] for x in creator_counts]
    results = (UserMappingType.search().filter(id__in=user_ids).values_dict(
        'id', 'username', 'display_name', 'avatar', 'twitter_usernames',
        'last_contribution_date'))[:count]

    # Calculate days since last activity and
    # create a {<user_id>: <user>,...} dict for convenience.
    user_lookup = {}
    for r in results:
        lcd = r.get('last_contribution_date', None)
        if lcd:
            delta = datetime.now() - lcd
            r['days_since_last_activity'] = delta.days
        else:
            r['days_since_last_activity'] = None

        user_lookup[r['id']] = r

    # Add the user to each dict in the creator_counts array.
    for item in creator_counts:
        item['user'] = user_lookup.get(item['term'], None)

    return [item for item in creator_counts if item['user'] != None]
Beispiel #21
0
    def test_data_in_index(self):
        """Verify the data we are indexing."""
        u = user(username="******", email="*****@*****.**", save=True)
        p = profile(user=u, name=u"Rick Róss")

        self.refresh()

        eq_(UserMappingType.search().count(), 1)
        data = UserMappingType.search().values_dict()[0]
        eq_(data["username"], p.user.username)
        eq_(data["display_name"], p.name)

        u = user(username="******", email="*****@*****.**", save=True)
        p = profile(user=u, name=u"Will Cage")
        self.refresh()
        eq_(UserMappingType.search().count(), 2)
Beispiel #22
0
def search(request):
    """Find users by username and displayname.

    Uses the ES user's index.
    """
    results = []
    search_errored = False
    q = request.GET.get('q')

    if q:
        lowerq = q.lower()
        try:
            results = (UserMappingType.search().query(
                iusername__match=lowerq,
                idisplay_name__match_whitespace=lowerq,
                itwitter_usernames__match=lowerq,
                should=True).values_dict('id', 'username', 'display_name',
                                         'avatar', 'twitter_usernames',
                                         'last_contribution_date'))
            results = UserMappingType.reshape(results)

            statsd.incr('community.usersearch.success')
        except ES_EXCEPTIONS:
            search_errored = True
            statsd.incr('community.usersearch.error')
            log.exception('User search failed.')

    # For now, we're just truncating results at 30 and not doing any
    # pagination. If somebody complains, we can add pagination or something.
    results = list(results[:30])

    # Calculate days since last activity.
    for r in results:
        lcd = r.get('last_contribution_date', None)
        if lcd:
            delta = datetime.now() - lcd
            r['days_since_last_activity'] = delta.days
        else:
            r['days_since_last_activity'] = None

    data = {
        'q': q,
        'results': results,
        'search_errored': search_errored,
    }

    return render(request, 'community/search.html', data)
Beispiel #23
0
    def test_query_twitter_usernames(self):
        u1 = user(username='******', save=True)
        p = profile(user=u1, name=u'Elite Mike')
        u2 = user(username='******', save=True)
        profile(user=u2, name=u'NotElite Mike')
        r1 = reply(user=u1, twitter_username='******', save=True)
        reply(user=u2, twitter_username='******', save=True)

        self.refresh()

        eq_(UserMappingType.search().query(
            itwitter_usernames__match='l33tmike').count(), 1)
        data = UserMappingType.search().query(
            itwitter_usernames__match='l33tmike')[0]
        eq_(data['username'], p.user.username)
        eq_(data['display_name'], p.name)
        assert r1.twitter_username in data['twitter_usernames']
Beispiel #24
0
def _get_creator_counts(query, count, page):
    total = query.count()

    start = (page - 1) * count
    end = page * count
    query_data = query.values("id", "query_count")[start:end]

    query_data = {obj["id"]: obj["query_count"] for obj in query_data}

    users_data = (UserMappingType.search().filter(
        id__in=list(query_data.keys())).values_dict(
            "id",
            "username",
            "display_name",
            "avatar",
            "twitter_usernames",
            "last_contribution_date",
        )[:count])

    users_data = UserMappingType.reshape(users_data)

    results = []
    now = datetime.now()

    for u_data in users_data:
        user_id = u_data.get("id")
        last_contribution_date = u_data.get("last_contribution_date", None)

        u_data["days_since_last_activity"] = ((now -
                                               last_contribution_date).days if
                                              last_contribution_date else None)

        data = {
            "count": query_data.get(user_id),
            "term": user_id,
            "user": u_data
        }

        results.append(data)

    # Descending Order the list according to count.
    # As the top number of contributor should be at first
    results = sorted(results, key=itemgetter("count"), reverse=True)

    return results, total
Beispiel #25
0
    def test_query_twitter_usernames(self):
        u1 = user(username='******', save=True)
        p = profile(user=u1, name=u'Elite Mike')
        u2 = user(username='******', save=True)
        profile(user=u2, name=u'NotElite Mike')
        r1 = reply(user=u1, twitter_username='******', save=True)
        r2 = reply(user=u2, twitter_username='******', save=True)

        self.refresh()

        eq_(
            UserMappingType.search().query(
                itwitter_usernames__match='l33tmike').count(), 1)
        data = UserMappingType.search().query(
            itwitter_usernames__match='l33tmike').values_dict()[0]
        eq_(data['username'], p.user.username)
        eq_(data['display_name'], p.name)
        assert r1.twitter_username in data['twitter_usernames']
Beispiel #26
0
    def test_data_in_index(self):
        """Verify the data we are indexing."""
        u = UserFactory(username='******', email='*****@*****.**', profile__name=u'Rick Róss')
        r1 = ReplyFactory(user=u, twitter_username='******')
        r2 = ReplyFactory(user=u, twitter_username='******')

        self.refresh()

        eq_(UserMappingType.search().count(), 1)
        data = UserMappingType.search()[0]
        eq_(data['username'], u.username)
        eq_(data['display_name'], u.profile.name)
        assert r1.twitter_username in data['twitter_usernames']
        assert r2.twitter_username in data['twitter_usernames']

        u = UserFactory(username='******', email='*****@*****.**', profile__name='Will Cage')
        self.refresh()
        eq_(UserMappingType.search().count(), 2)
Beispiel #27
0
    def test_data_in_index(self):
        """Verify the data we are indexing."""
        u = UserFactory(username='******', email='*****@*****.**', profile__name='Rick Róss')
        r1 = ReplyFactory(user=u, twitter_username='******')
        r2 = ReplyFactory(user=u, twitter_username='******')

        self.refresh()

        eq_(UserMappingType.search().count(), 1)
        data = UserMappingType.search()[0]
        eq_(data['username'], u.username)
        eq_(data['display_name'], u.profile.name)
        assert r1.twitter_username in data['twitter_usernames']
        assert r2.twitter_username in data['twitter_usernames']

        u = UserFactory(username='******', email='*****@*****.**', profile__name='Will Cage')
        self.refresh()
        eq_(UserMappingType.search().count(), 2)
Beispiel #28
0
    def test_data_in_index(self):
        """Verify the data we are indexing."""
        u = UserFactory(username="******",
                        email="*****@*****.**",
                        profile__name="Rick Róss")

        self.refresh()

        eq_(UserMappingType.search().count(), 1)
        data = UserMappingType.search()[0]
        eq_(data["username"], u.username)
        eq_(data["display_name"], u.profile.name)

        u = UserFactory(username="******",
                        email="*****@*****.**",
                        profile__name="Will Cage")
        self.refresh()
        eq_(UserMappingType.search().count(), 2)
Beispiel #29
0
    def test_data_in_index(self):
        """Verify the data we are indexing."""
        u = UserFactory(username="******", email="*****@*****.**", profile__name="Rick Róss")
        r1 = ReplyFactory(user=u, twitter_username="******")
        r2 = ReplyFactory(user=u, twitter_username="******")

        self.refresh()

        eq_(UserMappingType.search().count(), 1)
        data = UserMappingType.search()[0]
        eq_(data["username"], u.username)
        eq_(data["display_name"], u.profile.name)
        assert r1.twitter_username in data["twitter_usernames"]
        assert r2.twitter_username in data["twitter_usernames"]

        u = UserFactory(username="******", email="*****@*****.**", profile__name="Will Cage")
        self.refresh()
        eq_(UserMappingType.search().count(), 2)
Beispiel #30
0
    def test_last_contribution_date(self):
        """Verify the last_contribution_date field works properly."""
        u = UserFactory(username="******")
        self.refresh()

        data = UserMappingType.search().query(username__match="satdav")[0]
        assert not data["last_contribution_date"]

        # Add a AoA reply. It should be the last contribution.
        d = datetime(2014, 1, 1)
        ReplyFactory(user=u, created=d)
        self.refresh()

        data = UserMappingType.search().query(username__match="satdav")[0]
        eq_(data["last_contribution_date"], d)

        # Add a Support Forum answer. It should be the last contribution.
        d = datetime(2014, 1, 2)
        AnswerFactory(creator=u, created=d)
        u.profile.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(username__match="satdav")[0]
        eq_(data["last_contribution_date"], d)

        # Add a Revision edit. It should be the last contribution.
        d = datetime(2014, 1, 3)
        RevisionFactory(created=d, creator=u)
        u.profile.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(username__match="satdav")[0]
        eq_(data["last_contribution_date"], d)

        # Add a Revision review. It should be the last contribution.
        d = datetime(2014, 1, 4)
        RevisionFactory(reviewed=d, reviewer=u)

        u.profile.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(username__match="satdav")[0]
        eq_(data["last_contribution_date"], d)
Beispiel #31
0
    def test_last_contribution_date(self):
        """Verify the last_contribution_date field works properly."""
        u = UserFactory(username='******')
        self.refresh()

        data = UserMappingType.search().query(username__match='satdav')[0]
        assert not data['last_contribution_date']

        # Add a AoA reply. It should be the last contribution.
        d = datetime(2014, 1, 1)
        ReplyFactory(user=u, created=d)
        self.refresh()

        data = UserMappingType.search().query(username__match='satdav')[0]
        eq_(data['last_contribution_date'], d)

        # Add a Support Forum answer. It should be the last contribution.
        d = datetime(2014, 1, 2)
        AnswerFactory(creator=u, created=d)
        u.profile.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(username__match='satdav')[0]
        eq_(data['last_contribution_date'], d)

        # Add a Revision edit. It should be the last contribution.
        d = datetime(2014, 1, 3)
        RevisionFactory(created=d, creator=u)
        u.profile.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(username__match='satdav')[0]
        eq_(data['last_contribution_date'], d)

        # Add a Revision review. It should be the last contribution.
        d = datetime(2014, 1, 4)
        RevisionFactory(reviewed=d, reviewer=u)

        u.profile.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(username__match='satdav')[0]
        eq_(data['last_contribution_date'], d)
Beispiel #32
0
    def test_data_in_index(self):
        """Verify the data we are indexing."""
        u = user(username='******', email='*****@*****.**', save=True)
        p = profile(user=u, name=u'Rick Róss')
        r1 = reply(user=u, twitter_username='******', save=True)
        r2 = reply(user=u, twitter_username='******', save=True)

        self.refresh()

        eq_(UserMappingType.search().count(), 1)
        data = UserMappingType.search()[0]
        eq_(data['username'], p.user.username)
        eq_(data['display_name'], p.name)
        assert r1.twitter_username in data['twitter_usernames']
        assert r2.twitter_username in data['twitter_usernames']

        u = user(username='******', email='*****@*****.**', save=True)
        p = profile(user=u, name=u'Will Cage')
        self.refresh()
        eq_(UserMappingType.search().count(), 2)
Beispiel #33
0
    def test_data_in_index(self):
        """Verify the data we are indexing."""
        u = user(username='******', email='*****@*****.**', save=True)
        p = profile(user=u, name=u'Rick Róss')
        r1 = reply(user=u, twitter_username='******', save=True)
        r2 = reply(user=u, twitter_username='******', save=True)

        self.refresh()

        eq_(UserMappingType.search().count(), 1)
        data = UserMappingType.search()[0]
        eq_(data['username'], p.user.username)
        eq_(data['display_name'], p.name)
        assert r1.twitter_username in data['twitter_usernames']
        assert r2.twitter_username in data['twitter_usernames']

        u = user(username='******', email='*****@*****.**', save=True)
        p = profile(user=u, name=u'Will Cage')
        self.refresh()
        eq_(UserMappingType.search().count(), 2)
Beispiel #34
0
    def test_suggest_completions(self):
        u1 = UserFactory(username='******', profile__name='Rick Róss')
        u2 = UserFactory(username='******', profile__name='Will Cage')

        self.refresh()
        eq_(UserMappingType.search().count(), 2)

        results = UserMappingType.suggest_completions('wi')
        eq_(1, len(results))
        eq_('Will Cage (Willkg)', results[0]['text'])
        eq_(u2.id, results[0]['payload']['user_id'])

        results = UserMappingType.suggest_completions('R1')
        eq_(1, len(results))
        eq_('Rick Róss (r1cky)', results[0]['text'])
        eq_(u1.id, results[0]['payload']['user_id'])

        # Add another Ri....
        UserFactory(username='******', profile__name='Richard Smith')

        self.refresh()
        eq_(UserMappingType.search().count(), 3)

        results = UserMappingType.suggest_completions('ri')
        eq_(2, len(results))
        texts = [r['text'] for r in results]
        assert 'Rick Róss (r1cky)' in texts
        assert 'Richard Smith (richard)' in texts

        results = UserMappingType.suggest_completions('Rick Ró')
        eq_(1, len(results))
        texts = [r['text'] for r in results]
        eq_('Rick Róss (r1cky)', results[0]['text'])
Beispiel #35
0
def _get_creator_counts(query, count, page):
    total = query.count()

    start = (page - 1) * count
    end = page * count
    query_data = query.values('id', 'query_count')[start:end]

    query_data = {obj['id']: obj['query_count'] for obj in query_data}

    users_data = (UserMappingType.search().filter(
        id__in=query_data.keys()).values_dict(
            'id', 'username', 'display_name', 'avatar', 'twitter_usernames',
            'last_contribution_date')[:count])

    users_data = UserMappingType.reshape(users_data)

    results = []
    now = datetime.now()

    for u_data in users_data:
        user_id = u_data.get('id')
        last_contribution_date = u_data.get('last_contribution_date', None)

        u_data['days_since_last_activity'] = ((now -
                                               last_contribution_date).days if
                                              last_contribution_date else None)

        data = {
            'count': query_data.get(user_id),
            'term': user_id,
            'user': u_data
        }

        results.append(data)

    # Descending Order the list according to count.
    # As the top number of contributor should be at first
    results = sorted(results, key=itemgetter('count'), reverse=True)

    return results, total
Beispiel #36
0
    def test_suggest_completions(self):
        u1 = UserFactory(username='******', profile__name=u'Rick Róss')
        u2 = UserFactory(username='******', profile__name=u'Will Cage')

        self.refresh()
        eq_(UserMappingType.search().count(), 2)

        results = UserMappingType.suggest_completions('wi')
        eq_(1, len(results))
        eq_('Will Cage (Willkg)', results[0]['text'])
        eq_(u2.id, results[0]['payload']['user_id'])

        results = UserMappingType.suggest_completions('R1')
        eq_(1, len(results))
        eq_(u'Rick Róss (r1cky)', results[0]['text'])
        eq_(u1.id, results[0]['payload']['user_id'])

        # Add another Ri....
        UserFactory(username='******', profile__name=u'Richard Smith')

        self.refresh()
        eq_(UserMappingType.search().count(), 3)

        results = UserMappingType.suggest_completions('ri')
        eq_(2, len(results))
        texts = [r['text'] for r in results]
        assert u'Rick Róss (r1cky)' in texts
        assert u'Richard Smith (richard)' in texts

        results = UserMappingType.suggest_completions(u'Rick Ró')
        eq_(1, len(results))
        texts = [r['text'] for r in results]
        eq_(u'Rick Róss (r1cky)', results[0]['text'])
Beispiel #37
0
    def test_suggest_completions(self):
        u1 = UserFactory(username="******", profile__name="Rick Róss")
        u2 = UserFactory(username="******", profile__name="Will Cage")

        self.refresh()
        eq_(UserMappingType.search().count(), 2)

        results = UserMappingType.suggest_completions("wi")
        eq_(1, len(results))
        eq_("Will Cage (Willkg)", results[0]["text"])
        eq_(u2.id, results[0]["payload"]["user_id"])

        results = UserMappingType.suggest_completions("R1")
        eq_(1, len(results))
        eq_("Rick Róss (r1cky)", results[0]["text"])
        eq_(u1.id, results[0]["payload"]["user_id"])

        # Add another Ri....
        UserFactory(username="******", profile__name="Richard Smith")

        self.refresh()
        eq_(UserMappingType.search().count(), 3)

        results = UserMappingType.suggest_completions("ri")
        eq_(2, len(results))
        texts = [r["text"] for r in results]
        assert "Rick Róss (r1cky)" in texts
        assert "Richard Smith (richard)" in texts

        results = UserMappingType.suggest_completions("Rick Ró")
        eq_(1, len(results))
        texts = [r["text"] for r in results]
        eq_("Rick Róss (r1cky)", results[0]["text"])
Beispiel #38
0
def _get_creator_counts(query, count, page):
    total = query.count()

    start = (page - 1) * count
    end = page * count
    query_data = query.values('id', 'query_count')[start:end]

    query_data = {obj['id']: obj['query_count'] for obj in query_data}

    users_data = (UserMappingType.search().filter(id__in=query_data.keys())
                                 .values_dict('id', 'username', 'display_name',
                                              'avatar', 'twitter_usernames',
                                              'last_contribution_date')[:count])

    users_data = UserMappingType.reshape(users_data)

    results = []
    now = datetime.now()

    for u_data in users_data:
        user_id = u_data.get('id')
        last_contribution_date = u_data.get('last_contribution_date', None)

        u_data['days_since_last_activity'] = ((now - last_contribution_date).days
                                              if last_contribution_date else None)

        data = {
            'count': query_data.get(user_id),
            'term': user_id,
            'user': u_data
        }

        results.append(data)

    # Descending Order the list according to count.
    # As the top number of contributor should be at first
    results = sorted(results, key=itemgetter('count'), reverse=True)

    return results, total
Beispiel #39
0
    def test_reindex_users_that_contributed_yesterday(self):
        yesterday = datetime.now() - timedelta(days=1)

        # Verify for answers.
        u = user(username='******', save=True)
        p = profile(user=u)
        answer(creator=u, created=yesterday, save=True)

        reindex_users_that_contributed_yesterday()
        self.refresh()

        data = UserMappingType.search().query(
            username__match='answerer').values_dict()[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())

        # Verify for edits.
        u = user(username='******', save=True)
        p = profile(user=u)
        revision(creator=u, created=yesterday, save=True)

        reindex_users_that_contributed_yesterday()
        self.refresh()

        data = UserMappingType.search().query(
            username__match='editor').values_dict()[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())

        # Verify for reviews.
        u = user(username='******', save=True)
        p = profile(user=u)
        revision(reviewer=u, reviewed=yesterday, save=True)

        reindex_users_that_contributed_yesterday()
        self.refresh()

        data = UserMappingType.search().query(
            username__match='reviewer').values_dict()[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())
Beispiel #40
0
def search(request):
    """Find users by username and displayname.

    Uses the ES user's index.
    """
    results = []
    search_errored = False
    q = request.GET.get('q')

    if q:
        lowerq = q.lower()
        try:
            results = (
                UserMappingType
                .search()
                .query(
                    iusername__match=lowerq,
                    idisplay_name__match_whitespace=lowerq,
                    itwitter_usernames__match=lowerq,
                    should=True)
                .values_dict('id', 'username', 'display_name', 'avatar',
                             'twitter_usernames', 'last_contribution_date'))
            results = UserMappingType.reshape(results)

            statsd.incr('community.usersearch.success')
        except ES_EXCEPTIONS:
            search_errored = True
            statsd.incr('community.usersearch.error')
            log.exception('User search failed.')

    # For now, we're just truncating results at 30 and not doing any
    # pagination. If somebody complains, we can add pagination or something.
    results = list(results[:30])

    # Calculate days since last activity.
    for r in results:
        lcd = r.get('last_contribution_date', None)
        if lcd:
            delta = datetime.now() - lcd
            r['days_since_last_activity'] = delta.days
        else:
            r['days_since_last_activity'] = None

    data = {
        'q': q,
        'results': results,
        'search_errored': search_errored,
    }

    return render(request, 'community/search.html', data)
Beispiel #41
0
def _get_creator_counts(query, count, page):
    """Get the list of top contributors with the contribution count."""
    creator_counts = query.facet_counts()["creator_id"]["terms"]

    total = len(creator_counts)

    # Pagination
    creator_counts = creator_counts[((page - 1) * count) : (page * count)]

    # Grab all the users from the user index in ES.
    user_ids = [x["term"] for x in creator_counts]
    results = (
        UserMappingType.search()
        .filter(id__in=user_ids)
        .values_dict("id", "username", "display_name", "avatar", "twitter_usernames", "last_contribution_date")
    )[:count]
    results = UserMappingType.reshape(results)

    # Calculate days since last activity and
    # create a {<user_id>: <user>,...} dict for convenience.
    user_lookup = {}
    for r in results:
        lcd = r.get("last_contribution_date", None)
        if lcd:
            delta = datetime.now() - lcd
            r["days_since_last_activity"] = delta.days
        else:
            r["days_since_last_activity"] = None

        user_lookup[r["id"]] = r

    # Add the user to each dict in the creator_counts array.
    for item in creator_counts:
        item["user"] = user_lookup.get(item["term"], None)

    return ([item for item in creator_counts if item["user"] is not None], total)
Beispiel #42
0
    def filter_username(self, value):
        username_lower = value.lower()

        username_filter = (
            F(iusername__prefix=username_lower) |
            F(idisplay_name__prefix=username_lower) |
            F(itwitter_usernames__prefix=username_lower))

        users = UserMappingType.reshape(
            UserMappingType
            .search()
            .filter(username_filter)
            .values_dict('id')
            [:BIG_NUMBER])

        return F(creator_id__in=[u['id'] for u in users])
Beispiel #43
0
    def _filter_by_users(self, users_filter, invert=False):
        users = UserMappingType.reshape(
            UserMappingType
            .search()
            # Optimization: Filter out users that have never contributed.
            .filter(~F(last_contribution_date=None))
            .filter(users_filter)
            .values_dict('id')
            .everything())

        user_ids = [u['id'] for u in users]

        res = F(creator_id__in=user_ids)
        if invert:
            res = ~res
        return res
Beispiel #44
0
    def test_suggest_completions(self):
        u1 = user(username="******", save=True)
        profile(user=u1, name=u"Rick Róss")
        u2 = user(username="******", save=True)
        profile(user=u2, name=u"Will Cage")

        self.refresh()
        eq_(UserMappingType.search().count(), 2)

        results = UserMappingType.suggest_completions("wi")
        eq_(1, len(results))
        eq_("Will Cage (Willkg)", results[0]["text"])
        eq_(u2.id, results[0]["payload"]["user_id"])

        results = UserMappingType.suggest_completions("R1")
        eq_(1, len(results))
        eq_(u"Rick Róss (r1cky)", results[0]["text"])
        eq_(u1.id, results[0]["payload"]["user_id"])

        # Add another Ri....
        u3 = user(username="******", save=True)
        profile(user=u3, name=u"Richard Smith")

        self.refresh()
        eq_(UserMappingType.search().count(), 3)

        results = UserMappingType.suggest_completions("ri")
        eq_(2, len(results))
        texts = [r["text"] for r in results]
        assert u"Rick Róss (r1cky)" in texts
        assert u"Richard Smith (richard)" in texts

        results = UserMappingType.suggest_completions(u"Rick Ró")
        eq_(1, len(results))
        texts = [r["text"] for r in results]
        eq_(u"Rick Róss (r1cky)", results[0]["text"])
Beispiel #45
0
    def get_data(self, request):
        super(TopContributorsLocalization, self).get_data(request)

        # This is the base of all the metrics. Each metric branches off from
        # this to get a particular metric type, since we can't do Aggregates.
        base_query = RevisionMetricsMappingType.search()
        base_filters = self.get_filters()

        # This branch is to get the number of revisions made by each user.
        revision_query = (
            base_query
            .filter(base_filters)
            .facet('creator_id', filtered=True, size=BIG_NUMBER))

        # This branch is to get the number of reviews done by each user.
        reviewer_query = (
            base_query
            .filter(base_filters)
            .facet('reviewer_id', filtered=True, size=BIG_NUMBER))

        # Collect two lists of objects that correlates users and the appropriate metric count
        revision_creator_counts = revision_query.facet_counts()['creator_id']['terms']
        revision_reviewer_counts = reviewer_query.facet_counts()['reviewer_id']['terms']

        # Combine all the metric types into one big list.
        combined = defaultdict(lambda: {
            'revision_count': 0,
            'review_count': 0,
        })

        for d in revision_creator_counts:
            combined[d['term']]['user_id'] = d['term']
            combined[d['term']]['revision_count'] = d['count']

        for d in revision_reviewer_counts:
            combined[d['term']]['user_id'] = d['term']
            combined[d['term']]['review_count'] = d['count']

        # Sort by revision count, and get just the ids into a list.
        sort_key = self.query_values['ordering']
        if sort_key[0] == '-':
            sort_reverse = True
            sort_key = sort_key[1:]
        else:
            sort_reverse = False

        top_contributors = combined.values()
        top_contributors.sort(key=lambda d: d[sort_key], reverse=sort_reverse)
        user_ids = [c['user_id'] for c in top_contributors]
        full_count = len(user_ids)

        # Paginate those user ids.
        page_start = (self.query_values['page'] - 1) * self.query_values['page_size']
        page_end = page_start + self.query_values['page_size']
        user_ids = user_ids[page_start:page_end]

        # Get full user objects for every id on this page.
        users = UserMappingType.reshape(
            UserMappingType
            .search()
            .filter(id__in=user_ids)
            .values_dict('id', 'username', 'display_name', 'avatar', 'last_contribution_date')
            [:self.query_values['page_size']])

        # For ever user object found, mix in the metrics counts for that user,
        # and then reshape the data to make more sense to clients.
        data = []
        for u in users:
            d = combined[u['id']]
            d['user'] = u
            d['last_contribution_date'] = d['user'].get('last_contribution_date', None)
            d.pop('user_id', None)
            d['user'].pop('id', None)
            d['user'].pop('last_contribution_date', None)
            data.append(d)

        # One last sort, since ES didn't return the users in any particular order.
        data.sort(key=lambda d: d[sort_key], reverse=sort_reverse)

        # Add ranks to the objects.
        for i, contributor in enumerate(data, 1):
            contributor['rank'] = page_start + i

        return {
            'results': data,
            'count': full_count,
            'filters': self.query_values,
            'allowed_orderings': self.get_allowed_orderings(),
            'warnings': self.warnings,
        }
Beispiel #46
0
    def get_data(self, request):
        super(TopContributorsQuestions, self).get_data(request)

        # This is the base of all the metrics. Each metric branches off from
        # this to get a particular metric type, since we can't do Aggregates.
        query = AnswerMetricsMappingType.search()
        base_filters = self.get_filters()

        # This branch is to get the total number of answers for each user.
        answer_query = (
            query
            .filter(base_filters)
            .facet('creator_id', filtered=True, size=BIG_NUMBER))

        # This branch gets the number of answers that are solutions for each user.
        solutions_filter = base_filters & F(is_solution=True)
        solutions_query = (
            query
            .filter(solutions_filter)
            .facet('creator_id', filtered=True, size=BIG_NUMBER))

        # This branch gets the number of helpful votes across all answers for
        # each user. It is a raw facet because elasticutils only supports the
        # term facet type in non-raw facets. Because it is raw facet, we have
        # to also put the filter in the facet ourselves.
        helpful_query = (
            query
            .facet_raw(
                creator_id={
                    'terms_stats': {
                        'key_field': 'creator_id',
                        'value_field': 'helpful_count',
                    },
                    'facet_filter': query._process_filters(base_filters.filters),
                }))

        # Collect three lists of objects that correlates users and the appropriate metric count
        creator_answer_counts = answer_query.facet_counts()['creator_id']['terms']
        creator_solutions_counts = solutions_query.facet_counts()['creator_id']['terms']
        creator_helpful_counts = helpful_query.facet_counts()['creator_id']['terms']

        # Combine all the metric types into one big list.
        combined = defaultdict(lambda: {
            'answer_count': 0,
            'solution_count': 0,
            'helpful_vote_count': 0,
        })

        for d in creator_answer_counts:
            combined[d['term']]['user_id'] = d['term']
            combined[d['term']]['answer_count'] = d['count']

        for d in creator_solutions_counts:
            combined[d['term']]['user_id'] = d['term']
            combined[d['term']]['solution_count'] = d['count']

        for d in creator_helpful_counts:
            combined[d['term']]['user_id'] = d['term']
            # Since this is a term_stats filter, not just a term filter, it is total, not count.
            combined[d['term']]['helpful_vote_count'] = int(d['total'])

        # Sort by answer count, and get just the ids into a list.
        sort_key = self.query_values['ordering']
        if sort_key[0] == '-':
            sort_reverse = True
            sort_key = sort_key[1:]
        else:
            sort_reverse = False

        top_contributors = combined.values()
        top_contributors.sort(key=lambda d: d[sort_key], reverse=sort_reverse)
        user_ids = [c['user_id'] for c in top_contributors]
        full_count = len(user_ids)

        # Paginate those user ids.
        page_start = (self.query_values['page'] - 1) * self.query_values['page_size']
        page_end = page_start + self.query_values['page_size']
        user_ids = user_ids[page_start:page_end]

        # Get full user objects for every id on this page.
        users = UserMappingType.reshape(
            UserMappingType
            .search()
            .filter(id__in=user_ids)
            .values_dict('id', 'username', 'display_name', 'avatar', 'last_contribution_date')
            [:self.query_values['page_size']])

        # For ever user object found, mix in the metrics counts for that user,
        # and then reshape the data to make more sense to clients.
        data = []
        for u in users:
            d = combined[u['id']]
            d['user'] = u
            d['last_contribution_date'] = d['user'].get('last_contribution_date', None)
            d.pop('user_id', None)
            d['user'].pop('id', None)
            d['user'].pop('last_contribution_date', None)
            data.append(d)

        # One last sort, since ES didn't return the users in any particular order.
        data.sort(key=lambda d: d[sort_key], reverse=sort_reverse)

        # Add ranks to the objects.
        for i, contributor in enumerate(data, 1):
            contributor['rank'] = page_start + i

        return {
            'results': data,
            'count': full_count,
            'filters': self.query_values,
            'allowed_orderings': self.get_allowed_orderings(),
            'warnings': self.warnings,
        }
Beispiel #47
0
    def get_data(self, request):
        super(TopContributorsLocalization, self).get_data(request)

        # This is the base of all the metrics. Each metric branches off from
        # this to get a particular metric type, since we can't do Aggregates.
        base_query = RevisionMetricsMappingType.search()
        base_filters = self.get_filters()

        # This branch is to get the number of revisions made by each user.
        revision_query = (
            base_query
            .filter(base_filters)
            .facet('creator_id', filtered=True, size=BIG_NUMBER))

        # This branch is to get the number of reviews done by each user.
        reviewer_query = (
            base_query
            .filter(base_filters)
            .facet('reviewer_id', filtered=True, size=BIG_NUMBER))

        # Collect two lists of objects that correlates users and the appropriate metric count
        revision_creator_counts = revision_query.facet_counts()['creator_id']['terms']
        revision_reviewer_counts = reviewer_query.facet_counts()['reviewer_id']['terms']

        # Combine all the metric types into one big list.
        combined = defaultdict(lambda: {
            'revision_count': 0,
            'review_count': 0,
        })

        for d in revision_creator_counts:
            combined[d['term']]['user_id'] = d['term']
            combined[d['term']]['revision_count'] = d['count']

        for d in revision_reviewer_counts:
            combined[d['term']]['user_id'] = d['term']
            combined[d['term']]['review_count'] = d['count']

        # Sort by revision count, and get just the ids into a list.
        sort_key = self.query_values['ordering']
        if sort_key[0] == '-':
            sort_reverse = True
            sort_key = sort_key[1:]
        else:
            sort_reverse = False

        top_contributors = combined.values()
        top_contributors.sort(key=lambda d: d[sort_key], reverse=sort_reverse)
        user_ids = [c['user_id'] for c in top_contributors]
        full_count = len(user_ids)

        # Paginate those user ids.
        page_start = (self.query_values['page'] - 1) * self.query_values['page_size']
        page_end = page_start + self.query_values['page_size']
        user_ids = user_ids[page_start:page_end]

        # Get full user objects for every id on this page.
        users = UserMappingType.reshape(
            UserMappingType
            .search()
            .filter(id__in=user_ids)
            .values_dict('id', 'username', 'display_name', 'avatar', 'last_contribution_date')
            [:self.query_values['page_size']])

        # For ever user object found, mix in the metrics counts for that user,
        # and then reshape the data to make more sense to clients.
        data = []
        for u in users:
            d = combined[u['id']]
            d['user'] = u
            d['last_contribution_date'] = d['user'].get('last_contribution_date', None)
            d.pop('user_id', None)
            d['user'].pop('id', None)
            d['user'].pop('last_contribution_date', None)
            data.append(d)

        # One last sort, since ES didn't return the users in any particular order.
        data.sort(key=lambda d: d[sort_key], reverse=sort_reverse)

        # Add ranks to the objects.
        for i, contributor in enumerate(data, 1):
            contributor['rank'] = page_start + i

        return {
            'results': data,
            'count': full_count,
            'filters': self.query_values,
            'allowed_orderings': self.get_allowed_orderings(),
            'warnings': self.warnings,
        }
Beispiel #48
0
    def get_data(self, request):
        super(TopContributorsQuestions, self).get_data(request)

        # This is the base of all the metrics. Each metric branches off from
        # this to get a particular metric type, since we can't do Aggregates.
        query = AnswerMetricsMappingType.search()
        base_filters = self.get_filters()

        # This branch is to get the total number of answers for each user.
        answer_query = (
            query
            .filter(base_filters)
            .facet('creator_id', filtered=True, size=BIG_NUMBER))

        # This branch gets the number of answers that are solutions for each user.
        solutions_filter = base_filters & F(is_solution=True)
        solutions_query = (
            query
            .filter(solutions_filter)
            .facet('creator_id', filtered=True, size=BIG_NUMBER))

        # This branch gets the number of helpful votes across all answers for
        # each user. It is a raw facet because elasticutils only supports the
        # term facet type in non-raw facets. Because it is raw facet, we have
        # to also put the filter in the facet ourselves.
        helpful_query = (
            query
            .facet_raw(
                creator_id={
                    'terms_stats': {
                        'key_field': 'creator_id',
                        'value_field': 'helpful_count',
                    },
                    'facet_filter': query._process_filters(base_filters.filters),
                }))

        # Collect three lists of objects that correlates users and the appropriate metric count
        creator_answer_counts = answer_query.facet_counts()['creator_id']['terms']
        creator_solutions_counts = solutions_query.facet_counts()['creator_id']['terms']
        creator_helpful_counts = helpful_query.facet_counts()['creator_id']['terms']

        # Combine all the metric types into one big list.
        combined = defaultdict(lambda: {
            'answer_count': 0,
            'solution_count': 0,
            'helpful_vote_count': 0,
        })

        for d in creator_answer_counts:
            combined[d['term']]['user_id'] = d['term']
            combined[d['term']]['answer_count'] = d['count']

        for d in creator_solutions_counts:
            combined[d['term']]['user_id'] = d['term']
            combined[d['term']]['solution_count'] = d['count']

        for d in creator_helpful_counts:
            combined[d['term']]['user_id'] = d['term']
            # Since this is a term_stats filter, not just a term filter, it is total, not count.
            combined[d['term']]['helpful_vote_count'] = int(d['total'])

        # Sort by answer count, and get just the ids into a list.
        sort_key = self.query_values['ordering']
        if sort_key[0] == '-':
            sort_reverse = True
            sort_key = sort_key[1:]
        else:
            sort_reverse = False

        top_contributors = combined.values()
        top_contributors.sort(key=lambda d: d[sort_key], reverse=sort_reverse)
        user_ids = [c['user_id'] for c in top_contributors]
        full_count = len(user_ids)

        # Paginate those user ids.
        page_start = (self.query_values['page'] - 1) * self.query_values['page_size']
        page_end = page_start + self.query_values['page_size']
        user_ids = user_ids[page_start:page_end]

        # Get full user objects for every id on this page.
        users = UserMappingType.reshape(
            UserMappingType
            .search()
            .filter(id__in=user_ids)
            .values_dict('id', 'username', 'display_name', 'avatar', 'last_contribution_date')
            [:self.query_values['page_size']])

        # For ever user object found, mix in the metrics counts for that user,
        # and then reshape the data to make more sense to clients.
        data = []
        for u in users:
            d = combined[u['id']]
            d['user'] = u
            d['last_contribution_date'] = d['user'].get('last_contribution_date', None)
            d.pop('user_id', None)
            d['user'].pop('id', None)
            d['user'].pop('last_contribution_date', None)
            data.append(d)

        # One last sort, since ES didn't return the users in any particular order.
        data.sort(key=lambda d: d[sort_key], reverse=sort_reverse)

        # Add ranks to the objects.
        for i, contributor in enumerate(data, 1):
            contributor['rank'] = page_start + i

        return {
            'results': data,
            'count': full_count,
            'filters': self.query_values,
            'allowed_orderings': self.get_allowed_orderings(),
            'warnings': self.warnings,
        }
Beispiel #49
0
    def get_data(self, request):
        super(TopContributorsLocalization, self).get_data(request)

        # This is the base of all the metrics. Each metric branches off from
        # this to get a particular metric type, since we can't do Aggregates.
        base_query = RevisionMetricsMappingType.search()
        base_filters = self.get_filters()

        # This branch is to get the number of revisions made by each user.
        revision_query = base_query.filter(base_filters).facet("creator_id",
                                                               filtered=True,
                                                               size=BIG_NUMBER)

        # This branch is to get the number of reviews done by each user.
        reviewer_query = base_query.filter(base_filters).facet("reviewer_id",
                                                               filtered=True,
                                                               size=BIG_NUMBER)

        # Collect two lists of objects that correlates users and the appropriate metric count
        revision_creator_counts = revision_query.facet_counts(
        )["creator_id"]["terms"]
        revision_reviewer_counts = reviewer_query.facet_counts(
        )["reviewer_id"]["terms"]

        # Combine all the metric types into one big list.
        combined = defaultdict(lambda: {
            "revision_count": 0,
            "review_count": 0,
        })

        for d in revision_creator_counts:
            combined[d["term"]]["user_id"] = d["term"]
            combined[d["term"]]["revision_count"] = d["count"]

        for d in revision_reviewer_counts:
            combined[d["term"]]["user_id"] = d["term"]
            combined[d["term"]]["review_count"] = d["count"]

        # Sort by revision count, and get just the ids into a list.
        sort_key = self.query_values["ordering"]
        if sort_key[0] == "-":
            sort_reverse = True
            sort_key = sort_key[1:]
        else:
            sort_reverse = False

        top_contributors = list(combined.values())
        top_contributors.sort(key=lambda d: d[sort_key], reverse=sort_reverse)
        user_ids = [c["user_id"] for c in top_contributors]
        full_count = len(user_ids)

        # Paginate those user ids.
        page_start = (self.query_values["page"] -
                      1) * self.query_values["page_size"]
        page_end = page_start + self.query_values["page_size"]
        user_ids = user_ids[page_start:page_end]

        # Get full user objects for every id on this page.
        users = UserMappingType.reshape(
            UserMappingType.search().filter(id__in=user_ids).values_dict(
                "id", "username", "display_name", "avatar",
                "last_contribution_date")[:self.query_values["page_size"]])

        # For ever user object found, mix in the metrics counts for that user,
        # and then reshape the data to make more sense to clients.
        data = []
        for u in users:
            d = combined[u["id"]]
            d["user"] = u
            d["last_contribution_date"] = d["user"].get(
                "last_contribution_date", None)
            d.pop("user_id", None)
            d["user"].pop("id", None)
            d["user"].pop("last_contribution_date", None)
            data.append(d)

        # One last sort, since ES didn't return the users in any particular order.
        data.sort(key=lambda d: d[sort_key], reverse=sort_reverse)

        # Add ranks to the objects.
        for i, contributor in enumerate(data, 1):
            contributor["rank"] = page_start + i

        return {
            "results": data,
            "count": full_count,
            "filters": self.query_values,
            "allowed_orderings": self.get_allowed_orderings(),
            "warnings": self.warnings,
        }
Beispiel #50
0
    def get_data(self, request):
        super(TopContributorsQuestions, self).get_data(request)

        # This is the base of all the metrics. Each metric branches off from
        # this to get a particular metric type, since we can't do Aggregates.
        query = AnswerMetricsMappingType.search()
        base_filters = self.get_filters()

        # This branch is to get the total number of answers for each user.
        answer_query = query.filter(base_filters).facet("creator_id",
                                                        filtered=True,
                                                        size=BIG_NUMBER)

        # This branch gets the number of answers that are solutions for each user.
        solutions_filter = base_filters & F(is_solution=True)
        solutions_query = query.filter(solutions_filter).facet("creator_id",
                                                               filtered=True,
                                                               size=BIG_NUMBER)

        # This branch gets the number of helpful votes across all answers for
        # each user. It is a raw facet because elasticutils only supports the
        # term facet type in non-raw facets. Because it is raw facet, we have
        # to also put the filter in the facet ourselves.
        helpful_query = query.facet_raw(
            creator_id={
                "terms_stats": {
                    "key_field": "creator_id",
                    "value_field": "helpful_count",
                },
                "facet_filter": query._process_filters(base_filters.filters),
            })

        # Collect three lists of objects that correlates users and the appropriate metric count
        creator_answer_counts = answer_query.facet_counts(
        )["creator_id"]["terms"]
        creator_solutions_counts = solutions_query.facet_counts(
        )["creator_id"]["terms"]
        creator_helpful_counts = helpful_query.facet_counts(
        )["creator_id"]["terms"]

        # Combine all the metric types into one big list.
        combined = defaultdict(lambda: {
            "answer_count": 0,
            "solution_count": 0,
            "helpful_vote_count": 0,
        })

        for d in creator_answer_counts:
            combined[d["term"]]["user_id"] = d["term"]
            combined[d["term"]]["answer_count"] = d["count"]

        for d in creator_solutions_counts:
            combined[d["term"]]["user_id"] = d["term"]
            combined[d["term"]]["solution_count"] = d["count"]

        for d in creator_helpful_counts:
            combined[d["term"]]["user_id"] = d["term"]
            # Since this is a term_stats filter, not just a term filter, it is total, not count.
            combined[d["term"]]["helpful_vote_count"] = int(d["total"])

        # Sort by answer count, and get just the ids into a list.
        sort_key = self.query_values["ordering"]
        if sort_key[0] == "-":
            sort_reverse = True
            sort_key = sort_key[1:]
        else:
            sort_reverse = False

        top_contributors = list(combined.values())
        top_contributors.sort(key=lambda d: d[sort_key], reverse=sort_reverse)
        user_ids = [c["user_id"] for c in top_contributors]
        full_count = len(user_ids)

        # Paginate those user ids.
        page_start = (self.query_values["page"] -
                      1) * self.query_values["page_size"]
        page_end = page_start + self.query_values["page_size"]
        user_ids = user_ids[page_start:page_end]

        # Get full user objects for every id on this page.
        users = UserMappingType.reshape(
            UserMappingType.search().filter(id__in=user_ids).values_dict(
                "id", "username", "display_name", "avatar",
                "last_contribution_date")[:self.query_values["page_size"]])

        # For ever user object found, mix in the metrics counts for that user,
        # and then reshape the data to make more sense to clients.
        data = []
        for u in users:
            d = combined[u["id"]]
            d["user"] = u
            d["last_contribution_date"] = d["user"].get(
                "last_contribution_date", None)
            d.pop("user_id", None)
            d["user"].pop("id", None)
            d["user"].pop("last_contribution_date", None)
            data.append(d)

        # One last sort, since ES didn't return the users in any particular order.
        data.sort(key=lambda d: d[sort_key], reverse=sort_reverse)

        # Add ranks to the objects.
        for i, contributor in enumerate(data, 1):
            contributor["rank"] = page_start + i

        return {
            "results": data,
            "count": full_count,
            "filters": self.query_values,
            "allowed_orderings": self.get_allowed_orderings(),
            "warnings": self.warnings,
        }