Exemple #1
0
def usernames(request):
    """An API to provide auto-complete data for user names."""
    term = request.GET.get("term", "")
    query = request.GET.get("query", "")
    pre = term or query

    if not pre:
        return []
    if not request.user.is_authenticated:
        return []

    profile_ids = list(
        Profile.objects.filter(Q(name__istartswith=pre)).values_list(
            "user_id", flat=True)[:10])
    users = (User.objects.filter(
        Q(username__istartswith=pre) | Q(id__in=profile_ids)).filter(
            is_active=True).select_related("profile"))[:10]

    autocomplete_list = []
    exact_match_in_list = False

    for user in users:
        if user.username.lower() == pre.lower():
            exact_match_in_list = True
        autocomplete_list.append({
            "username": user.username,
            "display_name": display_name_or_none(user),
            "avatar": profile_avatar(user, 24),
        })

    if not exact_match_in_list:
        # The front-end dropdown which uses this API requires the exact match to be in the list
        # if it exists, so that user can be selected. Our code above won't necessarily always
        # return an exact match, even if it exists, so if it's missing attempt to fetch it and
        # prepend it to the list
        try:
            exact_match = (User.objects.filter(username__iexact=pre).filter(
                is_active=True).select_related("profile").get())
            autocomplete_list = [
                {
                    "username": exact_match.username,
                    "display_name": display_name_or_none(exact_match),
                    "avatar": profile_avatar(exact_match, 24),
                }
            ] + autocomplete_list
        except User.DoesNotExist:
            pass

    return autocomplete_list
 def test_profile_avatar(self):
     self.u.profile.avatar = 'images/foo.png'
     self.u.profile.save()
     email_hash = hashlib.md5(self.u.email.lower()).hexdigest()
     gravatar_url = 'https://secure.gravatar.com/avatar/%s?s=48' % (
         email_hash)
     assert profile_avatar(self.u).startswith(gravatar_url)
Exemple #3
0
 def test_creator_is_object(self):
     serializer = api.QuestionSerializer(instance=self.question)
     eq_(serializer.data['creator'], {
         'username': self.question.creator.username,
         'display_name': Profile.objects.get(user=self.question.creator).display_name,
         'avatar': profile_avatar(self.question.creator),
     })
Exemple #4
0
def usernames(request):
    """An API to provide auto-complete data for user names."""
    term = request.GET.get('term', '')
    query = request.GET.get('query', '')
    pre = term or query

    if not pre:
        return []
    if not request.user.is_authenticated():
        return []
    with statsd.timer('users.api.usernames.search'):
        profiles = (
            Profile.objects.filter(Q(name__istartswith=pre))
            .values_list('user_id', flat=True))
        users = (
            User.objects.filter(
                Q(username__istartswith=pre) | Q(id__in=profiles))
            .extra(select={'length': 'Length(username)'})
            .order_by('length').select_related('profile'))

        if not waffle.switch_is_active('users-dont-limit-by-login'):
            last_login = datetime.now() - timedelta(weeks=12)
            users = users.filter(last_login__gte=last_login)

        return [{'username': u.username,
                 'display_name': display_name_or_none(u),
                 'avatar': profile_avatar(u, 24)}
                for u in users[:10]]
Exemple #5
0
def usernames(request):
    """An API to provide auto-complete data for user names."""
    term = request.GET.get('term', '')
    query = request.GET.get('query', '')
    pre = term or query

    if not pre:
        return []
    if not request.user.is_authenticated():
        return []
    with statsd.timer('users.api.usernames.search'):
        profiles = (Profile.objects.filter(
            Q(name__istartswith=pre)).values_list('user_id', flat=True))
        users = (User.objects.filter(
            Q(username__istartswith=pre)
            | Q(id__in=profiles)).extra(select={
                'length': 'Length(username)'
            }).order_by('length').select_related('profile'))

        if not waffle.switch_is_active('users-dont-limit-by-login'):
            last_login = datetime.now() - timedelta(weeks=12)
            users = users.filter(last_login__gte=last_login)

        return [{
            'username': u.username,
            'display_name': display_name_or_none(u),
            'avatar': profile_avatar(u, 24)
        } for u in users[:10]]
