コード例 #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 delete(self, res_id):
        body = json.loads(self.request.body.decode('utf-8'))
        file_and_folder_paths = body.get('files')
        if file_and_folder_paths is None:
            self.set_status(400)  # Bad Request
            self.write('Could not find "files" in request body.')
            return

        local_folder = ResourceLocalData(res_id)
        success_count = 0
        failure_count = 0

        # Keep track of the folders that have been deleted so we don't try to
        # delete child files that have already
        # been deleted
        deleted_folders = []

        results = []
        for item_path in file_and_folder_paths:
            # Remove any leading /
            if item_path.startswith('/'):
                item_path = item_path[1:]
            try:
                for deleted_folder in deleted_folders:
                    # Check if this file is in a folder that was deleted (a
                    # slash is appended to ensure that a file in,
                    # say, '/My data 2' is not skipped because '/My data' was
                    # deleted)
                    if item_path.startswith(deleted_folder + '/'):
                        # We can skip deleting this file because it was already
                        # deleted with its parent folder
                        break
                else:  # Only runs if the break statement above is never hit
                    # (yes, the indentation is right here)
                    # Try to delete this item
                    deleted_type = local_folder.delete_file_or_folder(
                        item_path)
                    if deleted_type == 'folder':
                        deleted_folders.append(item_path)
                success_count += 1
                results.append({'success': True})
            except Exception as e:
                logging.error(e)
                results.append({
                    'success': False,
                    'error': {
                        'type':
                        'UnknownError',
                        'message': (f'An unknown error occurred when '
                                    f'attempting to delete {item_path}.')
                    }
                })
                failure_count += 1

        self.write({
            'results': results,
            'successCount': success_count,
            'failureCount': failure_count,
        })
コード例 #3
0
 def get(self, res_id):
     local_data = ResourceLocalData(res_id)
     if not local_data.is_downloaded():
         resource_manager.save_resource_locally(res_id)
     self.write({
         'readMe': local_data.get_readme(),
         'rootDir': local_data.get_files_and_folders(),
     })
コード例 #4
0
    def get(self, res_id):
        local_data = ResourceLocalData(res_id)

        local_data.get_md5(res_id)

        self.write({
            'success': 'success',
            'userInfo': '',
        })
コード例 #5
0
    def get(self, res_id):

        # Handling authentication first to ensure local data if not present is downloaded from Hydroshare

        if not resource_manager.is_authenticated():
            self.write({
                'success': False,
                'error': HYDROSHARE_AUTHENTICATION_ERROR,
            })
            return

        local_data = ResourceLocalData(res_id)

        if not local_data.is_downloaded():
            resource_manager.save_resource_locally(res_id)
        self.write({
            'readMe': local_data.get_readme(),
            'rootDir': local_data.get_files_and_folders(),
        })
コード例 #6
0
    def put(self, res_id):
        """ Creates a new file in the local copy of the resource

            :param res_id: the resource ID
            :type res_id: str
         """
        body = json.loads(self.request.body.decode('utf-8'))
        item_type = body.get('type')
        name = body.get('name')
        error_msg = None
        if item_type is None or name is None:
            error_msg = 'Request must include both "type" and "name" attributes.'
        if not error_msg and not (item_type == 'file' or item_type == 'folder'):
            error_msg = '"type" attribute must be either "file" or "folder".'
        if error_msg:
            self.set_status(400)  # Bad Request
            self.write({
                'success': False,
                'error': {
                    'type': 'InvalidRequest',
                    'message': error_msg,
                },
            })
            return

        local_data = ResourceLocalData(res_id)
        if item_type == 'file':
            local_data.create_file(name)
        elif item_type == 'folder':
            local_data.create_local_folder(name)

        self.write({
            'success': True,
        })
コード例 #7
0
    def post(self, res_id):
        """ Uploads a file from the user's computer to the local filesystem

            :param res_id: the resource ID
            :type res_id: str
         """
        local_data = ResourceLocalData(res_id)
        for field_name, files in self.request.files.items():
            for info in files:
                with open(str(local_data.data_path / info['filename']), "wb") as f:
                    f.write(info['body'])
        self.write({
            'success': True,
        })
