def show_tag(tag_id, order): """ 显示标签下的所有图片 :param tag_id: 标签id :param order: 排序规则 """ logger.info('url = ' + str(request.url)) # 标签 tag = Tag.query.get_or_404(tag_id) page = request.args.get("page", 1, type=int) per_page = current_app.config["ALBUMY_PHOTO_PER_PAGE"] # 规则 order_rule = "time" # 所有图片 pagination = ( Photo.query.with_parent(tag) .order_by(Photo.timestamp.desc()) .paginate(page, per_page) ) photos = pagination.items # 根据收藏人数排序 if order == "by_collects": photos.sort(key=lambda x: len(x.collectors), reverse=True) order_rule = "collects" return render_template( "main/tag.html", tag=tag, pagination=pagination, photos=photos, order_rule=order_rule, )
def reset_password(token): """ 重设密码 :param token: 点击邮件中的链接携带的token """ logger.info('url = ' + str(request.url)) # 如果用户已经登录,不需要重设密码 if current_user.is_authenticated: return redirect(url_for('main.index')) form = ResetPasswordForm() if form.validate_on_submit(): user = User.query.filter_by(email=form.email.data.lower()).first() # 用户不存在 if user is None: return redirect(url_for('main.index')) # 验证token的有效性 if validate_token(user=user, token=token, operation=Operations.RESET_PASSWORD, new_password=form.password.data): flash('密码重置成功!', 'success') return redirect(url_for('.login')) else: flash('无效或过期链接!', 'danger') # 跳转到忘记密码页面 return redirect(url_for('.forget_password')) # 重设密码 return render_template('auth/reset_password.html', form=form)
def new_comment(photo_id): """ 新的评论 :param photo_id: 图片id """ logger.info('url = ' + str(request.url)) photo = Photo.query.get_or_404(photo_id) page = request.args.get("page", 1, type=int) form = CommentForm() if form.validate_on_submit(): body = form.body.data author = current_user._get_current_object() comment = Comment(body=body, author=author, photo=photo) logger.info('用户:{}对图片:{}发表了评论:{}'.format(current_user.username, photo_id, body)) # 被回复的用户 replied_id = request.args.get("reply") if replied_id: comment.replied = Comment.query.get_or_404(replied_id) if comment.replied.author.receive_comment_notification: push_comment_notification( photo_id=photo.id, receiver=comment.replied.author ) db.session.add(comment) db.session.commit() flash("评论成功!", "success") if current_user != photo.author and photo.author.receive_comment_notification: push_comment_notification(photo_id, receiver=photo.author, page=page) flash_errors(form) return redirect(url_for(".show_photo", photo_id=photo_id, page=page))
def new_tag(photo_id): """ 新标签 :param photo_id: 图片id """ logger.info('url = ' + str(request.url)) photo = Photo.query.get_or_404(photo_id) if current_user != photo.author and not current_user.can("MODERATE"): abort(403) form = TagForm() if form.validate_on_submit(): # 添加新标签时,如果有多个标签,会以空格隔开 for name in form.tag.data.split(): # 查询,判断标签是否已经存在 tag = Tag.query.filter_by(name=name).first() # 如果不存在,则先创建标签 if tag is None: tag = Tag(name=name) logger.debug('用户:{}添加了新标签:{}'.format(current_user.username, name)) db.session.add(tag) db.session.commit() # 将标签加入到photo的标签中 if tag not in photo.tags: photo.tags.append(tag) db.session.commit() flash("标签添加成功!", "success") flash_errors(form) return redirect(url_for(".show_photo", photo_id=photo_id))
def show_photo(photo_id): """ 显示图片详细信息 :param photo_id: 图片id """ logger.info('url = ' + str(request.url)) photo = Photo.query.get_or_404(photo_id) page = request.args.get("page", 1, type=int) per_page = current_app.config["ALBUMY_COMMENT_PER_PAGE"] # 获取该图片下的所有评论 pagination = ( Comment.query.with_parent(photo) .order_by(Comment.timestamp.asc()) .paginate(page, per_page) ) comments = pagination.items comment_form = CommentForm() # 描述 description_form = DescriptionForm() # 标签 tag_form = TagForm() description_form.description.data = photo.description return render_template( "main/photo.html", photo=photo, comment_form=comment_form, description_form=description_form, tag_form=tag_form, pagination=pagination, comments=comments, )
def upload(): """ 上传图片 """ logger.info('url = ' + str(request.url)) if request.method == "POST" and "file" in request.files: # 文件对象 f = request.files.get("file") # 文件名 filename = rename_image(f.filename) # 保存 f.save(os.path.join(current_app.config["ALBUMY_UPLOAD_PATH"], filename)) # 小图 # 在resize_image函数中,会保存图片 filename_s = resize_image( f, filename, current_app.config["ALBUMY_PHOTO_SIZE"]["small"] ) # 中图 filename_m = resize_image( f, filename, current_app.config["ALBUMY_PHOTO_SIZE"]["medium"] ) # 保存图片对象 photo = Photo( filename=filename, filename_s=filename_s, filename_m=filename_m, author=current_user._get_current_object(), ) logger.info('上传文件,{},{},{}'.format(filename, filename_m, filename_s)) # 提交 db.session.add(photo) db.session.commit() return render_template("main/upload.html")
def get_avatar(filename): """ 获取头像 :param filename: 头像名字 """ logger.info('获取头像的名称,filename = ' + str(filename)) return send_from_directory(current_app.config["AVATARS_SAVE_PATH"], filename)
def register(): """ 注册 """ logger.info('url = ' + str(request.url)) # 如果用户已经登录,则直接返回主页 if current_user.is_authenticated: return redirect(url_for('main.index')) form = RegisterForm() if form.validate_on_submit(): name = form.name.data # 将邮箱转成小写,避免验证出问题 email = form.email.data.lower() username = form.username.data password = form.password.data user = User(name=name, email=email, username=username) user.set_password(password) db.session.add(user) db.session.commit() # 获取token token = generate_token(user=user, operation='confirm') # 发送验证邮箱 send_confirm_email(user=user, token=token) flash('邮件已发送,请登录邮箱验证!', 'info') return redirect(url_for('.login')) return render_template('auth/register.html', form=form)
def explore(): """ 发现,随机给出12张图片 """ logger.info('url = ' + str(request.url)) photos = Photo.query.order_by(func.random()).limit(12) return render_template("main/explore.html", photos=photos)
def login(): """ 用户登录 """ logger.info('url = ' + str(request.url)) # 如果用户已经登录,就不再需要登录,直接返回主页 if current_user.is_authenticated: return redirect(url_for('main.index')) form = LoginForm() # 登录 if form.validate_on_submit(): # 将email转成小写然后取用户数据,注册时也转成了小写 user = User.query.filter_by(email=form.email.data.lower()).first() # 用户不存在或者验证密码错误 # 取出用户数据后,调用validate_password来判断密码是否匹配,密码都是加密的 if user is not None and user.validate_password(form.password.data): # login_user是flask-login库的,用来保存用户信息 if login_user(user, form.remember_me.data): flash('登录成功!', 'info') return redirect_back() else: flash('你的账号已被禁止登录!', 'warning') return redirect(url_for('main.index')) flash('错误的邮箱或者密码,请确认后再登录!', 'warning') return render_template('auth/login.html', form=form)
def manage_photo(order): """ 管理图片,可以根据举报次数或者时间排序 :param order: 排序规则 """ logger.info('url = ' + str(request.url)) page = request.args.get("page", 1, type=int) per_page = current_app.config["ALBUMY_MANAGE_PHOTO_PER_PAGE"] # 默认是根据举报次数排序 order_rule = "flag" if order == "by_time": # 根据时间降序排序 pagination = Photo.query.order_by(Photo.timestamp.desc()).paginate( page, per_page) order_rule = "time" else: # 时间举报次数的降序排序 pagination = Photo.query.order_by(Photo.flag.desc()).paginate( page, per_page) photos = pagination.items return render_template( "admin/manage_photo.html", pagination=pagination, photos=photos, order_rule=order_rule, )
def manage_user(): """ 管理用户,根据过滤规则得到相应的用户数据 """ logger.info('url = ' + str(request.url)) # 过滤规则,默认是得到所有用户数据 filter_rule = request.args.get( "filter", "all") # 'all', 'locked', 'blocked', 'administrator', 'moderator' page = request.args.get("page", 1, type=int) per_page = current_app.config["ALBUMY_MANAGE_USER_PER_PAGE"] administrator = Role.query.filter_by(name="Administrator").first() moderator = Role.query.filter_by(name="Moderator").first() # 过滤 if filter_rule == "locked": filtered_users = User.query.filter_by(locked=True) elif filter_rule == "blocked": filtered_users = User.query.filter_by(active=False) elif filter_rule == "administrator": filtered_users = User.query.filter_by(role=administrator) elif filter_rule == "moderator": filtered_users = User.query.filter_by(role=moderator) else: # 得到所有用户数据 filtered_users = User.query pagination = filtered_users.order_by(User.member_since.desc()).paginate( page, per_page) users = pagination.items return render_template("admin/manage_user.html", pagination=pagination, users=users)
def manage_comment(order): """ 管理评论,可以根据时间或者举报次数排序 :param order: 排序规则 """ logger.info('url = ' + str(request.url)) page = request.args.get("page", 1, type=int) per_page = current_app.config["ALBUMY_MANAGE_COMMENT_PER_PAGE"] order_rule = "flag" if order == "by_time": # 根据时间排序 pagination = Comment.query.order_by(Comment.timestamp.desc()).paginate( page, per_page) order_rule = "time" else: # 根据举报次数排序 pagination = Comment.query.order_by(Comment.flag.desc()).paginate( page, per_page) comments = pagination.items return render_template( "admin/manage_comment.html", pagination=pagination, comments=comments, order_rule=order_rule, )
def index(): """ 管理员主页 """ logger.info('url = ' + str(request.url)) # 用户数量 user_count = User.query.count() # 被禁用功能用户数量 locked_user_count = User.query.filter_by(locked=True).count() # 被禁止登录用户 blocked_user_count = User.query.filter_by(active=False).count() # 图片数量 photo_count = Photo.query.count() # 图片被举报数量 reported_photos_count = Photo.query.filter(Photo.flag > 0).count() # 标签数量 tag_count = Tag.query.count() # 评论数量 comment_count = Comment.query.count() # 评论被举报数量 reported_comments_count = Comment.query.filter(Comment.flag > 0).count() return render_template( 'admin/index.html', user_count=user_count, photo_count=photo_count, tag_count=tag_count, comment_count=comment_count, locked_user_count=locked_user_count, blocked_user_count=blocked_user_count, reported_comments_count=reported_comments_count, reported_photos_count=reported_photos_count, )
def change_avatar(): """ 修改头像 """ logger.info('url = ' + str(request.url)) upload_form = UploadAvatarForm() crop_form = CropAvatarForm() return render_template('user/settings/change_avatar.html', upload_form=upload_form, crop_form=crop_form)
def get_image(filename): """ 获取图片 :param filename: 图片名字 :return: 返回图片的url """ logger.info('url = ' + str(request.url)) logger.info('获取图片的名称,filename = ' + str(filename)) return send_from_directory(current_app.config["ALBUMY_UPLOAD_PATH"], filename)
def logout(): """ 注销 """ logger.info('url = ' + str(request.url)) # 清空用户信息 logout_user() flash('注销成功!', 'info') return redirect(url_for('main.index'))
def block_user(user_id): """ 禁止登录 :param user_id: 用于id """ logger.info('url = ' + str(request.url)) user = User.query.get_or_404(user_id) user.block() flash("Account blocked.", "info") return redirect_back()
def unlock_user(user_id): """ 解除禁用 :param user_id: 用户id """ logger.info('url = ' + str(request.url)) user = User.query.get_or_404(user_id) user.unlock() flash("Lock canceled.", "info") return redirect_back()
def delete_tag(tag_id): """ 删除标签 :param tag_id: 标签id """ logger.info('url = ' + str(request.url)) tag = Tag.query.get_or_404(tag_id) db.session.delete(tag) db.session.commit() flash("Tag deleted.", "info") return redirect_back()
def lock_user(user_id): """ 禁用用户,停止使用某些功能 :param user_id: :return: """ logger.info('url = ' + str(request.url)) user = User.query.get_or_404(user_id) user.lock() flash("Account locked.", "info") return redirect_back()
def change_email(token): """ 修改邮箱 :param token: 从邮箱中点击链接携带的token """ logger.info('url = ' + str(request.url)) if validate_token(user=current_user, token=token, operation=Operations.CHANGE_EMAIL): flash('邮箱更新成功!', 'success') return redirect(url_for('.index', username=current_user.username)) else: flash('无效或过期的token!', 'warning') return redirect(url_for('.change_email_request'))
def show_following(username): """ 显示username用户所有关注的用户 :param username: 用户名 """ logger.info('url = ' + str(request.url)) user = User.query.filter_by(username=username).first_or_404() page = request.args.get('page', 1, type=int) per_page = current_app.config['ALBUMY_USER_PER_PAGE'] pagination = user.following.paginate(page, per_page) follows = pagination.items return render_template('user/following.html', user=user, pagination=pagination, follows=follows)
def change_password(): """ 修改密码 """ logger.info('url = ' + str(request.url)) form = ChangePasswordForm() if form.validate_on_submit() and current_user.validate_password(form.old_password.data): current_user.set_password(form.password.data) db.session.commit() flash('密码修改成功!', 'success') return redirect(url_for('.index', username=current_user.username)) return render_template('user/settings/change_password.html', form=form)
def resend_confirm_email(): """ 重新发送验证邮件 """ logger.info('url = ' + str(request.url)) if current_user.confirmed: return redirect(url_for('main.index')) token = generate_token(user=current_user, operation=Operations.CONFIRM) send_confirm_email(user=current_user, token=token) flash('新邮件已发送,请登录邮箱验证!', 'info') return redirect(url_for('main.index'))
def read_all_notification(): """ 一键已读所有消息 """ logger.info('url = ' + str(request.url)) # 遍历登录用户的所有消息 for notification in current_user.notifications: # 设置为True notification.is_read = True db.session.commit() flash("所有消息已读!", "success") return redirect(url_for(".show_notifications"))
def show_collections(username): """ 显示所有收藏的图片 :param username: 用户名 """ logger.info('url = ' + str(request.url)) user = User.query.filter_by(username=username).first_or_404() page = request.args.get('page', 1, type=int) per_page = current_app.config['ALBUMY_PHOTO_PER_PAGE'] # 所有收藏的数据 pagination = Collect.query.with_parent(user).order_by(Collect.timestamp.desc()).paginate(page, per_page) collects = pagination.items return render_template('user/collections.html', user=user, pagination=pagination, collects=collects)
def manage_tag(): """ 管理标签 """ logger.info('url = ' + str(request.url)) page = request.args.get("page", 1, type=int) per_page = current_app.config["ALBUMY_MANAGE_TAG_PER_PAGE"] # 根据标签id排序 pagination = Tag.query.order_by(Tag.id.desc()).paginate(page, per_page) tags = pagination.items return render_template("admin/manage_tag.html", pagination=pagination, tags=tags)
def privacy_setting(): """ 隐私设置 """ logger.info('url = ' + str(request.url)) form = PrivacySettingForm() if form.validate_on_submit(): current_user.public_collections = form.public_collections.data db.session.commit() flash('设置更新成功!', 'success') return redirect(url_for('.index', username=current_user.username)) form.public_collections.data = current_user.public_collections return render_template('user/settings/edit_privacy.html', form=form)
def delete_account(): """ 删除账号 """ logger.info('url = ' + str(request.url)) form = DeleteAccountForm() if form.validate_on_submit(): # 删除当前账号 db.session.delete(current_user._get_current_object()) db.session.commit() flash('账号已删除,如想再次加入,请重新注册!', 'success') return redirect(url_for('main.index')) return render_template('user/settings/delete_account.html', form=form)