Exemple #6
0
    def test_correct_fields(self):
        follower = UserFactory()
        followed = UserFactory()
        q = QuestionFactory(creator=followed)
        # The above might make follows, which this test isn't about. Clear them out.
        Follow.objects.all().delete()
        follow(follower, followed)

        # Make a new action for the above. This should trigger notifications
        action.send(followed, verb='asked', action_object=q)
        act = Action.objects.order_by('-id')[0]
        notification = Notification.objects.get(action=act)

        serializer = api.NotificationSerializer(instance=notification)

        eq_(serializer.data['is_read'], False)
        eq_(serializer.data['actor'], {
            'type': 'user',
            'username': followed.username,
            'display_name': followed.profile.name,
            'avatar': profile_avatar(followed),
        })
        eq_(serializer.data['verb'], 'asked')
        eq_(serializer.data['action_object']['type'], 'question')
        eq_(serializer.data['action_object']['id'], q.id)
        eq_(serializer.data['target'], None)
        # Check that the serialized data is in the correct format. If it is
        # not, this will throw an exception.
        datetime.strptime(serializer.data['timestamp'], '%Y-%m-%dT%H:%M:%SZ')
Exemple #7
0
def usernames(request):
    """An API to provide auto-complete data for user names."""
    term = request.GET.get("term", "")
    query = request.GET.get("query", "")
    pre = term or query

    if not pre:
        return []
    if not request.user.is_authenticated:
        return []

    profiles = Profile.objects.filter(Q(name__istartswith=pre)).values_list(
        "user_id", flat=True)
    users = (User.objects.filter(
        Q(username__istartswith=pre)
        | Q(id__in=profiles)).extra(select={
            "length": "Length(username)"
        }).order_by("length").select_related("profile"))

    if not waffle.switch_is_active("users-dont-limit-by-login"):
        last_login = datetime.now() - timedelta(weeks=12)
        users = users.filter(last_login__gte=last_login)

    return [{
        "username": u.username,
        "display_name": display_name_or_none(u),
        "avatar": profile_avatar(u, 24),
    } for u in users[:10]]
Exemple #8
0
def _get_creator_counts(query, count, page):
    total = query.count()
    results = []
    now = datetime.now()
    for user in query[((page - 1) * count):(page * count)]:
        last_contribution_date = user.profile.last_contribution_date
        days_since_last_activity = None
        if last_contribution_date:
            days_since_last_activity = now - last_contribution_date

        data = {
            'count': user.query_count,
            'term': user.id,
            'user': {
                'id': user.id,
                'username': user.username,
                'display_name': user.profile.display_name,
                'avatar': profile_avatar(user, size=120),
                'twitter_usernames': user.profile.twitter_usernames,
                'last_contribution_date': last_contribution_date,
                'days_since_last_activity': days_since_last_activity,
            }
        }
        results.append(data)

    return (results, total)
Exemple #9
0
def top_contributors_l10n(start=None,
                          end=None,
                          locale=None,
                          product=None,
                          count=10,
                          page=1,
                          use_cache=True):
    """Get the top l10n contributors for the KB."""
    if use_cache:
        cache_key = "{}_{}_{}_{}_{}_{}".format(start, end, locale, product,
                                               count, page)
        cache_key = hashlib.sha1(cache_key.encode("utf-8")).hexdigest()
        cache_key = "top_contributors_l10n_{}".format(cache_key)
        cached = cache.get(cache_key, None)
        if cached:
            return cached

    # Get the user ids and contribution count of the top contributors.
    revisions = Revision.objects.all()
    if locale is None:
        # If there is no locale specified, exclude en-US only. The rest are
        # l10n.
        revisions = revisions.exclude(
            document__locale=settings.WIKI_DEFAULT_LANGUAGE)
    if start is None:
        # By default we go back 90 days.
        start = date.today() - timedelta(days=90)
        revisions = revisions.filter(created__gte=start)
    if end:
        # If no end is specified, we don't need to filter by it.
        revisions = revisions.filter(created__lt=end)
    if locale:
        revisions = revisions.filter(document__locale=locale)
    if product:
        if isinstance(product, Product):
            product = product.slug
        revisions = revisions.filter(
            Q(document__products__slug=product)
            | Q(document__parent__products__slug=product))

    users = (User.objects.filter(
        created_revisions__in=revisions, is_active=True).annotate(
            query_count=Count("created_revisions")).order_by(
                "-query_count").select_related("profile"))
    total = users.count()

    results = [{
        "term": user.pk,
        "count": user.query_count,
        "user": {
            "id": user.pk,
            "username": user.username,
            "display_name": user.profile.display_name,
            "avatar": profile_avatar(user),
        },
    } for user in users[(page - 1) * count:page * count]]

    if use_cache:
        cache.set(cache_key, (results, total), settings.CACHE_MEDIUM_TIMEOUT)
    return results, total
