diff --git a/settings/common.py b/settings/common.py
index f227d97c..3ee3b3f3 100644
--- a/settings/common.py
+++ b/settings/common.py
@@ -477,10 +477,6 @@ THUMBNAIL_ALIASES = {
},
}
-# GRAVATAR_DEFAULT_AVATAR = "img/user-noimage.png"
-GRAVATAR_DEFAULT_AVATAR = ""
-GRAVATAR_AVATAR_SIZE = THN_AVATAR_SIZE
-
TAGS_PREDEFINED_COLORS = ["#fce94f", "#edd400", "#c4a000", "#8ae234",
"#73d216", "#4e9a06", "#d3d7cf", "#fcaf3e",
"#f57900", "#ce5c00", "#729fcf", "#3465a4",
diff --git a/taiga/projects/history/serializers.py b/taiga/projects/history/serializers.py
index 224cc6df..0f2dc658 100644
--- a/taiga/projects/history/serializers.py
+++ b/taiga/projects/history/serializers.py
@@ -19,7 +19,8 @@
from taiga.base.api import serializers
from taiga.base.fields import I18NJsonField, Field, MethodField
-from taiga.users.services import get_user_photo_or_gravatar_url
+from taiga.users.services import get_user_photo_url
+from taiga.users.gravatar import get_user_gravatar_id
HISTORY_ENTRY_I18N_FIELDS = ("points", "status", "severity", "priority", "type")
@@ -46,7 +47,8 @@ class HistoryEntrySerializer(serializers.LightSerializer):
def get_user(self, entry):
user = {"pk": None, "username": None, "name": None, "photo": None, "is_active": False}
user.update(entry.user)
- user["photo"] = get_user_photo_or_gravatar_url(entry.owner)
+ user["photo"] = get_user_photo_url(entry.owner)
+ user["gravatar_id"] = get_user_gravatar_id(entry.owner)
if entry.owner:
user["is_active"] = entry.owner.is_active
diff --git a/taiga/projects/serializers.py b/taiga/projects/serializers.py
index d4c93155..1d8a5799 100644
--- a/taiga/projects/serializers.py
+++ b/taiga/projects/serializers.py
@@ -22,7 +22,8 @@ from taiga.base.api import serializers
from taiga.base.fields import Field, MethodField, I18NField
from taiga.permissions import services as permissions_services
-from taiga.users.services import get_user_photo_or_gravatar_url, get_photo_or_gravatar_url
+from taiga.users.services import get_photo_url, get_user_photo_url
+from taiga.users.gravatar import get_gravatar_id, get_user_gravatar_id
from taiga.users.serializers import UserBasicInfoSerializer
from taiga.permissions.services import calculate_permissions
@@ -106,12 +107,16 @@ class MembershipDictSerializer(serializers.LightDictSerializer):
color = Field()
username = Field()
photo = MethodField()
+ gravatar_id = MethodField()
def get_full_name_display(self, obj):
return obj["full_name"] or obj["username"] or obj["email"]
def get_photo(self, obj):
- return get_photo_or_gravatar_url(obj['photo'], obj['email'])
+ return get_photo_url(obj['photo'])
+
+ def get_gravatar_id(self, obj):
+ return get_gravatar_id(obj['email'])
class MembershipSerializer(serializers.LightSerializer):
@@ -129,6 +134,7 @@ class MembershipSerializer(serializers.LightSerializer):
is_user_active = MethodField()
color = MethodField()
photo = MethodField()
+ gravatar_id = MethodField()
project_name = MethodField()
project_slug = MethodField()
invited_by = UserBasicInfoSerializer()
@@ -147,7 +153,10 @@ class MembershipSerializer(serializers.LightSerializer):
return obj.user.color if obj.user else None
def get_photo(self, obj):
- return get_user_photo_or_gravatar_url(obj.user)
+ return get_user_photo_url(obj.user)
+
+ def get_gravatar_id(self, obj):
+ return get_user_gravatar_id(obj.user)
def get_project_name(self, obj):
return obj.project.name if obj and obj.project else ""
diff --git a/taiga/timeline/serializers.py b/taiga/timeline/serializers.py
index a7f607c9..0b831d04 100644
--- a/taiga/timeline/serializers.py
+++ b/taiga/timeline/serializers.py
@@ -20,7 +20,8 @@ from django.contrib.auth import get_user_model
from taiga.base.api import serializers
from taiga.base.fields import Field, MethodField
-from taiga.users.services import get_user_photo_or_gravatar_url, get_big_photo_or_gravatar_url
+from taiga.users.services import get_user_photo_url, get_user_big_photo_url
+from taiga.users.gravatar import get_user_gravatar_id
from . import models
@@ -56,8 +57,9 @@ class TimelineSerializer(serializers.LightSerializer):
obj.data["user"] = {
"id": user.pk,
"name": user.get_full_name(),
- "photo": get_user_photo_or_gravatar_url(user),
- "big_photo": get_big_photo_or_gravatar_url(user),
+ "photo": get_user_photo_url(user),
+ "big_photo": get_user_big_photo_url(user),
+ "gravatar_id": get_user_gravatar_id(user),
"username": user.username,
"is_profile_visible": user.is_active and not user.is_system,
"date_joined": user.date_joined
diff --git a/taiga/users/gravatar.py b/taiga/users/gravatar.py
index 7793e59d..b8329d95 100644
--- a/taiga/users/gravatar.py
+++ b/taiga/users/gravatar.py
@@ -18,45 +18,22 @@
# along with this program. If not, see .
import hashlib
-import copy
-
-from urllib.parse import urlencode
-
-from django.conf import settings
-from django.templatetags.static import static
-
-GRAVATAR_BASE_URL = "//www.gravatar.com/avatar/{}?{}"
-def get_gravatar_url(email: str, **options) -> str:
- """Get the gravatar url associated to an email.
+def get_gravatar_id(email: str) -> str:
+ """Get the gravatar id associated to an email.
- :param options: Additional options to gravatar.
- - `default` defines what image url to show if no gravatar exists
- - `size` defines the size of the avatar.
-
- :return: Gravatar url.
+ :return: Gravatar id.
"""
- params = copy.copy(options)
+ return hashlib.md5(email.lower().encode()).hexdigest()
- default_avatar = getattr(settings, "GRAVATAR_DEFAULT_AVATAR", None)
- default_size = getattr(settings, "GRAVATAR_AVATAR_SIZE", None)
+def get_user_gravatar_id(user: object) -> str:
+ """Get the gravatar id associated to a user.
- avatar = options.get("default", None)
- size = options.get("size", None)
+ :return: Gravatar id.
+ """
+ if user and user.email:
+ return get_gravatar_id(user.email)
- if avatar:
- params["default"] = avatar
- elif default_avatar:
- params["default"] = static(default_avatar)
-
- if size:
- params["size"] = size
- elif default_size:
- params["size"] = default_size
-
- email_hash = hashlib.md5(email.lower().encode()).hexdigest()
- url = GRAVATAR_BASE_URL.format(email_hash, urlencode(params))
-
- return url
+ return None
diff --git a/taiga/users/serializers.py b/taiga/users/serializers.py
index a943183d..76fa6141 100644
--- a/taiga/users/serializers.py
+++ b/taiga/users/serializers.py
@@ -24,8 +24,8 @@ from taiga.base.fields import PgArrayField, Field, MethodField, I18NField
from taiga.base.utils.thumbnails import get_thumbnail_url
from taiga.projects.models import Project
-from .services import get_user_photo_or_gravatar_url, get_big_photo_or_gravatar_url
-from .gravatar import get_gravatar_url
+from .services import get_user_photo_url, get_big_photo_url, get_user_big_photo_url
+from taiga.users.gravatar import get_user_gravatar_id
from collections import namedtuple
@@ -53,7 +53,7 @@ class UserSerializer(serializers.LightSerializer):
is_active = Field()
photo = MethodField()
big_photo = MethodField()
- gravatar_url = MethodField()
+ gravatar_id = MethodField()
roles = MethodField()
projects_with_me = MethodField()
@@ -61,13 +61,13 @@ class UserSerializer(serializers.LightSerializer):
return obj.get_full_name() if obj else ""
def get_photo(self, user):
- return get_user_photo_or_gravatar_url(user)
+ return get_user_photo_url(user)
def get_big_photo(self, user):
- return get_big_photo_or_gravatar_url(user)
+ return get_user_big_photo_url(user)
- def get_gravatar_url(self, user):
- return get_gravatar_url(user.email)
+ def get_gravatar_id(self, user):
+ return get_user_gravatar_id(user)
def get_roles(self, user):
return user.memberships. order_by("role__name").values_list("role__name", flat=True).distinct()
@@ -108,6 +108,7 @@ class UserBasicInfoSerializer(serializers.LightSerializer):
full_name_display = MethodField()
photo = MethodField()
big_photo = MethodField()
+ gravatar_id = MethodField()
is_active = Field()
id = Field()
@@ -115,10 +116,13 @@ class UserBasicInfoSerializer(serializers.LightSerializer):
return obj.get_full_name()
def get_photo(self, obj):
- return get_user_photo_or_gravatar_url(obj)
+ return get_user_photo_url(obj)
def get_big_photo(self, obj):
- return get_big_photo_or_gravatar_url(obj)
+ return get_user_big_photo_url(obj)
+
+ def get_gravatar_id(self, obj):
+ return get_user_gravatar_id(obj)
def to_value(self, instance):
if instance is None:
@@ -181,6 +185,7 @@ class HighLightedContentSerializer(serializers.LightSerializer):
assigned_to_username = Field()
assigned_to_full_name = Field()
assigned_to_photo = MethodField()
+ assigned_to_gravatar_id = MethodField()
is_watcher = MethodField()
total_watchers = Field()
@@ -237,7 +242,16 @@ class HighLightedContentSerializer(serializers.LightSerializer):
UserData = namedtuple("UserData", ["photo", "email"])
user_data = UserData(photo=obj.assigned_to_photo, email=obj.assigned_to_email or "")
- return get_user_photo_or_gravatar_url(user_data)
+ return get_user_photo_url(user_data)
+
+ def get_assigned_to_gravatar_id(self, obj):
+ type = getattr(obj, "type", "")
+ if type == "project":
+ return None
+
+ UserData = namedtuple("UserData", ["photo", "email"])
+ user_data = UserData(photo=obj.assigned_to_photo, email=obj.assigned_to_email or "")
+ return get_user_gravatar_id(user_data)
def get_tags_colors(self, obj):
tags = getattr(obj, "tags", [])
diff --git a/taiga/users/services.py b/taiga/users/services.py
index 73ae2d74..98b813b1 100644
--- a/taiga/users/services.py
+++ b/taiga/users/services.py
@@ -37,9 +37,6 @@ from taiga.base.utils.urls import get_absolute_url
from taiga.projects.notifications.choices import NotifyLevel
from taiga.projects.notifications.services import get_projects_watched
-from .gravatar import get_gravatar_url
-
-
def get_user_by_username_or_email(username_or_email):
user_model = get_user_model()
@@ -75,6 +72,8 @@ def get_and_validate_user(*, username:str, password:str) -> bool:
def get_photo_url(photo):
"""Get a photo absolute url and the photo automatically cropped."""
+ if not photo:
+ return None
try:
url = get_thumbnailer(photo)[settings.THN_AVATAR_SMALL].url
return get_absolute_url(url)
@@ -82,24 +81,17 @@ def get_photo_url(photo):
return None
-def get_photo_or_gravatar_url(photo=None, email=None):
- """Get the user's photo/gravatar url."""
- if photo:
- return get_photo_url(photo)
- if email:
- return get_gravatar_url(email)
- return settings.GRAVATAR_DEFAULT_AVATAR
-
-
-def get_user_photo_or_gravatar_url(user):
- """Get the user's photo/gravatar url."""
- if user:
- return get_photo_url(user.photo) if user.photo else get_gravatar_url(user.email)
- return settings.GRAVATAR_DEFAULT_AVATAR
+def get_user_photo_url(user):
+ """Get the user's photo url."""
+ if not user:
+ return None
+ return get_photo_url(user.photo)
def get_big_photo_url(photo):
"""Get a big photo absolute url and the photo automatically cropped."""
+ if not photo:
+ return None
try:
url = get_thumbnailer(photo)[settings.THN_AVATAR_BIG].url
return get_absolute_url(url)
@@ -107,15 +99,11 @@ def get_big_photo_url(photo):
return None
-def get_big_photo_or_gravatar_url(user):
- """Get the user's big photo/gravatar url."""
+def get_user_big_photo_url(user):
+ """Get the user's big photo url."""
if not user:
- return ""
-
- if user.photo:
- return get_big_photo_url(user.photo)
- else:
- return get_gravatar_url(user.email, size=settings.THN_AVATAR_BIG_SIZE)
+ return None
+ return get_big_photo_url(user.photo)
def get_visible_project_ids(from_user, by_user):
diff --git a/taiga/webhooks/serializers.py b/taiga/webhooks/serializers.py
index f08f4ae7..61eea6cb 100644
--- a/taiga/webhooks/serializers.py
+++ b/taiga/webhooks/serializers.py
@@ -24,14 +24,14 @@ from taiga.front.templatetags.functions import resolve as resolve_front_url
from taiga.projects.services import get_logo_big_thumbnail_url
-from taiga.users.gravatar import get_gravatar_url
-from taiga.users.services import get_user_photo_or_gravatar_url
-
+from taiga.users.services import get_user_photo_url
+from taiga.users.gravatar import get_user_gravatar_id
########################################################################
# WebHooks
########################################################################
+
class WebhookSerializer(serializers.LightSerializer):
id = Field()
project = Field(attr="project_id")
@@ -64,17 +64,14 @@ class WebhookLogSerializer(serializers.LightSerializer):
class UserSerializer(serializers.LightSerializer):
id = Field(attr="pk")
permalink = MethodField()
- gravatar_url = MethodField()
username = MethodField()
full_name = MethodField()
photo = MethodField()
+ gravatar_id = MethodField()
def get_permalink(self, obj):
return resolve_front_url("user", obj.username)
- def get_gravatar_url(self, obj):
- return get_gravatar_url(obj.email)
-
def get_username(self, obj):
return obj.get_username()
@@ -82,7 +79,10 @@ class UserSerializer(serializers.LightSerializer):
return obj.get_full_name()
def get_photo(self, obj):
- return get_user_photo_or_gravatar_url(obj)
+ return get_user_photo_url(obj)
+
+ def get_gravatar_id(self, obj):
+ return get_user_gravatar_id(obj)
def to_value(self, instance):
if instance is None:
diff --git a/tests/unit/test_gravatar.py b/tests/unit/test_gravatar.py
deleted file mode 100644
index b6246fa8..00000000
--- a/tests/unit/test_gravatar.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (C) 2014-2016 Andrey Antukh
-# Copyright (C) 2014-2016 Jesús Espino
-# Copyright (C) 2014-2016 David Barragán
-# Copyright (C) 2014-2016 Alejandro Alonso
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-
-import hashlib
-
-from taiga.users.gravatar import get_gravatar_url
-
-
-def test_get_gravatar_url():
- email = "user@email.com"
- email_hash = hashlib.md5(email.encode()).hexdigest()
- url = get_gravatar_url(email, s=40, d="default-image-url")
-
- assert email_hash in url
- assert 's=40' in url
- assert 'd=default-image-url' in url