Beispiel #1
0
def update(entity_id):
    """
    ---
    post:
      summary: Update an entity
      description: >
        Update the entity with id `entity_id`. This only applies to
        entities which are backed by a database row, i.e. not any
        entities resulting from a mapping or bulk load.
      parameters:
      - in: path
        name: entity_id
        required: true
        schema:
          type: string
          format: entity_id
      - in: query
        name: sign
        description: Sign entity IDs referenced in nested properties.
        required: false
        schema:
          type: boolean
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EntityUpdate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Entity'
      tags:
      - Entity
    """
    data = parse_request("EntityUpdate")
    try:
        entity = get_index_entity(entity_id, request.authz.WRITE)
        require(check_write_entity(entity, request.authz))
        collection = get_db_collection(entity.get("collection_id"),
                                       request.authz.WRITE)
    except NotFound:
        collection = get_nested_collection(data, request.authz.WRITE)
    tag_request(collection_id=collection.id)
    data["id"] = entity_id
    if get_flag("validate", default=False):
        validate_entity(data)
    entity_id = upsert_entity(
        data,
        collection,
        authz=request.authz,
        sync=get_flag("sync", default=True),
        sign=get_flag("sign", default=False),
        job_id=get_session_id(),
    )
    db.session.commit()
    return view(entity_id)
Beispiel #2
0
    def _serialize(self, obj):
        pk = obj.get("id")
        collection_id = obj.pop("collection_id", None)
        obj["collection"] = self.resolve(
            Collection, collection_id, CollectionSerializer
        )
        proxy = model.get_proxy(obj)
        properties = obj.get("properties", {})
        for prop in proxy.iterprops():
            if prop.type != registry.entity:
                continue
            values = ensure_list(properties.get(prop.name))
            properties[prop.name] = []
            for value in values:
                entity = self.resolve(Entity, value, EntitySerializer)
                properties[prop.name].append(entity or value)

        links = {
            "self": url_for("entities_api.view", entity_id=pk),
            "references": url_for("entities_api.references", entity_id=pk),
            "tags": url_for("entities_api.tags", entity_id=pk),
            "ui": entity_url(pk),
        }
        if proxy.schema.is_a(Document.SCHEMA):
            content_hash = first(properties.get("contentHash"))
            if content_hash:
                name = entity_filename(proxy)
                mime = first(properties.get("mimeType"))
                links["file"] = archive_url(
                    content_hash,
                    file_name=name,
                    mime_type=mime,
                    expire=request.authz.expire,
                )

            pdf_hash = first(properties.get("pdfHash"))
            if pdf_hash:
                name = entity_filename(proxy, extension="pdf")
                links["pdf"] = archive_url(
                    pdf_hash,
                    file_name=name,
                    mime_type=PDF,
                    expire=request.authz.expire,
                )
            csv_hash = first(properties.get("csvHash"))
            if csv_hash:
                name = entity_filename(proxy, extension="csv")
                links["csv"] = archive_url(
                    csv_hash,
                    file_name=name,
                    mime_type=CSV,
                    expire=request.authz.expire,
                )

        obj["links"] = links
        obj["latinized"] = transliterate_values(proxy)
        obj["writeable"] = check_write_entity(obj, request.authz)
        obj["shallow"] = obj.get("shallow", True)
        return obj
Beispiel #3
0
    def _serialize(self, obj):
        pk = obj.get("id")
        proxy = model.get_proxy(obj)
        properties = {}
        for prop, value in proxy.itervalues():
            properties.setdefault(prop.name, [])
            if prop.type == registry.entity:
                entity = self.resolve(Entity, value, EntitySerializer)
                value = entity or value
            if value is not None:
                properties[prop.name].append(value)
        obj["properties"] = properties
        links = {
            "self": url_for("entities_api.view", entity_id=pk),
            "expand": url_for("entities_api.expand", entity_id=pk),
            "tags": url_for("entities_api.tags", entity_id=pk),
            "ui": entity_url(pk),
        }
        if proxy.schema.is_a(Document.SCHEMA):
            content_hash = proxy.first("contentHash", quiet=True)
            if content_hash:
                name = entity_filename(proxy)
                mime = proxy.first("mimeType", quiet=True)
                links["file"] = archive_url(content_hash,
                                            file_name=name,
                                            mime_type=mime)

            pdf_hash = proxy.first("pdfHash", quiet=True)
            if pdf_hash:
                name = entity_filename(proxy, extension="pdf")
                links["pdf"] = archive_url(pdf_hash,
                                           file_name=name,
                                           mime_type=PDF)

            csv_hash = proxy.first("csvHash", quiet=True)
            if csv_hash:
                name = entity_filename(proxy, extension="csv")
                links["csv"] = archive_url(csv_hash,
                                           file_name=name,
                                           mime_type=CSV)

        collection = obj.get("collection") or {}
        coll_id = obj.pop("collection_id", collection.get("id"))
        # This is a last resort catcher for entities nested in other
        # entities that get resolved without regard for authz.
        if not request.authz.can(coll_id, request.authz.READ):
            return None
        obj["collection"] = self.resolve(Collection, coll_id,
                                         CollectionSerializer)
        role_id = obj.pop("role_id", None)
        obj["role"] = self.resolve(Role, role_id, RoleSerializer)
        obj["links"] = links
        obj["latinized"] = transliterate_values(proxy)
        obj["writeable"] = check_write_entity(obj, request.authz)
        obj["shallow"] = obj.get("shallow", True)
        # Phasing out multi-values here (2021-01):
        obj["created_at"] = min(ensure_list(obj.get("created_at")),
                                default=None)
        obj["updated_at"] = max(ensure_list(obj.get("updated_at")),
                                default=None)
        return obj
Beispiel #4
0
def entities_update(entityset_id):
    """
    ---
    post:
      summary: Update an entity and add it to the entity set.
      description: >
        Update the entity with id `entity_id`. If it does not exist it will be
        created. If the user cannot edit the given entity, it is merely added
        to the entity set. New entities are always created in the collection of
        the entity set.

        Aside from these idiosyncracies, this is the same as `/api/2/entities/<id>`,
        but handles entity set membership transparently.
      parameters:
      - description: The entityset id.
        in: path
        name: entityset_id
        required: true
        schema:
          type: string
        example: 3a0d91ece2dce88ad3259594c7b642485235a048
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EntityUpdate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Entity'
      tags:
      - Entity
    """
    entityset = get_entityset(entityset_id, request.authz.WRITE)
    data = parse_request("EntityUpdate")
    entity_id = data.get("id", make_textid())
    try:
        entity = get_index_entity(entity_id, request.authz.READ)
        collection = get_db_collection(entity.get("collection_id"),
                                       request.authz.READ)
    except NotFound:
        entity = None
        collection = entityset.collection
    tag_request(collection_id=entityset.collection_id)
    if entity is None or check_write_entity(entity, request.authz):
        if get_flag("validate", default=False):
            validate_entity(data)
        sync = get_flag("sync", default=True)
        entity_id = upsert_entity(data,
                                  collection,
                                  authz=request.authz,
                                  sync=sync)
    EntitySetItem.save(
        entityset,
        entity_id,
        collection_id=collection.id,
        added_by_id=request.authz.id,
    )
    db.session.commit()
    return entity_view(entity_id)