Exemple #10
0
    def test_correct_fields(self):
        follower = UserFactory()
        followed = UserFactory()
        q = QuestionFactory(creator=followed)
        # The above might make follows, which this test isn't about. Clear them out.
        Follow.objects.all().delete()
        follow(follower, followed)

        # Make a new action for the above. This should trigger notifications
        action.send(followed, verb="asked", action_object=q)
        act = Action.objects.order_by("-id")[0]
        notification = Notification.objects.get(action=act)

        serializer = api.NotificationSerializer(instance=notification)

        eq_(serializer.data["is_read"], False)
        eq_(
            serializer.data["actor"],
            {
                "type": "user",
                "username": followed.username,
                "display_name": followed.profile.name,
                "avatar": profile_avatar(followed),
            },
        )
        eq_(serializer.data["verb"], "asked")
        eq_(serializer.data["action_object"]["type"], "question")
        eq_(serializer.data["action_object"]["id"], q.id)
        eq_(serializer.data["target"], None)
        # Check that the serialized data is in the correct format. If it is
        # not, this will throw an exception.
        datetime.strptime(serializer.data["timestamp"], "%Y-%m-%dT%H:%M:%SZ")
Exemple #11
0
    def test_correct_fields(self):
        follower = UserFactory()
        followed = UserFactory()
        q = QuestionFactory(creator=followed)
        # The above might make follows, which this test isn't about. Clear them out.
        Follow.objects.all().delete()
        follow(follower, followed)

        # Make a new action for the above. This should trigger notifications
        action.send(followed, verb='asked', action_object=q)
        act = Action.objects.order_by('-id')[0]
        notification = Notification.objects.get(action=act)

        serializer = api.NotificationSerializer(instance=notification)

        eq_(serializer.data['is_read'], False)
        eq_(
            serializer.data['actor'], {
                'type': 'user',
                'username': followed.username,
                'display_name': followed.profile.name,
                'avatar': profile_avatar(followed),
            })
        eq_(serializer.data['verb'], 'asked')
        eq_(serializer.data['action_object']['type'], 'question')
        eq_(serializer.data['action_object']['id'], q.id)
        eq_(serializer.data['target'], None)
        # Check that the serialized data is in the correct format. If it is
        # not, this will throw an exception.
        datetime.strptime(serializer.data['timestamp'], '%Y-%m-%dT%H:%M:%SZ')
Exemple #12
0
 def test_profile_avatar(self):
     self.u.profile.avatar = 'images/foo.png'
     self.u.profile.save()
     email_hash = hashlib.md5(self.u.email.lower()).hexdigest()
     gravatar_url = 'https://secure.gravatar.com/avatar/%s?s=48' % (
         email_hash)
     assert profile_avatar(self.u).startswith(gravatar_url)
