def update_contest_rank(self, contest): if contest.real_time_rank: get_cache_redis().delete(str(contest.id) + "_rank_cache") with transaction.atomic(): try: contest_rank = ContestRank.objects.select_for_update().get(contest=contest, user=self.user) contest_rank.update_rank(self.submission) except ContestRank.DoesNotExist: ContestRank.objects.create(contest=contest, user=self.user).update_rank(self.submission)
def update_contest_rank(self, contest): if contest.real_time_rank: get_cache_redis().delete(str(contest.id) + "_rank_cache") with transaction.atomic(): try: contest_rank = ContestRank.objects.select_for_update().get(contest=contest, user_id=self.submission.user_id) contest_rank.update_rank(self.submission) except ContestRank.DoesNotExist: ContestRank.objects.create(contest=contest, user_id=self.submission.user_id).update_rank(self.submission)
def contest_rank_page(request, contest_id): contest = Contest.objects.get(id=contest_id) contest_problems = ContestProblem.objects.filter(contest=contest, visible=True).order_by("sort_index") force_real_time_rank = False if request.GET.get("force_real_time_rank") == "true" and (request.user.admin_type == SUPER_ADMIN or request.user == contest.created_by): rank = _get_rank(contest_id) force_real_time_rank = True else: r = get_cache_redis() cache_key = str(contest_id) + "_rank_cache" rank = r.get(cache_key) if not rank: rank = _get_rank(contest_id) r.set(cache_key, json.dumps([dict(item) for item in rank])) else: rank = json.loads(rank) # 2016-05-19 增加了缓存项目,以前的缓存主动失效 if rank and "rank_number" not in rank[0]: rank = _get_rank(contest_id) r.set(cache_key, json.dumps([dict(item) for item in rank])) return render(request, "oj/contest/contest_rank.html", {"rank": rank, "contest": contest, "contest_problems": contest_problems, "auto_refresh": request.GET.get("auto_refresh", None) == "true", "show_real_name": request.GET.get("show_real_name", None) == "true", "force_real_time_rank": force_real_time_rank})
def contest_rank_page(request, contest_id): contest = Contest.objects.get(id=contest_id) contest_problems = ContestProblem.objects.filter( contest=contest, visible=True).order_by("sort_index") r = get_cache_redis() cache_key = str(contest_id) + "_rank_cache" rank = r.get(cache_key) if not rank: rank = ContestRank.objects.filter(contest_id=contest_id). \ select_related("user"). \ order_by("-total_ac_number", "total_time"). \ values("id", "user__id", "user__username", "user__real_name", "contest_id", "submission_info", "total_submission_number", "total_ac_number", "total_time") r.set(cache_key, json.dumps([dict(item) for item in rank])) else: rank = json.loads(rank) return render( request, "oj/contest/contest_rank.html", { "rank": rank, "contest": contest, "contest_problems": contest_problems, "auto_refresh": request.GET.get("auto_refresh", None) == "true", "show_real_name": request.GET.get("show_real_name", None) == "true", })
def contest_rank_page(request, contest_id): contest = Contest.objects.get(id=contest_id) contest_problems = ContestProblem.objects.filter(contest=contest, visible=True).order_by("sort_index") force_real_time_rank = False if request.GET.get("force_real_time_rank") == "true" and (request.user.admin_type == SUPER_ADMIN or request.user == contest.created_by): rank = _get_rank(contest_id) force_real_time_rank = True else: r = get_cache_redis() cache_key = str(contest_id) + "_rank_cache" rank = r.get(cache_key) if not rank: rank = _get_rank(contest_id) r.set(cache_key, json.dumps([dict(item) for item in rank])) else: rank = json.loads(rank) return render(request, "oj/contest/contest_rank.html", {"rank": rank, "contest": contest, "contest_problems": contest_problems, "auto_refresh": request.GET.get("auto_refresh", None) == "true", "show_real_name": request.GET.get("show_real_name", None) == "true", "force_real_time_rank": force_real_time_rank})
def contest_rank_page(request, contest_id): contest = Contest.objects.get(id=contest_id) contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index") r = get_cache_redis() cache_key = str(contest_id) + "_rank_cache" rank = r.get(cache_key) if not rank: rank = ( ContestRank.objects.filter(contest_id=contest_id) .select_related("user") .order_by("-total_ac_number", "total_time") .values( "id", "user__id", "user__username", "user__real_name", "contest_id", "submission_info", "total_submission_number", "total_ac_number", "total_time", ) ) r.set(cache_key, json.dumps([dict(item) for item in rank])) else: rank = json.loads(rank) try: paging_rank = paginate_data(request, rank, None) if request.GET.get("paging", None): rank = paging_rank["results"] else: rank = paging_rank except Exception as e: return error_page(request, e.message) if request.GET.get("paging", None): paging_info = paging_rank paging_info["offset"] = paging_rank["page_size"] * (int(paging_rank["current_page"]) - 1) else: paging_info = {"previous_page": None, "next_page": None, "count": 0, "total_page": 0, "offset": 0} return render( request, "oj/contest/contest_rank.html", { "rank": rank, "contest": contest, "contest_problems": contest_problems, "paging_info": paging_info, "auto_refresh": request.GET.get("auto_refresh", None) == "true", "show_real_name": request.GET.get("show_real_name", None) == "true", }, )
def get(self, request): tag = request.GET.get('tag') user_id = request.GET.get('user_id') user = User.objects.get(id=user_id) weibo_name = user.weibo_name cache = get_cache_redis() cache.srem(weibo_name, tag) content = dict() content['state_code'] = 100 content['message'] = "设置成功" return Response(data=content)
def contest_rank_page(request, contest_id): contest = Contest.objects.get(id=contest_id) contest_problems = ContestProblem.objects.filter( contest=contest, visible=True).order_by("sort_index") r = get_cache_redis() cache_key = str(contest_id) + "_rank_cache" rank = r.get(cache_key) if not rank: rank = ContestRank.objects.filter(contest_id=contest_id). \ select_related("user"). \ order_by("-total_ac_number", "total_time"). \ values("id", "user__id", "user__username", "user__real_name", "contest_id", "submission_info", "total_submission_number", "total_ac_number", "total_time") r.set(cache_key, json.dumps([dict(item) for item in rank])) else: rank = json.loads(rank) try: paging_rank = paginate_data(request, rank, None) if request.GET.get("paging", None): rank = paging_rank["results"] else: rank = paging_rank except Exception as e: return error_page(request, e.message) if request.GET.get("paging", None): paging_info = paging_rank paging_info["offset"] = paging_rank["page_size"] * ( int(paging_rank["current_page"]) - 1) else: paging_info = { "previous_page": None, "next_page": None, "count": 0, "total_page": 0, "offset": 0 } return render( request, "oj/contest/contest_rank.html", { "rank": rank, "contest": contest, "contest_problems": contest_problems, "paging_info": paging_info, "auto_refresh": request.GET.get("auto_refresh", None) == "true", "show_real_name": request.GET.get("show_real_name", None) == "true", })
def contest_rank_page(request, contest_id): contest = Contest.objects.get(id=contest_id) contest_problems = ContestProblem.objects.filter( contest=contest, visible=True).order_by("sort_index") force_real_time_rank = False #max_number_cache_key = str(contest_id) + '_max_number' #redis = get_cache_redis() #max_number = redis.get(max_number_cache_key) #if not max_number: #max_number = _get_max_number(contest_id) #redis.set(max_number_cache_key, max_number) max_number = _get_max_number(contest_id) if request.GET.get("force_real_time_rank") == "true" and ( request.user.admin_type == SUPER_ADMIN or request.user == contest.created_by): rank = _get_rank(contest_id) force_real_time_rank = True else: r = get_cache_redis() cache_key = str(contest_id) + "_rank_cache" rank = r.get(cache_key) if not rank: rank = _get_rank(contest_id) r.set(cache_key, json.dumps([dict(item) for item in rank])) else: rank = json.loads(rank) # 2016-05-19 增加了缓存项目,以前的缓存主动失效 if rank and "rank_number" not in rank[0]: rank = _get_rank(contest_id) r.set(cache_key, json.dumps([dict(item) for item in rank])) return render( request, "oj/contest/contest_rank.html", { "rank": rank, "contest": contest, "max_number": max_number, "contest_problems": contest_problems, "auto_refresh": request.GET.get("auto_refresh", None) == "true", "show_real_name": request.GET.get("show_real_name", None) == "true", "force_real_time_rank": force_real_time_rank })
def get(self, request): users = User.objects.all() cache = get_cache_redis() content = dict() content['cards'] = [] for user in users: card = dict() weibo_name = user.weibo_name cache_tags = cache.srandmember(weibo_name, 5) tags = [] for tag in cache_tags: tags.append(tag) card['id'] = user.id card['username'] = user.username card['rank'] = user.rank card['location'] = user.location card['tags'] = tags content['cards'].append(card) print content # return Response(data=content) return HttpResponse(json.dumps(content))
def contest_rank_page(request, contest_id): contest = Contest.objects.get(id=contest_id) contest_problems = ContestProblem.objects.filter(contest=contest, visible=True).order_by("sort_index") r = get_cache_redis() cache_key = str(contest_id) + "_rank_cache" rank = r.get(cache_key) if not rank: rank = ( ContestRank.objects.filter(contest_id=contest_id) .select_related("user") .order_by("-total_ac_number", "total_time") .values( "id", "user__id", "user__username", "user__real_name", "contest_id", "submission_info", "total_submission_number", "total_ac_number", "total_time", ) ) r.set(cache_key, json.dumps([dict(item) for item in rank])) else: rank = json.loads(rank) return render( request, "oj/contest/contest_rank.html", { "rank": rank, "contest": contest, "contest_problems": contest_problems, "auto_refresh": request.GET.get("auto_refresh", None) == "true", "show_real_name": request.GET.get("show_real_name", None) == "true", }, )
def post(self, request): """ 创建比赛的提交 --- request_serializer: CreateContestSubmissionSerializer """ serializer = CreateContestSubmissionSerializer(data=request.data) if serializer.is_valid(): data = serializer.data contest = Contest.objects.get(id=data["contest_id"]) try: problem = ContestProblem.objects.get(contest=contest, id=data["problem_id"]) # 更新题目提交计数器 problem.total_submit_number += 1 problem.save() except ContestProblem.DoesNotExist: return error_response(u"题目不存在") submission = Submission.objects.create(user_id=request.user.id, language=int(data["language"]), contest_id=contest.id, code=data["code"], problem_id=problem.id) try: judge.delay(submission.id, problem.time_limit, problem.memory_limit, problem.test_case_id) except Exception: return error_response(u"提交判题任务失败") # 修改用户解题状态 problems_status = request.user.problems_status if "contest_problems" not in problems_status: problems_status["contest_problems"] = {} problems_status["contest_problems"][str(data["problem_id"])] = 2 request.user.problems_status = problems_status request.user.save() # 增加redis 中判题队列长度的计数器 r = get_cache_redis() r.incr("judge_queue_length") return success_response({"submission_id": submission.id}) else: return serializer_invalid_response(serializer)
def put(self, request): """ 比赛编辑json api接口 --- request_serializer: EditContestSerializer response_serializer: ContestSerializer """ serializer = EditContestSerializer(data=request.data) if serializer.is_valid(): data = serializer.data groups = [] try: # 超级管理员可以编辑所有的 contest = Contest.objects.get(id=data["id"]) if request.user.admin_type != SUPER_ADMIN: contest_set = Contest.objects.filter(groups__in=request.user.managed_groups.all()) if contest not in contest_set: return error_response(u"无权访问!") except Contest.DoesNotExist: return error_response(u"该比赛不存在!") try: contest = Contest.objects.get(title=data["title"]) if contest.id != data["id"]: return error_response(u"该比赛名称已经存在") except Contest.DoesNotExist: pass if data["contest_type"] in [PUBLIC_CONTEST, PASSWORD_PROTECTED_CONTEST]: if request.user.admin_type != SUPER_ADMIN: return error_response(u"只有超级管理员才可创建公开赛") if data["contest_type"] == PASSWORD_PROTECTED_CONTEST: if not data["password"]: return error_response(u"此比赛为有密码的公开赛,密码不可为空") elif data["contest_type"] in [GROUP_CONTEST, PASSWORD_PROTECTED_GROUP_CONTEST]: if request.user.admin_type == SUPER_ADMIN: groups = Group.objects.filter(id__in=data["groups"]) else: groups = Group.objects.filter(id__in=data["groups"], admin=request.user) if not groups.count(): return error_response(u"请至少选择一个小组") if data["start_time"] >= data["end_time"]: return error_response(u"比赛的开始时间必须早于比赛结束的时间") # 之前是封榜,现在要开放,需要清除缓存 if contest.real_time_rank == False and data["real_time_rank"] == True: r = get_cache_redis() cache_key = str(contest.id) + "_rank_cache" r.delete(cache_key) contest.title = data["title"] contest.description = data["description"] contest.contest_type = data["contest_type"] contest.real_time_rank = data["real_time_rank"] contest.start_time = dateparse.parse_datetime(data["start_time"]) contest.end_time = dateparse.parse_datetime(data["end_time"]) contest.visible = data["visible"] contest.password = data["password"] contest.save() contest.groups.clear() contest.groups.add(*groups) return success_response(ContestSerializer(contest).data) else: return serializer_invalid_response(serializer)
def listen_task(self): while True: submission_id = self.conn.blpop(self.queue, 0)[1] logger.debug("receive submission_id: " + submission_id) try: submission = Submission.objects.get(id=submission_id) except Submission.DoesNotExist: logger.warning("Submission does not exist, submission_id: " + submission_id) continue # 更新该用户的解题状态用 try: user = User.objects.get(pk=submission.user_id) except User.DoesNotExist: logger.warning("Submission user does not exist, submission_id: " + submission_id) continue if not submission.contest_id: try: problem = Problem.objects.get(id=submission.problem_id) except Problem.DoesNotExist: logger.warning("Submission problem does not exist, submission_id: " + submission_id) continue problems_status = user.problems_status # 更新普通题目的计数器 problem.add_submission_number() if "problems" not in problems_status: problems_status["problems"] = {} if submission.result == result["accepted"]: problem.add_ac_number() problems_status["problems"][str(problem.id)] = 1 else: problems_status["problems"][str(problem.id)] = 2 user.problems_status = problems_status user.save() # 普通题目的话,到这里就结束了 continue # 能运行到这里的都是比赛题目 try: contest = Contest.objects.get(id=submission.contest_id) if contest.status != CONTEST_UNDERWAY: logger.info("Contest debug mode, id: " + str(contest.id) + ", submission id: " + submission_id) continue contest_problem = ContestProblem.objects.get(contest=contest, id=submission.problem_id) except Contest.DoesNotExist: logger.warning("Submission contest does not exist, submission_id: " + submission_id) continue except ContestProblem.DoesNotExist: logger.warning("Submission problem does not exist, submission_id: " + submission_id) continue # 如果比赛现在不是封榜状态,删除比赛的排名缓存 if contest.real_time_rank: get_cache_redis().delete(str(contest.id) + "_rank_cache") with transaction.atomic(): try: contest_rank = ContestRank.objects.get(contest=contest, user=user) contest_rank.update_rank(submission) except ContestRank.DoesNotExist: ContestRank.objects.create(contest=contest, user=user).update_rank(submission) problems_status = user.problems_status contest_problem.add_submission_number() if "contest_problems" not in problems_status: problems_status["contest_problems"] = {} if submission.result == result["accepted"]: contest_problem.add_ac_number() problems_status["contest_problems"][str(contest_problem.id)] = 1 else: problems_status["contest_problems"][str(contest_problem.id)] = 1 user.problems_status = problems_status user.save()
def post(self, request): """ 比赛编辑json api接口 --- request_serializer: EditContestSerializer response_serializer: ContestSerializer """ serializer = EditContestSerializer(data=request.data) if serializer.is_valid(): data = serializer.data groups = [] try: # 超级管理员可以编辑所有的 contest = Contest.objects.get(id=data["id"]) if request.user.admin_type != SUPER_ADMIN: contest_set = Contest.objects.filter( groups__in=request.user.managed_groups.all()) if contest not in contest_set: return error_response(u"无权访问!") except Contest.DoesNotExist: return error_response(u"该比赛不存在!") try: contest = Contest.objects.get(title=data["title"]) if contest.id != data["id"]: return error_response(u"该比赛名称已经存在") except Contest.DoesNotExist: pass if data["contest_type"] in [ PUBLIC_CONTEST, PASSWORD_PROTECTED_CONTEST ]: if request.user.admin_type != SUPER_ADMIN: return error_response(u"只有超级管理员才可创建公开赛") if data["contest_type"] == PASSWORD_PROTECTED_CONTEST: if not data["password"]: return error_response(u"此比赛为有密码的公开赛,密码不可为空") elif data["contest_type"] in [ GROUP_CONTEST, PASSWORD_PROTECTED_GROUP_CONTEST ]: if request.user.admin_type == SUPER_ADMIN: groups = Group.objects.filter(id__in=data["groups"]) else: groups = Group.objects.filter(id__in=data["groups"], admin=request.user) if not groups.count(): return error_response(u"请至少选择一个小组") if data["start_time"] >= data["end_time"]: return error_response(u"比赛的开始时间必须早于比赛结束的时间") # 之前是封榜,现在要开放,需要清除缓存 if contest.real_time_rank == False and data[ "real_time_rank"] == True: r = get_cache_redis() cache_key = str(contest.id) + "_rank_cache" r.delete(cache_key) contest.title = data["title"] contest.description = data["description"] contest.contest_type = data["contest_type"] contest.real_time_rank = data["real_time_rank"] contest.start_time = dateparse.parse_datetime(data["start_time"]) contest.end_time = dateparse.parse_datetime(data["end_time"]) contest.visible = data["visible"] contest.password = data["password"] contest.groups.clear() contest.groups.add(*groups) #把题目逐个加入,如果已经存在对应contestproblem,那就创建title不同的备份 #try: # problem_list = data["problems"] # if problem_list == None or problem_list == "": # contest.save() # return success_response(ContestSerializer(contest).data) # problem_list = problem_list.split(',') # contest_problem_list = ContestProblem.objects.filter(contest=contest, visible=True).select_related( # "contest").order_by("sort_index") # if len(problem_list) > 26: # return error_response(u"太多题目啦,添加失败") # sort_id = 'A' # for problem_id in problem_list: # pid = int(problem_id) # linked_problem = Problem.objects.get(id=pid) # linked_problem.visible = False # linked_problem.save() # titled = ContestProblem.objects.filter(title=linked_problem.title) # if titled.count() == 0: # contest_problem = ContestProblem.objects.create(title=linked_problem.title, # description=linked_problem.description, # input_description=linked_problem.input_description, # output_description=linked_problem.output_description, # test_case_id=linked_problem.test_case_id, # samples=linked_problem.samples, # time_limit=linked_problem.time_limit, # memory_limit=linked_problem.memory_limit, # spj=linked_problem.spj, # spj_language=linked_problem.spj_language, # spj_code=linked_problem.spj_code, # spj_version=linked_problem.spj_version, # created_by=request.user, # hint=linked_problem.hint, # contest=contest, # sort_index=sort_id, # is_public=True # ) # else: # is_include = False # for preproblems in titled: # if preproblems.contest == contest: # is_include = True # break # if not is_include: # titled = ContestProblem.objects.filter(title=linked_problem.title+ '('+contest.title + ')') # if titled.count(): # is_include = True # if not is_include: # contest_problem = ContestProblem.objects.create(title=linked_problem.title + '('+contest.title + ')', # description=linked_problem.description, # input_description=linked_problem.input_description, # output_description=linked_problem.output_description, # test_case_id=linked_problem.test_case_id, # samples=linked_problem.samples, # time_limit=linked_problem.time_limit, # memory_limit=linked_problem.memory_limit, # spj=linked_problem.spj, # spj_language=linked_problem.spj_language, # spj_code=linked_problem.spj_code, # spj_version=linked_problem.spj_version, # created_by=request.user, # hint=linked_problem.hint, # contest=contest, # sort_index=sort_id, # is_public=True # ) # sort_id = chr(ord(sort_id) + 1) # for existed_problem in contest_problem_list: # existed_problem.sort_index = str(sort_id) # existed_problem.save() # if sort_id == 'Z': # sort_id = 0; # elif sort_id.isalpha(): # sort_id = chr(ord(sort_id) + 1) # else: # sort_id += 1 contest.save() # #except: # # contest.save() # # return success_response(u"比赛已是部分问题解析错误") return success_response(ContestSerializer(contest).data) else: return serializer_invalid_response(serializer)
def _judge(submission_id, time_limit, memory_limit, test_case_id): judge.delay(submission_id, time_limit, memory_limit, test_case_id) get_cache_redis().incr("judge_queue_length")
def put(self, request): """ 比赛编辑json api接口 --- request_serializer: EditContestSerializer response_serializer: ContestSerializer """ serializer = EditContestSerializer(data=request.data) if serializer.is_valid(): data = serializer.data groups = [] try: # 超级管理员可以编辑所有的 contest = Contest.objects.get(id=data["id"]) if request.user.admin_type != SUPER_ADMIN: contest_set = Contest.objects.filter( groups__in=request.user.managed_groups.all()) if contest not in contest_set: return error_response(u"无权访问!") except Contest.DoesNotExist: return error_response(u"该比赛不存在!") try: contest = Contest.objects.get(title=data["title"]) if contest.id != data["id"]: return error_response(u"该比赛名称已经存在") except Contest.DoesNotExist: pass if data["contest_type"] in [ PUBLIC_CONTEST, PASSWORD_PROTECTED_CONTEST ]: if request.user.admin_type != SUPER_ADMIN: return error_response(u"只有超级管理员才可创建公开赛") if data["contest_type"] == PASSWORD_PROTECTED_CONTEST: if not data["password"]: return error_response(u"此比赛为有密码的公开赛,密码不可为空") elif data["contest_type"] in [ GROUP_CONTEST, PASSWORD_PROTECTED_GROUP_CONTEST ]: if request.user.admin_type == SUPER_ADMIN: groups = Group.objects.filter(id__in=data["groups"]) else: groups = Group.objects.filter(id__in=data["groups"], admin=request.user) if not groups.count(): return error_response(u"请至少选择一个小组") if data["start_time"] >= data["end_time"]: return error_response(u"比赛的开始时间必须早于比赛结束的时间") # 之前是封榜,现在要开放,需要清除缓存 if contest.real_time_rank == False and data[ "real_time_rank"] == True: r = get_cache_redis() cache_key = str(contest.id) + "_rank_cache" r.delete(cache_key) contest.title = data["title"] contest.description = data["description"] contest.contest_type = data["contest_type"] contest.real_time_rank = data["real_time_rank"] contest.start_time = dateparse.parse_datetime(data["start_time"]) contest.end_time = dateparse.parse_datetime(data["end_time"]) contest.visible = data["visible"] contest.password = data["password"] contest.save() contest.groups.clear() contest.groups.add(*groups) return success_response(ContestSerializer(contest).data) else: return serializer_invalid_response(serializer)