From f9055706cae845beccaa23fb93d7b3d0c79b218f Mon Sep 17 00:00:00 2001 From: tmeissner Date: Thu, 15 Nov 2018 21:58:46 +0100 Subject: [PATCH] Chapter 10: Caching of user avatar hashes (10d) --- app/models.py | 9 ++++++++- migrations/versions/5cffb9b6fccd_.py | 28 ++++++++++++++++++++++++++++ tests/test_user_model.py | 13 ++++++------- 3 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 migrations/versions/5cffb9b6fccd_.py diff --git a/app/models.py b/app/models.py index 89079af..42256c1 100644 --- a/app/models.py +++ b/app/models.py @@ -82,6 +82,7 @@ class User(UserMixin, db.Model): about_me = db.Column(db.Text()) member_since = db.Column(db.DateTime(), default=datetime.utcnow) last_seen = db.Column(db.DateTime(), default=datetime.utcnow) + avatar_hash = db.Column(db.String(32)) def __init__(self, **kwargs): super(User, self).__init__(**kwargs) @@ -90,6 +91,8 @@ class User(UserMixin, db.Model): self.role = Role.query.filter_by(name='Administrator').first() else: self.role = Role.query.filter_by(default=True).first() + if self.email is not None and self.avatar_hash is None: + self.avatar_hash = self.gravatar_hash() @property def password(self): @@ -155,6 +158,7 @@ class User(UserMixin, db.Model): if self.query.filter_by(email=new_email).first() is not None: return False self.email = new_email + self.gravatar_hash = self.gravatar_hash() db.session.add(self) return True @@ -169,9 +173,12 @@ class User(UserMixin, db.Model): db.session.add(self) db.session.commit() + def gravatar_hash(self): + return hashlib.md5(self.email.lower().encode('utf-8')).hexdigest() + def gravatar(self, size=100, default='identicon', rating='g'): url = 'https://secure.gravatar.com/avatar' - hash = hashlib.md5(self.email.lower().encode('utf-8')).hexdigest() + hash = self.avatar_hash or self.gravatar_hash() return '{url}/{hash}?s={size}&d={default}&r={rating}'.format( url=url, hash=hash, size=size, default=default, rating=rating) diff --git a/migrations/versions/5cffb9b6fccd_.py b/migrations/versions/5cffb9b6fccd_.py new file mode 100644 index 0000000..b48e779 --- /dev/null +++ b/migrations/versions/5cffb9b6fccd_.py @@ -0,0 +1,28 @@ +"""empty message + +Revision ID: 5cffb9b6fccd +Revises: 382a65f4b6c9 +Create Date: 2018-11-15 21:49:26.478624 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '5cffb9b6fccd' +down_revision = '382a65f4b6c9' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('users', sa.Column('avatar_hash', sa.String(length=32), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('users', 'avatar_hash') + # ### end Alembic commands ### diff --git a/tests/test_user_model.py b/tests/test_user_model.py index a3eccfd..0ee4fe5 100644 --- a/tests/test_user_model.py +++ b/tests/test_user_model.py @@ -160,13 +160,12 @@ class UserModelTestCase(unittest.TestCase): def test_gravatar(self): u = User(email='max@mustermann.de', password='cat') with self.app.test_request_context('/'): + gravatar = u.gravatar() gravatar_256 = u.gravatar(size=256) gravatar_pg = u.gravatar(rating='pg') gravatar_retro = u.gravatar(default='retro') - with self.app.test_request_context(): - gravatar_ssl = u.gravatar() - self.assertTrue('s=256' in gravatar_256) - self.assertTrue('r=pg'in gravatar_pg) - self.assertTrue('d=retro' in gravatar_retro) - self.assertTrue('https://secure.gravatar.com/avatar/' + - '3e64c371ba2b93f1c0fead369fe004ef' in gravatar_ssl) + self.assertTrue('https://secure.gravatar.com/avatar/' + + '3e64c371ba2b93f1c0fead369fe004ef' in gravatar) + self.assertTrue('s=256' in gravatar_256) + self.assertTrue('r=pg'in gravatar_pg) + self.assertTrue('d=retro' in gravatar_retro)