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)
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)
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
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 {}
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
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, }
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]
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))
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)
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)
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)
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)
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)