示例#1
0
def avatar(context, user, size, service_id=None):
    """Render the user's avatar to HTML.

    When the ``service_id`` argument is not provided, or the specified service
    is not registered or is not enabled, the user's specified avatar service
    will be used for rendering instead.

    Args:
        context (django.template.Context):
            The template rendering context.

        user (django.contrib.auth.models.User):
            The user whose avatar is to be rendered.

        size (int):
            The height and width of the avatar, in pixels.

        service_id (unicode, optional):
            The unique identifier of the avatar service to use. If this is
            omitted, or the specified service is not registered and enabled,
            the default avatar service will be used.

    Returns:
        django.utils.safestring.SafeText:
        The user's avatar rendered to HTML, or an empty string if no avatar
        service could be found.
    """
    service = avatar_services.for_user(user, service_id)

    if service is None:
        logging.error('Could not get a suitable avatar service for user %s.',
                      user)
        return mark_safe('')

    return service.render(request=context['request'], user=user, size=size)
示例#2
0
    def render_data(self, state, obj):
        """Render the user's name and avatar as HTML.

        Args:
            state (djblets.datagrid.grids.StatefulColumn):
                The column state.

            obj (django.db.models.Model):
                The object being rendered in the datagrid.

        Returns:
            django.utils.safestring.SafeText:
            The HTML for the column.
        """
        user = self.get_user(obj)

        # If avatars are eanbled, we'll want to include that in the resulting
        # HTML.
        siteconfig = SiteConfiguration.objects.get_current()
        request = state.datagrid.request
        avatar_html = ''

        if siteconfig.get(avatar_services.AVATARS_ENABLED_KEY):
            avatar_service = avatar_services.for_user(user)

            if avatar_service:
                avatar_html = avatar_service.render(request=request,
                                                    user=user,
                                                    size=self.AVATAR_SIZE)

        # Render the link to the user page, using the avatar and username.
        username = user.username

        return format_html('{0}{1}', avatar_html, username)
示例#3
0
def _serialize_user(request, user):
    """Serialize a user into a JSON-encodable format.

    Args:
        request (django.http.HttpRequest):
            The HTTP request.

        user (django.contrib.auth.models.User):
            The user to serialize.

    Returns:
        dict:
        A dictionary of data to be encoded and sent back to the client.
    """
    if user:
        service = avatar_services.for_user(user)

        if service:
            avatar_url = service.get_avatar_urls(request, user, 48)['1x']
        else:
            avatar_url = None

        return {
            'avatar_url': avatar_url,
            'id': user.id,
            'fullname': user.get_full_name(),
            'username': user.username,
        }
    else:
        return None
示例#4
0
    def serialize_avatar_urls_field(self, user, request=None, **kwargs):
        if avatar_services.avatars_enabled:
            service = avatar_services.for_user(user)

            if service:
                return service.get_avatar_urls(request, user, 48)

        return {}
示例#5
0
    def serialize_avatar_html_field(self, user, request=None, **kwargs):
        """Serialize the avatar_html field.

        Args:
            user (django.contrib.auth.models.User):
                The user the avatar is being serialized for.

            request (django.http.HttpRequest, optional):
                The HTTP request from the client.

            **kwargs (dict, unused):
                Additional keyword arguments.

        Returns:
            dict:
            Dictionaries, mapping sizes to renders.
        """
        if not avatar_services.avatars_enabled:
            return None

        renders = {}

        # Look for both the GET and PUT/POST/PATCH versions of this value.
        # If present, we'll render avatars at the sizes specified.
        avatar_sizes = request.GET.get('render-avatars-at',
                                       request.POST.get('render_avatars_at'))

        if avatar_sizes:
            norm_sizes = set()

            for size in avatar_sizes.split(','):
                try:
                    norm_sizes.add(int(size))
                except ValueError:
                    # A non-integer value was passed in. Ignore it.
                    pass

            avatar_sizes = norm_sizes

        if avatar_sizes:
            service = avatar_services.for_user(user)

            if service:
                for size in avatar_sizes:
                    try:
                        renders[six.text_type(size)] = \
                            service.render(request=request,
                                           user=user,
                                           size=size).strip()
                    except Exception as e:
                        logger.exception('Error rendering avatar at size %s '
                                         'for user %s: %s',
                                         size, user, e)

        return renders or None
示例#6
0
    def get_context_data(self, **kwargs):
        """Return data for the template.

        This will return information on the user, along with information from
        any extension hooks used for the page.

        Args:
            **kwargs (tuple):
                Additional keyword arguments from the URL pattern.

        Returns:
            dict:
            Context data for the template.
        """
        from reviewboard.extensions.hooks import UserInfoboxHook

        # These are accessed several times, so bring them in to reduce
        # attribute lookups.
        user = self._lookup_user
        username = user.username
        local_site = self.local_site

        extra_content = []

        for hook in UserInfoboxHook.hooks:
            try:
                extra_content.append(hook.render(
                    user=user,
                    request=self.request,
                    local_site=local_site))
            except Exception as e:
                logging.exception('Error when running UserInfoboxHook.'
                                  'render method in extension "%s": %s',
                                  hook.extension.id, e)

        review_requests_url = local_site_reverse('user', local_site=local_site,
                                                 args=[username])
        reviews_url = local_site_reverse('user-grid', local_site=local_site,
                                         args=[username, 'reviews'])

        has_avatar = (
            avatar_services.avatars_enabled and
            avatar_services.for_user(user) is not None
        )

        return {
            'extra_content': mark_safe(''.join(extra_content)),
            'full_name': user.get_full_name(),
            'has_avatar': has_avatar,
            'infobox_user': user,
            'review_requests_url': review_requests_url,
            'reviews_url': reviews_url,
            'show_profile': self._show_profile,
            'timezone': self._timezone,
        }