Exemple #13
0
def _get_creator_counts(query, count, page):
    total = query.count()
    results = []
    now = datetime.now()
    for user in query[((page - 1) * count):(page * count)]:
        last_contribution_date = user.profile.last_contribution_date
        days_since_last_activity = None
        if last_contribution_date:
            days_since_last_activity = now - last_contribution_date

        data = {
            'count': user.query_count,
            'term': user.id,
            'user': {
                'id': user.id,
                'username': user.username,
                'display_name': user.profile.display_name,
                'avatar': profile_avatar(user, size=120),
                'twitter_usernames': user.profile.twitter_usernames,
                'last_contribution_date': last_contribution_date,
                'days_since_last_activity': days_since_last_activity,
            }
        }
        results.append(data)

    return (results, total)
Exemple #14
0
 def test_creator_is_object(self):
     serializer = api.QuestionSerializer(instance=self.question)
     eq_(serializer.data['creator'], {
         'username': self.question.creator.username,
         'display_name': Profile.objects.get(user=self.question.creator).display_name,
         'avatar': profile_avatar(self.question.creator),
     })
Exemple #15
0
 def _names(self, *users):
     return sorted(
         {
             'username': u.username,
             'display_name': Profile.objects.get(user=u).name,
             'avatar': profile_avatar(u),
         }
         for u in users)
Exemple #16
0
 def _names(self, *users):
     return sorted((
         {
             'username': u.username,
             'display_name': Profile.objects.get(user=u).name,
             'avatar': profile_avatar(u),
         }
         for u in users), key=lambda d: d['username'])
Exemple #17
0
 def _names(self, *users):
     return sorted(
         ({
             "username": u.username,
             "display_name": Profile.objects.get(user=u).name,
             "avatar": profile_avatar(u),
         } for u in users),
         key=lambda d: d["username"],
     )
Exemple #18
0
 def test_creator_is_object(self):
     serializer = api.QuestionSerializer(instance=self.question)
     eq_(
         serializer.data["creator"],
         {
             "username": self.question.creator.username,
             "display_name":
             Profile.objects.get(user=self.question.creator).display_name,
             "avatar": profile_avatar(self.question.creator),
         },
     )
Exemple #19
0
    def extract_document(cls, obj_id, obj=None):
        """Extracts interesting thing from a Thread and its Posts"""
        if obj is None:
            model = cls.get_model()
            obj = model.objects.select_related("user").get(pk=obj_id)

        if not obj.user.is_active:
            raise UnindexMeBro()

        d = {}
        d["id"] = obj.pk
        d["model"] = cls.get_mapping_type_name()
        d["url"] = obj.get_absolute_url()
        d["indexed_on"] = int(time.time())

        d["username"] = obj.user.username
        d["display_name"] = obj.display_name
        d["twitter_usernames"] = obj.twitter_usernames

        d["last_contribution_date"] = obj.last_contribution_date

        d["iusername"] = obj.user.username.lower()
        d["idisplay_name"] = obj.display_name.lower()
        d["itwitter_usernames"] = [u.lower() for u in obj.twitter_usernames]

        from kitsune.users.templatetags.jinja_helpers import profile_avatar

        d["avatar"] = profile_avatar(obj.user, size=120)

        d["suggest"] = {
            "input": [d["iusername"], d["idisplay_name"]],
            "output":
            _("{displayname} ({username})").format(
                displayname=d["display_name"], username=d["username"]),
            "payload": {
                "user_id": d["id"]
            },
        }

        return d
Exemple #20
0
    def extract_document(cls, obj_id, obj=None):
        """Extracts interesting thing from a Thread and its Posts"""
        if obj is None:
            model = cls.get_model()
            obj = model.objects.select_related('user').get(pk=obj_id)

        if not obj.user.is_active:
            raise UnindexMeBro()

        d = {}
        d['id'] = obj.pk
        d['model'] = cls.get_mapping_type_name()
        d['url'] = obj.get_absolute_url()
        d['indexed_on'] = int(time.time())

        d['username'] = obj.user.username
        d['display_name'] = obj.display_name
        d['twitter_usernames'] = obj.twitter_usernames

        d['last_contribution_date'] = obj.last_contribution_date

        d['iusername'] = obj.user.username.lower()
        d['idisplay_name'] = obj.display_name.lower()
        d['itwitter_usernames'] = [u.lower() for u in obj.twitter_usernames]

        from kitsune.users.templatetags.jinja_helpers import profile_avatar
        d['avatar'] = profile_avatar(obj.user, size=120)

        d['suggest'] = {
            'input': [
                d['iusername'],
                d['idisplay_name']
            ],
            'output': _(u'{displayname} ({username})').format(
                displayname=d['display_name'], username=d['username']),
            'payload': {'user_id': d['id']},
        }

        return d
