Browse Source

Chapter 10: User avatars (10c)

master
T. Meissner 6 years ago
parent
commit
b2cbdefb7e
5 changed files with 61 additions and 26 deletions
  1. +7
    -0
      app/models.py
  2. +7
    -0
      app/static/styles.css
  3. +5
    -1
      app/templates/base.html
  4. +28
    -25
      app/templates/user.html
  5. +14
    -0
      tests/test_user_model.py

+ 7
- 0
app/models.py View File

@ -1,4 +1,5 @@
from datetime import datetime from datetime import datetime
import hashlib
from werkzeug.security import generate_password_hash, check_password_hash from werkzeug.security import generate_password_hash, check_password_hash
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from itsdangerous import BadSignature from itsdangerous import BadSignature
@ -168,6 +169,12 @@ class User(UserMixin, db.Model):
db.session.add(self) db.session.add(self)
db.session.commit() db.session.commit()
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()
return '{url}/{hash}?s={size}&d={default}&r={rating}'.format(
url=url, hash=hash, size=size, default=default, rating=rating)
def __repr__(self): def __repr__(self):
return '<User %r>' % self.username return '<User %r>' % self.username


+ 7
- 0
app/static/styles.css View File

@ -0,0 +1,7 @@
.profile-thumbnail {
position: absolute;
}
.profile-header {
min-height: 260px;
margin-left: 280px;
}

+ 5
- 1
app/templates/base.html View File

@ -6,6 +6,7 @@
{{ super() }} {{ super() }}
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon"> <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon"> <link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}" type="text/css">
{% endblock %} {% endblock %}
{% block navbar %} {% block navbar %}
@ -31,7 +32,10 @@
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
{% if current_user.is_authenticated %} {% if current_user.is_authenticated %}
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Account <b class="caret"></b></a>
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<img src="{{ current_user.gravatar(size=18) }}">
Account <b class="caret"></b>
</a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="{{ url_for('auth.change_password') }}">Change Password</a></li> <li><a href="{{ url_for('auth.change_password') }}">Change Password</a></li>
<li><a href="{{ url_for('auth.change_email_request') }}">Change Email</a></li> <li><a href="{{ url_for('auth.change_email_request') }}">Change Email</a></li>


+ 28
- 25
app/templates/user.html View File

@ -4,34 +4,37 @@
{% block page_content %} {% block page_content %}
<div class="page-header"> <div class="page-header">
<img class="img-rounded profile-thumbnail" src="{{ user.gravatar(size=256) }}">
<div class="profile-header">
<h1>{{ user.username }}</h1> <h1>{{ user.username }}</h1>
{% if user.name or user.location %}
<p>
{% if user.name %}
{{ user.name }}{% endif %}
{% if user.location %}from
<a href="https://maps.google.com/?q={{ user.location }}">
{{ user.location }}</a>
{% if user.name or user.location %}
<p>
{% if user.name %}
{{ user.name }}{% endif %}
{% if user.location %}from
<a href="https://maps.google.com/?q={{ user.location }}">
{{ user.location }}</a>
{% endif %}
</p>
{% endif %} {% endif %}
</p>
{% endif %}
{% if user.is_administrator %}
<p><a href="mailto:{{ user.email }}">{{ user.email }}</a></p>
{% endif %}
{% if user.about_me %}
<p>{{ user.about_me }}</p>
{% endif %}
<p>
Member since {{ moment(user.member_since).format('L') }}.
Last seen {{ moment(user.last_seen).fromNow() }}.
</p>
<p>
{% if user == current_user %}
<a class="btn btn-default" href="{{ url_for('.edit_profile') }}">Edit Profile</a>
{% if user.is_administrator %}
<p><a href="mailto:{{ user.email }}">{{ user.email }}</a></p>
{% endif %} {% endif %}
{% if current_user.is_administrator %}
<a class="btn btn-danger" href="{{ url_for('.edit_profile_admin', id=user.id) }}">Edit Profile [Admin]</a>
{% if user.about_me %}
<p>{{ user.about_me }}</p>
{% endif %} {% endif %}
</p>
<p>
Member since {{ moment(user.member_since).format('L') }}.
Last seen {{ moment(user.last_seen).fromNow() }}.
</p>
<p>
{% if user == current_user %}
<a class="btn btn-default" href="{{ url_for('.edit_profile') }}">Edit Profile</a>
{% endif %}
{% if current_user.is_administrator %}
<a class="btn btn-danger" href="{{ url_for('.edit_profile_admin', id=user.id) }}">Edit Profile [Admin]</a>
{% endif %}
</p>
</div>
</div> </div>
{% endblock %} {% endblock %}

+ 14
- 0
tests/test_user_model.py View File

@ -156,3 +156,17 @@ class UserModelTestCase(unittest.TestCase):
last_seen_before = u.last_seen last_seen_before = u.last_seen
u.ping() u.ping()
self.assertTrue(u.last_seen > last_seen_before) self.assertTrue(u.last_seen > last_seen_before)
def test_gravatar(self):
u = User(email='max@mustermann.de', password='cat')
with self.app.test_request_context('/'):
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)

Loading…
Cancel
Save