예제 #1
0
    def post(self, res_id):
        if not resource_manager.is_authenticated():
            self.write({
                'success': False,
                'error': HYDROSHARE_AUTHENTICATION_ERROR,
            })
            return
        hs_data = ResourceHydroShareData(resource_manager.hs_api_conn, res_id)
        data = json.loads(self.request.body.decode('utf-8'))

        file_and_folder_paths = data.get('files')
        filesChanged = 'sync'

        if file_and_folder_paths is None:
            self.set_status(400)  # Bad Request
            self.write('Could not find "files" in request body.')
            return
        for item_path in file_and_folder_paths:
            # Remove any leading /
            if item_path.startswith('/'):
                item_path = item_path[1:]

                local_data = ResourceLocalData(res_id)
                # resource_manager.save_file_locally(res_id, item_path)
                hs_data.download_to_local(local_data, Path(item_path),
                                          Path(item_path))

        self.write({
            'readMe': local_data.get_readme(),
            'rootDir': local_data.get_files_and_folders(),
        })
예제 #2
0
    def patch(self, res_id):
        body = json.loads(self.request.body.decode('utf-8'))
        local_data = ResourceLocalData(res_id)
        hs_data = ResourceHydroShareData(resource_manager.hs_api_conn, res_id)
        file_operations = body['operations']

        results = []
        success_count = 0
        failure_count = 0

        for operation in file_operations:
            method = operation['method']  # 'copy' or 'move'
            src_uri = operation['source']
            dest_uri = operation['destination']

            # Split paths into filesystem prefix ('hs' or 'local') and path
            # relative to the resource root on
            # that filesystem
            src_fs, src_path = src_uri.split(':')
            dest_fs, dest_path = dest_uri.split(':')

            # If this operation involves HydroShare, make sure we're
            # authenticated
            if ((src_path == HS_PREFIX or dest_fs == HS_PREFIX)
                    and not resource_manager.is_authenticated()):
                results.append({
                    'success': False,
                    'error': HYDROSHARE_AUTHENTICATION_ERROR,
                })
                failure_count += 1
                continue

            # Remove the leading forward slashes
            src_path = src_path[1:]
            dest_path = dest_path[1:]

            # Exactly what operation we perform depends on where the source
            # and destination files/folders are
            # Move/copy within HydroShare
            if src_fs == HS_PREFIX and dest_fs == HS_PREFIX:
                if method == MOVE:  # Move or rename
                    try:
                        hs_data.rename_or_move_file(Path(src_path),
                                                    Path(dest_path))
                        results.append({'success': True})
                        success_count += 1
                    except FileExistsError:
                        results.append({
                            'success': False,
                            'error': {
                                'type':
                                'FileOrFolderExists',
                                'message': (f'The file {dest_path} already '
                                            'exists in HydroShare.'),
                            },
                        })
                        failure_count += 1
                else:  # TODO: Copy (https://github.com/hydroshare/hydroshare_jupyter_sync/issues/42)
                    # The frontend never requests this, but if one were to
                    # add such functionality, you'd handle it here
                    raise NotImplementedError('Copy within HydroShare '
                                              'not implemented')
            # Move/copy within the local filesystem
            elif src_fs == LOCAL_PREFIX and dest_fs == LOCAL_PREFIX:
                if method == MOVE:  # Move or rename
                    ResourceLocalData(res_id).rename_or_move_item(
                        src_path, dest_path)
                    results.append({'success': True})
                    success_count += 1
                else:  # TODO: Copy (https://github.com/hydroshare/hydroshare_jupyter_sync/issues/42)
                    # The frontend never requests this, but if one were to
                    # add such functionality, you'd handle it here
                    raise NotImplementedError('Copy within the local '
                                              'filesystem not implemented yet')
            # Move/copy from the local filesystem to HydroShare
            elif src_fs == LOCAL_PREFIX and dest_fs == HS_PREFIX:
                # Transfer the file regardless of if we're moving or copying
                error = hs_data.upload_from_local(local_data, Path(src_path),
                                                  Path(dest_path))
                if not error and method == MOVE:
                    # Delete the local copy of the file
                    error = (ResourceLocalData(res_id).delete_file_or_folder(
                        src_path))
                results.append({
                    'success': error is None,
                    'error': error,
                })
                if error:
                    failure_count += 1
                else:
                    success_count += 1
            # Move/copy from HydroShare to the local filesystem
            elif src_fs == HS_PREFIX and dest_fs == LOCAL_PREFIX:
                # Transfer the file regardless of if we're moving or copying
                hs_data.download_to_local(local_data, Path(src_path),
                                          Path(dest_path))
                if method == MOVE:
                    # Delete the HS copy of the file
                    hs_data.delete_file_or_folder(src_path)
                results.append({'success': True})
                success_count += 1
            else:
                msg = f'"source" prefix "{src_fs}" and/or destination ' \
                      f'prefix "{dest_fs} not recognized. Valid options' \
                      f' are "hs" and "local"'
                logging.warning(msg)
                results.append({
                    'success': False,
                    'error': 'UnrecognizedPathPrefix',
                    'message': msg,
                })
                failure_count += 1

        self.write({
            'results': results,
            'successCount': success_count,
            'failureCount': failure_count,
        })