コード例 #8
0
    def get(self, res_id):
        if not resource_manager.is_authenticated():
            self.write({
                'success': False,
                'error': HYDROSHARE_AUTHENTICATION_ERROR,
            })
            return
        local_data = ResourceLocalData(res_id)
        if not local_data.is_downloaded():
            self.write({
                'success': False,
                'error': WORKSPACE_FILES_ERROR,
                # 'error' : 'HydroShare files not present in Workspace',
            })
            return
        else:
            local_file_data = local_data.get_files_and_folders()

            # checkFileSyncStatus(temporaryRoot, res_id)
            checkHydroShareSyncStatus(local_file_data, res_id, True)
            self.write({
                'readMe': local_data.get_readme(),
                'rootDir': local_file_data,
            })
コード例 #9
0
def checkFileSyncStatus(temporaryRoot, res_id):
    serverIsLatest = 'HydroShare is latest'
    localIsLatest = 'Local is Latest'
    localSyncServer = 'In Sync'
    isfileExists = ''
    local_data = ResourceLocalData(res_id)
    hs_data = ResourceHydroShareData(resource_manager.hs_api_conn, res_id)
    # find where are the files and its properties in temporaryRoot
    contents = temporaryRoot['contents']
    for file in contents:

        modified_time_local = file['modifiedTime']
        checksum_local = file["checksum"]

        checksum_hs, modified_time_hs = hs_data.get_modified_time_hs(
            file['name'])

        if checksum_hs == None or modified_time_hs == None:
            syncStatus = " "
            isfileExists = "File doesn't exist in HydroShare"
            file.update({
                "fileChanged": isfileExists,
                "syncStatus": syncStatus
            })
        else:
            if checksum_local != checksum_hs:
                syncStatus = "Out of Sync"
                if modified_time_hs < modified_time_local:
                    # add fileChanged value
                    file.update({
                        "fileChanged": localIsLatest,
                        "syncStatus": syncStatus
                    })

                elif modified_time_hs > modified_time_local:
                    file.update({
                        "fileChanged": serverIsLatest,
                        "syncStatus": syncStatus
                    })

            elif checksum_local == checksum_hs:
                syncStatus = "In Sync"
                file.update({
                    "fileChanged": "Local and HydroShare are synced",
                    "syncStatus": syncStatus
                })

    temporaryRoot = sorted(contents, key=lambda x: x['syncStatus'] == ' ')
コード例 #10
0
def checkHydroShareSyncStatus(local_or_hs_file_data, res_id, is_local_data):
    serverIsLatest = 'HydroShare is latest'
    localIsLatest = 'Local is Latest'
    localSyncServer = 'In Sync'
    isFileExist = ''
    """
    if its localdata then get hydroshare data for the res_id
    else if hydrosharedata then get local data for the res_id
    """
    if is_local_data:
        data_to_compare = ResourceHydroShareData(resource_manager.hs_api_conn,
                                                 res_id)
    else:
        data_to_compare = ResourceLocalData(res_id)

    data_to_check_sync_status = local_or_hs_file_data['contents']

    for data in data_to_check_sync_status:
        addParameters(data, data_to_compare, localIsLatest, serverIsLatest,
                      res_id, is_local_data)
コード例 #11
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,
        })
コード例 #12
0
    def post(self, res_id):
        if not resource_manager.is_authenticated():
            self.write({
                'success': False,
                'error': HYDROSHARE_AUTHENTICATION_ERROR,
            })
            return

        data = json.loads(self.request.body.decode('utf-8'))

        file_and_folder_paths = data.get('files')

        myList = []

        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:
            # file_path = item_path
            # Remove any leading /
            if item_path.startswith('/'):
                file_name = item_path[1:]

                local_data = ResourceLocalData(res_id)

                CheckSyncStatusFilesRequestHandler.modified_time_local = local_data.get_md5_files(
                    file_name)

                # appending local modified time to list
                hs_data = ResourceHydroShareData(resource_manager.hs_api_conn,
                                                 res_id)
                CheckSyncStatusFilesRequestHandler.modified_time_hs = hs_data.get_md5_files(
                    res_id, file_name)

                if CheckSyncStatusFilesRequestHandler.modified_time_hs < CheckSyncStatusFilesRequestHandler.modified_time_local:

                    CheckSyncStatusFilesRequestHandler.filesChanged = 'local'

                    myDict = {
                        'resourceId': res_id,
                        'filesChanged':
                        CheckSyncStatusFilesRequestHandler.filesChanged,
                        'modified_time_local':
                        CheckSyncStatusFilesRequestHandler.modified_time_local,
                        'file_name': file_name,
                        'file_path': item_path
                    }
                    myList.append(myDict)
                    myJson = json.dumps(myList)

                elif CheckSyncStatusFilesRequestHandler.modified_time_hs > CheckSyncStatusFilesRequestHandler.modified_time_local:

                    myDict = {
                        'resourceId': res_id,
                        'filesChanged':
                        CheckSyncStatusFilesRequestHandler.filesChanged,
                        'modified_time_local':
                        CheckSyncStatusFilesRequestHandler.modified_time_hs,
                        'file_name': file_name,
                        'file_path': item_path
                    }
                    myList.append(myDict)
                    myJson = json.dumps(myList)

        temporaryRoot = local_data.get_files_and_folders()

        self.write({
            'readMe': local_data.get_readme(),
            'rootDir': temporaryRoot,
            'myJson': myJson
        })
コード例 #13
0
def addParameters(data, data_to_compare, localIsLatest, serverIsLatest, res_id,
                  is_local_data):
    # First iterate through folders, and then recrusively call the same method for each file.
    if data['type'] == 'folder':
        for k, v in data.items():
            if k == 'contents':
                for j in v:
                    addParameters(j, data_to_compare, localIsLatest,
                                  serverIsLatest, res_id, is_local_data)
    else:
        """
         TODO: Soumya 
         If checksum present for 
            local file - then local file exist
            hydroshare file - then file exist in Hydroshare server

         If checksum matches
            Then both files are in sync
         Else
            If they are not in sync, then check their last update time and identify which is latest.

         Sync status is dependent upon checksum. So, if checksum is present for both, then the file exist in both HS and local.
         if local file doesnt have checksum the file is no

        """
        # Identify if its Hydroshare file or local file
        if data['path'].startswith('hs'):
            file_name = data['path'][4:]
        else:
            file_name = data['path'][7:]

        # Get checksum for both Hydroshare and local files

        if is_local_data:
            item_path = str(
                ResourceLocalData(res_id).data_path) + '/' + file_name
            checksum_local = ResourceLocalData(res_id).get_md5_files(item_path)
            checksum_hs = data_to_compare.checksum_hs(
                file_name.partition('.')[0],
                file_name.partition('.')[2])
            modified_time_local = str(
                datetime.datetime.fromtimestamp(
                    Path(item_path).stat().st_mtime))
            modified_time_hs = data_to_compare.modified_time_hs(
                file_name.partition('.')[0],
                file_name.partition('.')[2])

        else:
            item_path = str(data_to_compare.data_path) + '/' + file_name
            checksum_local = data_to_compare.get_md5_files(item_path)
            modified_time_local = None
            if Path(item_path).exists():
                modified_time_local = str(
                    datetime.datetime.fromtimestamp(
                        Path(item_path).stat().st_mtime))
            checksum_hs = data['checksum']
            modified_time_hs = data['modifiedTime']

        syncStatus = " "

        if checksum_local is None:
            isFileExist = "File doesn't exist in Local System"
            data.update({"fileChanged": isFileExist, "syncStatus": syncStatus})
        elif checksum_hs is None:
            isfileExists = "File doesn't exist in HydroShare Server"
            data.update({
                "fileChanged": isfileExists,
                "syncStatus": syncStatus
            })
        else:

            if checksum_local != checksum_hs:
                syncStatus = 'Out of Sync'
                if modified_time_hs < modified_time_local:
                    # add fileChanged value
                    data.update({
                        "fileChanged": localIsLatest,
                        "syncStatus": syncStatus
                    })
                elif modified_time_hs > modified_time_local:
                    data.update({
                        "fileChanged": serverIsLatest,
                        "syncStatus": syncStatus
                    })

            else:
                syncStatus = 'In Sync'
                data.update({
                    "fileChanged": "Local and HydroShare are synced",
                    "syncStatus": syncStatus
                })
コード例 #14
0
 def get(self, res_id):
     local_data = ResourceLocalData(res_id)
     self.write({
         'readMe': local_data.get_readme(),
         'rootDir': local_data.get_files_and_folders(),
     })