Exemple #21
0
    def extract_document(cls, obj_id, obj=None):
        """Extracts interesting thing from a Thread and its Posts"""
        if obj is None:
            model = cls.get_model()
            obj = model.objects.select_related('user').get(pk=obj_id)

        if not obj.user.is_active:
            raise UnindexMeBro()

        d = {}
        d['id'] = obj.pk
        d['model'] = cls.get_mapping_type_name()
        d['url'] = obj.get_absolute_url()
        d['indexed_on'] = int(time.time())

        d['username'] = obj.user.username
        d['display_name'] = obj.display_name
        d['twitter_usernames'] = obj.twitter_usernames

        d['last_contribution_date'] = obj.last_contribution_date

        d['iusername'] = obj.user.username.lower()
        d['idisplay_name'] = obj.display_name.lower()
        d['itwitter_usernames'] = [u.lower() for u in obj.twitter_usernames]

        from kitsune.users.templatetags.jinja_helpers import profile_avatar
        d['avatar'] = profile_avatar(obj.user, size=120)

        d['suggest'] = {
            'input': [d['iusername'], d['idisplay_name']],
            'output':
            _(u'{displayname} ({username})').format(
                displayname=d['display_name'], username=d['username']),
            'payload': {
                'user_id': d['id']
            },
        }

        return d
 def test_profile_avatar_anonymous(self):
     email_hash = '00000000000000000000000000000000'
     gravatar_url = 'https://secure.gravatar.com/avatar/%s?s=48' % (
         email_hash)
     assert profile_avatar(AnonymousUser()).startswith(gravatar_url)
 def test_profile_avatar_default(self):
     email_hash = hashlib.md5(self.u.email.lower()).hexdigest()
     gravatar_url = 'https://secure.gravatar.com/avatar/%s?s=48' % (
         email_hash)
     assert profile_avatar(self.u).startswith(gravatar_url)
Exemple #24
0
 def test_profile_avatar_unicode(self):
     self.u.email = u'rá[email protected]'
     self.u.save()
     gravatar_url = 'https://secure.gravatar.com/'
     assert profile_avatar(self.u).startswith(gravatar_url)
Exemple #25
0
 def get_avatar_url(self, profile):
     request = self.context.get('request')
     size = request.REQUEST.get('avatar_size', 48) if request else 48
     return profile_avatar(profile.user, size=size)
Exemple #26
0
 def get_avatar_url(self, profile):
     request = self.context.get("request")
     size = request.GET.get("avatar_size", 200) if request else 200
     return profile_avatar(profile.user, size=size)
Exemple #27
0
 def get_avatar_url(self, profile):
     request = self.context.get('request')
     size = request.REQUEST.get('avatar_size', 48) if request else 48
     return profile_avatar(profile.user, size=size)
Exemple #28
0
 def test_profile_avatar_anonymous(self):
     email_hash = '00000000000000000000000000000000'
     gravatar_url = 'https://secure.gravatar.com/avatar/%s?s=48' % (
         email_hash)
     assert profile_avatar(AnonymousUser()).startswith(gravatar_url)
 def test_profile_avatar_unicode(self):
     self.u.email = u'rá[email protected]'
     self.u.save()
     gravatar_url = 'https://secure.gravatar.com/'
     assert profile_avatar(self.u).startswith(gravatar_url)
Exemple #30
0
 def test_profile_avatar_default(self):
     email_hash = hashlib.md5(self.u.email.lower()).hexdigest()
     gravatar_url = 'https://secure.gravatar.com/avatar/%s?s=48' % (
         email_hash)
     assert profile_avatar(self.u).startswith(gravatar_url)