Return user photo cropped and with absolute url
Remember to run `pip install -r requirements.txt` to install the additional dependencies.remotes/origin/enhancement/email-actions
parent
5ff7ec1c00
commit
a8085a2feb
|
@ -25,3 +25,4 @@ requests==2.3.0
|
||||||
enum34==1.0
|
enum34==1.0
|
||||||
|
|
||||||
django-reversion==1.8.1
|
django-reversion==1.8.1
|
||||||
|
easy-thumbnails==2.0
|
||||||
|
|
|
@ -191,6 +191,7 @@ INSTALLED_APPS = [
|
||||||
"rest_framework",
|
"rest_framework",
|
||||||
"djmail",
|
"djmail",
|
||||||
"django_jinja",
|
"django_jinja",
|
||||||
|
"easy_thumbnails",
|
||||||
]
|
]
|
||||||
|
|
||||||
WSGI_APPLICATION = "taiga.wsgi.application"
|
WSGI_APPLICATION = "taiga.wsgi.application"
|
||||||
|
@ -306,4 +307,21 @@ if "test" in sys.argv:
|
||||||
print ("Try: \033[1;33mpy.test\033[0m")
|
print ("Try: \033[1;33mpy.test\033[0m")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
DEFAULT_AVATAR_URL = ""
|
SOUTH_MIGRATION_MODULES = {
|
||||||
|
'easy_thumbnails': 'easy_thumbnails.south_migrations',
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFAULT_AVATAR_SIZE = 80 # 80x80 pixels
|
||||||
|
|
||||||
|
DEFAULT_AVATAR_URL = ''
|
||||||
|
|
||||||
|
THUMBNAIL_ALIASES = {
|
||||||
|
'': {
|
||||||
|
'avatar': {'size': (DEFAULT_AVATAR_SIZE, DEFAULT_AVATAR_SIZE), 'crop': True},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
GRAVATAR_DEFAULT_OPTIONS = {
|
||||||
|
'default': DEFAULT_AVATAR_URL, # default avatar to show if there's no gravatar image
|
||||||
|
'size': DEFAULT_AVATAR_SIZE
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import django_sites as sites
|
||||||
|
|
||||||
|
URL_TEMPLATE = "{scheme}://{domain}/{path}"
|
||||||
|
|
||||||
|
|
||||||
|
def build_url(path, scheme="http", domain="localhost"):
|
||||||
|
return URL_TEMPLATE.format(scheme=scheme, domain=domain, path=path.lstrip("/"))
|
||||||
|
|
||||||
|
|
||||||
|
def is_absolute_url(path):
|
||||||
|
"""Test wether or not `path` is absolute url."""
|
||||||
|
return path.startswith("http")
|
||||||
|
|
||||||
|
|
||||||
|
def get_absolute_url(path):
|
||||||
|
"""Return a path as an absolute url."""
|
||||||
|
if is_absolute_url(path):
|
||||||
|
return path
|
||||||
|
site = sites.get_current()
|
||||||
|
return build_url(path, scheme=site.scheme, domain=site.domain)
|
|
@ -3,22 +3,26 @@ from urllib.parse import urlencode
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
from taiga.base.utils.urls import get_absolute_url
|
||||||
|
|
||||||
|
|
||||||
GRAVATAR_BASE_URL = "http://www.gravatar.com/avatar/{}?{}"
|
GRAVATAR_BASE_URL = "http://www.gravatar.com/avatar/{}?{}"
|
||||||
|
|
||||||
|
|
||||||
def get_gravatar_url(email: str, **options) -> str:
|
def get_gravatar_url(email: str, **options) -> str:
|
||||||
"""Get the gravatar url associated to an email.
|
"""Get the gravatar url associated to an email.
|
||||||
|
|
||||||
:param options: Additional options to gravatar:
|
:param options: Additional options to gravatar.
|
||||||
- `d` defines what image url to show if no gravatar exists
|
- `default` defines what image url to show if no gravatar exists
|
||||||
- `s` defines the size of the avatar.
|
- `size` defines the size of the avatar.
|
||||||
By default these options are:
|
By default the `settings.GRAVATAR_DEFAULT_OPTIONS` are used.
|
||||||
- `d` is `settings.DEFAULT_AVATAR_URL`
|
|
||||||
- `s` gravatar's default value which is 80x80 px
|
|
||||||
|
|
||||||
:return: Gravatar url.
|
:return: Gravatar url.
|
||||||
"""
|
"""
|
||||||
defaults = {'d': settings.DEFAULT_AVATAR_URL}
|
defaults = settings.GRAVATAR_DEFAULT_OPTIONS.copy()
|
||||||
|
default = defaults.get("default", None)
|
||||||
|
if default:
|
||||||
|
defaults["default"] = get_absolute_url(default)
|
||||||
defaults.update(options)
|
defaults.update(options)
|
||||||
email_hash = hashlib.md5(email.lower().encode()).hexdigest()
|
email_hash = hashlib.md5(email.lower().encode()).hexdigest()
|
||||||
url = GRAVATAR_BASE_URL.format(email_hash, urlencode(defaults))
|
url = GRAVATAR_BASE_URL.format(email_hash, urlencode(defaults))
|
||||||
|
|
|
@ -15,10 +15,12 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from .models import User
|
from .models import User
|
||||||
|
from .services import get_photo_url
|
||||||
from .gravatar import get_gravatar_url
|
from .gravatar import get_gravatar_url
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +39,11 @@ class UserSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
def get_photo(self, user):
|
def get_photo(self, user):
|
||||||
"Return the user photo or her gravatar"
|
"Return the user photo or her gravatar"
|
||||||
return user.photo or get_gravatar_url(user.email)
|
if user.photo:
|
||||||
|
url = get_photo_url(user.photo)
|
||||||
|
else:
|
||||||
|
url = get_gravatar_url(user.email)
|
||||||
|
return url
|
||||||
|
|
||||||
|
|
||||||
class RecoverySerializer(serializers.Serializer):
|
class RecoverySerializer(serializers.Serializer):
|
||||||
|
|
|
@ -21,7 +21,10 @@ This model contains a domain logic for users application.
|
||||||
from django.db.models.loading import get_model
|
from django.db.models.loading import get_model
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
|
from easy_thumbnails.files import get_thumbnailer
|
||||||
|
|
||||||
from taiga.base import exceptions as exc
|
from taiga.base import exceptions as exc
|
||||||
|
from taiga.base.utils.urls import get_absolute_url
|
||||||
|
|
||||||
|
|
||||||
def get_and_validate_user(*, username:str, password:str) -> bool:
|
def get_and_validate_user(*, username:str, password:str) -> bool:
|
||||||
|
@ -44,3 +47,9 @@ def get_and_validate_user(*, username:str, password:str) -> bool:
|
||||||
raise exc.WrongArguments("Username or password does not matches user.")
|
raise exc.WrongArguments("Username or password does not matches user.")
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
def get_photo_url(photo):
|
||||||
|
"""Get a photo absolute url and the photo automatically cropped."""
|
||||||
|
url = get_thumbnailer(photo)['avatar'].url
|
||||||
|
return get_absolute_url(url)
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import django_sites as sites
|
||||||
|
|
||||||
|
from taiga.base.utils.urls import get_absolute_url, is_absolute_url, build_url
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_absolute_url():
|
||||||
|
assert is_absolute_url("http://domain/path")
|
||||||
|
assert is_absolute_url("https://domain/path")
|
||||||
|
assert not is_absolute_url("://domain/path")
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_absolute_url():
|
||||||
|
site = sites.get_current()
|
||||||
|
assert get_absolute_url("http://domain/path") == "http://domain/path"
|
||||||
|
assert get_absolute_url("/path") == build_url("/path", domain=site.domain, scheme=site.scheme)
|
Loading…
Reference in New Issue