kopia lustrzana https://github.com/wagtail/wagtail
first working attempt to make gravatar optional
rodzic
1849f0d54a
commit
5b8ca7d7e7
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="612px" height="792px" viewBox="0 0 612 792" enable-background="new 0 0 612 792" xml:space="preserve">
|
||||
<path fill="#999999" d="M306,181.8c51,0,91.8,40.8,91.8,91.8S357,365.4,306,365.4s-91.8-40.8-91.8-91.8S255,181.8,306,181.8z"/>
|
||||
<path fill="#999999" d="M306,616.575c-76.5,0-144.075-39.525-183.6-98.175c1.275-61.2,122.4-94.351,183.6-94.351
|
||||
S488.325,457.2,489.6,518.4C450.075,577.05,382.5,616.575,306,616.575z"/>
|
||||
</svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 784 B |
|
@ -0,0 +1,27 @@
|
|||
{% extends "wagtailadmin/base.html" %}
|
||||
{% load avatar i18n %}
|
||||
|
||||
{% block titletag %}{% trans "Change profile picture" %}{% endblock %}
|
||||
{% block content %}
|
||||
{% trans "Change profile picture" as change_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=change_str %}
|
||||
|
||||
<div class="nice-padding">
|
||||
<form action="{% url 'wagtailadmin_account_change_avatar' %}" method="POST" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
|
||||
<ul class="fields">
|
||||
{% for field in form %}
|
||||
{% include "wagtailadmin/shared/field_as_li.html" with field=field %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<li class="submit"><input type="submit" value="{% trans 'Update' %}" class="button" /></li>
|
||||
</form>
|
||||
<p>{% trans "Your current profile picture:" %}</p>
|
||||
<p>
|
||||
<span class="avatar square"><img src="{% avatar_url request.user size=50 %}"></span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "wagtailadmin/base.html" %}
|
||||
{% load gravatar staticfiles i18n %}
|
||||
{% load avatar staticfiles i18n %}
|
||||
{% block titletag %}{% trans "Dashboard" %}{% endblock %}
|
||||
{% block bodyclass %}homepage{% endblock %}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
|||
<header class="merged nice-padding">
|
||||
<div class="row row-flush">
|
||||
<div class="col1">
|
||||
<div class="avatar"><img src="{% gravatar_url user.email %}" alt="" /></div>
|
||||
<div class="avatar"><img src="{% avatar_url user.email %}" alt="" /></div>
|
||||
</div>
|
||||
<div class="col9">
|
||||
<h1>{% block branding_welcome %}{% blocktrans %}Welcome to the {{ site_name }} Wagtail CMS{% endblocktrans %}{% endblock %}</h1>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends "wagtailadmin/base.html" %}
|
||||
{% load wagtailadmin_tags %}
|
||||
{% load gravatar %}
|
||||
{% load avatar %}
|
||||
{% load i18n %}
|
||||
{% load l10n %}
|
||||
{% block titletag %}{% blocktrans with title=page.get_admin_display_title page_type=content_type.model_class.get_verbose_name %}Editing {{ page_type }}: {{ title }}{% endblocktrans %}{% endblock %}
|
||||
|
@ -89,7 +89,7 @@
|
|||
{% blocktrans with last_mod=page.get_latest_revision.created_at %}Last modified: {{ last_mod }}{% endblocktrans %}
|
||||
{% if page.get_latest_revision.user %}
|
||||
{% blocktrans with modified_by=page.get_latest_revision.user.get_full_name|default:page.get_latest_revision.user.get_username %}by {{ modified_by }}{% endblocktrans %}
|
||||
<span class="avatar small"><img src="{% gravatar_url page.get_latest_revision.user.email 25 %}" /></span>
|
||||
<span class="avatar small"><img src="{% avatar_url page.get_latest_revision.user size=25 %}" /></span>
|
||||
{% endif %}
|
||||
<a href="{% url 'wagtailadmin_pages:revisions_index' page.id %}" class="underlined">{% trans 'Revisions' %}</a>
|
||||
{% endif %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load i18n wagtailadmin_tags gravatar %}
|
||||
{% load i18n wagtailadmin_tags avatar %}
|
||||
{% load l10n %}
|
||||
|
||||
<table class="listing">
|
||||
|
@ -17,7 +17,7 @@
|
|||
<h2>
|
||||
<a href="{% url 'wagtailadmin_pages:revisions_revert' page.id revision.id %}">{{ revision.created_at }}</a>
|
||||
<span class="unbold">
|
||||
{% trans 'by' context 'points to a user who created a revision' %}<span class="avatar small"><img src="{% gravatar_url revision.user.email 25 %}" /></span>{{ revision.user }}
|
||||
{% trans 'by' context 'points to a user who created a revision' %}<span class="avatar small"><img src="{% avatar_url revision.user size=25 %}" /></span>{{ revision.user }}
|
||||
</span>
|
||||
{% if revision == page.get_latest_revision %}({% trans 'Current draft' %}){% endif %}
|
||||
{% if revision == page.live_revision %}({% trans 'Live version' %}){% endif %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load gravatar wagtailadmin_tags %}
|
||||
{% load avatar wagtailadmin_tags %}
|
||||
{% load i18n %}
|
||||
<nav class="nav-main">
|
||||
<ul>
|
||||
|
@ -7,7 +7,7 @@
|
|||
<li class="footer" id="footer">
|
||||
<div class="account" id="account-settings" title="{% trans 'Edit your account' %}">
|
||||
<span class="avatar square avatar-on-dark">
|
||||
<img src="{% gravatar_url request.user.email 25 %}" />
|
||||
<img src="{% avatar_url request.user size=50 %}" />
|
||||
</span>
|
||||
<em class="icon icon-arrow-up-after">{{ request.user.first_name|default:request.user.get_username }}</em>
|
||||
</div>
|
||||
|
@ -19,4 +19,4 @@
|
|||
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</nav>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% load gravatar %}
|
||||
{% load avatar %}
|
||||
|
||||
<span class="avatar small">
|
||||
<img src="{% gravatar_url user.email 25 %}" />
|
||||
<img src="{% avatar_url user size=25 %}" />
|
||||
</span>
|
||||
|
||||
{{ user }}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from django import template
|
||||
from django.contrib.staticfiles.templatetags.staticfiles import static
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def avatar_url(context, user, size=50):
|
||||
"""
|
||||
A template tag that receives a user and size and return
|
||||
the appropiate avatar url for that user.
|
||||
Example usage: {% avatar_url request.user 50 %}
|
||||
"""
|
||||
|
||||
if hasattr(user, 'wagtail_userprofile'): # A user could not have profile yet, so this is necessay
|
||||
return user.wagtail_userprofile.get_avatar_url(size=size)
|
||||
return static('wagtailadmin/images/default-user-avatar.svg')
|
|
@ -1,44 +0,0 @@
|
|||
# place inside a 'templatetags' directory inside the top level of a Django app (not project, must be inside an app)
|
||||
# at the top of your page template include this:
|
||||
# {% load gravatar %}
|
||||
# and to use the url do this:
|
||||
# <img src="{% gravatar_url 'someone@somewhere.com' %}">
|
||||
# or
|
||||
# <img src="{% gravatar_url sometemplatevariable %}">
|
||||
# just make sure to update the "default" image path below
|
||||
|
||||
import hashlib
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from django import template
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
class GravatarUrlNode(template.Node):
|
||||
def __init__(self, email, size=50):
|
||||
self.email = template.Variable(email)
|
||||
self.size = size
|
||||
|
||||
def render(self, context):
|
||||
try:
|
||||
email = self.email.resolve(context)
|
||||
except template.VariableDoesNotExist:
|
||||
return ''
|
||||
|
||||
default = "mm"
|
||||
size = int(self.size) * 2 # requested at retina size by default and scaled down at point of use with css
|
||||
|
||||
gravatar_url = "//www.gravatar.com/avatar/{hash}?{params}".format(
|
||||
hash=hashlib.md5(email.lower().encode('utf-8')).hexdigest(),
|
||||
params=urlencode({'s': size, 'd': default})
|
||||
)
|
||||
|
||||
return gravatar_url
|
||||
|
||||
|
||||
@register.tag
|
||||
def gravatar_url(parser, token):
|
||||
bits = token.split_contents()
|
||||
|
||||
return GravatarUrlNode(*bits[1:])
|
|
@ -1,3 +1,6 @@
|
|||
import os
|
||||
import tempfile
|
||||
|
||||
import pytz
|
||||
|
||||
from django.contrib.auth import views as auth_views
|
||||
|
@ -13,6 +16,8 @@ from wagtail.admin.utils import (
|
|||
from wagtail.tests.utils import WagtailTestUtils
|
||||
from wagtail.users.models import UserProfile
|
||||
|
||||
TMP_MEDIA_ROOT = tempfile.mktemp()
|
||||
|
||||
|
||||
class TestAuthentication(TestCase, WagtailTestUtils):
|
||||
"""
|
||||
|
@ -468,6 +473,101 @@ class TestAccountSection(TestCase, WagtailTestUtils):
|
|||
self.assertNotContains(response, 'Set Time Zone')
|
||||
|
||||
|
||||
class TestAvatarSection(TestCase, WagtailTestUtils):
|
||||
def _create_image(self):
|
||||
from PIL import Image
|
||||
|
||||
with tempfile.NamedTemporaryFile(suffix='.jpg', delete=False) as f:
|
||||
image = Image.new('RGB', (200, 200), 'white')
|
||||
image.save(f, 'JPEG')
|
||||
|
||||
return open(f.name, mode='rb')
|
||||
|
||||
def setUp(self):
|
||||
self.user = self.login()
|
||||
self.avatar = self._create_image()
|
||||
self.other_avatar = self._create_image()
|
||||
|
||||
def tearDown(self):
|
||||
self.avatar.close()
|
||||
self.other_avatar.close()
|
||||
|
||||
def test_avatar_preferences_view(self):
|
||||
"""
|
||||
This tests that the change user profile(avatar) view responds with an index page
|
||||
"""
|
||||
response = self.client.get(reverse('wagtailadmin_account_change_avatar'))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'wagtailadmin/account/change_avatar.html')
|
||||
self.assertContains(response, "Change profile picture")
|
||||
|
||||
def test_avatar_preferences_post(self):
|
||||
"""
|
||||
This tests that the change user profile(avatar) view change the user preferences
|
||||
"""
|
||||
post_data = {
|
||||
'avatar_choice': 'default',
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_account_change_avatar'), post_data, follow=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))
|
||||
self.assertEqual('default', profile.avatar_choice)
|
||||
|
||||
def test_get_avatar_returns_default_if_not_changed(self):
|
||||
profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))
|
||||
|
||||
self.assertEqual(profile.avatar_choice, 'default')
|
||||
self.assertIn('default-user-avatar', profile.get_avatar_url())
|
||||
|
||||
def test_set_gravatar_returns_gravatar(self):
|
||||
post_data = {
|
||||
'avatar_choice': 'gravatar',
|
||||
}
|
||||
response = self.client.post(reverse('wagtailadmin_account_change_avatar'), post_data, follow=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))
|
||||
self.assertEqual(profile.avatar_choice, 'gravatar')
|
||||
self.assertIn('www.gravatar.com', profile.get_avatar_url())
|
||||
|
||||
@override_settings(MEDIA_ROOT=TMP_MEDIA_ROOT)
|
||||
def test_set_custom_avatar_stores_and_get_custom_avatar(self):
|
||||
response = self.client.post(reverse('wagtailadmin_account_change_avatar'),
|
||||
{'avatar_choice': 'custom',
|
||||
'avatar': self.avatar},
|
||||
follow=True)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))
|
||||
self.assertEqual('custom', profile.avatar_choice)
|
||||
self.assertIn(os.path.basename(self.avatar.name), profile.get_avatar_url())
|
||||
|
||||
@override_settings(MEDIA_ROOT=TMP_MEDIA_ROOT)
|
||||
def test_user_upload_another_image_removes_previous_one(self):
|
||||
response = self.client.post(reverse('wagtailadmin_account_change_avatar'),
|
||||
{'avatar_choice': 'custom',
|
||||
'avatar': self.avatar},
|
||||
follow=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk))
|
||||
old_avatar_path = profile.avatar.path
|
||||
|
||||
# Upload a new avatar
|
||||
new_response = self.client.post(reverse('wagtailadmin_account_change_avatar'),
|
||||
{'avatar_choice': 'custom',
|
||||
'avatar': self.other_avatar},
|
||||
follow=True)
|
||||
self.assertEqual(new_response.status_code, 200)
|
||||
|
||||
# Check old avatar doesn't exist anymore in filesystem
|
||||
with self.assertRaises(FileNotFoundError):
|
||||
open(old_avatar_path)
|
||||
|
||||
|
||||
class TestAccountManagementForNonModerator(TestCase, WagtailTestUtils):
|
||||
"""
|
||||
Tests of reduced-functionality for editors
|
||||
|
|
|
@ -50,6 +50,7 @@ urlpatterns = [
|
|||
account.notification_preferences,
|
||||
name='wagtailadmin_account_notification_preferences'
|
||||
),
|
||||
url(r'account/change_avatar/$', account.change_avatar, name='wagtailadmin_account_change_avatar'),
|
||||
url(
|
||||
r'^account/language_preferences/$',
|
||||
account.language_preferences,
|
||||
|
|
|
@ -12,7 +12,7 @@ from django.utils.translation import activate
|
|||
from wagtail.admin import forms
|
||||
from wagtail.core import hooks
|
||||
from wagtail.users.forms import (
|
||||
CurrentTimeZoneForm, EmailForm, NotificationPreferencesForm, PreferredLanguageForm)
|
||||
AvatarPreferencesForm, CurrentTimeZoneForm, EmailForm, NotificationPreferencesForm, PreferredLanguageForm)
|
||||
from wagtail.users.models import UserProfile
|
||||
from wagtail.utils.loading import get_custom_form
|
||||
|
||||
|
@ -185,6 +185,20 @@ def current_time_zone(request):
|
|||
})
|
||||
|
||||
|
||||
def change_avatar(request):
|
||||
if request.method == 'POST':
|
||||
user_profile = UserProfile.get_for_user(request.user)
|
||||
form = AvatarPreferencesForm(request.POST, request.FILES, instance=user_profile)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, _("Your preferences have been updated successfully!"))
|
||||
return redirect('wagtailadmin_account_change_avatar')
|
||||
else:
|
||||
form = AvatarPreferencesForm(instance=UserProfile.get_for_user(request.user))
|
||||
|
||||
return render(request, 'wagtailadmin/account/change_avatar.html', {'form': form})
|
||||
|
||||
|
||||
class LoginView(auth_views.LoginView):
|
||||
template_name = 'wagtailadmin/login.html'
|
||||
|
||||
|
|
|
@ -194,15 +194,11 @@ def register_viewsets_urls():
|
|||
|
||||
|
||||
@hooks.register('register_account_menu_item')
|
||||
def register_account_set_gravatar(request):
|
||||
def register_account_set_profile_picture(request):
|
||||
return {
|
||||
'url': 'https://gravatar.com/emails/',
|
||||
'label': _('Set gravatar'),
|
||||
'help_text': _(
|
||||
"Your avatar image is provided by Gravatar and is connected to "
|
||||
"your email address. With a Gravatar account you can set an "
|
||||
"avatar for any number of other email addresses you use."
|
||||
)
|
||||
'url': reverse('wagtailadmin_account_change_avatar'),
|
||||
'label': _('Set profile picture'),
|
||||
'help_text': _("Change your profile picture")
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "wagtailadmin/base.html" %}
|
||||
{% load wagtailadmin_tags i18n staticfiles gravatar %}
|
||||
{% load wagtailadmin_tags i18n staticfiles avatar %}
|
||||
|
||||
{% block extra_css %}
|
||||
{{ block.super }}
|
||||
|
@ -582,12 +582,9 @@
|
|||
<h2>Misc formatters</h2>
|
||||
<h3>Avatar icons</h3>
|
||||
|
||||
<p><span class="avatar"><img src="{% gravatar_url "david@torchbox.com" %}" /></span> Gravatar set (normal)</p>
|
||||
<p><span class="avatar"><img src="{% gravatar_url "aeon@torchbox.com" %}" /></span> Gravatar not set (normal)</p>
|
||||
<p><span class="avatar square"><img src="{% gravatar_url "david@torchbox.com" %}" /></span> Gravatar set (square)</p>
|
||||
<p><span class="avatar square"><img src="{% gravatar_url "aeon@torchbox.com" %}" /></span> Gravatar not set (square)</p>
|
||||
<p><span class="avatar small"><img src="{% gravatar_url "david@torchbox.com" %}" /></span> Gravatar set (small)</p>
|
||||
<p><span class="avatar small"><img src="{% gravatar_url "aeon@torchbox.com" %}" /></span> Gravatar not set (small)</p>
|
||||
<p><span class="avatar"><img src="{% avatar_url user size=50 %}" /></span> Avatar normal</p>
|
||||
<p><span class="avatar square"><img src="{% avatar_url user size=50 %}" /></span> Avatar square</p>
|
||||
<p><span class="avatar small"><img src="{% avatar_url user size=25 %}" /></span> Avatar small</p>
|
||||
|
||||
<h3>Status tags</h3>
|
||||
<div class="status-tag primary">Primary tag</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django import forms
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.paginator import Paginator
|
||||
from django.shortcuts import render
|
||||
from django.utils.translation import ugettext as _
|
||||
|
@ -71,8 +72,11 @@ def index(request):
|
|||
paginator = Paginator(list(range(100)), 10)
|
||||
page = paginator.page(2)
|
||||
|
||||
user = User(email='david@torchbox.com')
|
||||
|
||||
return render(request, 'wagtailstyleguide/base.html', {
|
||||
'search_form': form,
|
||||
'example_form': example_form,
|
||||
'example_page': page,
|
||||
'user': user,
|
||||
})
|
||||
|
|
|
@ -418,3 +418,12 @@ class CurrentTimeZoneForm(forms.ModelForm):
|
|||
class Meta:
|
||||
model = UserProfile
|
||||
fields = ("current_time_zone",)
|
||||
|
||||
|
||||
class AvatarPreferencesForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = UserProfile
|
||||
fields = ("avatar_choice", "avatar")
|
||||
widgets = {
|
||||
'avatar_choice': forms.RadioSelect(),
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.5 on 2017-11-24 14:18
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import wagtail.users.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wagtailusers', '0007_userprofile_current_time_zone'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userprofile',
|
||||
name='avatar',
|
||||
field=models.ImageField(blank=True, upload_to=wagtail.users.models.upload_avatar_to, verbose_name='Upload your custom avatar'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userprofile',
|
||||
name='avatar_choice',
|
||||
field=models.CharField(choices=[('default', 'Default'), ('custom', 'Custom'), ('gravatar', 'Gravatar')], default='default', max_length=10, verbose_name='Select profile picture type'),
|
||||
),
|
||||
]
|
|
@ -1,9 +1,34 @@
|
|||
import os
|
||||
import uuid
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.staticfiles.templatetags.staticfiles import static
|
||||
from django.db import models
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from wagtail.users.utils import get_gravatar_url
|
||||
|
||||
|
||||
def upload_avatar_to(instance, filename):
|
||||
filename, ext = os.path.splitext(filename)
|
||||
return os.path.join(
|
||||
'avatar_images',
|
||||
'avatar_{uuid}_{filename}{ext}'.format(
|
||||
uuid=uuid.uuid4(), filename=filename, ext=ext)
|
||||
)
|
||||
|
||||
|
||||
class UserProfile(models.Model):
|
||||
DEFAULT = 'default'
|
||||
CUSTOM = 'custom'
|
||||
GRAVATAR = 'gravatar'
|
||||
AVATAR_CHOICES = (
|
||||
(DEFAULT, _('Default')),
|
||||
(CUSTOM, _('Custom')),
|
||||
(GRAVATAR, 'Gravatar')
|
||||
)
|
||||
|
||||
user = models.OneToOneField(
|
||||
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='wagtail_userprofile'
|
||||
)
|
||||
|
@ -40,6 +65,19 @@ class UserProfile(models.Model):
|
|||
default=''
|
||||
)
|
||||
|
||||
avatar_choice = models.CharField(
|
||||
verbose_name=_('Select profile picture type'),
|
||||
default=DEFAULT,
|
||||
choices=AVATAR_CHOICES,
|
||||
max_length=10
|
||||
)
|
||||
|
||||
avatar = models.ImageField(
|
||||
verbose_name=_('Upload your custom avatar'),
|
||||
upload_to=upload_avatar_to,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_for_user(cls, user):
|
||||
return cls.objects.get_or_create(user=user)[0]
|
||||
|
@ -53,5 +91,30 @@ class UserProfile(models.Model):
|
|||
def __str__(self):
|
||||
return self.user.get_username()
|
||||
|
||||
@cached_property
|
||||
def default_avatar(self):
|
||||
return static('wagtailadmin/images/default-user-avatar.svg')
|
||||
|
||||
def get_avatar_url(self, size=50):
|
||||
if self.avatar_choice == self.DEFAULT:
|
||||
return self.default_avatar
|
||||
|
||||
if self.avatar_choice == self.CUSTOM:
|
||||
try:
|
||||
return self.avatar.url
|
||||
except ValueError:
|
||||
return self.default_avatar
|
||||
|
||||
if self.avatar_choice == self.GRAVATAR and self.user.email:
|
||||
return get_gravatar_url(self.user.email, default=None, size=50)
|
||||
|
||||
return self.default_avatar
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.avatar:
|
||||
this = UserProfile.objects.get(pk=self.pk)
|
||||
this.avatar.delete(save=False)
|
||||
return super(UserProfile, self).save(*args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('user profile')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends "wagtailadmin/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load gravatar %}
|
||||
{% load avatar %}
|
||||
{% block titletag %}{% trans "groups" %}{% endblock %}
|
||||
{% block extra_js %}
|
||||
{{ block.super }}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends "wagtailadmin/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load gravatar %}
|
||||
{% load avatar %}
|
||||
{% block titletag %}{% trans "Users" %}{% endblock %}
|
||||
{% block extra_js %}
|
||||
{{ block.super }}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% load i18n wagtailusers_tags %}
|
||||
{% load gravatar %}
|
||||
{% load avatar %}
|
||||
<table class="listing">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -28,7 +28,7 @@
|
|||
<tr>
|
||||
<td class="title" valign="top">
|
||||
<h2>
|
||||
<span class="avatar small"><img src="{% gravatar_url user.email 25 %}" /></span>
|
||||
<span class="avatar small"><img src="{% avatar_url user size=25 %}" /></span>
|
||||
<a href="{% url 'wagtailusers_users:edit' user.pk %}">{{ user.get_full_name|default:user.get_username }}</a>
|
||||
</h2>
|
||||
<ul class="actions">
|
||||
|
|
|
@ -19,6 +19,10 @@ delete_user_perm_codename = "delete_{0}".format(AUTH_USER_MODEL_NAME.lower())
|
|||
change_user_perm_codename = "change_{0}".format(AUTH_USER_MODEL_NAME.lower())
|
||||
|
||||
|
||||
def test_avatar_provider(user, default, size=50):
|
||||
return '/nonexistent/path/to/avatar.png'
|
||||
|
||||
|
||||
class CustomUserCreationForm(UserCreationForm):
|
||||
country = forms.CharField(required=True, label="Country")
|
||||
attachment = forms.FileField(required=True, label="Attachment")
|
||||
|
@ -929,7 +933,7 @@ class TestUserProfileCreation(TestCase, WagtailTestUtils):
|
|||
self.test_user = get_user_model().objects.create_user(
|
||||
username='testuser',
|
||||
email='testuser@email.com',
|
||||
password='password'
|
||||
password='password',
|
||||
)
|
||||
|
||||
def test_user_created_without_profile(self):
|
||||
|
@ -942,6 +946,16 @@ class TestUserProfileCreation(TestCase, WagtailTestUtils):
|
|||
# and get it from the db too
|
||||
self.assertEqual(UserProfile.objects.filter(user=self.test_user).count(), 1)
|
||||
|
||||
def test_get_avatar_url_default(self):
|
||||
user_profile = UserProfile.get_for_user(self.test_user)
|
||||
self.assertEqual(user_profile.avatar_choice, 'default')
|
||||
self.assertIn('default-user-avatar', user_profile.get_avatar_url())
|
||||
|
||||
def test_get_avatar_url_fallback_default(self):
|
||||
user_profile = UserProfile.get_for_user(self.test_user)
|
||||
user_profile.avatar_choice = 'Non-existent'
|
||||
self.assertIn('default-user-avatar', user_profile.get_avatar_url())
|
||||
|
||||
|
||||
class TestUserEditViewForNonSuperuser(TestCase, WagtailTestUtils):
|
||||
def setUp(self):
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import hashlib
|
||||
from django.utils.http import urlencode
|
||||
|
||||
from wagtail.core.compat import AUTH_USER_APP_LABEL, AUTH_USER_MODEL_NAME
|
||||
|
||||
delete_user_perm = "{0}.delete_{1}".format(AUTH_USER_APP_LABEL, AUTH_USER_MODEL_NAME.lower())
|
||||
|
@ -16,3 +19,12 @@ def user_can_delete_user(current_user, user_to_delete):
|
|||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def get_gravatar_url(email, default=None, size=50):
|
||||
params = {'s': str(size)}
|
||||
if default is not None:
|
||||
params['default'] = default
|
||||
gravatar_url = "https://www.gravatar.com/avatar/" + hashlib.md5(email.lower().encode('utf-8')).hexdigest() + "?"
|
||||
gravatar_url += urlencode(params)
|
||||
return gravatar_url
|
||||
|
|
Ładowanie…
Reference in New Issue