def replace_items(worksheet_uuid):
    """
    Replace worksheet items with 'ids' with new 'items'.
    The new items will be inserted after the after_sort_key
    """
    worksheet = local.model.get_worksheet(worksheet_uuid, fetch_items=False)
    check_worksheet_has_all_permission(local.model, request.user, worksheet)
    worksheet_util.check_worksheet_not_frozen(worksheet)

    ids = request.json.get('ids', [])
    item_type = request.json.get('item_type', 'markup')
    after_sort_key = request.json.get('after_sort_key')
    # Default to process only markup items.
    if item_type == "markup":
        items = [
            worksheet_util.markup_item(item)
            for item in request.json.get('items', [])
        ]
    elif item_type == "bundle":
        items = [
            worksheet_util.bundle_item(item)
            for item in request.json.get('items', [])
        ]
    elif item_type == "directive":
        # Note: for directives, the item should not include the preceding "%" symbol
        items = [
            worksheet_util.directive_item(item)
            for item in request.json.get('items', [])
        ]
    local.model.add_worksheet_items(worksheet_uuid, items, after_sort_key, ids)
Beispiel #2
0
def add_worksheet_item(worksheet_uuid, item):
    """
    Add the given item to the worksheet.
    """
    worksheet = local.model.get_worksheet(worksheet_uuid, fetch_items=False)
    check_worksheet_has_all_permission(local.model, request.user, worksheet)
    worksheet_util.check_worksheet_not_frozen(worksheet)
    local.model.add_worksheet_item(worksheet_uuid, item)
def add_worksheet_item(worksheet_uuid, item):
    """
    Add the given item to the worksheet.
    """
    worksheet = local.model.get_worksheet(worksheet_uuid, fetch_items=False)
    check_worksheet_has_all_permission(local.model, request.user, worksheet)
    worksheet_util.check_worksheet_not_frozen(worksheet)
    local.model.add_worksheet_items(worksheet_uuid, [item])
def set_worksheet_permissions():
    """
    Bulk set worksheet permissions.
    """
    new_permissions = WorksheetPermissionSchema(strict=True, many=True).load(
        request.json).data

    for p in new_permissions:
        worksheet = local.model.get_worksheet(p['object_uuid'],
                                              fetch_items=False)
        worksheet_util.check_worksheet_not_frozen(worksheet)
        set_worksheet_permission(worksheet, p['group_uuid'], p['permission'])
    return WorksheetPermissionSchema(many=True).dump(new_permissions).data
Beispiel #5
0
def update_worksheet_items(worksheet_info, new_items, convert_items=True):
    """
    Set the worksheet to have items |new_items|.
    """
    worksheet_uuid = worksheet_info['uuid']
    last_item_id = worksheet_info['last_item_id']
    length = len(worksheet_info['items'])
    worksheet = local.model.get_worksheet(worksheet_uuid, fetch_items=False)
    check_worksheet_has_all_permission(local.model, request.user, worksheet)
    worksheet_util.check_worksheet_not_frozen(worksheet)
    try:
        if convert_items:
            new_items = [worksheet_util.convert_item_to_db(item) for item in new_items]
        local.model.update_worksheet_items(worksheet_uuid, last_item_id, length, new_items)
    except UsageError:
        # Turn the model error into a more readable one using the object.
        raise UsageError('%s was updated concurrently!' % (worksheet,))
def update_worksheet_items(worksheet_info, new_items, convert_items=True):
    """
    Set the worksheet to have items |new_items|.
    """
    worksheet_uuid = worksheet_info['uuid']
    last_item_id = worksheet_info['last_item_id']
    length = len(worksheet_info['items'])
    worksheet = local.model.get_worksheet(worksheet_uuid, fetch_items=False)
    check_worksheet_has_all_permission(local.model, request.user, worksheet)
    worksheet_util.check_worksheet_not_frozen(worksheet)
    try:
        if convert_items:
            new_items = [worksheet_util.convert_item_to_db(item) for item in new_items]
        local.model.update_worksheet_items(worksheet_uuid, last_item_id, length, new_items)
    except UsageError:
        # Turn the model error into a more readable one using the object.
        raise UsageError('%s was updated concurrently!' % (worksheet,))
def update_worksheet_metadata(uuid, info):
    """
    Change the metadata of the worksheet |uuid| to |info|,
    where |info| specifies name, title, owner, etc.
    """
    worksheet = local.model.get_worksheet(uuid, fetch_items=False)
    check_worksheet_has_all_permission(local.model, request.user, worksheet)
    metadata = {}
    for key, value in info.items():
        if key == 'name':
            ensure_unused_worksheet_name(value)
        elif key == 'frozen' and value and not worksheet.frozen:
            # ignore the value the client provided, just freeze as long as it's truthy
            value = datetime.datetime.utcnow()
        metadata[key] = value

    # If we're updating any metadata key, we want to ensure that the worksheet
    # isn't frozen. The exception is if we're also unfreezing the worksheet---regardless of
    # whether the worksheet is frozen or not, we're going to unfreeze it, so allow all
    # other updates as well.
    if "frozen" not in metadata or metadata["frozen"]:
        worksheet_util.check_worksheet_not_frozen(worksheet)

    local.model.update_worksheet_metadata(worksheet, metadata)
def _create_bundles():
    """
    Bulk create bundles.

    Query parameters:
    - `worksheet`: UUID of the parent worksheet of the new bundle, add to
      this worksheet if not detached or shadowing another bundle. The new
      bundle also inherits permissions from this worksheet.
    - `shadow`: UUID of the bundle to "shadow" (the new bundle will be added
      as an item immediately after this bundle in its parent worksheet).
    - `detached`: 1 if should not add new bundle to any worksheet,
      or 0 otherwise. Default is 0.
    - `wait_for_upload`: 1 if the bundle state should be initialized to
      "uploading" regardless of the bundle type, or 0 otherwise. Used when
      copying bundles from another CodaLab instance, this prevents these new
      bundles from being executed by the BundleManager. Default is 0.
    """
    worksheet_uuid = request.query.get('worksheet')
    shadow_parent_uuid = request.query.get('shadow')
    after_sort_key = request.query.get('after_sort_key')
    detached = query_get_bool('detached', default=False)
    if worksheet_uuid is None:
        abort(
            http.client.BAD_REQUEST,
            "Parent worksheet id must be specified as"
            "'worksheet' query parameter",
        )

    # Deserialize bundle fields
    bundles = (BundleSchema(strict=True,
                            many=True,
                            dump_only=BUNDLE_CREATE_RESTRICTED_FIELDS).load(
                                request.json).data)

    # Check for all necessary permissions
    worksheet = local.model.get_worksheet(worksheet_uuid, fetch_items=False)
    check_worksheet_has_all_permission(local.model, request.user, worksheet)
    worksheet_util.check_worksheet_not_frozen(worksheet)
    request.user.check_quota(need_time=True, need_disk=True)

    created_uuids = []
    for bundle in bundles:
        # Prep bundle info for saving into database
        # Unfortunately cannot use the `construct` methods because they don't
        # provide a uniform interface for constructing bundles for all types
        # Hopefully this can all be unified after REST migration is complete
        bundle_uuid = bundle.setdefault('uuid', spec_util.generate_uuid())
        created_uuids.append(bundle_uuid)
        bundle_class = get_bundle_subclass(bundle['bundle_type'])
        bundle['owner_id'] = request.user.user_id

        metadata = bundle.get("metadata", {})
        if metadata.get("link_url"):
            bundle['state'] = State.READY
        elif issubclass(bundle_class, UploadedBundle) or query_get_bool(
                'wait_for_upload', False):
            bundle['state'] = State.UPLOADING
        else:
            bundle['state'] = State.CREATED
        bundle[
            'is_anonymous'] = worksheet.is_anonymous  # inherit worksheet anonymity
        bundle.setdefault('metadata', {})['created'] = int(time.time())
        for dep in bundle.setdefault('dependencies', []):
            dep['child_uuid'] = bundle_uuid

        # Create bundle object
        bundle = bundle_class(bundle, strict=False)

        # Save bundle into model
        local.model.save_bundle(bundle)

        # Inherit worksheet permissions
        group_permissions = local.model.get_group_worksheet_permissions(
            request.user.user_id, worksheet_uuid)
        set_bundle_permissions([{
            'object_uuid': bundle_uuid,
            'group_uuid': p['group_uuid'],
            'permission': p['permission'],
        } for p in group_permissions])

        # Add as item to worksheet
        if not detached:
            if shadow_parent_uuid is None:
                local.model.add_worksheet_items(
                    worksheet_uuid, [worksheet_util.bundle_item(bundle_uuid)],
                    after_sort_key)
            else:
                local.model.add_shadow_worksheet_items(shadow_parent_uuid,
                                                       bundle_uuid)

    # Get created bundles
    bundles_dict = get_bundle_infos(created_uuids)

    # Return bundles in original order
    # Need to check if the UUID is in the dict, since there is a chance that a bundle is deleted
    # right after being created.
    bundles = [
        bundles_dict[uuid] for uuid in created_uuids if uuid in bundles_dict
    ]
    return BundleSchema(many=True).dump(bundles).data
Beispiel #9
0
def _create_bundles():
    """
    Bulk create bundles.

    |worksheet_uuid| - The parent worksheet of the bundle, add to this worksheet
                       if not detached or shadowing another bundle. Also used
                       to inherit permissions.
    |shadow| - the uuid of the bundle to shadow
    |detached| - True ('1') if should not add new bundle to any worksheet,
                 or False ('0') otherwise. Default is False.
    |wait_for_upload| - True ('1') if the bundle state should be initialized to
                        UPLOADING regardless of the bundle type, or False ('0')
                        otherwise. This prevents run bundles that are being
                        copied from another instance from being run by the
                        BundleManager. Default is False.
    """
    worksheet_uuid = request.query.get('worksheet')
    shadow_parent_uuid = request.query.get('shadow')
    detached = query_get_bool('detached', default=False)
    if worksheet_uuid is None:
        abort(
            httplib.BAD_REQUEST, "Parent worksheet id must be specified as"
            "'worksheet' query parameter")

    # Deserialize bundle fields
    bundles = BundleSchema(
        strict=True,
        many=True,
        dump_only=BUNDLE_CREATE_RESTRICTED_FIELDS,
    ).load(request.json).data

    # Check for all necessary permissions
    worksheet = local.model.get_worksheet(worksheet_uuid, fetch_items=False)
    check_worksheet_has_all_permission(local.model, request.user, worksheet)
    worksheet_util.check_worksheet_not_frozen(worksheet)
    request.user.check_quota(need_time=True, need_disk=True)

    created_uuids = []
    for bundle in bundles:
        # Prep bundle info for saving into database
        # Unfortunately cannot use the `construct` methods because they don't
        # provide a uniform interface for constructing bundles for all types
        # Hopefully this can all be unified after REST migration is complete
        bundle_uuid = bundle.setdefault('uuid', spec_util.generate_uuid())
        created_uuids.append(bundle_uuid)
        bundle_class = get_bundle_subclass(bundle['bundle_type'])
        bundle['owner_id'] = request.user.user_id
        bundle['state'] = (
            State.UPLOADING if issubclass(bundle_class, UploadedBundle)
            or query_get_bool('wait_for_upload', False) else State.CREATED)
        bundle.setdefault('metadata', {})['created'] = int(time.time())
        for dep in bundle.setdefault('dependencies', []):
            dep['child_uuid'] = bundle_uuid

        # Create bundle object
        bundle = bundle_class(bundle, strict=False)

        # Save bundle into model
        local.model.save_bundle(bundle)

        # Inherit worksheet permissions
        group_permissions = local.model.get_group_worksheet_permissions(
            request.user.user_id, worksheet_uuid)
        set_bundle_permissions([{
            'object_uuid': bundle_uuid,
            'group_uuid': p['group_uuid'],
            'permission': p['permission'],
        } for p in group_permissions])

        # Add as item to worksheet
        if not detached:
            if shadow_parent_uuid is None:
                local.model.add_worksheet_item(
                    worksheet_uuid, worksheet_util.bundle_item(bundle_uuid))
            else:
                local.model.add_shadow_worksheet_items(shadow_parent_uuid,
                                                       bundle_uuid)

    # Get created bundles
    bundles_dict = get_bundle_infos(created_uuids)

    # Return bundles in original order
    bundles = [bundles_dict[uuid] for uuid in created_uuids]
    return BundleSchema(many=True).dump(bundles).data