Skip to content

Commit efeacf0

Browse files
Chapter 10: User avatars (10c)
1 parent 6aa8227 commit efeacf0

File tree

5 files changed

+60
-21
lines changed

5 files changed

+60
-21
lines changed

app/models.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from datetime import datetime
2+
import hashlib
23
from werkzeug.security import generate_password_hash, check_password_hash
34
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
4-
from flask import current_app
5+
from flask import current_app, request
56
from flask_login import UserMixin, AnonymousUserMixin
67
from . import db, login_manager
78

@@ -166,6 +167,12 @@ def ping(self):
166167
self.last_seen = datetime.utcnow()
167168
db.session.add(self)
168169

170+
def gravatar(self, size=100, default='identicon', rating='g'):
171+
url = 'https://secure.gravatar.com/avatar'
172+
hash = hashlib.md5(self.email.lower().encode('utf-8')).hexdigest()
173+
return '{url}/{hash}?s={size}&d={default}&r={rating}'.format(
174+
url=url, hash=hash, size=size, default=default, rating=rating)
175+
169176
def __repr__(self):
170177
return '<User %r>' % self.username
171178

app/static/styles.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.profile-thumbnail {
2+
position: absolute;
3+
}
4+
.profile-header {
5+
min-height: 260px;
6+
margin-left: 280px;
7+
}
8+

app/templates/base.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
{{ super() }}
77
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
88
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
9+
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles.css') }}">
910
{% endblock %}
1011

1112
{% block navbar %}
@@ -30,7 +31,10 @@
3031
<ul class="nav navbar-nav navbar-right">
3132
{% if current_user.is_authenticated %}
3233
<li class="dropdown">
33-
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Account <b class="caret"></b></a>
34+
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
35+
<img src="{{ current_user.gravatar(size=18) }}">
36+
Account <b class="caret"></b>
37+
</a>
3438
<ul class="dropdown-menu">
3539
<li><a href="{{ url_for('auth.change_password') }}">Change Password</a></li>
3640
<li><a href="{{ url_for('auth.change_email_request') }}">Change Email</a></li>

app/templates/user.html

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,30 @@
44

55
{% block page_content %}
66
<div class="page-header">
7-
<h1>{{ user.username }}</h1>
8-
{% if user.name or user.location %}
9-
<p>
10-
{% if user.name %}{{ user.name }}{% endif %}
11-
{% if user.location %}
12-
from <a href="http://maps.google.com/?q={{ user.location }}">{{ user.location }}</a>
13-
{% endif %}
14-
</p>
15-
{% endif %}
16-
{% if current_user.is_administrator() %}
17-
<p><a href="mailto:{{ user.email }}">{{ user.email }}</a></p>
18-
{% endif %}
19-
{% if user.about_me %}<p>{{ user.about_me }}</p>{% endif %}
20-
<p>Member since {{ moment(user.member_since).format('L') }}. Last seen {{ moment(user.last_seen).fromNow() }}.</p>
21-
<p>
22-
{% if user == current_user %}
23-
<a class="btn btn-default" href="{{ url_for('.edit_profile') }}">Edit Profile</a>
7+
<img class="img-rounded profile-thumbnail" src="{{ user.gravatar(size=256) }}">
8+
<div class="profile-header">
9+
<h1>{{ user.username }}</h1>
10+
{% if user.name or user.location %}
11+
<p>
12+
{% if user.name %}{{ user.name }}<br>{% endif %}
13+
{% if user.location %}
14+
from <a href="http://maps.google.com/?q={{ user.location }}">{{ user.location }}</a><br>
15+
{% endif %}
16+
</p>
2417
{% endif %}
2518
{% if current_user.is_administrator() %}
26-
<a class="btn btn-danger" href="{{ url_for('.edit_profile_admin', id=user.id) }}">Edit Profile [Admin]</a>
19+
<p><a href="mailto:{{ user.email }}">{{ user.email }}</a></p>
2720
{% endif %}
28-
</p>
21+
{% if user.about_me %}<p>{{ user.about_me }}</p>{% endif %}
22+
<p>Member since {{ moment(user.member_since).format('L') }}. Last seen {{ moment(user.last_seen).fromNow() }}.</p>
23+
<p>
24+
{% if user == current_user %}
25+
<a class="btn btn-default" href="{{ url_for('.edit_profile') }}">Edit Profile</a>
26+
{% endif %}
27+
{% if current_user.is_administrator() %}
28+
<a class="btn btn-danger" href="{{ url_for('.edit_profile_admin', id=user.id) }}">Edit Profile [Admin]</a>
29+
{% endif %}
30+
</p>
31+
</div>
2932
</div>
3033
{% endblock %}

tests/test_user_model.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,20 @@ def test_ping(self):
156156
last_seen_before = u.last_seen
157157
u.ping()
158158
self.assertTrue(u.last_seen > last_seen_before)
159+
160+
def test_gravatar(self):
161+
u = User(email='[email protected]', password='cat')
162+
with self.app.test_request_context('/'):
163+
gravatar = u.gravatar()
164+
gravatar_256 = u.gravatar(size=256)
165+
gravatar_pg = u.gravatar(rating='pg')
166+
gravatar_retro = u.gravatar(default='retro')
167+
with self.app.test_request_context('/', base_url='https://example.com'):
168+
gravatar_ssl = u.gravatar()
169+
self.assertTrue('http://www.gravatar.com/avatar/' +
170+
'd4c74594d841139328695756648b6bd6'in gravatar)
171+
self.assertTrue('s=256' in gravatar_256)
172+
self.assertTrue('r=pg' in gravatar_pg)
173+
self.assertTrue('d=retro' in gravatar_retro)
174+
self.assertTrue('https://secure.gravatar.com/avatar/' +
175+
'd4c74594d841139328695756648b6bd6' in gravatar_ssl)

0 commit comments

Comments
 (0)