class File(db.Model): id = db.Column(db.Integer, primary_key=True) filename = db.Column(db.String(120), index=True) md5 = db.Column(db.String(50), index=True) def __init__(self, file): self.file = file self.md5 = self.calc_md5(file) @staticmethod def calc_md5(file): file.seek(0) m = hashlib.md5() while True: data = file.read(8192) if not data: break m.update(data) md5 = m.hexdigest() return md5 def save_file(self): self.file.seek(0) self.file.save(os.path.join(oj.config['UPLOAD_FOLDER'], self.md5)) def get_file_path(self): return os.path.join(oj.config["UPLOAD_FOLDER"], self.md5) def save(self): db.session.add(self) db.session.commit()
class Article(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(80)) content = db.Column(db.Text) user_id = db.Column(db.Integer, db.ForeignKey("user.id"), index=True) user = db.relationship("User", backref=db.backref("articles", lazy='dynamic')) public_time = db.Column(db.Integer) # googbye at 2038-1-19 update_time = db.Column(db.Integer) sort_time = db.Column(db.Integer, index=True) tags = db.relationship('ArticleTag', secondary=tags_table, backref=db.backref('articles', lazy='dynamic')) comments_num = db.Column(db.Integer) allow_comment = db.Column(db.Boolean) def __init__(self, title, content, user, allow_comment=True, public_time=None): if not public_time: public_time = int(time.time()) self.title = title self.content = content self.user = user self.public_time = public_time self.update_time = public_time self.sort_time = public_time self.comments_num = 0 self.allow_comment = allow_comment def __repr__(self): return "<Article %r>" % self.title def save(self): db.session.add(self) db.session.commit() def delete(self): db.session.delete(self) db.session.commit() def is_allowed_edit(self, user=None): if not user: return False if user.id == self.user_id: return True if user.have_privilege(6): return True return False
class ArticleTag(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), index=True) def __init__(self, name): self.name = name def __repr__(self): return "<ArticleTag %r>" % self.name def save(self): db.session.add(self) db.session.commit()
class Session(db.Model): id = db.Column(db.String(120), primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey("user.id"), index=True) user = db.relationship("User", backref=db.backref("sessions", lazy='dynamic')) login_time = db.Column(db.Integer) # googbye at 2038-1-19 expiration_time = db.Column(db.Integer) def __init__(self, user, login_time=None, valid_time=3600 * 24 * 7): if not login_time: login_time = int(time.time()) self.id = str(randint(1, int(1e50))) self.user = user self.login_time = login_time self.expiration_time = login_time + valid_time def __repr__(self): print("<Session_id %r User_id %r" % (self.id, self.user_id)) def save(self): db.session.add(self) db.session.commit() def delete(self): db.session.delete(self) db.session.commit() def is_valid(self, now=None): # print "now:%r expiration_tim:%r" % (now,self.expiration_time) if not now: now = int(time.time()) if now < self.expiration_time: return True else: self.delete() return False
class Contest(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(80)) start_time = db.Column(db.Integer) # goodbye at 2038-1-19 end_time = db.Column(db.Integer) holder_id = db.Column(db.Integer, db.ForeignKey("user.id"), index=True) holder = db.relationship("User", backref=db.backref("hold_contests", lazy='dynamic')) information = db.Column(db.Text) # save use text represent problems id,split by "|" # for example use "2|23|123" represent this contest use problems which id equal 2\23 or 123 problems = db.Column(db.Text) ranklist_id = db.Column(db.Integer, db.ForeignKey("contest_ranklist.id"), index=True) ranklist = db.relationship("ContestRanklist", backref=db.backref("contests", lazy="dynamic")) def __init__(self, title, start_time, end_time, holder): self.title = title self.start_time = start_time self.end_time = end_time self.holder = holder ranklist = ContestRanklist() self.ranklist = ranklist def __repr__(self): return "<Contest %r>" % self.title def save(self): db.session.add(self) db.session.commit() def is_allowed_edit(self, user=None): if user and user.have_privilege(4): return True if user and user.id == self.holder.id: return True return False def new_submission(self, judge): problems = self.get_problems() if judge.problem not in problems: pass return False player = self.players.filter_by(user_id=judge.user_id).first() if not player: player = ContestPlayer(self.id, judge.user_id) player.update_score(judge.problem, judge.score, judge.id) player.save() self.ranklist.update(player) self.ranklist.save() def is_running(self, now=None): if not now: now = int(time.time()) return self.start_time <= now and now <= self.end_time def get_ranklist(self): return self.ranklist.ranklist def get_problems(self): if not self.problems: return [] problems = [] for pid in self.problems.split('|'): pid = int(pid) problems.append(Problem.query.filter_by(id=int(pid)).first()) return problems def set_problems(self, problems_list): self.problems = "" for pid in problems_list: if Problem.query.filter_by(id=pid).first(): if self.problems: self.problems += '|' self.problems += str(pid) else: pass
class Problem(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(80), index=True) user_id = db.Column(db.Integer, db.ForeignKey("user.id"), index=True) user = db.relationship("User", backref=db.backref("upload_problems", lazy='dynamic')) description = db.Column(db.Text) input_format = db.Column(db.Text) output_format = db.Column(db.Text) example = db.Column(db.Text) limit_and_hint = db.Column(db.Text) time_limit = db.Column(db.Integer) memory_limit = db.Column(db.Integer) testdata_id = db.Column(db.Integer, db.ForeignKey("file.id")) testdata = db.relationship("File", backref=db.backref('problems', lazy='dynamic')) tags = db.relationship('ProblemTag', secondary=tags_table, backref=db.backref('problems', lazy='dynamic')) ac_num = db.Column(db.Integer) submit_num = db.Column(db.Integer) is_public = db.Column(db.Boolean) def __init__(self, title, user, description="", input_format="", output_format="", example="", limit_and_hint="", time_limit=1000, memory_limit=128 ): self.title = title self.user = user self.description = description self.input_format = input_format self.output_format = output_format self.example = example self.limit_and_hint = limit_and_hint self.time_limit = time_limit self.memory_limit = memory_limit self.ac_num = 0 self.submit_num = 0 self.is_public = False def __repr__(self): return "<Problem %r>" % self.title def save(self): db.session.add(self) db.session.commit() def update(self, title=None, description=None, input_format=None, output_format=None, example=None, limit_and_hint=None): self.title = title self.description = description self.input_format = input_format self.output_format = output_format self.example = example self.limit_and_hint = limit_and_hint def update_testdata(self, file): self.testdata = File(file) self.testdata.filename = "test_data_%d.zip" % self.id self.testdata.save_file() self.testdata.save() def is_allowed_edit(self, user=None): if not user: return False if self.user_id == user.id or user.have_privilege(2): return True return False def is_allowed_use(self, user=None): if self.is_public: return True if not user: return False if self.user_id == user.id or user.have_privilege(3) or user.have_privilege(2): return True return False def set_is_public(self, public): self.is_public = public self.save()
class JudgeState(db.Model): id = db.Column(db.Integer, primary_key=True) code = db.Column(db.Text) language = db.Column(db.String(20)) status = db.Column(db.String(50), index=True) score = db.Column(db.Integer, index=True) result = db.Column(db.Text) user_id = db.Column(db.Integer, db.ForeignKey("user.id"), index=True) user = db.relationship("User", backref=db.backref("submit", lazy='dynamic')) problem_id = db.Column(db.Integer, db.ForeignKey("problem.id"), index=True) problem = db.relationship("Problem", backref=db.backref("submit", lazy='dynamic')) submit_time = db.Column(db.Integer) # googbye at 2038-1-19 # "type" indicate it's contest's submission(type = 1) or normal submission(type = 0) # type=2: this is a test submission # if it's contest's submission (type = 1), the type_info is contest_id # use this way represent because it's easy to expand type = db.Column(db.Integer) type_info = db.Column(db.Integer) def __init__(self, code, language, user, problem, type=0, type_info=None, submit_time=None): if not submit_time: submit_time = int(time.time()) self.code = code self.language = language self.user = user self.problem = problem self.submit_time = submit_time self.type = type self.type_info = type_info self.score = 0 self.status = "Waiting" self.result = '{"status": "Waiting", "total_time": 0, "total_memory": 0, "score":0, "case_num": 0}' def __repr__(self): print("<JudgeState %r>" % self.id) def save(self): db.session.add(self) db.session.commit() def is_allowed_see_result(self, user=None): if user and user.id == self.problem.user.id: return True if self.type == 0: if not self.problem.is_public: if user and (user.have_privilege(2) or user.have_privilege(3)): return True return False return True elif self.type == 1: if user and user.have_privilege(4): return True contest = Contest.query.filter_by(id=self.type_info).first() if contest.is_running(): return False else: return True elif self.type == 2: if user and (user.have_privilege(2) or user.have_privilege(3) or self.user == user.id): return True else: return False return False def is_allowed_see_code(self, user=None): if user and user.id == self.problem.user.id: return True if self.type == 0: if not self.problem.is_public: if user and (user.have_privilege(2) or user.have_privilege(3)): return True return False return True elif self.type == 1: if user and user.have_privilege(4): return True contest = Contest.query.filter_by(id=self.type_info).first() if contest.is_running(): if user and self.user == user: return True else: return False else: return True elif self.type == 2: if user and (user.have_privilege(2) or user.have_privilege(3) or self.user == user.id): return True else: return False return False def get_result(self): return json.loads(self.result) def update_result(self, result): self.score = result["score"] self.status = result["status"] self.result = json.dumps(result) def update_related_info(self): if self.type == 0: self.user.refresh_submit_info() self.user.save() self.problem.submit_num += 1 if self.status == "Accepted": self.problem.ac_num += 1 self.problem.save() elif self.type == 1: contest = Contest.query.filter_by(id=self.type_info).first() contest.new_submission(self) # only normal submittion is counted def update_userac_info(self): if self.type == 0: all_user_ac = UserAcProblem.query.filter_by( user_id=self.user.id).all() for ac_info in all_user_ac: if ac_info.problem_id == self.problem.id: if ac_info.is_accepted and self.status != "Accepted": return new_ac_info = UserAcProblem(user_id=ac_info.user_id, problem_id=ac_info.problem_id, judge_id=self.id) ac_info.delete() if self.status == "Accepted": new_ac_info.is_accepted = True else: new_ac_info.is_accepted = False new_ac_info.save() return new_ac_info = UserAcProblem(user_id=self.user.id, problem_id=self.problem.id, judge_id=self.id) if self.status == "Accepted": new_ac_info.is_accepted = True else: new_ac_info.is_accepted = False new_ac_info.save() return
class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, index=True) email = db.Column(db.String(120)) password = db.Column(db.String(120)) nickname = db.Column(db.String(80), index=True) nameplate = db.Column(db.Text) information = db.Column(db.Text) ac_num = db.Column(db.Integer, index=True) submit_num = db.Column(db.Integer) is_admin = db.Column(db.Boolean) def get_gravatar_url(self, size=40): url = "http://cn.gravatar.com/avatar/" + hashlib.md5(self.email.lower()).hexdigest() + "?" url += urllib.urlencode({'d': 'mm', 's': str(size)}) return url def __init__(self, username, password, email): self.username = username self.password = password self.email = email self.nickname = username self.is_admin = False self.ac_num = 0 self.submit_num = 0 def __repr__(self): return "<User:%r password:%r email:%r>" % (self.username, self.password, self.email) def save(self): db.session.add(self) db.session.commit() def have_privilege(self, privilege_type): for privilege in UserPrivilege.query.filter_by(user_id = self.id).all(): if privilege.privilege_type == privilege_type or privilege.privilege_type == 1: return True return False def is_allowed_edit(self, user): if not user: return False if self.id == user.id or user.have_privilege(7): return True return False def get_submitted_problems(self): submitted_problems = dict() for ac_info in UserAcProblem.query.filter_by(user_id = self.id).all(): submitted_problems[ac_info.problem_id] = [ac_info.is_accepted, ac_info.judge_id] return submitted_problems def refresh_submit_info(self): cnt = 0 for ac_info in UserAcProblem.query.filter_by(user_id = self.id).all(): if ac_info.is_accepted: cnt += 1 self.ac_num = cnt @staticmethod def get_cur_user(session_id=None): if not session_id: session_id = request.cookies.get('session_id') sessions = Session.query.filter_by(id=session_id).all() for s in sessions: if s.is_valid(): return s.user return None @staticmethod def find_user(nickname=None, id=None): if id: return User.query.filter_by(id=id).first() if nickname: return User.query.filter_by(nickname=nickname).first() return None def give_privilege(self, privilege_type): for privilege in UserPrivilege.query.filter_by(user_id = self.id).all(): if privilege.privilege_type == privilege_type: return False # User already had privilege new_privilege = UserPrivilege(user_id = self.id, privilege_type = privilege_type) new_privilege.save() return True def del_privilege(self, privilege_type): for privilege in UserPrivilege.query.filter_by(user_id = self.id).all(): if privilege.privilege_type == privilege_type: privilege.delete() return True return False # User doesnt have privilege