def NewSubmission(problem_id=0, contest_id=0, type='problem_submission'): code, language = request.form['code'], request.form['lang'] submitter = modules.GetCurrentOperator() submit_time = datetime.datetime.now().strftime('%Y.%m.%d %H:%M:%S') if submitter == None: return {'success': False, 'message': '请先登录'} if len(code.strip()) == 0: return {'success': False, 'message': '你这么短?emmm....'} if len(code) > config.config['limits']['max_code_length'] * 1024: return { 'success': False, 'message': '代码过长(代码长度限制为 %d KB)' % config.config['limits']['max_code_length'] } id = db.Execute('SELECT MAX(id) FROM submissions')[0]['MAX(id)'] id = 1 if id == None else int(id) + 1 db.Execute( 'INSERT INTO submissions(id,problem_id,contest_id,type,submitter,submit_time,language,code,detail) VALUES(%s,%s,%s,%s,%s,%s,%s,%s,"{}")', (id, problem_id, contest_id, type, submitter, submit_time, language, code)) redis = reedis.NewConnection() redis.rpush('intoj-waiting-judge', id) return {'success': True, 'message': '提交成功', 'submission_id': id}
def UserEditRun(username): userinfo = GetUserInfo(username) if userinfo == None: return modules.RedirectBack('无此用户') username = userinfo['username'] operator = modules.GetCurrentOperator() if operator == None: return modules.RedirectBack('请先登录') if operator != username and not modules.CheckPrivilege(operator,'user_manager'): return modules.RedirectBack('无此权限') if request.method == 'GET': return render_template('useredit.html',user=userinfo) else: if not modules.ValidatePassword(operator,request.form['password'])['success']: return modules.RedirectBack('密码错误(密码应是当前登录的用户的密码)') if len(request.form['realname']) > 16: return modules.RedirectBack('真实姓名过长(限制为 16 字符)') if not modules.IsVaildUsername(request.form['realname']): return modules.RedirectBack('真实姓名中不能包含特殊符号') if len(request.form['new_password'].strip()) != 0: new_password = request.form['new_password'].strip() if new_password != request.form['repeat_new_password'].strip(): return modules.RedirectBack('「新密码」与「确认新密码」不符') salt = db.Execute('SELECT salt FROM users WHERE username=%s',username)[0]['salt'] new_password_hash = hashlib.sha256(("intoj"+new_password+salt).encode('utf-8')).hexdigest() db.Execute('UPDATE users SET password=%s WHERE username=%s',(new_password_hash,username)) db.Execute('UPDATE users SET `email`=%s,`realname`=%s,`motto`=%s,`background-url`=%s WHERE username=%s', (request.form['email'],request.form['realname'],request.form['motto'],request.form['background-url'],username)) return modules.RedirectBack( ok_message = '修改成功' )
def Submit(req): is_public = 1 if req.get('is_public') != None else 0 id = req['id'] if req['id'] != '': if int(req['id']) <= 0: flash(r'编号必须为正', 'error') return render_template("problemadd.html") count = int( db.Fetchone('SELECT COUNT(*) FROM problems WHERE id=%s', req['id'])['COUNT(*)']) if count > 0: flash(r'题目编号 %s 已经有过了.', 'error') return render_template("problemadd.html") db.Execute("INSERT INTO problems VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);",(req['id'],req['title'],req['description'],req['input_format'],req['output_format'],\ req['example'],req['limit_and_hint'],req['time_limit'],req['memory_limit'],is_public)) else: id = 1 count = int(db.Fetchone('SELECT COUNT(*) FROM problems')['COUNT(*)']) if count > 0: id = int( db.Fetchone('SELECT MAX(id) FROM problems')['MAX(id)']) + 1 db.Execute("INSERT INTO problems VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);",(id,req['title'],req['description'],req['input_format'],req['output_format'],\ req['example'],req['limit_and_hint'],req['time_limit'],req['memory_limit'],is_public)) return redirect('/problem/%s' % id)
def ProblemDeleteRun(problem_id): operator = modules.GetCurrentOperator() if not modules.CheckPrivilegeOfProblem(operator, problem_id): return modules.RedirectBack(error_message='无此权限') db.Execute('DELETE FROM problems WHERE id=%s', problem_id) db.Execute('DELETE FROM submissions WHERE problem_id=%s', problem_id) os.system('rm -rf %s' % os.path.join(config.config['data_path'], str(problem_id))) flash('成功删除题目 #%d' % problem_id, 'ok') return redirect('/problems')
def GetSubmissionInfo(submission_id): res = db.Execute('SELECT * FROM submissions WHERE id=%s', submission_id) if len(res) == 0: return None res = res[0] res['length'] = len(res['code']) res['detail'] = json.loads(res['detail']) return res
def Contestadd(req): id = 1 count = int(db.Fetchone('SELECT COUNT(*) FROM contests')[0]) if count > 0: id = int(db.Fetchone('SELECT MAX(id) FROM contests')[0]) + 1 req_problems = req['problems'].split(',') problems = [] for problem in req_problems: if db.Read_Problem(problem) == None: flash(r'题目#%s不存在' % problem, 'error') return modules.Page_Back() problems.append({'id': int(problem)}) try: begin_time = datetime.datetime.strptime(req['begin_time'], date_format) end_time = datetime.datetime.strptime(req['end_time'], date_format) except: flash(r'日期格式不对. 应为 yyyy-mm-dd HH:MM:SS', 'error') return modules.Page_Back() db.Execute('INSERT INTO contests VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)', (id, req['title'], req['subtitle'], req['begin_time'], req['end_time'], req['description'], '{"type":"oi-intoj"}', request.cookies['username'], json.dumps(problems), '')) flash('添加成功', 'ok') return redirect('/contest/%d' % id)
def ProblemListRun(): per_page = config.config['site']['per_page']['problem_list'] current_page = modules.GetCurrentPage() total_page = (db.Execute('SELECT COUNT(*) FROM problems')[0]['COUNT(*)']+per_page-1) / per_page; problems = db.Execute('SELECT id,title,is_public FROM problems LIMIT %s OFFSET %s', (per_page,per_page*(current_page-1))) nowuser = modules.GetCurrentOperator() if nowuser != None: for problem in problems: latest_submission = db.Execute('SELECT * FROM submissions WHERE submitter=%s AND problem_id=%s AND status != %s \ ORDER BY status DESC, score DESC, submit_time ASC \ LIMIT 1', (nowuser,problem['id'],static.name_to_id['Skipped'])) if len(latest_submission) == 0: continue problem['submission'] = latest_submission[0] return render_template('problemlist.html',problems=problems,pageinfo={ 'per': per_page, 'tot': total_page })
def Delegate(submission_id, submission_info, testdata_path): log.Log('cyan', 'Fetching data info...') data_config = {} problem_id = submission_info['problem_id'] problems = db.Execute( 'SELECT time_limit, memory_limit FROM problems WHERE id=%s', problem_id) if len(problems) == 0: raise BaseException('题目 %d 不存在' % problem_id) data_config['time_limit'] = problems[0]['time_limit'] data_config['memory_limit'] = problems[0]['memory_limit'] data_config['data'] = GetTestdataInfo(testdata_path) print("data_config:") print(data_config) log.Log('green', 'Fetched.') log.Log('cyan', 'Validate data existence...') if data_config['data'].get('subtask', False) == False: ValidateDataExistenceWithoutSubtask(testdata_path, data_config['data']) else: ValidataDataExistenceWithSubtask(testdata_path, data_config['data']) ValidateSPJExistence(testdata_path, data_config['data']) log.Log('green', 'Validated.') return data_config
def Send_Zisheng(): if not modules.Is_Loggedin(): flash('请先登录', 'error') return False if not config.config['site']['zisheng']['enable']: flash('管理员已关闭「吱声」', 'error') return False message = request.form['message'] max_length = config.config['site']['zisheng']['max_length'] if len(message) > max_length: flash('超过最长长度: %d' % max_length, 'error') return False username = request.cookies['username'] last_zisheng_time = modules.Get_Session('last_zisheng_time', username) now_time = datetime.datetime.now() if last_zisheng_time != None: seconds = (now_time - last_zisheng_time).seconds if seconds < zisheng_delay_time: flash('请在 %ss 后提交' % (zisheng_delay_time - seconds), 'error') return False modules.Set_Session('last_zisheng_time', username, now_time) nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') db.Execute("INSERT INTO zisheng VALUES(NULL,%s,%s,%s);", (username, request.form['message'], nowtime)) flash('发送成功', 'ok') return True
def Submit(problemid,req,contest_id=0): if not modules.Is_Loggedin(): flash('请先登录','error') return modules.Page_Back() code = req['code'] if len(code) < 10: flash('这么短真的没问题?','error') return modules.Page_Back() username = request.cookies['username'] last_submit_time = modules.Get_Session('last_submit_time',username) now_time = datetime.datetime.now() if last_submit_time != None: seconds = (now_time-last_submit_time).seconds if seconds < submit_delay_time: flash('请在 %ss 后提交'%(submit_delay_time-seconds),'error') return modules.Page_Back() modules.Set_Session('last_submit_time',username,now_time) maxid_result = db.Fetchone("SELECT MAX(id) FROM records;")[0] runid = 1 if maxid_result == None else int(maxid_result) + 1 nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') db.Execute("INSERT INTO records VALUES(%s,%s,%s,%s,0,0,'','{\"subtasks\":[]}',0,0,'',%s,%s,%s);",(runid,problemid,code,'cpp',username,contest_id,nowtime)) r=redis.Redis(host='localhost',port=6379,decode_responses=True) r.rpush('intoj-waiting',str(runid)) return redirect('/record/%d'%runid)
def Run(): if request.method == 'GET': return render_template('login.html') else: username, password = \ request.form['username'], request.form['password'] res = modules.ValidatePassword(username, password) if not res['success']: return modules.ReturnJSON(res) registered_username = db.Execute( 'SELECT username FROM users WHERE username=%s', username)[0]['username'] client_key = hashlib.sha256( (str(random.randint(1, 10000000000)) + username + password + "intoj").encode('utf-8')).hexdigest() if session.get('client_keys') == None: session['client_keys'] = {} session['client_keys'][client_key] = registered_username session.update() return modules.ReturnJSON({ 'success': True, 'message': '登录成功!欢迎你,%s。' % registered_username, 'username': registered_username, 'client_key': client_key })
def CheckPrivilegeOfProblem(username,problem_id): ok_privileges = ['problemset_manager'] problems = db.Execute('SELECT provider FROM problems WHERE id=%s',problem_id) if len(problems) != 0: problem_provider = problems[0]['provider'] if problem_provider == username: ok_privileges.append('problem_owner') return CheckPrivilege(username,ok_privileges)
def UpdateInfo(submission_id, result): detail = { 'subtask': result.get('subtask', False), 'cases': result.get('cases'), 'subtasks': result.get('subtasks') } db.Execute( 'UPDATE submissions SET time_usage=%s, memory_usage=%s, status=%s, score=%s, detail=%s WHERE id=%s', (result['time_usage'], result['memory_usage'], result['status'], result['score'], json.dumps(detail), submission_id))
def CheckPrivilegeOfCode(username,submission_id): if config.config['security']['can_view_code'] == True: return True submissions = db.Execute('SELECT submitter,problem_id FROM submissions WHERE id=%s',submission_id) if len(submissions) == 0: return False submitter = submissions[0]['submitter'] if submitter == username: return True return False
def Rejudge(record_id): if db.Fetchone("SELECT * FROM records WHERE id=%s",record_id) == None: flash(r'提交记录R%d没找着!\\\n可能是因为编号不对.'%record_id,'error') return redirect('/status') db.Execute("UPDATE records SET status=0,score=0,time_usage=0,memory_usage=0,result='{\"subtasks\":[]}',compilation='' WHERE id=%s",record_id) myredis.Rpush('intoj-waiting',str(record_id)) flash('成功重测.','ok') return redirect('/record/%d'%record_id)
def ValidatePassword(username,password): if username == None or password == None: return { 'success': False, 'message': '缺少用户名或密码' } std_password_list = db.Execute('SELECT password,salt FROM users WHERE username=%s',username) if len(std_password_list) == 0: return { 'success': False, 'message': '无此用户' } std_password, salt = \ std_password_list[0]['password'], std_password_list[0]['salt'] if std_password != hashlib.sha256(('intoj'+password+salt).encode('utf-8')).hexdigest(): return { 'success': False, 'message': '密码错误' } return { 'success': True, 'message': 'ok' }
def SubmissionDeleteRun(submission_id): submission_info = GetSubmissionInfo(submission_id) operator = modules.GetCurrentOperator() if submission_info == None: return modules.ReturnJSON({'success': False, 'message': '无此提交'}) if not modules.CheckPrivilegeOfProblem(operator, submission_info['problem_id']): return modules.ReturnJSON({'success': False, 'message': '无此权限'}) db.Execute('DELETE FROM submissions WHERE id=%s', submission_id) return modules.ReturnJSON({'success': True, 'message': '成功删除'})
def ProblemAddRun(): operator = modules.GetCurrentOperator() if not modules.CheckPrivilege(operator, ['problemset_manager', 'problem_owner']): return modules.RedirectBack(error_message='无此权限') if request.method == 'GET': return render_template('problemadd.html') else: id = db.Execute('SELECT MAX(id) FROM problems')[0]['MAX(id)'] id = 1 if id == None else int(id) + 1 default_time_limit = config.config['default']['problem']['time_limit'] default_memory_limit = config.config['default']['problem'][ 'memory_limit'] db.Execute( 'INSERT INTO problems(id,title,provider,time_limit,memory_limit) VALUES(%s,%s,%s,%s,%s)', (id, request.form['title'], operator, default_time_limit, default_memory_limit)) os.system('mkdir %s' % os.path.join(config.config['data_path'], str(id))) return redirect('/problem/%d' % id)
def Rejudge(record_id): if db.Fetchone("SELECT * FROM records WHERE id=%s",record_id) == None: flash(r'提交记录R%d没找着!\\\n可能是因为编号不对.'%record_id,'error') return redirect('/status') db.Execute("UPDATE records SET status=0,score=0,result='{\"subtasks\":[]}',compilation='' WHERE id=%s",record_id) r=redis.Redis(host='localhost',port=6379,decode_responses=True) r.rpush('intoj-waiting',str(record_id)) flash('成功重测.','ok') return redirect('/record/%d'%record_id)
def GetUserInfo(username): res = db.Execute('SELECT * FROM users WHERE username=%s',username) if len(res) == 0: return None res = res[0] return { 'username': res['username'], 'email': res['email'], 'sex': res['sex'], 'motto': res['motto'], 'realname': res['realname'], 'background-url': res['background-url'], 'rating': res['rating'] }
def CustomTestRun(): if request.method == 'GET': return render_template('custom-test.html',languages=config.config['languages']) else: input_data = request.form['input_data'] if len(input_data) > config.config['limits']['max_custom_test_input_length']*1024: return modules.ReturnJSON({ 'success': False , 'message': '输入数据过长(长度限制为 %d KB)'%config.config['limits']['max_custom_test_input_length']}) result = submissions.NewSubmission( type = 'custom_test' ) if result['success'] == False: return modules.ReturnJSON(result) id = result['submission_id'] db.Execute('INSERT INTO custom_tests(id,input) VALUES(%s,%s)',(id,input_data)) return modules.ReturnJSON(result)
def CustomTest( submission_id, submission_info, code_path, exe_path, language_config ): log.Log('cyan','Running...') input_data = db.Execute('SELECT input FROM custom_tests WHERE id=%s',submission_id)[0]['input'] input_path = config.config['custom_test_stdin_path'] with open(input_path,'w') as inputfile: inputfile.write(input_data) data_config = { 'time_limit': config.config['custom_test']['max_time'], 'memory_limit': config.config['custom_test']['max_memory'] } run_result = run_and_judge.Run( data_config = data_config, exe_path = exe_path, input_rel_path = '', output_rel_path = '', input_path = input_path, output_path = '', language_config = language_config ) if run_result['status'] == static.name_to_id['Accepted']: run_result['status'] = static.name_to_id['Done'] output_data = modules.GetPreview(config.config['stdout_path'],config.config['custom_test']['max_output_show']) run_detail = { 'stderr_preview': run_result['stderr_preview'], 'runner_message': run_result['runner_message'] } db.Execute('UPDATE custom_tests SET output=%s WHERE id=%s',(output_data,submission_id)) db.Execute('UPDATE submissions SET time_usage=%s, memory_usage=%s, status=%s, detail=%s WHERE id=%s', (run_result['time_usage'],run_result['memory_usage'],run_result['status'],json.dumps(run_detail),submission_id)) log.Log('green','Done.')
def AdminHomeRun(): operator = modules.GetCurrentOperator() if not modules.CheckPrivilege(operator, 'system_admin'): return modules.RedirectBack('无此权限') statistic_datas = { 'problems_count': db.Execute('SELECT COUNT(*) FROM problems')[0]['COUNT(*)'], 'submissions_count': db.Execute('SELECT COUNT(*) FROM submissions')[0]['COUNT(*)'], 'users_count': db.Execute('SELECT COUNT(*) FROM users')[0]['COUNT(*)'] } system_infos = {} try: with open('.git/FETCH_HEAD', 'r') as f: system_infos['version_number'] = f.readline().split()[0] except: pass return render_template('admin.html', statistic_datas=statistic_datas, system_infos=system_infos)
def Run(): if request.method == 'GET': if not config.config['security']['allow_registration']: flash('先提醒一句:当前禁止注册。如需要注册,请联系管理员。','error') return render_template('register.html') else: if not config.config['security']['allow_registration']: return modules.ReturnJSON({ 'success': False, 'message': '当前禁止注册' }) username, password, repeat_password, salt = \ request.form['username'], request.form['password'], request.form['repeat_password'], request.form['salt'] if password != repeat_password: return modules.ReturnJSON({ 'success': False, 'message': '两次输入的密码不同' }) if len(username) == 0: return modules.ReturnJSON({ 'success': False, 'message': '你注册一个空用户名干啥' }) if not modules.IsVaildUsername(username): return modules.ReturnJSON({ 'success': False, 'message': '非法的用户名' }) same_username_cnt = db.Execute('SELECT COUNT(*) FROM users WHERE username=%s',username)[0]['COUNT(*)'] if same_username_cnt != 0: return modules.ReturnJSON({ 'success': False, 'message': '该用户名已被注册' }) if password == hashlib.sha256(('intoj'+salt).encode('utf-8')).hexdigest(): return modules.ReturnJSON({ 'success': False, 'message': '你的密码好短啊' }) db.Execute('INSERT INTO users VALUES(NULL,%s,%s,%s,"",0,"","","",1500)',(username,password,salt)) return modules.ReturnJSON({ 'success': True, 'message': '注册成功!欢迎你,%s。<br />前去登录吧!'%username })
def Total_Ac_Submit_Recalculate(username): print('Updating user %s'%username) total_ac = total_submit = 0 ac_set = set() submissions = db.Read_Submissions({'username':username}) for submission in submissions: status = submission['status'] problem_id = submission['problem_id'] total_submit += 1 if status == 10: ac_set.add(problem_id) total_ac = len(ac_set) ac_list = json.dumps(list(ac_set)) db.Execute('UPDATE users SET total_ac=%s, total_submit=%s, ac_list=%s WHERE username=%s',(total_ac,total_submit,ac_list,username))
def Contest_Players_Recalculate(contest_id): print('Recalculating Contest %d...' % contest_id) db.Execute('DELETE FROM contest_players WHERE contest_id=%s', contest_id) contest = db.Read_Contest(contest_id) submissions = list(db.Read_Submissions({'contest_id': contest_id})) submissions.sort(key=lambda x: x[0]) details = {} for submission in submissions: if submission[4] <= 3: continue username = submission[11] if details.get(username) == None: details[username] = {} problem_id = submission[1] details[username][problem_id] = { 'record_id': submission[0], 'score': modules.Toint(submission[5]), 'submit_cnt': 1 if details[username].get(problem_id) == None else details[username][problem_id]['submit_cnt'] + 1 } for username, detail in details.items(): db.Execute('INSERT INTO contest_players VALUES(NULL,%s,%s,%s)', (username, contest_id, json.dumps(detail)))
def SubmissionRejudgeRun(submission_id): submission_info = GetSubmissionInfo(submission_id) operator = modules.GetCurrentOperator() if submission_info == None: return modules.ReturnJSON({'success': False, 'message': '无此提交'}) if not modules.CheckPrivilegeOfProblem(operator, submission_info['problem_id']): return modules.ReturnJSON({'success': False, 'message': '无此权限'}) db.Execute('UPDATE submissions SET status=1 WHERE id=%s', submission_id) redis = reedis.NewConnection() redis.rpush('intoj-waiting-rejudge', submission_id) return modules.ReturnJSON({'success': True, 'message': '成功重测'})
def GetProblemInfo(problem_id): res = db.Execute('SELECT * FROM problems WHERE id=%s',problem_id) if len(res) == 0: return None res = res[0] def F(s): return '' if s == None else s.decode('utf-8') return { 'id': int(problem_id), 'title': res['title'], 'background': F(res['background']), 'description': F(res['description']), 'input_format': F(res['input_format']), 'output_format': F(res['output_format']), 'limit_and_hint': F(res['limit_and_hint']), 'time_limit': int(res['time_limit']), 'memory_limit': int(res['memory_limit']), 'is_public': bool(res['is_public']), 'provider': res['provider'] }
def Register(req): username,password,ensure_password,email = req['username'],req['password'],req['ensure_password'],req['email'] if username == '': return 0,'用户名不能为空' if password == '': return 0,'密码不能为空' if password != ensure_password: return 0,'两次输入的密码不同' if email == '': return 0,'邮箱地址不能为空' if not modules.Vaild_Username(username): return 0,'用户名只能包含大小写字母,数字,下划线和减号' count = int(db.Fetchone("SELECT COUNT(*) FROM users WHERE username=%s;",username)[0]) if count != 0: return 0,'用户名已被占用' password_sha256 = hashlib.sha256(password.encode('utf-8')).hexdigest() password_sha1 = hashlib.sha1(password.encode('utf-8')).hexdigest() db.Execute("INSERT INTO users(`username`,`password_sha256`,`password_sha1`,`email`,`nameplate`,`total_ac`,`total_submit`) VALUES(%s,%s,%s,%s,'',0,0);",(username,password_sha256,password_sha1,email)) return 1,''
def Change(origin_id, req): id = req['id'] if req['id'] == '': id = origin_id else: if int(req['id']) < 0: flash(r'编号不可以为负', 'error') return modules.Page_Back() count = int( db.Fetchone('SELECT COUNT(*) FROM problems WHERE id=%s', req['id'])[0]) if count > 0: flash(r'题目编号 %s 已经有过了.' % req['id'], 'error') modules.Page_Back() is_public = 1 if req.get('is_public') == 'on' else 0 db.Execute( "UPDATE problems SET `id`=%s,`title`=%s,`description`=%s,`input_format`=%s,`output_format`=%s,\ `example`=%s,`limit_and_hint`=%s,`time_limit`=%s,`memory_limit`=%s,`is_public`=%s\ WHERE id=%s;", (id, req['title'], req['description'], req['input_format'], req['output_format'], req['example'], req['limit_and_hint'], req['time_limit'], req['memory_limit'], is_public, origin_id)) return redirect('/problem/%s' % id)