示例#1
0
class RemoteBundleService(object):
    '''
    Adapts the RemoteBundleClient for REST calls.
    TODO(klopyrev): This version should eventually go away once the file upload
    logic is cleaned up. See below where this class is used for more information.
    '''
    def __init__(self):
        self.client = RemoteBundleClient(self._cli_url(),
                                         lambda command: self._get_user_token(), verbose=0)

    def _cli_url(self):
        return 'http://' + local.config['server']['host'] + ':' + str(local.config['server']['port'])

    def _get_user_token(self):
        """
        Returns an access token for the user. This function facilitates interactions
        with the bundle service.
        """
        CLIENT_ID = 'codalab_cli_client'
    
        if request.user is None:
            return None
    
        # Try to find an existing token that will work.
        token = local.model.find_oauth2_token(
            CLIENT_ID,
            request.user.user_id,
            datetime.utcnow() + timedelta(minutes=5))
        if token is not None:
            return token.access_token
    
        # Otherwise, generate a new one.
        token = OAuth2Token(
            local.model,
            access_token=generate_token(),
            refresh_token=None,
            scopes='',
            expires=datetime.utcnow() + timedelta(hours=10),
            client_id=CLIENT_ID,
            user_id=request.user.user_id,
        )
        local.model.save_oauth2_token(token)
    
        return token.access_token

    def upload_bundle(self, source_file, bundle_type, worksheet_uuid):
        """
        Upload |source_file| (a stream) to |worksheet_uuid|.
        """
        # Construct info for creating the bundle.
        bundle_subclass = get_bundle_subclass(bundle_type) # program or data
        metadata = metadata_util.fill_missing_metadata(bundle_subclass, {}, initial_metadata={'name': source_file.filename, 'description': 'Upload ' + source_file.filename})
        info = {'bundle_type': bundle_type, 'metadata': metadata}

        # Upload it by creating a file handle and copying source_file to it (see RemoteBundleClient.upload_bundle in the CLI).
        remote_file_uuid = self.client.open_temp_file(metadata['name'])
        try:
            with closing(RPCFileHandle(remote_file_uuid, self.client.proxy)) as dest:
                file_util.copy(source_file.file, dest, autoflush=False, print_status='Uploading %s' % metadata['name'])
           
            pack = False  # For now, always unpack (note: do this after set remote_file_uuid, which needs the extension)
            if not pack and zip_util.path_is_archive(metadata['name']):
                metadata['name'] = zip_util.strip_archive_ext(metadata['name'])
           
            # Then tell the client that the uploaded file handle is there.
            new_bundle_uuid = self.client.finish_upload_bundle(
                [remote_file_uuid],
                not pack,  # unpack
                info,
                worksheet_uuid,
                True)  # add_to_worksheet
        except:
            self.client.finalize_file(remote_file_uuid)
            raise
        return new_bundle_uuid
示例#2
0
class RemoteBundleService(object):
    '''
    Adapts the RemoteBundleClient for REST calls.
    TODO(klopyrev): This version should eventually go away once the file upload
    logic is cleaned up. See below where this class is used for more information.
    '''
    def __init__(self):
        self.client = RemoteBundleClient(
            self._cli_url(), lambda command: self._get_user_token(), verbose=0)

    def _cli_url(self):
        return 'http://' + local.config['server']['host'] + ':' + str(
            local.config['server']['port'])

    def _get_user_token(self):
        """
        Returns an access token for the user. This function facilitates interactions
        with the bundle service.
        """
        CLIENT_ID = 'codalab_cli_client'

        if request.user is None:
            return None

        # Try to find an existing token that will work.
        token = local.model.find_oauth2_token(
            CLIENT_ID, request.user.user_id,
            datetime.utcnow() + timedelta(minutes=5))
        if token is not None:
            return token.access_token

        # Otherwise, generate a new one.
        token = OAuth2Token(
            local.model,
            access_token=generate_token(),
            refresh_token=None,
            scopes='',
            expires=datetime.utcnow() + timedelta(hours=10),
            client_id=CLIENT_ID,
            user_id=request.user.user_id,
        )
        local.model.save_oauth2_token(token)

        return token.access_token

    def upload_bundle(self, source_file, bundle_type, worksheet_uuid):
        """
        Upload |source_file| (a stream) to |worksheet_uuid|.
        """
        # Construct info for creating the bundle.
        bundle_subclass = get_bundle_subclass(bundle_type)  # program or data
        metadata = metadata_util.fill_missing_metadata(
            bundle_subclass, {},
            initial_metadata={
                'name': source_file.filename,
                'description': 'Upload ' + source_file.filename
            })
        info = {'bundle_type': bundle_type, 'metadata': metadata}

        # Upload it by creating a file handle and copying source_file to it (see RemoteBundleClient.upload_bundle in the CLI).
        remote_file_uuid = self.client.open_temp_file(metadata['name'])
        try:
            with closing(RPCFileHandle(remote_file_uuid,
                                       self.client.proxy)) as dest:
                file_util.copy(source_file.file,
                               dest,
                               autoflush=False,
                               print_status='Uploading %s' % metadata['name'])

            pack = False  # For now, always unpack (note: do this after set remote_file_uuid, which needs the extension)
            if not pack and zip_util.path_is_archive(metadata['name']):
                metadata['name'] = zip_util.strip_archive_ext(metadata['name'])

            # Then tell the client that the uploaded file handle is there.
            new_bundle_uuid = self.client.finish_upload_bundle(
                [remote_file_uuid],
                not pack,  # unpack
                info,
                worksheet_uuid,
                True)  # add_to_worksheet
        except:
            self.client.finalize_file(remote_file_uuid)
            raise
        return new_bundle_uuid