예제 #1
0
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,
	)
예제 #2
0
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)
예제 #3
0
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))
예제 #4
0
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))
예제 #5
0
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,
	)
예제 #6
0
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")
예제 #7
0
def get_avatar(filename):
	"""
	获取头像
	:param filename: 头像名字
	"""
	logger.info('获取头像的名称,filename = ' + str(filename))
	return send_from_directory(current_app.config["AVATARS_SAVE_PATH"], filename)
예제 #8
0
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)
예제 #9
0
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)
예제 #10
0
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)
예제 #11
0
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,
    )
예제 #12
0
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)
예제 #13
0
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,
    )
예제 #14
0
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,
    )
예제 #15
0
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)
예제 #16
0
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)
예제 #17
0
def logout():
	"""
	注销
	"""
	logger.info('url = ' + str(request.url))
	# 清空用户信息
	logout_user()
	flash('注销成功!', 'info')
	return redirect(url_for('main.index'))
예제 #18
0
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()
예제 #19
0
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()
예제 #20
0
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()
예제 #21
0
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()
예제 #22
0
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'))
예제 #23
0
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)
예제 #24
0
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)
예제 #25
0
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'))
예제 #26
0
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"))
예제 #27
0
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)
예제 #28
0
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)
예제 #29
0
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)
예제 #30
0
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)