diff --git a/contest/views/oj.py b/contest/views/oj.py index 6bf7358..8a64d48 100644 --- a/contest/views/oj.py +++ b/contest/views/oj.py @@ -10,7 +10,11 @@ from utils.api import APIView, validate_serializer from utils.constants import CacheKey, CONTEST_PASSWORD_SESSION_KEY from utils.shortcuts import datetime2str, check_is_id from account.models import AdminType -from account.decorators import login_required, check_contest_permission, check_contest_password +from account.decorators import ( + login_required, + check_contest_permission, + check_contest_password, +) from utils.constants import ContestRuleType, ContestStatus from ..models import ContestAnnouncement, Contest, OIContestRank, ACMContestRank @@ -25,7 +29,9 @@ class ContestAnnouncementListAPI(APIView): contest_id = request.GET.get("contest_id") if not contest_id: return self.error("Invalid parameter, contest_id is required") - data = ContestAnnouncement.objects.select_related("created_by").filter(contest_id=contest_id, visible=True) + data = ContestAnnouncement.objects.select_related("created_by").filter( + contest_id=contest_id, visible=True + ) max_id = request.GET.get("max_id") if max_id: data = data.filter(id__gt=max_id) @@ -76,7 +82,9 @@ class ContestPasswordVerifyAPI(APIView): def post(self, request): data = request.data try: - contest = Contest.objects.get(id=data["contest_id"], visible=True, password__isnull=False) + contest = Contest.objects.get( + id=data["contest_id"], visible=True, password__isnull=False + ) except Contest.DoesNotExist: return self.error("Contest does not exist") if not check_contest_password(data["password"], contest.password): @@ -98,25 +106,41 @@ class ContestAccessAPI(APIView): if not contest_id: return self.error() try: - contest = Contest.objects.get(id=contest_id, visible=True, password__isnull=False) + contest = Contest.objects.get( + id=contest_id, visible=True, password__isnull=False + ) except Contest.DoesNotExist: return self.error("Contest does not exist") - session_pass = request.session.get(CONTEST_PASSWORD_SESSION_KEY, {}).get(contest.id) - return self.success({"access": check_contest_password(session_pass, contest.password)}) + session_pass = request.session.get(CONTEST_PASSWORD_SESSION_KEY, {}).get( + contest.id + ) + return self.success( + {"access": check_contest_password(session_pass, contest.password)} + ) class ContestRankAPI(APIView): def get_rank(self): if self.contest.rule_type == ContestRuleType.ACM: - return ACMContestRank.objects.filter(contest=self.contest, - user__admin_type=AdminType.REGULAR_USER, - user__is_disabled=False).\ - select_related("user").order_by("-accepted_number", "total_time") + return ( + ACMContestRank.objects.filter( + contest=self.contest, + user__admin_type=AdminType.REGULAR_USER, + user__is_disabled=False, + ) + .select_related("user") + .order_by("-accepted_number", "total_time") + ) else: - return OIContestRank.objects.filter(contest=self.contest, - user__admin_type=AdminType.REGULAR_USER, - user__is_disabled=False). \ - select_related("user").order_by("-total_score") + return ( + OIContestRank.objects.filter( + contest=self.contest, + user__admin_type=AdminType.REGULAR_USER, + user__is_disabled=False, + ) + .select_related("user") + .order_by("-total_score") + ) def column_string(self, n): string = "" @@ -129,13 +153,17 @@ class ContestRankAPI(APIView): def get(self, request): download_csv = request.GET.get("download_csv") force_refresh = request.GET.get("force_refresh") - is_contest_admin = request.user.is_authenticated and request.user.is_contest_admin(self.contest) + is_contest_admin = ( + request.user.is_authenticated + and request.user.is_contest_admin(self.contest) + ) if self.contest.rule_type == ContestRuleType.OI: serializer = OIContestRankSerializer else: serializer = ACMContestRankSerializer - if force_refresh == "1" and is_contest_admin: + # if force_refresh == "1" and is_contest_admin: + if force_refresh == "1": qs = self.get_rank() else: cache_key = f"{CacheKey.contest_rank_cache}:{self.contest.id}" @@ -146,7 +174,9 @@ class ContestRankAPI(APIView): if download_csv: data = serializer(qs, many=True, is_contest_admin=is_contest_admin).data - contest_problems = Problem.objects.filter(contest=self.contest, visible=True).order_by("_id") + contest_problems = Problem.objects.filter( + contest=self.contest, visible=True + ).order_by("_id") problem_ids = [item.id for item in contest_problems] f = io.BytesIO() @@ -158,38 +188,56 @@ class ContestRankAPI(APIView): if self.contest.rule_type == ContestRuleType.OI: worksheet.write("D1", "Total Score") for item in range(contest_problems.count()): - worksheet.write(self.column_string(5 + item) + "1", f"{contest_problems[item].title}") + worksheet.write( + self.column_string(5 + item) + "1", + f"{contest_problems[item].title}", + ) for index, item in enumerate(data): worksheet.write_string(index + 1, 0, str(item["user"]["id"])) worksheet.write_string(index + 1, 1, item["user"]["username"]) - worksheet.write_string(index + 1, 2, item["user"]["real_name"] or "") + worksheet.write_string( + index + 1, 2, item["user"]["real_name"] or "" + ) worksheet.write_string(index + 1, 3, str(item["total_score"])) for k, v in item["submission_info"].items(): - worksheet.write_string(index + 1, 4 + problem_ids.index(int(k)), str(v)) + worksheet.write_string( + index + 1, 4 + problem_ids.index(int(k)), str(v) + ) else: worksheet.write("D1", "AC") worksheet.write("E1", "Total Submission") worksheet.write("F1", "Total Time") for item in range(contest_problems.count()): - worksheet.write(self.column_string(7 + item) + "1", f"{contest_problems[item].title}") + worksheet.write( + self.column_string(7 + item) + "1", + f"{contest_problems[item].title}", + ) for index, item in enumerate(data): worksheet.write_string(index + 1, 0, str(item["user"]["id"])) worksheet.write_string(index + 1, 1, item["user"]["username"]) - worksheet.write_string(index + 1, 2, item["user"]["real_name"] or "") + worksheet.write_string( + index + 1, 2, item["user"]["real_name"] or "" + ) worksheet.write_string(index + 1, 3, str(item["accepted_number"])) worksheet.write_string(index + 1, 4, str(item["submission_number"])) worksheet.write_string(index + 1, 5, str(item["total_time"])) for k, v in item["submission_info"].items(): - worksheet.write_string(index + 1, 6 + problem_ids.index(int(k)), str(v["is_ac"])) + worksheet.write_string( + index + 1, 6 + problem_ids.index(int(k)), str(v["is_ac"]) + ) workbook.close() f.seek(0) response = HttpResponse(f.read()) - response["Content-Disposition"] = f"attachment; filename=content-{self.contest.id}-rank.xlsx" + response["Content-Disposition"] = ( + f"attachment; filename=content-{self.contest.id}-rank.xlsx" + ) response["Content-Type"] = "application/xlsx" return response page_qs = self.paginate_data(request, qs) - page_qs["results"] = serializer(page_qs["results"], many=True, is_contest_admin=is_contest_admin).data + page_qs["results"] = serializer( + page_qs["results"], many=True, is_contest_admin=is_contest_admin + ).data return self.success(page_qs)