示例#7
0
def avatar_url(context, user, size, resolution='1x', service_id=None):
    """Return the URL of the requested avatar.

    Args:
        context (django.template.Context):
            The template rendering context.

        user (django.contrib.auth.models.User):
            The user whose avatar is to be rendered.

        size (int):
            The height and width of the avatar, in pixels.

        resolution (unicode, optional):
            The resolution of the avatar. This should be one of ``'1x'``, for
            normal DPI, or ``'2x'``, for high DPI. This defaults to normal DPI.

        service_id (unicode, optional):
            The unique identifier of the avatar service to use. If this is
            omitted, or the specified service is not registered and enabled,
            the default avatar service will be used.

    Returns:
        django.utils.safestring.SafeText:
        The URL of the requested avatar, or an empty string if no avatar
        service could be found.
    """
    if resolution not in ('1x', '2x'):
        raise ValueError('resolution should be "1x" or "2x", not %r.'
                         % resolution)

    service = avatar_services.for_user(user, service_id)

    if service is None:
        logging.error('Could not get a suitable avatar service for user %s.',
                      user)
        return mark_safe('')

    urls = service.get_avatar_urls(request=context['request'],
                                   user=user,
                                   size=size)
    return urls[resolution]
示例#8
0
def avatar_urls(context, user, size, service_id=None):
    """Serialize the user's avatar URLs into a JavaScript object.

    Args:
        context (django.template.Context):
            The template rendering context.

        user (django.contrib.auth.models.User):
            The user whose avatar URLs are to be serialized.

        size (int):
            The height and width of the avatar, in pixels.

        service_id (unicode, optional):
            The unique identifier of the avatar service to use. If this is
            omitted, or the specified service is not registered and enabled,
            the default avatar service will be used.

    Returns:
        django.utils.safestring.SafeText:
        The rendered JavaScript object.
    """
    service = avatar_services.for_user(user, service_id)

    if service is None:
        logging.error('Could not get a suitable avatar service for user %s.',
                      user)
        urls = {}
    else:
        urls = {
            resolution: url
            for resolution, url in six.iteritems(
                service.get_avatar_urls(request=context['request'],
                                        user=user,
                                        size=size)
            )
        }

    return mark_safe(json.dumps(urls, sort_keys=True))
示例#9
0
    def render_user(self, state, user):
        """Render the user's name and avatar as HTML."""
        siteconfig = SiteConfiguration.objects.get_current()

        avatar_html = ''

        if siteconfig.get(avatar_services.AVATARS_ENABLED_KEY):
            avatar_service = avatar_services.for_user(user)

            if avatar_service:
                avatar_html = avatar_service.render(
                    request=state.datagrid.request,
                    user=user,
                    size=self.AVATAR_SIZE)

        request = state.datagrid.request

        user_url = local_site_reverse('user', request=request, kwargs={
            'username': user.username,
        })

        return format_html(
            '<a class="user" href="{0}">{1}{2}</a>',
            user_url, avatar_html, user.username)
示例#10
0
    def render(self, name, value, attrs=None):
        """Render the widget.

        Args:
            name (unicode):
                The name of the field.

            value (list or None):
                The current value of the field.

            attrs (dict):
                Attributes for the HTML element.

        Returns:
            django.utils.safestring.SafeText:
            The rendered HTML.
        """
        if value:
            if not self.multivalued:
                value = [value]

            value = [v for v in value if v]
            input_value = ','.join(force_text(v) for v in value)
            existing_users = (
                User.objects
                .filter(pk__in=value)
                .order_by('first_name', 'last_name', 'username')
            )
        else:
            input_value = None
            existing_users = []

        final_attrs = self.build_attrs(attrs, name=name)

        input_html = super(RelatedUserWidget, self).render(
            name, input_value, attrs)

        use_avatars = avatar_services.avatars_enabled
        user_data = []

        for user in existing_users:
            data = {
                'fullname': user.get_full_name(),
                'id': user.pk,
                'username': user.username,
            }

            if use_avatars:
                try:
                    data['avatarURL'] = (
                        avatar_services.for_user(user)
                        .get_avatar_urls_uncached(user, 40)
                    )['1x']
                except (AttributeError, KeyError):
                    data['avatarURL'] = None

            user_data.append(data)

        extra_html = render_to_string('admin/related_user_widget.html', {
            'input_id': final_attrs['id'],
            'local_site_name': self.local_site_name,
            'multivalued': self.multivalued,
            'use_avatars': use_avatars,
            'users': user_data,
        })

        return mark_safe(input_html + extra_html)
