From d8865c6ec3056a69353c48ae53174745012ef946 Mon Sep 17 00:00:00 2001 From: KanonKC Date: Tue, 30 Jan 2024 01:40:28 +0700 Subject: [PATCH 1/8] Handle numpy error --- .../problem/update_problem_difficulty.py | 12 +++++++++++- api/difficulty_predictor/predictor.py | 15 ++++++++++----- api/difficulty_predictor/preprocess.py | 12 ++++++++++-- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/api/controllers/problem/update_problem_difficulty.py b/api/controllers/problem/update_problem_difficulty.py index c88445f..4739499 100644 --- a/api/controllers/problem/update_problem_difficulty.py +++ b/api/controllers/problem/update_problem_difficulty.py @@ -7,11 +7,21 @@ from rest_framework import status from django.forms.models import model_to_dict from ...serializers import * -import pandas as pd from ...difficulty_predictor.preprocess import * from ...difficulty_predictor.predictor import * +try: + import pandas as pd + pd.options.mode.chained_assignment = None + success = True +except: + success = False + def update_problem_difficulty(problem:Problem): + + if not success: + return + submissions = Submission.objects.filter(problem=problem) if submissions.count() < 10: diff --git a/api/difficulty_predictor/predictor.py b/api/difficulty_predictor/predictor.py index 5a68bad..c1ff3b8 100644 --- a/api/difficulty_predictor/predictor.py +++ b/api/difficulty_predictor/predictor.py @@ -1,11 +1,16 @@ -import pickle -# Read sav - -with open('./api/difficulty_predictor/difficulty_predictor_667.sav', 'rb') as f: - difficulty = pickle.load(f) +try: + import pickle + with open('./api/difficulty_predictor/difficulty_predictor_667.sav', 'rb') as f: + difficulty = pickle.load(f) +except: + print("Error during loading difficulty_predictor_667.sav") + difficulty = None + pass # Predict some model def predict(avg_first_passed_total_attempts,avg_first_passed_time_used): + if not difficulty: + return 0 return int(difficulty.predict([[avg_first_passed_total_attempts,avg_first_passed_time_used]])[0]) \ No newline at end of file diff --git a/api/difficulty_predictor/preprocess.py b/api/difficulty_predictor/preprocess.py index f087313..7527775 100644 --- a/api/difficulty_predictor/preprocess.py +++ b/api/difficulty_predictor/preprocess.py @@ -1,7 +1,15 @@ -import pandas as pd -pd.options.mode.chained_assignment = None +try: + import pandas as pd + pd.options.mode.chained_assignment = None + success = True +except: + success = False def modelgrader_preprocessor(submission_df): + + if not success: + return [-1,-1] + submission_df = submission_df[['account_id', 'problem_id','is_passed','language','date','submission_code','passed_ratio']] # Change submission_code to string From 4b76765bea3b0215f48aaa66c7a5d9578d98755a Mon Sep 17 00:00:00 2001 From: KanonKC Date: Tue, 30 Jan 2024 01:41:52 +0700 Subject: [PATCH 2/8] Remove pd --- api/views/script.py | 1 - 1 file changed, 1 deletion(-) diff --git a/api/views/script.py b/api/views/script.py index b2b2741..f907379 100644 --- a/api/views/script.py +++ b/api/views/script.py @@ -1,4 +1,3 @@ -import pandas as pd from api.utility import passwordEncryption from rest_framework.response import Response from rest_framework.decorators import api_view From 39346662a2bd17b7b14107af8cfdb88b157ef5e2 Mon Sep 17 00:00:00 2001 From: KanonKC Date: Sun, 21 Jul 2024 13:42:45 +0700 Subject: [PATCH 3/8] Security container (Not working right now) --- api/sandbox/container.py | 41 ++++++++++++++++++++++++++++++++++++++++ api/sandbox/grader.py | 1 + 2 files changed, 42 insertions(+) create mode 100644 api/sandbox/container.py diff --git a/api/sandbox/container.py b/api/sandbox/container.py new file mode 100644 index 0000000..4ab25ac --- /dev/null +++ b/api/sandbox/container.py @@ -0,0 +1,41 @@ +import sys +import resource +import pyseccomp as seccomp + + +MEMORY_LIMIT = 64 * 1024 * 1024 # 64kb +CPU_TIME_LIMIT = 1 # 1sec +WRITE_LIMIT = 512 # 512bytes + + +def drop_perms(): + # respond with EPERM: operation not permitted so users can tell + # they're being blocked from doing something + filter = seccomp.SyscallFilter(seccomp.ERRNO(seccomp.errno.EPERM)) + + # allow `write`ing to two already-opened files stdout and stderr + filter.add_rule( + seccomp.ALLOW, "write", seccomp.Arg(0, seccomp.EQ, sys.stdout.fileno()) + ) + filter.add_rule( + seccomp.ALLOW, "write", seccomp.Arg(0, seccomp.EQ, sys.stderr.fileno()) + ) + + # load the filter in the kernel + filter.load() + + +def set_mem_limit(): + # virtual memory + resource.setrlimit(resource.RLIMIT_AS, (MEMORY_LIMIT, MEMORY_LIMIT)) + # cpu time + resource.setrlimit(resource.RLIMIT_CPU, (CPU_TIME_LIMIT, CPU_TIME_LIMIT)) + # write limit i.e. don't allow an infinite stream to stdout/stderr + resource.setrlimit(resource.RLIMIT_FSIZE, (WRITE_LIMIT, WRITE_LIMIT)) + + +if __name__ == "__main__": + code = sys.argv[1] + set_mem_limit() + drop_perms() + exec(code) \ No newline at end of file diff --git a/api/sandbox/grader.py b/api/sandbox/grader.py index fb40e71..7ba0752 100644 --- a/api/sandbox/grader.py +++ b/api/sandbox/grader.py @@ -4,6 +4,7 @@ Usecases: - Create problem - Update code + - Update testcases - Submit problem """ From 00e5b04f4d0d3d56a87031f380cb16b549a766f1 Mon Sep 17 00:00:00 2001 From: KanonKC Date: Mon, 11 Nov 2024 16:24:02 +0700 Subject: [PATCH 4/8] Add pdf field --- api/migrations/0054_problem_pdf_url.py | 18 ++++++++++++++++++ api/models.py | 1 + 2 files changed, 19 insertions(+) create mode 100644 api/migrations/0054_problem_pdf_url.py diff --git a/api/migrations/0054_problem_pdf_url.py b/api/migrations/0054_problem_pdf_url.py new file mode 100644 index 0000000..134cd65 --- /dev/null +++ b/api/migrations/0054_problem_pdf_url.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.2 on 2024-11-11 08:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0053_problem_difficulty'), + ] + + operations = [ + migrations.AddField( + model_name='problem', + name='pdf_url', + field=models.FileField(blank=True, default=None, null=True, upload_to='import-pdf/'), + ), + ] diff --git a/api/models.py b/api/models.py index b2a874e..ee4367e 100644 --- a/api/models.py +++ b/api/models.py @@ -44,6 +44,7 @@ class Problem(models.Model): updated_date = models.DateTimeField(default=timezone.now) sharing = models.BooleanField(default=False,blank=True) allowed_languages = models.CharField(max_length=1000,blank=True,default="") + pdf_url = models.FileField(upload_to='import-pdf/',null=True,blank=True,default=None) difficulty = models.IntegerField(default=0,blank=True) class Testcase(models.Model): From 2ed6063ae47c08a51b821afbc63a90aa5b16b4ba Mon Sep 17 00:00:00 2001 From: KanonKC Date: Sun, 13 Apr 2025 11:18:17 +0700 Subject: [PATCH 5/8] Get all problems as creator hide some testcase field --- .../problem/get_all_problems_by_account.py | 4 ++-- api/serializers.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/api/controllers/problem/get_all_problems_by_account.py b/api/controllers/problem/get_all_problems_by_account.py index a9d373b..43ff2ca 100644 --- a/api/controllers/problem/get_all_problems_by_account.py +++ b/api/controllers/problem/get_all_problems_by_account.py @@ -29,8 +29,8 @@ def get_all_problems_by_account(account:Account,request): problem.testcases = Testcase.objects.filter(problem=problem,deprecated=False) # problem_ser = ProblemPopulateTestcaseSerializer(problems,many=True) - personalSerialize = ProblemPopulateTestcaseSerializer(personalProblems,many=True) - manageableSerialize = ProblemPopulateTestcaseSerializer(manageableProblems,many=True) + personalSerialize = ProblemPopulatePartialTestcaseSerializer(personalProblems,many=True) + manageableSerialize = ProblemPopulatePartialTestcaseSerializer(manageableProblems,many=True) return Response({ "start":start, diff --git a/api/serializers.py b/api/serializers.py index 7f61023..14ef9d6 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -131,6 +131,17 @@ class Meta: model = Testcase fields = "__all__" +class TestcasePartialSerializer(serializers.ModelSerializer): + class Meta: + model = Testcase + fields = ['testcase_id','runtime_status'] +class ProblemPopulatePartialTestcaseSerializer(serializers.ModelSerializer): + creator = AccountSecureSerializer() + testcases = TestcasePartialSerializer(many=True) + class Meta: + model = Problem + fields = "__all__" + include = ['testcases'] class ProblemPopulateTestcaseSerializer(serializers.ModelSerializer): creator = AccountSecureSerializer() testcases = TestcaseSerializer(many=True) From 6f1780291d2f9b548c5ffda9f495e85deab0983d Mon Sep 17 00:00:00 2001 From: KanonKC Date: Sun, 13 Apr 2025 11:35:44 +0700 Subject: [PATCH 6/8] Can query problems --- api/controllers/problem/get_all_problems_by_account.py | 9 +++++++-- api/serializers.py | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/api/controllers/problem/get_all_problems_by_account.py b/api/controllers/problem/get_all_problems_by_account.py index 43ff2ca..06ecce6 100644 --- a/api/controllers/problem/get_all_problems_by_account.py +++ b/api/controllers/problem/get_all_problems_by_account.py @@ -12,16 +12,21 @@ def get_all_problems_by_account(account:Account,request): start = int(request.query_params.get("start",0)) end = int(request.query_params.get("end",-1)) + query = request.query_params.get("query","") if end == -1: end = None - personalProblems = Problem.objects.filter(creator=account).order_by('-updated_date') + personalProblems = Problem.objects.filter(creator=account, title__icontains=query).order_by('-updated_date') maxPersonal = len(personalProblems) if start < maxPersonal and start < maxPersonal: personalProblems = personalProblems[start:end] for problem in personalProblems: problem.testcases = Testcase.objects.filter(problem=problem,deprecated=False) - manageableProblems = Problem.objects.filter(problemgrouppermission__permission_manage_problems=True,problemgrouppermission__group__in=GroupMember.objects.filter(account=account).values_list("group",flat=True)).order_by('-updated_date') + manageableProblems = Problem.objects.filter( + problemgrouppermission__permission_manage_problems=True, + problemgrouppermission__group__in=GroupMember.objects.filter(account=account).values_list("group",flat=True), + title__icontains=query + ).order_by('-updated_date') maxManageable = len(manageableProblems) if start < maxManageable and start < maxManageable: manageableProblems = manageableProblems[start:end] diff --git a/api/serializers.py b/api/serializers.py index 14ef9d6..72b59bf 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -141,6 +141,7 @@ class ProblemPopulatePartialTestcaseSerializer(serializers.ModelSerializer): class Meta: model = Problem fields = "__all__" + # fields = ['problem_id','title','creator','testcases'] include = ['testcases'] class ProblemPopulateTestcaseSerializer(serializers.ModelSerializer): creator = AccountSecureSerializer() From eb3de5439dc86e872a79c9d96ce077f994e078c9 Mon Sep 17 00:00:00 2001 From: KanonKC Date: Sun, 13 Apr 2025 14:55:24 +0700 Subject: [PATCH 7/8] Problem submissions pagination --- .../get_all_submissions_by_creator_problem.py | 18 ++++++++++++++++-- api/views/submission.py | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/api/controllers/submission/get_all_submissions_by_creator_problem.py b/api/controllers/submission/get_all_submissions_by_creator_problem.py index c4a4dde..2bf134a 100644 --- a/api/controllers/submission/get_all_submissions_by_creator_problem.py +++ b/api/controllers/submission/get_all_submissions_by_creator_problem.py @@ -8,13 +8,22 @@ from django.forms.models import model_to_dict from ...serializers import * -def get_all_submissions_by_creator_problem(problem:Problem): +def get_all_submissions_by_creator_problem(problem:Problem, request): + + start = int(request.query_params.get("start",0)) + end = int(request.query_params.get("end",-1)) + # query = request.query_params.get("query","") + if end == -1: end = None + submissions = Submission.objects.filter(problem=problem) + total = submissions.count() + if submissions.count() == 0: return Response({"submissions": []},status=status.HTTP_204_NO_CONTENT) submissions = submissions.order_by('-date') + submissions = submissions[start:end] result = [] @@ -25,4 +34,9 @@ def get_all_submissions_by_creator_problem(problem:Problem): submissions_serializer = SubmissionPopulateSubmissionTestcaseAndAccountSerializer(result,many=True) - return Response({"submissions": submissions_serializer.data},status=status.HTTP_200_OK) \ No newline at end of file + return Response({ + "submissions": submissions_serializer.data, + "start": start, + "end": end, + "total": total, + },status=status.HTTP_200_OK) \ No newline at end of file diff --git a/api/views/submission.py b/api/views/submission.py index 1ede8e0..bd9ec4a 100644 --- a/api/views/submission.py +++ b/api/views/submission.py @@ -29,7 +29,7 @@ def account_problem_submission_view(request,problem_id,account_id): @api_view([GET]) def creator_problem_submissions_view(request,account_id,problem_id): problem = Problem.objects.get(problem_id=problem_id) - return get_all_submissions_by_creator_problem(problem) + return get_all_submissions_by_creator_problem(problem, request) @api_view([GET]) def all_submission_view(request): From d7cc0711340bdb361a273a8b9172fe52feaef1a7 Mon Sep 17 00:00:00 2001 From: KanonKC Date: Sun, 13 Apr 2025 17:04:15 +0700 Subject: [PATCH 8/8] Get problem submissions return problem data --- .../submission/get_all_submissions_by_creator_problem.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/controllers/submission/get_all_submissions_by_creator_problem.py b/api/controllers/submission/get_all_submissions_by_creator_problem.py index 2bf134a..1f46dee 100644 --- a/api/controllers/submission/get_all_submissions_by_creator_problem.py +++ b/api/controllers/submission/get_all_submissions_by_creator_problem.py @@ -32,9 +32,13 @@ def get_all_submissions_by_creator_problem(problem:Problem, request): submission.runtime_output = submission_testcases result.append(submission) + problem.testcases = Testcase.objects.filter(problem=problem,deprecated=False) + submissions_serializer = SubmissionPopulateSubmissionTestcaseAndAccountSerializer(result,many=True) + problem_serializer = ProblemPopulateTestcaseSerializer(problem) return Response({ + "problem": problem_serializer.data, "submissions": submissions_serializer.data, "start": start, "end": end,