2017-10-21 12:39:39 +00:00
|
|
|
import random
|
2017-05-01 05:30:47 +00:00
|
|
|
from django.db.models import Q
|
2017-01-24 05:22:40 +00:00
|
|
|
from utils.api import APIView
|
2017-07-18 03:25:08 +00:00
|
|
|
from account.decorators import check_contest_permission
|
2017-09-24 01:48:17 +00:00
|
|
|
from ..models import ProblemTag, Problem, ProblemRuleType
|
2017-05-01 05:03:48 +00:00
|
|
|
from ..serializers import ProblemSerializer, TagSerializer
|
2017-10-27 10:36:29 +00:00
|
|
|
from ..serializers import ContestProblemSerializer, ContestProblemSafeSerializer
|
2017-09-12 03:45:17 +00:00
|
|
|
from contest.models import ContestRuleType
|
2017-01-24 05:22:40 +00:00
|
|
|
|
2017-09-13 14:37:57 +00:00
|
|
|
|
2017-01-24 05:22:40 +00:00
|
|
|
class ProblemTagAPI(APIView):
|
|
|
|
def get(self, request):
|
2017-05-01 05:20:26 +00:00
|
|
|
return self.success(TagSerializer(ProblemTag.objects.all(), many=True).data)
|
2017-05-01 05:03:48 +00:00
|
|
|
|
|
|
|
|
2017-10-21 12:39:39 +00:00
|
|
|
class PickOneAPI(APIView):
|
|
|
|
def get(self, request):
|
|
|
|
problems = Problem.objects.filter(contest_id__isnull=True, visible=True)
|
|
|
|
count = problems.count()
|
|
|
|
if count == 0:
|
|
|
|
return self.error("No problem to pick")
|
|
|
|
return self.success(problems[random.randint(0, count - 1)]._id)
|
|
|
|
|
|
|
|
|
2017-05-01 05:03:48 +00:00
|
|
|
class ProblemAPI(APIView):
|
2017-10-15 10:36:55 +00:00
|
|
|
@staticmethod
|
|
|
|
def _add_problem_status(request, queryset_values):
|
|
|
|
if request.user.is_authenticated():
|
|
|
|
profile = request.user.userprofile
|
|
|
|
acm_problems_status = profile.acm_problems_status.get("problems", {})
|
|
|
|
oi_problems_status = profile.oi_problems_status.get("problems", {})
|
|
|
|
# paginate data
|
|
|
|
results = queryset_values.get("results")
|
2017-10-16 01:45:29 +00:00
|
|
|
if results is not None:
|
2017-10-15 10:36:55 +00:00
|
|
|
problems = results
|
|
|
|
else:
|
2017-10-21 12:39:39 +00:00
|
|
|
problems = [queryset_values, ]
|
2017-10-15 10:36:55 +00:00
|
|
|
for problem in problems:
|
|
|
|
if problem["rule_type"] == ProblemRuleType.ACM:
|
|
|
|
problem["my_status"] = acm_problems_status.get(str(problem["id"]), {}).get("status")
|
|
|
|
else:
|
|
|
|
problem["my_status"] = oi_problems_status.get(str(problem["id"]), {}).get("status")
|
|
|
|
|
2017-05-01 05:03:48 +00:00
|
|
|
def get(self, request):
|
|
|
|
# 问题详情页
|
2017-07-20 07:52:11 +00:00
|
|
|
problem_id = request.GET.get("problem_id")
|
2017-05-01 05:03:48 +00:00
|
|
|
if problem_id:
|
|
|
|
try:
|
2017-10-21 12:39:39 +00:00
|
|
|
problem = Problem.objects.select_related("created_by") \
|
2017-09-29 13:58:20 +00:00
|
|
|
.get(_id=problem_id, contest_id__isnull=True, visible=True)
|
2017-10-15 10:36:55 +00:00
|
|
|
problem_data = ProblemSerializer(problem).data
|
|
|
|
self._add_problem_status(request, problem_data)
|
|
|
|
return self.success(problem_data)
|
2017-05-01 05:03:48 +00:00
|
|
|
except Problem.DoesNotExist:
|
|
|
|
return self.error("Problem does not exist")
|
|
|
|
|
2017-09-13 14:37:57 +00:00
|
|
|
limit = request.GET.get("limit")
|
|
|
|
if not limit:
|
|
|
|
return self.error("Limit is needed")
|
|
|
|
|
2017-09-29 13:58:20 +00:00
|
|
|
problems = Problem.objects.select_related("created_by").filter(contest_id__isnull=True, visible=True)
|
2017-05-01 05:03:48 +00:00
|
|
|
# 按照标签筛选
|
2017-05-08 12:37:54 +00:00
|
|
|
tag_text = request.GET.get("tag")
|
2017-05-01 05:03:48 +00:00
|
|
|
if tag_text:
|
2017-10-16 01:45:29 +00:00
|
|
|
problems = problems.filter(tags__name=tag_text)
|
2017-05-01 05:03:48 +00:00
|
|
|
|
|
|
|
# 搜索的情况
|
|
|
|
keyword = request.GET.get("keyword", "").strip()
|
|
|
|
if keyword:
|
2017-11-15 02:32:31 +00:00
|
|
|
problems = problems.filter(Q(title__icontains=keyword) | Q(_id__icontains=keyword))
|
2017-05-01 05:03:48 +00:00
|
|
|
|
|
|
|
# 难度筛选
|
2017-09-22 08:41:29 +00:00
|
|
|
difficulty = request.GET.get("difficulty")
|
|
|
|
if difficulty:
|
|
|
|
problems = problems.filter(difficulty=difficulty)
|
2017-09-12 03:45:17 +00:00
|
|
|
# 根据profile 为做过的题目添加标记
|
|
|
|
data = self.paginate_data(request, problems, ProblemSerializer)
|
2017-10-15 10:36:55 +00:00
|
|
|
self._add_problem_status(request, data)
|
2017-09-12 03:45:17 +00:00
|
|
|
return self.success(data)
|
2017-07-17 13:28:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ContestProblemAPI(APIView):
|
2017-10-15 10:36:55 +00:00
|
|
|
def _add_problem_status(self, request, queryset_values):
|
2017-10-16 01:45:29 +00:00
|
|
|
if request.user.is_authenticated():
|
2017-10-15 10:36:55 +00:00
|
|
|
profile = request.user.userprofile
|
|
|
|
if self.contest.rule_type == ContestRuleType.ACM:
|
|
|
|
problems_status = profile.acm_problems_status.get("contest_problems", {})
|
|
|
|
else:
|
|
|
|
problems_status = profile.oi_problems_status.get("contest_problems", {})
|
|
|
|
for problem in queryset_values:
|
|
|
|
problem["my_status"] = problems_status.get(str(problem["id"]), {}).get("status")
|
|
|
|
|
2017-10-27 10:36:29 +00:00
|
|
|
@check_contest_permission(check_type="problems")
|
2017-07-17 13:28:06 +00:00
|
|
|
def get(self, request):
|
2017-07-18 03:18:18 +00:00
|
|
|
problem_id = request.GET.get("problem_id")
|
|
|
|
if problem_id:
|
|
|
|
try:
|
2017-09-24 01:48:17 +00:00
|
|
|
problem = Problem.objects.select_related("created_by").get(_id=problem_id,
|
|
|
|
contest=self.contest,
|
|
|
|
visible=True)
|
|
|
|
except Problem.DoesNotExist:
|
2017-07-18 03:18:18 +00:00
|
|
|
return self.error("Problem does not exist.")
|
2017-10-27 10:36:29 +00:00
|
|
|
if self.contest.problem_details_permission(request.user):
|
|
|
|
problem_data = ContestProblemSerializer(problem).data
|
|
|
|
self._add_problem_status(request, [problem_data, ])
|
|
|
|
else:
|
|
|
|
problem_data = ContestProblemSafeSerializer(problem).data
|
2017-10-15 10:36:55 +00:00
|
|
|
return self.success(problem_data)
|
2017-10-27 10:36:29 +00:00
|
|
|
|
2017-09-24 01:48:17 +00:00
|
|
|
contest_problems = Problem.objects.select_related("created_by").filter(contest=self.contest, visible=True)
|
2017-10-27 10:36:29 +00:00
|
|
|
if self.contest.problem_details_permission(request.user):
|
|
|
|
data = ContestProblemSerializer(contest_problems, many=True).data
|
|
|
|
self._add_problem_status(request, data)
|
|
|
|
else:
|
|
|
|
data = ContestProblemSafeSerializer(contest_problems, many=True).data
|
2017-09-29 13:58:20 +00:00
|
|
|
return self.success(data)
|