Skip to content
Snippets Groups Projects
Verified Commit c54e906c authored by Peter Stanko's avatar Peter Stanko
Browse files

Submission tree support

parent aaf3a264
No related branches found
No related tags found
1 merge request!13Cascade everywhere
Pipeline #
...@@ -5,6 +5,8 @@ from celery.utils.log import get_task_logger ...@@ -5,6 +5,8 @@ from celery.utils.log import get_task_logger
from portal import storage from portal import storage
from portal.async_celery import celery_app from portal.async_celery import celery_app
from portal.async_celery.storage import submission_store_ended from portal.async_celery.storage import submission_store_ended
from portal.database import SubmissionState
from portal.service import general
from portal.service.general import find_submission from portal.service.general import find_submission
log = get_task_logger(__name__) log = get_task_logger(__name__)
...@@ -29,6 +31,9 @@ def upload_results_to_storage(new_submission_id: str, path: str): ...@@ -29,6 +31,9 @@ def upload_results_to_storage(new_submission_id: str, path: str):
f"[ASYNC] Uploading result for the submission {new_submission.id} with {file_params}") f"[ASYNC] Uploading result for the submission {new_submission.id} with {file_params}")
entity = storage.results.create(entity_id=new_submission.id, **file_params) entity = storage.results.create(entity_id=new_submission.id, **file_params)
Path(path).unlink() Path(path).unlink()
new_submission.state = SubmissionState.FINISHED
general.write_entity(new_submission)
@celery_app.task(name='clone-submission-files') @celery_app.task(name='clone-submission-files')
......
import logging import logging
import flask
from flask_jwt_extended import jwt_required from flask_jwt_extended import jwt_required
from flask_restplus import Namespace, Resource from flask_restplus import Namespace, Resource
...@@ -10,7 +11,8 @@ from portal.service import auth, general, permissions ...@@ -10,7 +11,8 @@ from portal.service import auth, general, permissions
from portal.service.permissions import check_client, require_client from portal.service.permissions import check_client, require_client
from portal.service.reviews import create_review, create_review_items from portal.service.reviews import create_review, create_review_items
from portal.service.submissions import copy_submission, delete_submission, \ from portal.service.submissions import copy_submission, delete_submission, \
update_submission_state, cancel_submission, send_file_or_zip, upload_results_to_storage update_submission_state, cancel_submission, send_file_or_zip, upload_results_to_storage, \
send_files_tree
submissions_namespace = Namespace('submissions') submissions_namespace = Namespace('submissions')
...@@ -119,6 +121,28 @@ class SubmissionFiles(Resource): ...@@ -119,6 +121,28 @@ class SubmissionFiles(Resource):
raise NotImplementedError() raise NotImplementedError()
@submissions_namespace.route('/<string:sid>/files/sources/tree')
@submissions_namespace.doc({'sid': 'Submission id'})
@submissions_namespace.response(404, 'Submissions not found')
class SubmissionSourcesTree(Resource):
@jwt_required
def get(self, sid: str):
client = auth.find_client()
submission = general.find_submission(sid)
course = submission.project.course
# authorization
checks = [
check_client(client, course, ['read_submissions_all']),
submission_access_group(client, submission, course, [
'read_submissions_groups']),
(check_client(client, course, [
'read_submissions_own']) and submission.user == client)
]
permissions.require_any_check(client, checks=checks)
storage_submission = storage.submissions.get(submission.id)
return send_files_tree(storage_submission)
@submissions_namespace.route('/<string:sid>/files/sources') @submissions_namespace.route('/<string:sid>/files/sources')
@submissions_namespace.param('sid', 'Submission id') @submissions_namespace.param('sid', 'Submission id')
@submissions_namespace.response(404, 'Submissions not found') @submissions_namespace.response(404, 'Submissions not found')
...@@ -141,8 +165,29 @@ class SubmissionSourceFiles(Resource): ...@@ -141,8 +165,29 @@ class SubmissionSourceFiles(Resource):
return send_file_or_zip(storage_submission) return send_file_or_zip(storage_submission)
@submissions_namespace.route('/<string:sid>/files/test_files/tree')
@submissions_namespace.doc({'sid': 'Submission id'})
@submissions_namespace.response(404, 'Submissions not found')
class SubmissionTestFilesTree(Resource):
@jwt_required
def get(self, sid: str):
client = auth.find_client()
submission = general.find_submission(sid)
course = submission.project.course
# authorization
checks = [
check_client(client, course, ['read_submissions_all']),
submission_access_group(client, submission, course, [
'read_submissions_groups'])
]
permissions.require_any_check(client, checks=checks)
storage_entity = storage.test_files.get(submission.project.id)
return send_files_tree(storage_entity)
@submissions_namespace.route('/<string:sid>/files/test_files') @submissions_namespace.route('/<string:sid>/files/test_files')
@submissions_namespace.doc({'sid': 'Submission id'}) @submissions_namespace.doc({'sid': 'Submission id'})
@submissions_namespace.response(404, 'Submissions not found')
class SubmissionTestFiles(Resource): class SubmissionTestFiles(Resource):
@jwt_required @jwt_required
def get(self, sid: str): def get(self, sid: str):
...@@ -160,6 +205,27 @@ class SubmissionTestFiles(Resource): ...@@ -160,6 +205,27 @@ class SubmissionTestFiles(Resource):
return send_file_or_zip(storage_entity) return send_file_or_zip(storage_entity)
@submissions_namespace.route('/<string:sid>/files/results/tree')
@submissions_namespace.param('sid', 'Submission id')
@submissions_namespace.response(404, 'Submissions not found')
class SubmissionResultFilesTree(Resource):
@jwt_required
def get(self, sid: str):
client = auth.find_client()
submission = general.find_submission(sid)
course = submission.project.course
# authorization
checks = [
check_client(client, course, ['read_submissions_all']),
submission_access_group(client, submission, course, [
'read_submissions_groups'])
]
permissions.require_any_check(client, checks=checks)
storage_entity = storage.results.get(submission.id)
tree = send_files_tree(storage_entity)
return flask.jsonify(tree), 200
@submissions_namespace.route('/<string:sid>/files/results') @submissions_namespace.route('/<string:sid>/files/results')
@submissions_namespace.param('sid', 'Submission id') @submissions_namespace.param('sid', 'Submission id')
@submissions_namespace.response(404, 'Submissions not found') @submissions_namespace.response(404, 'Submissions not found')
......
...@@ -168,6 +168,12 @@ def send_file_or_zip(storage_entity): ...@@ -168,6 +168,12 @@ def send_file_or_zip(storage_entity):
return send_selected_file(storage_entity, path_query) return send_selected_file(storage_entity, path_query)
def send_files_tree(storage_entity):
tree = storage_entity.tree()
log.debug(f"[TREE] Tree for the storage entity {storage_entity.entity_id}: {tree} ")
return tree
def upload_file_is_allowed(file): def upload_file_is_allowed(file):
extension = Path(file.filename).suffix extension = Path(file.filename).suffix
log.debug(f"[ZIP] Extension for {file.filename}: {extension}") log.debug(f"[ZIP] Extension for {file.filename}: {extension}")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment