Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
bd5d9ef
Merge pull request #5 from KanonKC/main
KanonKC Nov 12, 2023
3c285db
MOD-59 Improved GradingResult + RuntimeResult
KanonKC Nov 13, 2023
6cc40a7
Removed print
KanonKC Nov 13, 2023
dc7ce2f
MOD-54,55: Removed is_admin and creator field
KanonKC Nov 24, 2023
34ec6a0
MOD-56: Secure subission serializer
KanonKC Nov 24, 2023
d5a1f92
detail -> message
KanonKC Nov 24, 2023
7722a96
Minor fixed
KanonKC Nov 26, 2023
11d7b8a
Removed print
KanonKC Nov 27, 2023
bbf04e3
Controller (Usecases)
KanonKC Nov 28, 2023
65167a4
Update to new api model
KanonKC Nov 29, 2023
d2fd708
Change to view-controller model
KanonKC Nov 29, 2023
85ea632
API: Get All Submissions from Account for one Problem
KanonKC Nov 29, 2023
e4ea13b
Submission and get are same path
KanonKC Nov 29, 2023
0c49fb2
Fail on grading (Wrong answer) + GET method for submission
KanonKC Nov 30, 2023
f0cbe25
Better submission
KanonKC Dec 1, 2023
78affbd
Fix: submission type + test program files
KanonKC Dec 1, 2023
3021752
Add runtime_status to Testcase model
KanonKC Dec 2, 2023
39197ec
Spare vite origin
KanonKC Dec 2, 2023
d5a3834
Problem -> create/update date and sort all problems by update date
KanonKC Dec 2, 2023
f9f4928
MOD-67,76: Submission handle many language
KanonKC Dec 4, 2023
ff62126
Updated Collection API
KanonKC Dec 4, 2023
86b2817
ProblemSecureSerializer also provide created/updated time
KanonKC Dec 5, 2023
29d35ea
Draft: All problem with best submission
KanonKC Dec 6, 2023
0e3b1c5
Explore problems api
KanonKC Dec 7, 2023
cb203e4
Best submission sorted by passed_ratio + sub_id
KanonKC Dec 9, 2023
5bb8072
Fix: Submission missing after problem updated
KanonKC Dec 10, 2023
c077858
Deprecated testcases
KanonKC Dec 11, 2023
91b630f
MOD-72,73: CreateProblem accept problem with runtime error
KanonKC Dec 12, 2023
c52b84d
Ignore testcase+source
KanonKC Dec 14, 2023
2b525ba
Created date + updated date for Collection
KanonKC Dec 14, 2023
9f6d71f
Update some collection API
KanonKC Dec 15, 2023
6a3a1b1
Topic (Course) API
KanonKC Dec 16, 2023
b7bc096
Update Topic API
KanonKC Dec 17, 2023
b3dd86c
Update get topic API
KanonKC Dec 17, 2023
1f97808
API: Public topic view (Populate hell)
KanonKC Dec 19, 2023
f532696
API for problem in course view
KanonKC Dec 20, 2023
5a00b0d
Extend descirption length
KanonKC Dec 20, 2023
62541a3
Valid description for older version
KanonKC Dec 21, 2023
c6d3372
fix: submission serializer also include account
KanonKC Dec 23, 2023
53a51bb
DB updated script folder
KanonKC Dec 24, 2023
f9d71b0
Improve submission search quality
KanonKC Dec 25, 2023
f0150ce
MOD-90: Model: Group, GroupMember
KanonKC Dec 25, 2023
8b4836b
Group API (Not finished)
KanonKC Dec 26, 2023
4f2d919
More group apis
KanonKC Dec 27, 2023
c1fa2e3
MOD-91: Basic API for Group
KanonKC Dec 29, 2023
cac6066
Change ID from sequence number to random uuid4
KanonKC Dec 31, 2023
c92efc5
Get topics by accessible
KanonKC Dec 31, 2023
422745d
TopicPopulateTopicCollectionPopulateCollection
KanonKC Jan 3, 2024
d7f2297
Migration to main account
KanonKC Jan 3, 2024
fbc2271
Removed runner code
KanonKC Jan 3, 2024
40ad874
Update topic apis
KanonKC Jan 4, 2024
1a74dec
Get topic populate problems
KanonKC Jan 4, 2024
5fdc9d2
Collection permission
KanonKC Jan 6, 2024
0f584e7
Public collections show only permitted collections
KanonKC Jan 7, 2024
288a1eb
Get topic populate for collection group permissions
KanonKC Jan 8, 2024
355bdf4
Get problem included group permissions
KanonKC Jan 10, 2024
2ebb12d
Manage problem permissions api
KanonKC Jan 11, 2024
6fcafa8
Get problems in collection populated problem groups permissions
KanonKC Jan 11, 2024
b55a676
Get topic public can check permission at problem level
KanonKC Jan 11, 2024
15b11f9
Update delete api
KanonKC Jan 12, 2024
01b4b1f
Merge pull request #6 from KanonKC/uuid-pk
KanonKC Jan 13, 2024
6456f52
manual distinct in get accessed topics by account
KanonKC Jan 13, 2024
eaeae9a
Update default allowed language
KanonKC Jan 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
.dist/
__pycache__

