From b65820b0eab12e0c11e99e026adb1ad5f75f5793 Mon Sep 17 00:00:00 2001 From: Stephen Brennan Date: Thu, 16 Feb 2017 13:47:39 -0500 Subject: [PATCH 1/4] Implement Gravatar support behind config variable. --- config-example.py | 6 ++++++ models/employee.py | 21 +++++++++++++++++++++ themes/default/templates/parts/avatar.html | 4 ++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/config-example.py b/config-example.py index 83e2054..ec67185 100644 --- a/config-example.py +++ b/config-example.py @@ -22,3 +22,9 @@ # Name of the S3 bucket used to import employee data from a file named employees.json # Check out /import/employees.json.example to see how this file should look like. S3_BUCKET = 'employees' + +# When do we use Gravatar? Options are: +# * 'always' - prefers Gravatar over the Employee.photo_url +# * 'backup' - use Gravatar when photo_url is empty +# * anything else - disabled +GRAVATAR = 'always' diff --git a/models/employee.py b/models/employee.py index 13704f3..4eff909 100644 --- a/models/employee.py +++ b/models/employee.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import base64 +import hashlib import functools from google.appengine.ext import ndb @@ -78,6 +80,25 @@ def update_from_dict(self, d): self.department = d.get('department') self.meta_department = get_meta_department(self.department) + def get_gravatar(self): + """Creates gravatar URL from email address.""" + email = '{user}@{domain}'.format(user=self.username, domain=config.DOMAIN) + m = hashlib.md5() + m.update(email) + encoded_hash = base64.b16encode(m.digest()).lower() + return '//gravatar.com/avatar/{}?s=200'.format(encoded_hash) + + def get_photo_url(self): + """Return an avatar photo URL (depending on Gravatar config). This still could + be empty, in which case the theme needs to provide an alternate photo. + """ + if config.GRAVATAR == 'always': + return self.get_gravatar() + elif config.GRAVATAR == 'backup' and not self.photo_url: + return self.get_gravatar() + else: + return self.photo_url + @property def full_name(self): """Return user's full name (first name + ' ' + last name).""" diff --git a/themes/default/templates/parts/avatar.html b/themes/default/templates/parts/avatar.html index aa4684b..55139fe 100644 --- a/themes/default/templates/parts/avatar.html +++ b/themes/default/templates/parts/avatar.html @@ -1,6 +1,6 @@ {% macro avatar_url_for(employee) -%} - {% if employee.photo_url -%} - {{ employee.photo_url }} + {% if employee.get_photo_url() -%} + {{ employee.get_photo_url() }} {%- else -%} {{ theme_static('img/user_medium_square.png', external=True) }} {%- endif %} From fc39da7c36f439220e32e23c8a27aa65d7e60f38 Mon Sep 17 00:00:00 2001 From: Stephen Brennan Date: Thu, 16 Feb 2017 14:16:25 -0500 Subject: [PATCH 2/4] Add tests for Gravatar support. --- testing/factories/employee.py | 6 +++++- tests/models/employee_test.py | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/testing/factories/employee.py b/testing/factories/employee.py index 73352d7..54b1c7a 100644 --- a/testing/factories/employee.py +++ b/testing/factories/employee.py @@ -7,12 +7,16 @@ def create_employee( department='Engineering', first_name='John', last_name='Doe', + photo_url=None, ): + if photo_url is None: + photo_url = 'http://example.com/photos/{0}.jpg'.format(username) + return Employee.create_from_dict({ 'username': username, 'department': department, 'first_name': first_name, 'last_name': last_name, - 'photo_url': 'http://exmaple.com/photos/{0}.jpg'.format(username), + 'photo_url': photo_url, }) diff --git a/tests/models/employee_test.py b/tests/models/employee_test.py index 6c99182..c0dd97b 100644 --- a/tests/models/employee_test.py +++ b/tests/models/employee_test.py @@ -49,3 +49,27 @@ def test_get_current_employee_raises(self, mock_get_current_user): def test_full_name(self): employee = create_employee(first_name='Foo', last_name='Bar') self.assertEqual('Foo Bar', employee.full_name) + + @mock.patch('models.employee.config') + def test_gravatar_backup(self, mock_config): + mock_config.GRAVATAR = 'backup' + employee = create_employee(photo_url='') + self.assertEqual(employee.get_gravatar(), employee.get_photo_url()) + employee = create_employee(photo_url='http://example.com/example.jpg') + self.assertEqual(employee.photo_url, employee.get_photo_url()) + + @mock.patch('models.employee.config') + def test_gravatar_always(self, mock_config): + mock_config.GRAVATAR = 'always' + employee = create_employee(photo_url='') + self.assertEqual(employee.get_gravatar(), employee.get_photo_url()) + employee = create_employee(photo_url='http://example.com/example.jpg') + self.assertEqual(employee.get_gravatar(), employee.get_photo_url()) + + @mock.patch('models.employee.config') + def test_gravatar_disabled(self, mock_config): + mock_config.GRAVATAR = 'disabled' + employee = create_employee(photo_url='') + self.assertEqual(employee.photo_url, employee.get_photo_url()) + employee = create_employee(photo_url='http://example.com/example.jpg') + self.assertEqual(employee.photo_url, employee.get_photo_url()) From 56683df002f36e5bcd4192b514dac1439507b404 Mon Sep 17 00:00:00 2001 From: Stephen Brennan Date: Thu, 16 Feb 2017 14:41:47 -0500 Subject: [PATCH 3/4] Use employee.user.email() instead of constructing it --- models/employee.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/models/employee.py b/models/employee.py index 4eff909..67da795 100644 --- a/models/employee.py +++ b/models/employee.py @@ -82,9 +82,8 @@ def update_from_dict(self, d): def get_gravatar(self): """Creates gravatar URL from email address.""" - email = '{user}@{domain}'.format(user=self.username, domain=config.DOMAIN) m = hashlib.md5() - m.update(email) + m.update(self.user.email()) encoded_hash = base64.b16encode(m.digest()).lower() return '//gravatar.com/avatar/{}?s=200'.format(encoded_hash) From bd726022048603641b044a80e78d1da283a87982 Mon Sep 17 00:00:00 2001 From: Stephen Brennan Date: Thu, 16 Feb 2017 14:42:09 -0500 Subject: [PATCH 4/4] Make GRAVATAR='backup' the default --- config-example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config-example.py b/config-example.py index ec67185..11a65ae 100644 --- a/config-example.py +++ b/config-example.py @@ -27,4 +27,4 @@ # * 'always' - prefers Gravatar over the Employee.photo_url # * 'backup' - use Gravatar when photo_url is empty # * anything else - disabled -GRAVATAR = 'always' +GRAVATAR = 'backup'