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();
           })