kopia lustrzana https://github.com/wagtail/wagtail
Add support for query string params in WAGTAIL_GRAVATAR_PROVIDER_URL
- Enhance capabilities for WAGTAIL_GRAVATAR_PROVIDER_URL URL to support merging of URL params. - Fixes #12659 - Rework of original PR #11077pull/12681/head
rodzic
32417f9adc
commit
3e75c018be
|
@ -14,6 +14,7 @@ Changelog
|
|||
* Allow plain strings in panel definitions as shorthand for `FieldPanel` / `InlinePanel` (Matt Westcott)
|
||||
* Only allow selection of valid new parents within the copy Page view (Mauro Soche)
|
||||
* Add `on_serve_page` hook to modify the serving chain of pages (Krystian Magdziarz, Dawid Bugajewski)
|
||||
* Add support for `WAGTAIL_GRAVATAR_PROVIDER_URL` URLs with query string parameters (Ayaan Qadri, Guilhem Saurel)
|
||||
* Fix: Improve handling of translations for bulk page action confirmation messages (Matt Westcott)
|
||||
* Fix: Ensure custom rich text feature icons are correctly handled when provided as a list of SVG paths (Temidayo Azeez, Joel William, LB (Ben) Johnston)
|
||||
* Fix: Ensure manual edits to `StreamField` values do not throw an error (Stefan Hammer)
|
||||
|
|
|
@ -861,6 +861,7 @@
|
|||
* Harsh Dange
|
||||
* Mauro Soche
|
||||
* Krystian Magdziarz
|
||||
* Guilhem Saurel
|
||||
|
||||
## Translators
|
||||
|
||||
|
|
|
@ -636,6 +636,14 @@ WAGTAIL_GRAVATAR_PROVIDER_URL = '//www.gravatar.com/avatar'
|
|||
|
||||
If a user has not uploaded a profile picture, Wagtail will look for an avatar linked to their email address on gravatar.com. This setting allows you to specify an alternative provider such as like robohash.org, or can be set to `None` to disable the use of remote avatars completely.
|
||||
|
||||
Any provided query string will merge with the default parameters. For example, using the setting `//www.gravatar.com/avatar?d=robohash` will use the `robohash` override instead of the default `mp` (mystery person). The `s` parameter will be ignored as this is specified depending on location within the admin interface.
|
||||
|
||||
See the [Gravatar images URL documentation](https://docs.gravatar.com/api/avatars/images/) for more details.
|
||||
|
||||
```{versionchanged} 6.4
|
||||
Added query string merging.
|
||||
```
|
||||
|
||||
(wagtail_user_time_zones)=
|
||||
|
||||
### `WAGTAIL_USER_TIME_ZONES`
|
||||
|
|
|
@ -23,6 +23,7 @@ depth: 1
|
|||
* Allow plain strings in panel definitions as shorthand for `FieldPanel` / `InlinePanel` (Matt Westcott)
|
||||
* Only allow selection of valid new parents within the copy Page view (Mauro Soche)
|
||||
* Add [`on_serve_page`](on_serve_page) hook to modify the serving chain of pages (Krystian Magdziarz, Dawid Bugajewski)
|
||||
* Add support for [`WAGTAIL_GRAVATAR_PROVIDER_URL`](wagtail_gravatar_provider_url) URLs with query string parameters (Ayaan Qadri, Guilhem Saurel)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
|
|
|
@ -283,7 +283,7 @@ class TestAdaptMainMenuModule(WagtailTestUtils, DjangoTestCase):
|
|||
],
|
||||
{
|
||||
"name": user.first_name or user.get_username(),
|
||||
"avatarUrl": "//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=100&d=mp",
|
||||
"avatarUrl": "//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?d=mp&s=100",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
from django.test import TestCase, override_settings
|
||||
|
||||
from wagtail.users.utils import get_gravatar_url
|
||||
|
||||
|
||||
class TestGravatar(TestCase):
|
||||
def test_gravatar_default(self):
|
||||
"""Test with the default settings"""
|
||||
self.assertEqual(
|
||||
get_gravatar_url("something@example.com"),
|
||||
"//www.gravatar.com/avatar/76ebd6fecabc982c205dd056e8f0415a?d=mp&s=100",
|
||||
)
|
||||
|
||||
def test_gravatar_custom_size(self):
|
||||
"""Test with a custom size (note that the size will be doubled)"""
|
||||
self.assertEqual(
|
||||
get_gravatar_url("something@example.com", size=100),
|
||||
"//www.gravatar.com/avatar/76ebd6fecabc982c205dd056e8f0415a?d=mp&s=200",
|
||||
)
|
||||
|
||||
@override_settings(
|
||||
WAGTAIL_GRAVATAR_PROVIDER_URL="https://robohash.org/avatar?d=robohash&s=200"
|
||||
)
|
||||
def test_gravatar_params_that_overlap(self):
|
||||
"""
|
||||
Test with params that overlap with default s (size) and d (default_image)
|
||||
Also test the `s` is not overridden by the provider URL's query parameters.
|
||||
"""
|
||||
self.assertEqual(
|
||||
get_gravatar_url("something@example.com", size=80),
|
||||
"https://robohash.org/avatar/76ebd6fecabc982c205dd056e8f0415a?d=robohash&s=160",
|
||||
)
|
||||
|
||||
@override_settings(WAGTAIL_GRAVATAR_PROVIDER_URL="https://robohash.org/avatar?f=y")
|
||||
def test_gravatar_params_that_dont_overlap(self):
|
||||
"""Test with params that don't default `s (size)` and `d (default_image)`"""
|
||||
self.assertEqual(
|
||||
get_gravatar_url("something@example.com"),
|
||||
"https://robohash.org/avatar/76ebd6fecabc982c205dd056e8f0415a?d=mp&f=y&s=100",
|
||||
)
|
||||
|
||||
@override_settings(
|
||||
WAGTAIL_GRAVATAR_PROVIDER_URL="https://robohash.org/avatar?d=robohash&f=y"
|
||||
)
|
||||
def test_gravatar_query_params_override_default_params(self):
|
||||
"""Test that query parameters of `WAGTAIL_GRAVATAR_PROVIDER_URL` override default_params"""
|
||||
self.assertEqual(
|
||||
get_gravatar_url(
|
||||
"something@example.com", default_params={"d": "monsterid"}
|
||||
),
|
||||
"https://robohash.org/avatar/76ebd6fecabc982c205dd056e8f0415a?d=robohash&f=y&s=100",
|
||||
)
|
||||
|
||||
@override_settings(WAGTAIL_GRAVATAR_PROVIDER_URL="https://robohash.org/avatar/")
|
||||
def test_gravatar_trailing_slash(self):
|
||||
"""Test with a trailing slash in the URL"""
|
||||
self.assertEqual(
|
||||
get_gravatar_url("something@example.com"),
|
||||
"https://robohash.org/avatar/76ebd6fecabc982c205dd056e8f0415a?d=mp&s=100",
|
||||
)
|
||||
|
||||
@override_settings(WAGTAIL_GRAVATAR_PROVIDER_URL="https://robohash.org/avatar")
|
||||
def test_gravatar_no_trailing_slash(self):
|
||||
"""Test with no trailing slash in the URL"""
|
||||
self.assertEqual(
|
||||
get_gravatar_url("something@example.com"),
|
||||
"https://robohash.org/avatar/76ebd6fecabc982c205dd056e8f0415a?d=mp&s=100",
|
||||
)
|
||||
|
||||
@override_settings(WAGTAIL_GRAVATAR_PROVIDER_URL="https://robohash.org/avatar?")
|
||||
def test_gravatar_trailing_question_mark(self):
|
||||
"""Test with a trailing question mark in the URL"""
|
||||
self.assertEqual(
|
||||
get_gravatar_url("something@example.com"),
|
||||
"https://robohash.org/avatar/76ebd6fecabc982c205dd056e8f0415a?d=mp&s=100",
|
||||
)
|
|
@ -1,3 +1,5 @@
|
|||
from urllib.parse import parse_qs, urlparse, urlunparse
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.http import urlencode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
@ -25,11 +27,29 @@ def user_can_delete_user(current_user, user_to_delete):
|
|||
return True
|
||||
|
||||
|
||||
def get_gravatar_url(email, size=50):
|
||||
default = "mp"
|
||||
size = (
|
||||
int(size) * 2
|
||||
) # requested at retina size by default and scaled down at point of use with css
|
||||
def get_gravatar_url(email, size=50, default_params={"d": "mp"}):
|
||||
"""
|
||||
See https://gravatar.com/site/implement/images/ for Gravatar image options.
|
||||
|
||||
Example usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Basic usage
|
||||
gravatar_url = get_gravatar_url('user@example.com')
|
||||
|
||||
# Customize size and default image
|
||||
gravatar_url = get_gravatar_url(
|
||||
'user@example.com',
|
||||
size=100,
|
||||
default_params={'d': 'robohash', 'f': 'y'}
|
||||
)
|
||||
|
||||
Note:
|
||||
If any parameter in ``default_params`` also exists in the provider URL,
|
||||
it will be overridden by the provider URL's query parameter.
|
||||
"""
|
||||
|
||||
gravatar_provider_url = getattr(
|
||||
settings, "WAGTAIL_GRAVATAR_PROVIDER_URL", "//www.gravatar.com/avatar"
|
||||
)
|
||||
|
@ -37,14 +57,26 @@ def get_gravatar_url(email, size=50):
|
|||
if (not email) or (gravatar_provider_url is None):
|
||||
return None
|
||||
|
||||
email_bytes = email.lower().encode("utf-8")
|
||||
hash = safe_md5(email_bytes, usedforsecurity=False).hexdigest()
|
||||
gravatar_url = "{gravatar_provider_url}/{hash}?{params}".format(
|
||||
gravatar_provider_url=gravatar_provider_url.rstrip("/"),
|
||||
hash=hash,
|
||||
params=urlencode({"s": size, "d": default}),
|
||||
parsed_url = urlparse(gravatar_provider_url)
|
||||
|
||||
params = {
|
||||
**default_params,
|
||||
**(parse_qs(parsed_url.query or "")),
|
||||
# requested at retina size by default and scaled down at point of use with css
|
||||
"s": int(size) * 2,
|
||||
}
|
||||
|
||||
email_hash = safe_md5(
|
||||
email.lower().encode("utf-8"), usedforsecurity=False
|
||||
).hexdigest()
|
||||
|
||||
parsed_url = parsed_url._replace(
|
||||
path=f"{parsed_url.path.rstrip('/')}/{email_hash}",
|
||||
query=urlencode(params, doseq=True),
|
||||
)
|
||||
|
||||
gravatar_url = urlunparse(parsed_url)
|
||||
|
||||
return gravatar_url
|
||||
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue