From b3af7202a989890e8aef916197a3eac1b6577028 Mon Sep 17 00:00:00 2001 From: Stefano Alberto Russo <stefano.russo@gmail.com> Date: Mon, 29 Mar 2021 20:25:48 +0200 Subject: [PATCH] Added support for file uploads. --- services/webapp/code/rosetta/core_app/api.py | 62 ++++++++++++++++---- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/services/webapp/code/rosetta/core_app/api.py b/services/webapp/code/rosetta/core_app/api.py index e7afc3f..5ea5cb1 100644 --- a/services/webapp/code/rosetta/core_app/api.py +++ b/services/webapp/code/rosetta/core_app/api.py @@ -345,11 +345,6 @@ print(port) # File manager APIs #========================================== - - - - - class FileManagerAPI(PrivateGETAPI, PrivatePOSTAPI): """ get: @@ -365,6 +360,14 @@ class FileManagerAPI(PrivateGETAPI, PrivatePOSTAPI): def scp_command(self, source, dest, user, computing, mode='get'): + # Prepare paths for scp. They have been already made shell-ready, but we need to triple-escape + # spaces on remote source or destination: My\ Folder mut become My\\\ Folder. + + if mode=='get': + source = source.replace('\ ', '\\\\\\ ') + else: + dest = dest.replace('\ ', '\\\\\\ ') + # Get user key user_keys = KeyPair.objects.get(user=user, default=True) @@ -387,7 +390,7 @@ class FileManagerAPI(PrivateGETAPI, PrivatePOSTAPI): if mode=='get': command = 'scp -o LogLevel=ERROR -i {} -4 -o StrictHostKeyChecking=no {}@{}:{} {}'.format(user_keys.private_key_file, computing_user, computing_host, source, dest) elif mode == 'put': - command = 'scp -o LogLevel=ERROR -i {} -4 -o StrictHostKeyChecking=no {} {}@{}: '.format(user_keys.private_key_file, computing_user, computing_host, source, dest) + command = 'scp -o LogLevel=ERROR -i {} -4 -o StrictHostKeyChecking=no {} {}@{}:{}'.format(user_keys.private_key_file, source, computing_user, computing_host, dest) else: raise ValueError('Unknown mode "{}"'.format(mode)) @@ -713,6 +716,9 @@ class FileManagerAPI(PrivateGETAPI, PrivatePOSTAPI): elif mode in ['download', 'getimage']: logger.debug('Downloading "{}"'.format(path)) + if path.endswith('/'): + return error400('Downloading a folder is not supported') + # TOOD: here we are not handling ajax request, Maybe they have been deperacted? # The download process consists of 2 requests: # - Ajax GET request. Perform all checks and validation. Should return file/folder object in the response data to proceed. @@ -973,12 +979,48 @@ class FileManagerAPI(PrivateGETAPI, PrivatePOSTAPI): if mode == 'savefile': - #logger.debug('Reading "{}"'.format(path)) - #computing = self.get_computing(path, request) - #cat_path = '/'.join(path.split('/')[2:]) - #data = self.echo(cat_path, request.user, computing) return error400('Operation "{}" not supported'.format(mode)) + elif mode == 'upload': + + # Set support vars + computing = self.get_computing(path, request) + path = '/'+'/'.join(path.split('/')[2:]) + + # Get the file upload + file_upload = request.FILES['files'] + + # generate temporary UUID + file_uuid = uuid.uuid4() + + with open('/tmp/{}'.format(file_uuid), 'wb') as temp_file: + temp_file.write(file_upload.read()) + + logger.debug('Wrote "/tmp/{}" for "{}"'.format(file_uuid, file_upload.name)) + + # Now copy with scp + self.scp('/tmp/{}'.format(file_uuid), path + file_upload.name , request.user, computing, mode='put') + + # Response data + data = { 'data': [{ + 'id': '/{}{}{}'.format(computing.name, path, file_upload.name), + 'type': 'file', + 'attributes':{ + #'created': 1616415170, + #'modified': 1616415170, + 'name': file_upload.name, + 'readable': 1, + #'timestamp': 1616415170, + 'writable': 1, + 'path': '/{}{}{}'.format(computing.name, path, file_upload.name) + } + }] + } + + + # Return + return Response(data, status=status.HTTP_200_OK) + else: return error400('Operation "{}" not supported'.format(mode)) -- GitLab