api/sandbox/testcases/*.txt
api/sandbox/section*/testcases/*.txt
api/sandbox/section*/runner*
runner.py
@/*

env/
.env

[0-9]*.txt
# [0-9]*.txt

media/testfile
media/topic
Expand All @@ -20,5 +22,4 @@ media/resource
tempCodeRunnerFile.py

*.sqlite3
*.exe

*.exe
4 changes: 4 additions & 0 deletions Backend/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,14 @@

CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
"http://localhost:4000",
"http://localhost:5173",
"http://localhost:5174",
"http://localhost:3001",
"http://192.168.216.250:3000",
"http://192.168.0.2:3000",
"http://192.168.0.5:3000",
"http://192.168.0.11:5173",
FRONEND_URL
]

Expand Down
4 changes: 2 additions & 2 deletions api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ class ProblemAdmin(admin.ModelAdmin):
list_filter = ['language']

class AccountAdmin(admin.ModelAdmin):
list_display = ['account_id','username','email','is_admin','is_active']
list_filter = ['is_admin','is_active']
list_display = ['account_id','username','email','is_active']
list_filter = ['is_active']

admin.site.register(Problem,ProblemAdmin)
admin.site.register(Account,AccountAdmin)
18 changes: 18 additions & 0 deletions api/controllers/account/create_account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *

def create_account(request):
request.data['password'] = passwordEncryption(request.data['password'])
try:
account = Account.objects.create(**request.data)
except Exception as e:
return Response({'message':str(e)},status=status.HTTP_400_BAD_REQUEST)
serialize = AccountSerializer(account)
return Response(serialize.data,status=status.HTTP_201_CREATED)
17 changes: 17 additions & 0 deletions api/controllers/account/get_account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *

def get_account(account_id:str):
try:
account = Account.objects.get(account_id=account_id)
serialize = AccountSerializer(account)
return Response(serialize.data,status=status.HTTP_200_OK)
except:
return Response({'message':'Account not found!'},status=status.HTTP_404_NOT_FOUND)
16 changes: 16 additions & 0 deletions api/controllers/account/get_all_accounts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *

def get_all_accounts():
accounts = Account.objects.all()
serialize = AccountSecureSerializer(accounts,many=True)
return Response({
"accounts": serialize.data
},status=status.HTTP_200_OK)
21 changes: 21 additions & 0 deletions api/controllers/auth/authorization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *
from time import time

def authorization(request):
try:
account = Account.objects.get(account_id=request.data['account_id'])
account_dict = model_to_dict(account)
if account_dict['token_expire'] >= time() and account_dict['token'] == request.data['token']:
return Response({'result':True},status=status.HTTP_200_OK)
return Response({'result':False},status=status.HTTP_200_OK)
except Account.DoesNotExist:
return Response({'result':False},status=status.HTTP_200_OK)
# return Response({'message':"User doesn't exists!"},status=status.HTTP_404_NOT_FOUND)
29 changes: 29 additions & 0 deletions api/controllers/auth/login.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *
from decouple import config
from uuid import uuid4
from time import time

TOKEN_LIFETIME = int(config('TOKEN_LIFETIME_SECOND')) # (Second)

def login(request):
try:
account = Account.objects.get(username=request.data['username'])
account_dict = model_to_dict(account)

if passwordEncryption(request.data['password']) == account_dict['password']:
account.token = uuid4().hex
account.token_expire = int(time()+TOKEN_LIFETIME)
account.save()
return Response(model_to_dict(account),status=status.HTTP_202_ACCEPTED)
else:
return Response({'message':"Incorrect password!"},status=status.HTTP_406_NOT_ACCEPTABLE)
except Account.DoesNotExist:
return Response({'message':"User doesn't exists!"},status=status.HTTP_404_NOT_FOUND)
24 changes: 24 additions & 0 deletions api/controllers/auth/logout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *
from decouple import config
from uuid import uuid4
from time import time

def logout(request):
try:
account = Account.objects.get(account_id=request.data['account_id'])
if account.token == request.data['token']:
account.token = None
account.save()
return Response(model_to_dict(account),status=status.HTTP_200_OK)
else:
return Response({'message':"Invalid token!"},status=status.HTTP_200_OK)
except Account.DoesNotExist:
return Response({'message':"User doesn't exists!"},status=status.HTTP_404_NOT_FOUND)
38 changes: 38 additions & 0 deletions api/controllers/collection/add_problems_to_collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *

def add_problems_to_collection(collection:Collection,request):
populated_problems = []

index = 0
for problem_id in request.data['problem_ids']:

problem = Problem.objects.get(problem_id=problem_id)

alreadyExist = CollectionProblem.objects.filter(problem=problem,collection=collection)
if alreadyExist:
alreadyExist.delete()

collection_problem = CollectionProblem(
problem=problem,
collection=collection,
order=index
)
collection_problem.save()
index += 1
populated_problems.append(collection_problem)
collection.updated_date = timezone.now()
problem_serialize = CollectionProblemPopulateProblemSecureSerializer(populated_problems,many=True)
collection_serialize = CollectionSerializer(collection)

return Response({
**collection_serialize.data,
'problems': problem_serialize.data
},status=status.HTTP_201_CREATED)
20 changes: 20 additions & 0 deletions api/controllers/collection/create_collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *

def create_collection(account_id:str,request):

request.data['creator'] = account_id
serialize = CollectionSerializer(data=request.data)

if serialize.is_valid():
serialize.save()
return Response(serialize.data,status=status.HTTP_201_CREATED)
else:
return Response(serialize.errors,status=status.HTTP_400_BAD_REQUEST)
13 changes: 13 additions & 0 deletions api/controllers/collection/delete_collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *

def delete_collection(collection:Collection):
collection.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
37 changes: 37 additions & 0 deletions api/controllers/collection/get_all_collections.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *

def get_all_collections(request):
collections = Collection.objects.all()

account_id = request.query_params.get('account_id',0)

if account_id:
collections = collections.filter(creator_id=account_id)

populated_collections = []
for collection in collections:
con_probs = CollectionProblem.objects.filter(collection=collection)

populated_cp = []
for cp in con_probs:
prob_serialize = ProblemSerializer(cp.problem)
cp_serialize = CollectionProblemSerializer(cp)
populated_cp.append({**cp_serialize.data,**prob_serialize.data})

serialize = CollectionSerializer(collection)
collection_data = serialize.data
collection_data['problems'] = populated_cp

populated_collections.append(collection_data)

return Response({
'collections': populated_collections
},status=status.HTTP_200_OK)
34 changes: 34 additions & 0 deletions api/controllers/collection/get_all_collections_by_account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *

def populated_problems(collections: Collection):
problemCollections = CollectionProblem.objects.filter(collection__in=collections)

populated_collections = []
for collection in collections:
collection.problems = problemCollections.filter(collection=collection)
populated_collections.append(collection)

return populated_collections

def get_all_collections_by_account(account:Account):

collections = Collection.objects.filter(creator=account).order_by('-updated_date')
collections = populated_problems(collections)
serialize = CollectionPopulateCollectionProblemsPopulateProblemSerializer(collections,many=True)

manageableCollections = Collection.objects.filter(collectiongrouppermission__permission_manage_collections=True,collectiongrouppermission__group__in=GroupMember.objects.filter(account=account).values_list("group",flat=True)).order_by('-updated_date')
manageableCollections = populated_problems(manageableCollections)
manageableSerialize = CollectionPopulateCollectionProblemsPopulateProblemSerializer(manageableCollections,many=True)

return Response({
'collections': serialize.data,
'manageable_collections': manageableSerialize.data
},status=status.HTTP_200_OK)
23 changes: 23 additions & 0 deletions api/controllers/collection/get_collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *

def get_collection(collection:Collection):

collection.problems = CollectionProblem.objects.filter(collection=collection).order_by('order')
collection.group_permissions = CollectionGroupPermission.objects.filter(collection=collection)

for cp in collection.problems:
cp.problem.testcases = Testcase.objects.filter(problem=cp.problem,deprecated=False)
cp.problem.group_permissions = ProblemGroupPermission.objects.filter(problem=cp.problem)

serializer = CollectionPopulateCollectionProblemsPopulateProblemPopulateAccountAndTestcasesAndProblemGroupPermissionsPopulateGroupAndCollectionGroupPermissionsPopulateGroupSerializer(collection)


return Response(serializer.data ,status=status.HTTP_200_OK)
14 changes: 14 additions & 0 deletions api/controllers/collection/remove_problems_from_collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *

def remove_problems_from_collection(collection:Collection,request):
CollectionProblem.objects.filter(collection=collection,problem_id__in=request.data['problem_ids']).delete()
collection.updated_date = timezone.now()
return Response(status=status.HTTP_204_NO_CONTENT)
22 changes: 22 additions & 0 deletions api/controllers/collection/update_collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from api.utility import passwordEncryption
from rest_framework.response import Response
from rest_framework.decorators import api_view
from api.sandbox.grader import PythonGrader
from ...constant import GET,POST,PUT,DELETE
from ...models import *
from rest_framework import status
from django.forms.models import model_to_dict
from ...serializers import *

def update_collection(collection:Collection,request):

collection.name = request.data.get('name',collection.name)
collection.description = request.data.get('description',collection.description)
collection.is_private = request.data.get('is_private',collection.is_private)
collection.is_active = request.data.get('is_active',collection.is_active)
collection.updated_date = timezone.now()

collection.save()
collection_ser = CollectionSerializer(collection)

return Response(collection_ser.data,status=status.HTTP_200_OK)
Loading