text: from flask import render_template, redirect, url_for, abort, flash, request, current_app, make_response
  from flask_login import login_required, current_user
  from . import main
  from .forms import EditProfileForm, EditProfileAdminForm, PostForm, CommentForm
  from .. import db
  from ..models import Role, User, Post, Permission, Comment
  from ..decorators import admin_required, permission_required
  
  @main.route('/shutdown')
  def server_shutdown():
      if not current_app.testing:
          abort(404)
      shutdown = request.environ.get('werkzeug.server.shutdown')
      if not shutdown:
          abort(500)
      shutdown()
  
      return 'Shutting down...'
  
  @main.route('/', methods=['GET', 'POST'])
  def index():
      form = PostForm()
      if current_user.can(Permission.WRITE) and form.validate_on_submit():
          post = Post(body=form.body.data, author=current_user._get_current_object())
          db.session.add(post)
          db.session.commit()
          return redirect(url_for('.index'))
  
      page = request.args.get('page', 1, type=int)  # 在访问某个页码代表的网页时，需要的url为
      # http://127.0.0.1:5000/?page=1
      # 前半段是将所有的博文按照时间戳降序排列，后半段的paginate()
      # 函数中，第一个参数page是必须的参数，我们可以这样理解：以上的这段代码返回了一个Paginate()
      # 对象，
      # 对pagination变量的赋值将所有的对象按时间排序赋给pagination
      pagination = Post.query.order_by(Post.timestamp.desc()).paginate(
          page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
          error_out=False)  # per_page表示每页显示的记录数量，未指定则默认为20
      show_followed = False
      if current_user.is_authenticated:
  
          show_followed = bool(request.cookies.get('show_followed', ''))
  
      if show_followed:
  
          query = current_user.followed_posts
  
      else:
  
          query = Post.query
  
      pagination = query.order_by(Post.timestamp.desc()).paginate(
  
          page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
  
          error_out=False)
      posts = pagination.items
      return render_template('index.html', form=form, posts=posts, show_followed=show_followed,
  
                             pagination=pagination)
  
  
  @main.route('/user/<username>')
  def user(username):
  
      user = User.query.filter_by(username=username).first_or_404()
  
      page = request.args.get('page', 1, type=int)
      #   分页的内容,该语句中，request.args.get() 函数中，第一个参数为page，代表页码。
      #   在访问某个页码代表的网页时，需要的url为:http://127.0.0.1:5000/?page=1
      #  这里的page便是刚刚函数中的第一个参数。
      # 而第二个参数为默认值，当对首页进行访问的时候默认显示第二个参数所代表的页。
      # 由于第三个参数中要求page的类型为整数，所以当我们输出类似于：http://127.0.0.1:5000/?page=3.5
      #  这样page为非整数的url时，不满足type=int，所以页面会自动返回默认值所代表的那一页
      pagination = user.posts.order_by(Post.timestamp.desc()).paginate(
  
          page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
  
          error_out=False)
      #  前半段是将所有的博文按照时间戳降序排列，后半段的paginate() 函数中，第一个参数page是必须的参数
      posts = pagination.items
  
      return render_template('user.html', user=user, posts=posts,
  
                             pagination=pagination)
  
  
  @main.route('/edit-profile', methods=['GET', 'POST'])
  @login_required
  def edit_profile():
  
      form = EditProfileForm()
  
      if form.validate_on_submit():
  
          current_user.name = form.name.data
  
          current_user.location = form.location.data
  
          current_user.about_me = form.about_me.data
  
          db.session.add(current_user._get_current_object())
  
          db.session.commit()
  
          flash('Your profile has been updated.')
  
          return redirect(url_for('.user', username=current_user.username))
  
      form.name.data = current_user.name
  
      form.location.data = current_user.location
  
      form.about_me.data = current_user.about_me
  
      return render_template('edit_profile.html', form=form)
  
  
  @main.route('/edit-profile/<int:id>', methods=['GET', 'POST'])
  @login_required
  @admin_required
  def edit_profile_admin(id):
      user = User.query.get_or_404(id)
      form = EditProfileAdminForm(user=user)
      if form.validate_on_submit():
          user.email = form.email.data
          user.username = form.username.data
          user.confirmed = form.confirmed.data
          user.role = Role.query.get(form.role.data)
          user.name = form.name.data
          user.location = form.location.data
          user.about_me = form.about_me.data
          db.session.add(user)
          db.session.commit()
          flash('The profile has been updated.')
          return redirect(url_for('.user', username=user.username))
      form.email.data = user.email
      form.username.data = user.username
      form.confirmed.data = user.confirmed
      form.role.data = user.role_id
      form.name.data = user.name
      form.location.data = user.location
      form.about_me.data = user.about_me
      return render_template('edit_profile.html', form=form, user=user)
  
  #  用户点击submit按钮提交→数据库根据提交的内容进行更新 → 跳转到-1页(请求最后一页) →
  #  当加载-1页的时候重新计算页数(因为加载-1页代表有新评论) → 分页、渲染。
  
  @main.route('/post/<int:id>', methods=['GET', 'POST'])
  def post(id):
  
      post = Post.query.get_or_404(id)
  
      form = CommentForm()
  
      if form.validate_on_submit():
  
          comment = Comment(body=form.body.data,
  
                            post=post,
  
                            author=current_user._get_current_object())
  
          db.session.add(comment)
  
          db.session.commit()
  
          flash('Your comment has been published.')
  
          return redirect(url_for('.post', id=post.id, page=-1))
  
      page = request.args.get('page', 1, type=int)
  
      if page == -1:
  
          page = (post.comments.count() - 1) // \
                 current_app.config['FLASKY_COMMENTS_PER_PAGE'] + 1
  
      pagination = post.comments.order_by(Comment.timestamp.asc()).paginate(
  
          page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
  
          error_out=False)
  
      comments = pagination.items
  
      return render_template('post.html', posts=[post], form=form,
  
                             comments=comments, pagination=pagination)
  
  
  @main.route('/edit/<int:id>', methods=['GET', 'POST'])
  @login_required
  def edit(id):
      post = Post.query.get_or_404(id)
      if current_user != post.author and \
              not current_user.can(Permission.ADMIN):
          abort(403)
      form = PostForm()
      if form.validate_on_submit():
          post.body = form.body.data
          db.session.add(post)
          db.session.commit()
          flash('The post has been updated.')
          return redirect(url_for('.post', id=post.id))
      form.body.data = post.body
      return render_template('edit_post.html', form=form)
  
  # 用户点击关注按钮后执行/follow/<username>路由
  @main.route('/follow/<username>')
  @login_required
  @permission_required(Permission.FOLLOW)
  def follow(username):
  
      user = User.query.filter_by(username=username).first()
  
      if user is None:
  
          flash('Invalid user.')
  
          return redirect(url_for('.index'))
  
      if current_user.is_following(user):
  
          flash('你已经关注过.')
  
          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))
  
  # 用户点击取消关注按钮后执行/unfollow/<username>路由
  @main.route('/unfollow/<username>')
  @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))
  
  # 用户点击关注者数量后调用/followers/<username>
  @main.route('/followers/<username>')
  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="关注",
  
                             endpoint='.followers', pagination=pagination,
  
                             follows=follows)
  
  # 用户点击粉丝数量后调用/followed/<username>
  @main.route('/followed-by/<username>')
  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)
  
  
  @main.route('/all')
  @login_required
  def show_all():
      # cookies只能在响应中设置，需要用make_response创建响应对象
      resp = make_response(redirect(url_for('.index')))
  
      resp.set_cookie('show_followed', '', max_age=30*24*60*60)
  
      return resp
  
  
  @main.route('/followed')
  @login_required
  def show_followed():
  
      resp = make_response(redirect(url_for('.index')))
  
      resp.set_cookie('show_followed', '1', max_age=30*24*60*60)
  
      return resp
  
  
  @main.route('/moderate')
  @login_required
  @permission_required(Permission.MODERATE)
  def moderate():
  
      page = request.args.get('page', 1, type=int)
  
      pagination = Comment.query.order_by(Comment.timestamp.desc()).paginate(
  
          page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
  
          error_out=False)
  
      comments = pagination.items
  
      return render_template('moderate.html', comments=comments,
  
                             pagination=pagination, page=page)
  
  
  @main.route('/moderate/enable/<int:id>')
  @login_required
  @permission_required(Permission.MODERATE)
  def moderate_enable(id):
  
      comment = Comment.query.get_or_404(id)
  
      comment.disabled = False
  
      db.session.add(comment)
  
      db.session.commit()
  
      return redirect(url_for('.moderate',
  
                              page=request.args.get('page', 1, type=int)))
  
  
  @main.route('/moderate/disable/<int:id>')
  @login_required
  @permission_required(Permission.MODERATE)
  def moderate_disable(id):
  
      comment = Comment.query.get_or_404(id)
  
      comment.disabled = True
  
      db.session.add(comment)
  
      db.session.commit()
  
      return redirect(url_for('.moderate',
  
                              page=request.args.get('page', 1, type=int)))