From f35793218a9436dd6ae0d2a3a29b9c3db8843ad3 Mon Sep 17 00:00:00 2001
From: tmeissner
Date: Sat, 24 Nov 2018 01:13:23 +0100
Subject: [PATCH] Chapter 12: Followers in the application (12b)
---
app/main/views.py | 70 +++++++++++++++++++++++++++++++++++-
app/static/styles.css | 3 ++
app/templates/followers.html | 27 ++++++++++++++
app/templates/user.html | 21 +++++++++++
config.py | 1 +
5 files changed, 121 insertions(+), 1 deletion(-)
create mode 100644 app/templates/followers.html
diff --git a/app/main/views.py b/app/main/views.py
index 1ee95b6..cbbadb0 100644
--- a/app/main/views.py
+++ b/app/main/views.py
@@ -5,7 +5,7 @@ from . import main
from .forms import EditProfileForm, EditProfileAdminForm, PostForm
from .. import db
from ..models import User, Role, Permission, Post
-from ..decorators import admin_required
+from ..decorators import admin_required, permission_required
@main.route('/', methods=['GET', 'POST'])
@@ -106,3 +106,71 @@ def edit(id):
return redirect(url_for('.post', id=post.id))
form.body.data = post.body
return render_template('edit_post.html', form=form)
+
+
+@main.route('/follow/')
+@login_required
+@permission_required(Permission.FOLLOW)
+def follow(username):
+ user = User.query.filter_by(username=username).first()
+ if user is None:
+ flash('Invalud user')
+ return redirect(url_for('.index'))
+ if current_user.is_following(user):
+ flash('You are already follwoing this user.')
+ return redirect(url_for('.user', username=username))
+ current_user.follow(user)
+ db.session.commit()
+ flash('You are now following %s' % username)
+ return redirect(url_for('.user', username=username))
+
+
+@main.route('/unfollow/')
+@login_required
+@permission_required(Permission.FOLLOW)
+def unfollow(username):
+ user = User.query.filter_by(username=username).first()
+ if user is None:
+ flash('Invalid user')
+ return redirect(url_for('.index'))
+ if not current_user.is_following(user):
+ flash('You are not following this user.')
+ return redirect(url_for('.user', username=username))
+ current_user.unfollow(user)
+ db.session.commit()
+ flash('You are not following %s anymore' % username)
+ return redirect(url_for('.user', username=username))
+
+
+@main.route('/followers/')
+def followers(username):
+ user = User.query.filter_by(username=username).first()
+ if user is None:
+ flash('Invalid user')
+ return redirect(url_for('.index'))
+ page = request.args.get('page', 1, type=int)
+ pagination = user.followers.paginate(
+ page, per_page=current_app.config['FLASKY_FOLLOWERS_PER_PAGE'],
+ error_out=False)
+ follows = [{'user': item.follower, 'timestamp': item.timestamp}
+ for item in pagination.items]
+ return render_template('followers.html', user=user, title="Followers of",
+ endpoint='.followers', pagination=pagination,
+ follows=follows)
+
+
+@main.route('/followed-by/')
+def followed_by(username):
+ user = User.query.filter_by(username=username).first()
+ if user is None:
+ flash('Invalid user')
+ return redirect(url_for('.index'))
+ page = request.args.get('page', 1, type=int)
+ pagination = user.followed.paginate(
+ page, per_page=current_app.config['FLASKY_FOLLOWERS_PER_PAGE'],
+ error_out=False)
+ follows = [{'user': item.followed, 'timestamp': item.timestamp}
+ for item in pagination.items]
+ return render_template('followers.html', user=user, title="Followed by",
+ endpoint='.followed_by', pagination=pagination,
+ follows=follows)
diff --git a/app/static/styles.css b/app/static/styles.css
index 32fd714..7084ad1 100644
--- a/app/static/styles.css
+++ b/app/static/styles.css
@@ -63,3 +63,6 @@ div.flask-pagedown-preview {
.post-body h3 {
font-size: 120%;
}
+.table.followers tr {
+ border-bottom: 1px solid #e0e0e0;
+}
diff --git a/app/templates/followers.html b/app/templates/followers.html
new file mode 100644
index 0000000..c5dbbb1
--- /dev/null
+++ b/app/templates/followers.html
@@ -0,0 +1,27 @@
+{% extends "base.html" %}
+{% import "_macros.html" as macros %}
+
+{% block title %}Flasky - {{ title }} {{ user.username }}{% endblock %}
+
+{% block page_content %}
+
+
+
+{% endblock %}
diff --git a/app/templates/user.html b/app/templates/user.html
index 4acddaa..548b437 100644
--- a/app/templates/user.html
+++ b/app/templates/user.html
@@ -29,6 +29,27 @@
Last seen {{ moment(user.last_seen).fromNow() }}.
{{ user.posts.count() }} blog post{% if user.posts.count() > 1 %}s{% endif %}.
+
+ {% if current_user.can(Permission.FOLLOW) and user != current_user %}
+ {% if not current_user.is_following(user) %}
+ Follow
+ {% else %}
+ Unfollow
+ {% endif %}
+ {% endif %}
+
+ Followers: {{ user.followers.count() }}
+
+
+ Following: {{ user.followed.count() }}
+
+ {% if current_user.is_authenticated and user != current_user and
+ user.is_following(current_user) %}
+ | Follows you
+ {% endif %}
+
{% if user == current_user %}
Edit Profile
diff --git a/config.py b/config.py
index 0503a70..7094673 100644
--- a/config.py
+++ b/config.py
@@ -15,6 +15,7 @@ class Config:
FLASKY_ADMIN = os.environ.get('FLASKY_ADMIN')
SQLALCHEMY_TRACK_MODIFICATIONS = False
FLASKY_POSTS_PER_PAGE = 20
+ FLASKY_FOLLOWERS_PER_PAGE = 50
@staticmethod
def init_app(app):