from flask import Flask, request, render_template, send_from_directory, abort, redirect, session from flask_sqlalchemy import SQLAlchemy from flask_limiter import Limiter from flask_limiter.util import get_remote_address import re import random from datetime import datetime from dateutil.tz import tzlocal import html2text from config_fudan import C app = Flask(__name__) app.config.from_object('config_fudan.C') app.secret_key = C.session_key limiter = Limiter( app, key_func=get_remote_address, default_limits=["50 / minute"], ) db = SQLAlchemy(app) class Candidate(db.Model): id = db.Column(db.Integer, primary_key=True) content = db.Column(db.String(4000)) private = db.Column(db.String(1000)) time = db.Column(db.DateTime) likeNum = db.Column(db.Integer, default=0) # always increment 1 for the id of a new record __table_args__ = { 'sqlite_autoincrement': True } class Like(db.Model): id = db.Column(db.Integer, primary_key=True) cid = db.Column(db.Integer) # (member) id of class Candidate uid = db.Column(db.Integer) # id of user db.create_all() @app.route('/img/') def send_img(path): return send_from_directory('static/img', path) @app.route('/ordinary/set_session') @limiter.limit("2 / hour; 1 / 5 minute") def set_session(): if 'uid' not in session: session['uid'] = random.randint(0, 2000000000) session.permanent = True return redirect('.') @app.route('/ordinary/') def can_list(): key = request.args.get('key') sort_by = request.args.get('sort_by', 'time') if 'uid' not in session: return redirect('set_session') uid = session['uid'] q = Candidate.query q = q.order_by(db.desc('likeNum')) if sort_by=='likeNum' else q.order_by(db.desc('id')) pag = q.paginate(max_per_page=100) def check_like(c): c.liked = 'liked' if Like.query.filter_by(uid=uid, cid=c.id).count() else 'like' return c pag.items = map(check_like, pag.items) vs = [{ 'name': name, 'ques': ques, 'hint': hint } for name, ques, hint, ans in C.verify ] return render_template('list.html', pagination=pag, vs=vs, showPrivate=(key==C.key), sort_by=sort_by, key=key, text1=C.text1, text2=C.text2) @app.route('/ordinary/new', methods=['POST']) @limiter.limit("5 / hour; 1 / 2 second") def new_one(): content = request.form.get('text') private = request.form.get('privateText') for name, ques, hint, ans in C.verify: if request.form.get(name) != ans: return ''' 错误

验证问题回答错误

回退 ''', 401 if not content or len(content)>4000: abort(422) if private and len(private)>1000: abort(422) if not Candidate.query.filter_by(content=content).first(): c = Candidate( content=content, private=private, time=datetime.now() ) db.session.add(c) db.session.commit() return redirect(".") @limiter.limit("100 / hour") @app.route('/ordinary//like', methods=['POST']) def like(id): c = Candidate.query.get(id) if not c: abort(404) uid = session['uid'] if not uid: abort(401) if Like.query.filter_by(uid=uid, cid=id).first(): return '点赞过了', 403 l = Like(uid=uid, cid=id) c.likeNum += 1 db.session.add(l) db.session.commit() return str(c.likeNum) @app.route('/ordinary//delete', methods=['POST']) def delete(id): key = request.form.get('key') if key != C.key: abort(401) c = Candidate.query.get(id) if not c: abort(404) db.session.delete(c) db.session.commit() return redirect('..') if __name__ == '__main__': app.run(debug=True)