示例#11
0
    def get_etag_data(self, request, username, *args, **kwargs):
        """Return an ETag for the view.

        This will look up some state needed for the request and generate a
        suitable ETag.

        Args:
            request (django.http.HttpRequest):
                The HTTP request from the client.

            username (unicode):
                The username of the user being looked up.

            *args (tuple):
                Positional arguments to pass to the handler.

            **kwargs (tuple):
                Keyword arguments to pass to the handler.

                These will be arguments provided by the URL pattern.

        Returns:
            unicode:
            The ETag for the page.
        """
        from reviewboard.extensions.hooks import UserInfoboxHook

        user = get_object_or_404(User, username=username)
        self._lookup_user = user

        try:
            profile = user.get_profile()
            self._show_profile = not profile.is_private
            self._timezone = profile.timezone
        except Profile.DoesNotExist:
            self._show_profile = True
            self._timezone = 'UTC'

        etag_data = [
            user.first_name,
            user.last_name,
            user.email,
            six.text_type(user.last_login),
            six.text_type(settings.TEMPLATE_SERIAL),
            six.text_type(self._show_profile),
            self._timezone,
        ]

        if avatar_services.avatars_enabled:
            avatar_service = avatar_services.for_user(user)

            if avatar_service:
                etag_data.extend(avatar_service.get_etag_data(user))

        local_site = self.local_site

        for hook in UserInfoboxHook.hooks:
            try:
                etag_data.append(hook.get_etag_data(
                    user=user,
                    request=request,
                    local_site=local_site))
            except Exception as e:
                logging.exception('Error when running UserInfoboxHook.'
                                  'get_etag_data method in extension "%s": %s',
                                  hook.extension.id, e)

        return ':'.join(etag_data)
示例#12
0
    def get_etag_data(self, request, username, *args, **kwargs):
        """Return an ETag for the view.

        This will look up some state needed for the request and generate a
        suitable ETag.

        Args:
            request (django.http.HttpRequest):
                The HTTP request from the client.

            username (unicode):
                The username of the user being looked up.

            *args (tuple):
                Positional arguments to pass to the handler.

            **kwargs (tuple):
                Keyword arguments to pass to the handler.

                These will be arguments provided by the URL pattern.

        Returns:
            unicode:
            The ETag for the page.
        """
        from reviewboard.extensions.hooks import UserInfoboxHook

        user = get_object_or_404(User, username=username)
        self._lookup_user = user

        try:
            profile = user.get_profile()
            self._show_profile = user.is_profile_visible(request.user)
            self._timezone = profile.timezone
        except Profile.DoesNotExist:
            self._show_profile = True
            self._timezone = 'UTC'

        etag_data = [
            user.first_name,
            user.last_name,
            user.email,
            six.text_type(user.last_login),
            six.text_type(settings.TEMPLATE_SERIAL),
            six.text_type(self._show_profile),
            self._timezone,
        ]

        if avatar_services.avatars_enabled:
            avatar_service = avatar_services.for_user(user)

            if avatar_service:
                etag_data.extend(avatar_service.get_etag_data(user))

        local_site = self.local_site

        for hook in UserInfoboxHook.hooks:
            try:
                etag_data.append(hook.get_etag_data(
                    user=user,
                    request=request,
                    local_site=local_site))
            except Exception as e:
                logging.exception('Error when running UserInfoboxHook.'
                                  'get_etag_data method in extension "%s": %s',
                                  hook.extension.id, e)

        return ':'.join(etag_data)
示例#13
0
    def render(self, name, value, attrs=None):
        """Render the widget.

        Args:
            name (unicode):
                The name of the field.

            value (list or None):
                The current value of the field.

            attrs (dict):
                Attributes for the HTML element.

        Returns:
            django.utils.safestring.SafeText:
            The rendered HTML.
        """
        if value:
            if not self.multivalued:
                value = [value]

            value = [v for v in value if v]
            input_value = ','.join(force_text(v) for v in value)
            existing_users = (User.objects.filter(pk__in=value).order_by(
                'first_name', 'last_name', 'username'))
        else:
            input_value = None
            existing_users = []

        final_attrs = self.build_attrs(attrs, name=name)

        input_html = super(RelatedUserWidget,
                           self).render(name, input_value, attrs)

        use_avatars = avatar_services.avatars_enabled
        user_data = []

        for user in existing_users:
            data = {
                'fullname': user.get_full_name(),
                'id': user.pk,
                'username': user.username,
            }

            if use_avatars:
                data['avatarURL'] = (
                    avatar_services.for_user(user).get_avatar_urls_uncached(
                        user, 40))['1x']

            user_data.append(data)

        extra_html = render_to_string(
            'admin/related_user_widget.html', {
                'input_id': final_attrs['id'],
                'local_site_name': self.local_site_name,
                'multivalued': self.multivalued,
                'use_avatars': use_avatars,
                'users': user_data,
            })

        return mark_safe(input_html + extra_html)