You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2019/05/22 23:17:09 UTC
[airavata-django-portal] 02/04: AIRAVATA-3033 user storage API:
make dirs, upload file
This is an automated email from the ASF dual-hosted git repository.
machristie pushed a commit to branch airavata-3016
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git
commit 028fd9eb326f2649766b9246ef6d562bc8420594
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Wed May 22 14:51:26 2019 -0400
AIRAVATA-3033 user storage API: make dirs, upload file
---
django_airavata/apps/api/data_products_helper.py | 4 ++
django_airavata/apps/api/datastore.py | 5 +-
django_airavata/apps/api/serializers.py | 2 +
django_airavata/apps/api/urls.py | 1 -
django_airavata/apps/api/views.py | 57 +++++++++-------------
.../experiment/input-editors/FileInputEditor.vue | 6 ++-
6 files changed, 35 insertions(+), 40 deletions(-)
diff --git a/django_airavata/apps/api/data_products_helper.py b/django_airavata/apps/api/data_products_helper.py
index 008f3bb..51f8951 100644
--- a/django_airavata/apps/api/data_products_helper.py
+++ b/django_airavata/apps/api/data_products_helper.py
@@ -38,6 +38,10 @@ def exists(request, data_product):
return datastore.exists(request.user.username, path)
+def dir_exists(request, path):
+ return datastore.exists(request.user.username, path)
+
+
def delete(request, data_product):
"Delete replica for data product in this data store."
path = _get_replica_filepath(data_product)
diff --git a/django_airavata/apps/api/datastore.py b/django_airavata/apps/api/datastore.py
index fa625f0..220803f 100644
--- a/django_airavata/apps/api/datastore.py
+++ b/django_airavata/apps/api/datastore.py
@@ -41,9 +41,8 @@ def save(username, path, file):
def create_user_dir(username, path):
user_data_storage = _user_data_storage(username)
- user_dir = user_data_storage.get_valid_name(path)
- if not user_data_storage.exists(user_dir):
- os.mkdir(user_data_storage.path(user_dir))
+ if not user_data_storage.exists(path):
+ os.makedirs(user_data_storage.path(path))
else:
raise Exception(
"Directory {} already exists".format(path))
diff --git a/django_airavata/apps/api/serializers.py b/django_airavata/apps/api/serializers.py
index 05825b8..1f0d69e 100644
--- a/django_airavata/apps/api/serializers.py
+++ b/django_airavata/apps/api/serializers.py
@@ -772,6 +772,8 @@ class UserStorageDirectorySerializer(serializers.Serializer):
class UserStoragePathSerializer(serializers.Serializer):
directories = UserStorageDirectorySerializer(many=True)
files = UserStorageFileSerializer(many=True)
+ # uploaded is populated after a file upload
+ uploaded = DataProductSerializer(read_only=True)
# ModelSerializers
diff --git a/django_airavata/apps/api/urls.py b/django_airavata/apps/api/urls.py
index 6b80b19..9150e7c 100644
--- a/django_airavata/apps/api/urls.py
+++ b/django_airavata/apps/api/urls.py
@@ -49,7 +49,6 @@ urlpatterns = [
# url(r'^get-ufiles$', views.get_user_files, name='get_user_files'),
# url(r'^upload-ufiles$', views.upload_user_file, name='upload_user_file'),
# url(r'^delete-ufiles$', views.delete_user_file, name='delete_user_file'),
- url(r'^upload$', views.upload_input_file, name='upload_input_file'),
url(r'^download', views.download_file, name='download_file'),
url(r'^delete-file$', views.delete_file, name='delete_file'),
url(r'^data-products', views.DataProductView.as_view(),
diff --git a/django_airavata/apps/api/views.py b/django_airavata/apps/api/views.py
index bc2edfc..caf1c35 100644
--- a/django_airavata/apps/api/views.py
+++ b/django_airavata/apps/api/views.py
@@ -858,30 +858,6 @@ class DataProductView(APIView):
@login_required
-def upload_input_file(request):
- try:
- project_id = request.POST['project-id']
- project = request.airavata_client.getProject(
- request.authz_token, project_id)
- exp_name = request.POST['experiment-name']
- input_file = request.FILES['file']
- # TODO: experiment_data_dir should be passed in
- experiment_data_dir = data_products_helper.get_experiment_dir(
- request, project_name=project.name, experiment_name=exp_name)
- data_product = data_products_helper.save(request, experiment_data_dir,
- input_file)
- serializer = serializers.DataProductSerializer(
- data_product, context={'request': request})
- return JsonResponse({'uploaded': True,
- 'data-product': serializer.data})
- except Exception as e:
- log.error("Failed to upload file", exc_info=True)
- resp = JsonResponse({'uploaded': False, 'error': str(e)})
- resp.status_code = 500
- return resp
-
-
-@login_required
def download_file(request):
# TODO check that user has access to this file using sharing API
data_product_uri = request.GET.get('data-product-uri', '')
@@ -906,13 +882,6 @@ def download_file(request):
@login_required
-def user_storage_download_file(request, path):
- user_storage_path = path
- if user_storage_path.startswith("/"):
- user_storage_path = "." + user_storage_path
-
-
-@login_required
def delete_file(request):
# TODO check that user has write access to this file using sharing API
data_product_uri = request.GET.get('data-product-uri', '')
@@ -1377,10 +1346,30 @@ class UserStoragePathView(APIView):
if user_storage_path.startswith("/"):
user_storage_path = "." + user_storage_path
# TODO: check if path is directory or file
+ return self._create_response(request, path)
+
+ def post(self, request, path="/", format=None):
+ user_storage_path = path
+ if user_storage_path.startswith("/"):
+ user_storage_path = "." + user_storage_path
+ if not data_products_helper.dir_exists(request, user_storage_path):
+ data_products_helper.create_user_dir(request, user_storage_path)
+
+ if 'file' in request.FILES:
+ user_file = request.FILES['file']
+ data_product = data_products_helper.save(
+ request, user_storage_path, user_file)
+ return self._create_response(request, path, uploaded=data_product)
+
+ def _create_response(self, request, path, uploaded=None):
directories, files = data_products_helper.listdir(request, path)
- serializer = self.serializer_class(
- {'directories': directories, 'files': files},
- context={'request': request})
+ data = {
+ 'directories': directories,
+ 'files': files
+ }
+ if uploaded is not None:
+ data['uploaded'] = uploaded
+ serializer = self.serializer_class(data, context={'request': request})
return Response(serializer.data)
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/FileInputEditor.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/FileInputEditor.vue
index 8cdc03b..84c1bcd 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/FileInputEditor.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/input-editors/FileInputEditor.vue
@@ -88,9 +88,11 @@ export default {
data.append("project-id", this.experiment.projectId);
data.append("experiment-name", this.experiment.experimentName);
this.$emit("uploadstart");
- utils.FetchUtils.post("/api/upload", data, "", { showSpinner: false })
+ // TODO: use the experimentDataDir off the experiment model as the path
+ // to upload to
+ utils.FetchUtils.post("/api/user-storage/~/tmp/", data, "", { showSpinner: false })
.then(result => {
- this.dataProduct = new models.DataProduct(result["data-product"]);
+ this.dataProduct = new models.DataProduct(result["uploaded"]);
this.data = this.dataProduct.productUri;
this.valueChanged();
})