Reformat using black
This commit is contained in:
parent
efee4ad081
commit
a87fb49918
221 changed files with 19127 additions and 7310 deletions
|
@ -5,27 +5,40 @@ from django.http import Http404, JsonResponse
|
|||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from dmoj import settings
|
||||
from judge.models import Contest, ContestParticipation, ContestTag, Problem, Profile, Submission
|
||||
from judge.models import (
|
||||
Contest,
|
||||
ContestParticipation,
|
||||
ContestTag,
|
||||
Problem,
|
||||
Profile,
|
||||
Submission,
|
||||
)
|
||||
|
||||
|
||||
def sane_time_repr(delta):
|
||||
days = delta.days
|
||||
hours = delta.seconds / 3600
|
||||
minutes = (delta.seconds % 3600) / 60
|
||||
return '%02d:%02d:%02d' % (days, hours, minutes)
|
||||
return "%02d:%02d:%02d" % (days, hours, minutes)
|
||||
|
||||
|
||||
def api_v1_contest_list(request):
|
||||
queryset = Contest.get_visible_contests(request.user).prefetch_related(
|
||||
Prefetch('tags', queryset=ContestTag.objects.only('name'), to_attr='tag_list'))
|
||||
|
||||
return JsonResponse({c.key: {
|
||||
'name': c.name,
|
||||
'start_time': c.start_time.isoformat(),
|
||||
'end_time': c.end_time.isoformat(),
|
||||
'time_limit': c.time_limit and sane_time_repr(c.time_limit),
|
||||
'labels': list(map(attrgetter('name'), c.tag_list)),
|
||||
} for c in queryset})
|
||||
Prefetch("tags", queryset=ContestTag.objects.only("name"), to_attr="tag_list")
|
||||
)
|
||||
|
||||
return JsonResponse(
|
||||
{
|
||||
c.key: {
|
||||
"name": c.name,
|
||||
"start_time": c.start_time.isoformat(),
|
||||
"end_time": c.end_time.isoformat(),
|
||||
"time_limit": c.time_limit and sane_time_repr(c.time_limit),
|
||||
"labels": list(map(attrgetter("name"), c.tag_list)),
|
||||
}
|
||||
for c in queryset
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def api_v1_contest_detail(request, contest):
|
||||
|
@ -33,61 +46,87 @@ def api_v1_contest_detail(request, contest):
|
|||
|
||||
in_contest = contest.is_in_contest(request.user)
|
||||
can_see_rankings = contest.can_see_full_scoreboard(request.user)
|
||||
problems = list(contest.contest_problems.select_related('problem')
|
||||
.defer('problem__description').order_by('order'))
|
||||
participations = (contest.users.filter(virtual=0)
|
||||
.prefetch_related('user__organizations')
|
||||
.annotate(username=F('user__user__username'))
|
||||
.order_by('-score', 'cumtime') if can_see_rankings else [])
|
||||
problems = list(
|
||||
contest.contest_problems.select_related("problem")
|
||||
.defer("problem__description")
|
||||
.order_by("order")
|
||||
)
|
||||
participations = (
|
||||
contest.users.filter(virtual=0)
|
||||
.prefetch_related("user__organizations")
|
||||
.annotate(username=F("user__user__username"))
|
||||
.order_by("-score", "cumtime")
|
||||
if can_see_rankings
|
||||
else []
|
||||
)
|
||||
|
||||
can_see_problems = (in_contest or contest.ended or contest.is_editable_by(request.user))
|
||||
can_see_problems = (
|
||||
in_contest or contest.ended or contest.is_editable_by(request.user)
|
||||
)
|
||||
|
||||
return JsonResponse({
|
||||
'time_limit': contest.time_limit and contest.time_limit.total_seconds(),
|
||||
'start_time': contest.start_time.isoformat(),
|
||||
'end_time': contest.end_time.isoformat(),
|
||||
'tags': list(contest.tags.values_list('name', flat=True)),
|
||||
'is_rated': contest.is_rated,
|
||||
'rate_all': contest.is_rated and contest.rate_all,
|
||||
'has_rating': contest.ratings.exists(),
|
||||
'rating_floor': contest.rating_floor,
|
||||
'rating_ceiling': contest.rating_ceiling,
|
||||
'format': {
|
||||
'name': contest.format_name,
|
||||
'config': contest.format_config,
|
||||
},
|
||||
'problems': [
|
||||
{
|
||||
'points': int(problem.points),
|
||||
'partial': problem.partial,
|
||||
'name': problem.problem.name,
|
||||
'code': problem.problem.code,
|
||||
} for problem in problems] if can_see_problems else [],
|
||||
'rankings': [
|
||||
{
|
||||
'user': participation.username,
|
||||
'points': participation.score,
|
||||
'cumtime': participation.cumtime,
|
||||
'is_disqualified': participation.is_disqualified,
|
||||
'solutions': contest.format.get_problem_breakdown(participation, problems),
|
||||
} for participation in participations],
|
||||
})
|
||||
return JsonResponse(
|
||||
{
|
||||
"time_limit": contest.time_limit and contest.time_limit.total_seconds(),
|
||||
"start_time": contest.start_time.isoformat(),
|
||||
"end_time": contest.end_time.isoformat(),
|
||||
"tags": list(contest.tags.values_list("name", flat=True)),
|
||||
"is_rated": contest.is_rated,
|
||||
"rate_all": contest.is_rated and contest.rate_all,
|
||||
"has_rating": contest.ratings.exists(),
|
||||
"rating_floor": contest.rating_floor,
|
||||
"rating_ceiling": contest.rating_ceiling,
|
||||
"format": {
|
||||
"name": contest.format_name,
|
||||
"config": contest.format_config,
|
||||
},
|
||||
"problems": [
|
||||
{
|
||||
"points": int(problem.points),
|
||||
"partial": problem.partial,
|
||||
"name": problem.problem.name,
|
||||
"code": problem.problem.code,
|
||||
}
|
||||
for problem in problems
|
||||
]
|
||||
if can_see_problems
|
||||
else [],
|
||||
"rankings": [
|
||||
{
|
||||
"user": participation.username,
|
||||
"points": participation.score,
|
||||
"cumtime": participation.cumtime,
|
||||
"is_disqualified": participation.is_disqualified,
|
||||
"solutions": contest.format.get_problem_breakdown(
|
||||
participation, problems
|
||||
),
|
||||
}
|
||||
for participation in participations
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def api_v1_problem_list(request):
|
||||
queryset = Problem.objects.filter(is_public=True, is_organization_private=False)
|
||||
if settings.ENABLE_FTS and 'search' in request.GET:
|
||||
query = ' '.join(request.GET.getlist('search')).strip()
|
||||
if settings.ENABLE_FTS and "search" in request.GET:
|
||||
query = " ".join(request.GET.getlist("search")).strip()
|
||||
if query:
|
||||
queryset = queryset.search(query)
|
||||
queryset = queryset.values_list('code', 'points', 'partial', 'name', 'group__full_name')
|
||||
queryset = queryset.values_list(
|
||||
"code", "points", "partial", "name", "group__full_name"
|
||||
)
|
||||
|
||||
return JsonResponse({code: {
|
||||
'points': points,
|
||||
'partial': partial,
|
||||
'name': name,
|
||||
'group': group,
|
||||
} for code, points, partial, name, group in queryset})
|
||||
return JsonResponse(
|
||||
{
|
||||
code: {
|
||||
"points": points,
|
||||
"partial": partial,
|
||||
"name": name,
|
||||
"group": group,
|
||||
}
|
||||
for code, points, partial, name, group in queryset
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def api_v1_problem_info(request, problem):
|
||||
|
@ -95,60 +134,83 @@ def api_v1_problem_info(request, problem):
|
|||
if not p.is_accessible_by(request.user):
|
||||
raise Http404()
|
||||
|
||||
return JsonResponse({
|
||||
'name': p.name,
|
||||
'authors': list(p.authors.values_list('user__username', flat=True)),
|
||||
'types': list(p.types.values_list('full_name', flat=True)),
|
||||
'group': p.group.full_name,
|
||||
'time_limit': p.time_limit,
|
||||
'memory_limit': p.memory_limit,
|
||||
'points': p.points,
|
||||
'partial': p.partial,
|
||||
'languages': list(p.allowed_languages.values_list('key', flat=True)),
|
||||
})
|
||||
return JsonResponse(
|
||||
{
|
||||
"name": p.name,
|
||||
"authors": list(p.authors.values_list("user__username", flat=True)),
|
||||
"types": list(p.types.values_list("full_name", flat=True)),
|
||||
"group": p.group.full_name,
|
||||
"time_limit": p.time_limit,
|
||||
"memory_limit": p.memory_limit,
|
||||
"points": p.points,
|
||||
"partial": p.partial,
|
||||
"languages": list(p.allowed_languages.values_list("key", flat=True)),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def api_v1_user_list(request):
|
||||
queryset = Profile.objects.filter(is_unlisted=False).values_list('user__username', 'points', 'performance_points',
|
||||
'display_rank')
|
||||
return JsonResponse({username: {
|
||||
'points': points,
|
||||
'performance_points': performance_points,
|
||||
'rank': rank,
|
||||
} for username, points, performance_points, rank in queryset})
|
||||
queryset = Profile.objects.filter(is_unlisted=False).values_list(
|
||||
"user__username", "points", "performance_points", "display_rank"
|
||||
)
|
||||
return JsonResponse(
|
||||
{
|
||||
username: {
|
||||
"points": points,
|
||||
"performance_points": performance_points,
|
||||
"rank": rank,
|
||||
}
|
||||
for username, points, performance_points, rank in queryset
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def api_v1_user_info(request, user):
|
||||
profile = get_object_or_404(Profile, user__username=user)
|
||||
submissions = list(Submission.objects.filter(case_points=F('case_total'), user=profile, problem__is_public=True,
|
||||
problem__is_organization_private=False)
|
||||
.values('problem').distinct().values_list('problem__code', flat=True))
|
||||
submissions = list(
|
||||
Submission.objects.filter(
|
||||
case_points=F("case_total"),
|
||||
user=profile,
|
||||
problem__is_public=True,
|
||||
problem__is_organization_private=False,
|
||||
)
|
||||
.values("problem")
|
||||
.distinct()
|
||||
.values_list("problem__code", flat=True)
|
||||
)
|
||||
resp = {
|
||||
'points': profile.points,
|
||||
'performance_points': profile.performance_points,
|
||||
'rank': profile.display_rank,
|
||||
'solved_problems': submissions,
|
||||
'organizations': list(profile.organizations.values_list('id', flat=True)),
|
||||
"points": profile.points,
|
||||
"performance_points": profile.performance_points,
|
||||
"rank": profile.display_rank,
|
||||
"solved_problems": submissions,
|
||||
"organizations": list(profile.organizations.values_list("id", flat=True)),
|
||||
}
|
||||
|
||||
last_rating = profile.ratings.last()
|
||||
|
||||
contest_history = {}
|
||||
participations = ContestParticipation.objects.filter(user=profile, virtual=0, contest__is_visible=True,
|
||||
contest__is_private=False,
|
||||
contest__is_organization_private=False)
|
||||
participations = ContestParticipation.objects.filter(
|
||||
user=profile,
|
||||
virtual=0,
|
||||
contest__is_visible=True,
|
||||
contest__is_private=False,
|
||||
contest__is_organization_private=False,
|
||||
)
|
||||
for contest_key, rating, mean, performance in participations.values_list(
|
||||
'contest__key', 'rating__rating', 'rating__mean', 'rating__performance',
|
||||
"contest__key",
|
||||
"rating__rating",
|
||||
"rating__mean",
|
||||
"rating__performance",
|
||||
):
|
||||
contest_history[contest_key] = {
|
||||
'rating': rating,
|
||||
'raw_rating': mean,
|
||||
'performance': performance,
|
||||
"rating": rating,
|
||||
"raw_rating": mean,
|
||||
"performance": performance,
|
||||
}
|
||||
|
||||
resp['contests'] = {
|
||||
'current_rating': last_rating.rating if last_rating else None,
|
||||
'history': contest_history,
|
||||
resp["contests"] = {
|
||||
"current_rating": last_rating.rating if last_rating else None,
|
||||
"history": contest_history,
|
||||
}
|
||||
|
||||
return JsonResponse(resp)
|
||||
|
@ -156,14 +218,30 @@ def api_v1_user_info(request, user):
|
|||
|
||||
def api_v1_user_submissions(request, user):
|
||||
profile = get_object_or_404(Profile, user__username=user)
|
||||
subs = Submission.objects.filter(user=profile, problem__is_public=True, problem__is_organization_private=False)
|
||||
subs = Submission.objects.filter(
|
||||
user=profile, problem__is_public=True, problem__is_organization_private=False
|
||||
)
|
||||
|
||||
return JsonResponse({sub['id']: {
|
||||
'problem': sub['problem__code'],
|
||||
'time': sub['time'],
|
||||
'memory': sub['memory'],
|
||||
'points': sub['points'],
|
||||
'language': sub['language__key'],
|
||||
'status': sub['status'],
|
||||
'result': sub['result'],
|
||||
} for sub in subs.values('id', 'problem__code', 'time', 'memory', 'points', 'language__key', 'status', 'result')})
|
||||
return JsonResponse(
|
||||
{
|
||||
sub["id"]: {
|
||||
"problem": sub["problem__code"],
|
||||
"time": sub["time"],
|
||||
"memory": sub["memory"],
|
||||
"points": sub["points"],
|
||||
"language": sub["language__key"],
|
||||
"status": sub["status"],
|
||||
"result": sub["result"],
|
||||
}
|
||||
for sub in subs.values(
|
||||
"id",
|
||||
"problem__code",
|
||||
"time",
|
||||
"memory",
|
||||
"points",
|
||||
"language__key",
|
||||
"status",
|
||||
"result",
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -9,7 +9,7 @@ from judge.views.contests import contest_ranking_list
|
|||
|
||||
|
||||
def error(message):
|
||||
return JsonResponse({'error': message}, status=422)
|
||||
return JsonResponse({"error": message}, status=422)
|
||||
|
||||
|
||||
def api_v2_user_info(request):
|
||||
|
@ -44,9 +44,9 @@ def api_v2_user_info(request):
|
|||
// ...
|
||||
]
|
||||
}
|
||||
"""
|
||||
"""
|
||||
try:
|
||||
username = request.GET['username']
|
||||
username = request.GET["username"]
|
||||
except KeyError:
|
||||
return error("no username passed")
|
||||
if not username:
|
||||
|
@ -56,66 +56,90 @@ def api_v2_user_info(request):
|
|||
except Profile.DoesNotExist:
|
||||
return error("no such user")
|
||||
|
||||
last_rating = list(profile.ratings.order_by('-contest__end_time'))
|
||||
last_rating = list(profile.ratings.order_by("-contest__end_time"))
|
||||
|
||||
resp = {
|
||||
"rank": profile.display_rank,
|
||||
"organizations": list(profile.organizations.values_list('key', flat=True)),
|
||||
"organizations": list(profile.organizations.values_list("key", flat=True)),
|
||||
}
|
||||
|
||||
contest_history = []
|
||||
for participation in (ContestParticipation.objects.filter(user=profile, virtual=0, contest__is_visible=True)
|
||||
.order_by('-contest__end_time')):
|
||||
for participation in ContestParticipation.objects.filter(
|
||||
user=profile, virtual=0, contest__is_visible=True
|
||||
).order_by("-contest__end_time"):
|
||||
contest = participation.contest
|
||||
|
||||
problems = list(contest.contest_problems.select_related('problem').defer('problem__description')
|
||||
.order_by('order'))
|
||||
rank, result = next(filter(lambda data: data[1].user == profile.user,
|
||||
ranker(contest_ranking_list(contest, problems),
|
||||
key=attrgetter('points', 'cumtime'))))
|
||||
problems = list(
|
||||
contest.contest_problems.select_related("problem")
|
||||
.defer("problem__description")
|
||||
.order_by("order")
|
||||
)
|
||||
rank, result = next(
|
||||
filter(
|
||||
lambda data: data[1].user == profile.user,
|
||||
ranker(
|
||||
contest_ranking_list(contest, problems),
|
||||
key=attrgetter("points", "cumtime"),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
contest_history.append({
|
||||
'contest': {
|
||||
'code': contest.key,
|
||||
'name': contest.name,
|
||||
'tags': list(contest.tags.values_list('name', flat=True)),
|
||||
'time_limit': contest.time_limit and contest.time_limit.total_seconds(),
|
||||
'start_time': contest.start_time.isoformat(),
|
||||
'end_time': contest.end_time.isoformat(),
|
||||
},
|
||||
'rank': rank,
|
||||
'rating': result.participation_rating,
|
||||
})
|
||||
contest_history.append(
|
||||
{
|
||||
"contest": {
|
||||
"code": contest.key,
|
||||
"name": contest.name,
|
||||
"tags": list(contest.tags.values_list("name", flat=True)),
|
||||
"time_limit": contest.time_limit
|
||||
and contest.time_limit.total_seconds(),
|
||||
"start_time": contest.start_time.isoformat(),
|
||||
"end_time": contest.end_time.isoformat(),
|
||||
},
|
||||
"rank": rank,
|
||||
"rating": result.participation_rating,
|
||||
}
|
||||
)
|
||||
|
||||
resp['contests'] = {
|
||||
resp["contests"] = {
|
||||
"current_rating": last_rating[0].rating if last_rating else None,
|
||||
'history': contest_history,
|
||||
"history": contest_history,
|
||||
}
|
||||
|
||||
solved_problems = []
|
||||
attempted_problems = []
|
||||
|
||||
problem_data = (Submission.objects.filter(points__gt=0, user=profile, problem__is_public=True,
|
||||
problem__is_organization_private=False)
|
||||
.annotate(max_pts=Max('points'))
|
||||
.values_list('max_pts', 'problem__points', 'problem__code')
|
||||
.distinct())
|
||||
problem_data = (
|
||||
Submission.objects.filter(
|
||||
points__gt=0,
|
||||
user=profile,
|
||||
problem__is_public=True,
|
||||
problem__is_organization_private=False,
|
||||
)
|
||||
.annotate(max_pts=Max("points"))
|
||||
.values_list("max_pts", "problem__points", "problem__code")
|
||||
.distinct()
|
||||
)
|
||||
for awarded_pts, max_pts, problem in problem_data:
|
||||
if awarded_pts == max_pts:
|
||||
solved_problems.append(problem)
|
||||
else:
|
||||
attempted_problems.append({
|
||||
'awarded': awarded_pts,
|
||||
'max': max_pts,
|
||||
'problem': problem,
|
||||
})
|
||||
attempted_problems.append(
|
||||
{
|
||||
"awarded": awarded_pts,
|
||||
"max": max_pts,
|
||||
"problem": problem,
|
||||
}
|
||||
)
|
||||
|
||||
resp['problems'] = {
|
||||
'points': profile.points,
|
||||
'solved': solved_problems,
|
||||
'attempted': attempted_problems,
|
||||
'authored': list(Problem.objects.filter(is_public=True, is_organization_private=False, authors=profile)
|
||||
.values_list('code', flat=True)),
|
||||
resp["problems"] = {
|
||||
"points": profile.points,
|
||||
"solved": solved_problems,
|
||||
"attempted": attempted_problems,
|
||||
"authored": list(
|
||||
Problem.objects.filter(
|
||||
is_public=True, is_organization_private=False, authors=profile
|
||||
).values_list("code", flat=True)
|
||||
),
|
||||
}
|
||||
|
||||
return JsonResponse(resp)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue