mirror of
https://github.com/zulip/zulip.git
synced 2025-11-03 13:33:24 +00:00
Support email changes for !avatar syntax.
Significantly modified by tabbott to avoid calling get_user_profile_by_email in bugdown, and have 100% test coverage of the views code. Fixes #2041.
This commit is contained in:
@@ -37,7 +37,7 @@ from zerver.lib.timeout import timeout, TimeoutExpired
|
|||||||
from zerver.lib.cache import (
|
from zerver.lib.cache import (
|
||||||
cache_with_key, cache_get_many, cache_set_many, NotFoundInCache)
|
cache_with_key, cache_get_many, cache_set_many, NotFoundInCache)
|
||||||
from zerver.lib.url_preview import preview as link_preview
|
from zerver.lib.url_preview import preview as link_preview
|
||||||
from zerver.models import Message, Realm
|
from zerver.models import Message, Realm, UserProfile, get_user_profile_by_email
|
||||||
import zerver.lib.alert_words as alert_words
|
import zerver.lib.alert_words as alert_words
|
||||||
import zerver.lib.mention as mention
|
import zerver.lib.mention as mention
|
||||||
from zerver.lib.str_utils import force_text, force_str
|
from zerver.lib.str_utils import force_text, force_str
|
||||||
@@ -635,10 +635,18 @@ class Avatar(markdown.inlinepatterns.Pattern):
|
|||||||
# type: (Match[Text]) -> Optional[Element]
|
# type: (Match[Text]) -> Optional[Element]
|
||||||
img = markdown.util.etree.Element('img')
|
img = markdown.util.etree.Element('img')
|
||||||
email_address = match.group('email')
|
email_address = match.group('email')
|
||||||
|
email = email_address.strip().lower()
|
||||||
|
profile_id = None
|
||||||
|
|
||||||
|
if db_data is not None:
|
||||||
|
user_dict = db_data['by_email'].get(email)
|
||||||
|
if user_dict is not None:
|
||||||
|
profile_id = user_dict['id']
|
||||||
|
|
||||||
img.set('class', 'message_body_gravatar')
|
img.set('class', 'message_body_gravatar')
|
||||||
img.set('src', '/avatar/%s?s=30' % (email_address,))
|
img.set('src', '/avatar/{0}?s=30'.format(profile_id or email))
|
||||||
img.set('title', email_address)
|
img.set('title', email)
|
||||||
img.set('alt', email_address)
|
img.set('alt', email)
|
||||||
return img
|
return img
|
||||||
|
|
||||||
emoji_tree = os.path.join(settings.STATIC_ROOT, "generated", "emoji", "images", "emoji")
|
emoji_tree = os.path.join(settings.STATIC_ROOT, "generated", "emoji", "images", "emoji")
|
||||||
@@ -1350,6 +1358,7 @@ def do_convert(content, message=None, message_realm=None, possible_words=None, s
|
|||||||
db_data = {'possible_words': possible_words,
|
db_data = {'possible_words': possible_words,
|
||||||
'full_names': dict((user['full_name'].lower(), user) for user in realm_users),
|
'full_names': dict((user['full_name'].lower(), user) for user in realm_users),
|
||||||
'short_names': dict((user['short_name'].lower(), user) for user in realm_users),
|
'short_names': dict((user['short_name'].lower(), user) for user in realm_users),
|
||||||
|
'by_email': dict((user['email'].lower(), user) for user in realm_users),
|
||||||
'emoji': message_realm.get_emoji(),
|
'emoji': message_realm.get_emoji(),
|
||||||
'sent_by_bot': sent_by_bot,
|
'sent_by_bot': sent_by_bot,
|
||||||
'stream_names': dict((stream['name'], stream) for stream in realm_streams)}
|
'stream_names': dict((stream['name'], stream) for stream in realm_streams)}
|
||||||
|
|||||||
@@ -896,3 +896,30 @@ class BugdownErrorTests(ZulipTestCase):
|
|||||||
# handle i18n properly here on some systems.
|
# handle i18n properly here on some systems.
|
||||||
with self.assertRaises(JsonableError):
|
with self.assertRaises(JsonableError):
|
||||||
self.send_message("othello@zulip.com", "Denmark", Recipient.STREAM, message)
|
self.send_message("othello@zulip.com", "Denmark", Recipient.STREAM, message)
|
||||||
|
|
||||||
|
|
||||||
|
class BugdownAvatarTestCase(ZulipTestCase):
|
||||||
|
def test_avatar_with_id(self):
|
||||||
|
# type: () -> None
|
||||||
|
sender_user_profile = get_user_profile_by_email("othello@zulip.com")
|
||||||
|
message = Message(sender=sender_user_profile, sending_client=get_client("test"))
|
||||||
|
|
||||||
|
user_profile = get_user_profile_by_email("hamlet@zulip.com")
|
||||||
|
msg = '!avatar({0})'.format(user_profile.email)
|
||||||
|
converted = bugdown.convert(msg, message=message)
|
||||||
|
values = {'email': user_profile.email, 'id': user_profile.id}
|
||||||
|
self.assertEqual(
|
||||||
|
converted,
|
||||||
|
'<p><img alt="{email}" class="message_body_gravatar" src="/avatar/{id}?s=30" title="{email}"></p>'.format(**values))
|
||||||
|
|
||||||
|
def test_avatar_of_unregistered_user(self):
|
||||||
|
# type: () -> None
|
||||||
|
sender_user_profile = get_user_profile_by_email("othello@zulip.com")
|
||||||
|
message = Message(sender=sender_user_profile, sending_client=get_client("test"))
|
||||||
|
|
||||||
|
email = 'fakeuser@example.com'
|
||||||
|
msg = '!avatar({0})'.format(email)
|
||||||
|
converted = bugdown.convert(msg, message=message)
|
||||||
|
self.assertEqual(
|
||||||
|
converted,
|
||||||
|
'<p><img alt="{0}" class="message_body_gravatar" src="/avatar/{0}?s=30" title="{0}"></p>'.format(email))
|
||||||
|
|||||||
@@ -381,6 +381,10 @@ class AvatarTest(UploadSerializeMixin, ZulipTestCase):
|
|||||||
redirect_url = response['Location']
|
redirect_url = response['Location']
|
||||||
self.assertTrue(redirect_url.endswith(avatar_url(cordelia) + '&foo=bar'))
|
self.assertTrue(redirect_url.endswith(avatar_url(cordelia) + '&foo=bar'))
|
||||||
|
|
||||||
|
response = self.client_get("/avatar/%s?foo=bar" % (cordelia.id))
|
||||||
|
redirect_url = response['Location']
|
||||||
|
self.assertTrue(redirect_url.endswith(avatar_url(cordelia) + '&foo=bar'))
|
||||||
|
|
||||||
def test_non_valid_user_avatar(self):
|
def test_non_valid_user_avatar(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ from zerver.lib.validator import check_bool, check_string
|
|||||||
from zerver.lib.users import check_change_full_name, check_full_name
|
from zerver.lib.users import check_change_full_name, check_full_name
|
||||||
from zerver.lib.utils import generate_random_token
|
from zerver.lib.utils import generate_random_token
|
||||||
from zerver.models import UserProfile, Stream, Realm, Message, get_user_profile_by_email, \
|
from zerver.models import UserProfile, Stream, Realm, Message, get_user_profile_by_email, \
|
||||||
email_allowed_for_realm
|
email_allowed_for_realm, get_user_profile_by_id
|
||||||
from zproject.jinja2 import render_to_response
|
from zproject.jinja2 import render_to_response
|
||||||
|
|
||||||
|
|
||||||
@@ -112,12 +112,26 @@ def update_user_backend(request, user_profile, email,
|
|||||||
|
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
def avatar(request, email):
|
# TODO: Since eventually we want to support using the same email with
|
||||||
|
# different organizations, we'll eventually want this to be a
|
||||||
|
# logged-in endpoint so that we can access the realm_id.
|
||||||
|
def avatar(request, email_or_id):
|
||||||
# type: (HttpRequest, str) -> HttpResponse
|
# type: (HttpRequest, str) -> HttpResponse
|
||||||
|
"""Accepts an email address or user ID and returns the avatar"""
|
||||||
try:
|
try:
|
||||||
user_profile = get_user_profile_by_email(email)
|
int(email_or_id)
|
||||||
|
except ValueError:
|
||||||
|
get_user_func = get_user_profile_by_email
|
||||||
|
else:
|
||||||
|
get_user_func = get_user_profile_by_id
|
||||||
|
|
||||||
|
try:
|
||||||
|
# If there is a valid user account passed in, use its avatar
|
||||||
|
user_profile = get_user_func(email_or_id)
|
||||||
url = avatar_url(user_profile)
|
url = avatar_url(user_profile)
|
||||||
except UserProfile.DoesNotExist:
|
except UserProfile.DoesNotExist:
|
||||||
|
# If there is no such user, treat it as a new gravatar
|
||||||
|
email = email_or_id
|
||||||
avatar_source = 'G'
|
avatar_source = 'G'
|
||||||
avatar_version = 1
|
avatar_version = 1
|
||||||
url = get_avatar_url(avatar_source, email, avatar_version)
|
url = get_avatar_url(avatar_source, email, avatar_version)
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ i18n_urls = [
|
|||||||
{'template_name': 'zerver/reset_done.html'}),
|
{'template_name': 'zerver/reset_done.html'}),
|
||||||
|
|
||||||
# Avatar
|
# Avatar
|
||||||
url(r'^avatar/(?P<email>[\S]+)?', zerver.views.users.avatar, name='zerver.views.users.avatar'),
|
url(r'^avatar/(?P<email_or_id>[\S]+)?', zerver.views.users.avatar, name='zerver.views.users.avatar'),
|
||||||
|
|
||||||
# Registration views, require a confirmation ID.
|
# Registration views, require a confirmation ID.
|
||||||
url(r'^accounts/home/', zerver.views.registration.accounts_home,
|
url(r'^accounts/home/', zerver.views.registration.accounts_home,
|
||||||
|
|||||||
Reference in New Issue
Block a user