Ejemplo n.º 1
0
    def make_metadata(self, create, extracted, **kwargs):
        """Create associated document metadata for the annotation."""
        # The metadata objects are going to be added to the db, so if we're not
        # using the create strategy then simply don't make any.
        if not create:
            return

        def document_uri_dict():
            """
            Return a randomly generated DocumentURI dict for this annotation.

            This doesn't add anything to the database session yet.
            """
            document_uri = DocumentURI.build(claimant=self.target_uri,
                                             uri=self.target_uri)
            return dict(
                claimant=document_uri.claimant,
                uri=document_uri.uri,
                type=document_uri.type,
                content_type=document_uri.content_type,
            )

        document_uri_dicts = [
            document_uri_dict() for _ in range(random.randint(1, 3))
        ]

        def document_meta_dict(**kwargs):
            """
            Return a randomly generated DocumentMeta dict for this annotation.

            This doesn't add anything to the database session yet.
            """
            kwargs.setdefault('claimant', self.target_uri)
            document_meta = DocumentMeta.build(**kwargs)
            return dict(
                claimant=document_meta.claimant,
                type=document_meta.type,
                value=document_meta.value,
            )

        document_meta_dicts = [
            document_meta_dict() for _ in range(random.randint(1, 3))
        ]

        # Make sure that there's always at least one DocumentMeta with
        # type='title', so that we never get annotation.document.title is None:
        if 'title' not in [m['type'] for m in document_meta_dicts]:
            document_meta_dicts.append(document_meta_dict(type='title'))

        api_models.update_document_metadata(
            orm.object_session(self),
            self,
            document_meta_dicts=document_meta_dicts,
            document_uri_dicts=document_uri_dicts,
        )
Ejemplo n.º 2
0
    def make_metadata(self, create, extracted, **kwargs):
        """Create associated document metadata for the annotation."""
        # The metadata objects are going to be added to the db, so if we're not
        # using the create strategy then simply don't make any.
        if not create:
            return

        def document_uri_dict():
            """
            Return a randomly generated DocumentURI dict for this annotation.

            This doesn't add anything to the database session yet.
            """
            document_uri = DocumentURI.build(claimant=self.target_uri,
                                             uri=self.target_uri)
            return dict(
                claimant=document_uri.claimant,
                uri=document_uri.uri,
                type=document_uri.type,
                content_type=document_uri.content_type,
            )

        document_uri_dicts = [document_uri_dict()
                              for _ in range(random.randint(1, 3))]

        def document_meta_dict(**kwargs):
            """
            Return a randomly generated DocumentMeta dict for this annotation.

            This doesn't add anything to the database session yet.
            """
            kwargs.setdefault('claimant', self.target_uri)
            document_meta = DocumentMeta.build(**kwargs)
            return dict(
                claimant=document_meta.claimant,
                type=document_meta.type,
                value=document_meta.value,
            )

        document_meta_dicts = [document_meta_dict()
                               for _ in range(random.randint(1, 3))]

        # Make sure that there's always at least one DocumentMeta with
        # type='title', so that we never get annotation.document.title is None:
        if 'title' not in [m['type'] for m in document_meta_dicts]:
            document_meta_dicts.append(document_meta_dict(type='title'))

        api_models.update_document_metadata(
            orm.object_session(self),
            self,
            document_meta_dicts=document_meta_dicts,
            document_uri_dicts=document_uri_dicts,
        )
Ejemplo n.º 3
0
def create_annotation(request, data):
    """
    Create an annotation from passed data.

    :param request: the request object
    :type request: pyramid.request.Request

    :param data: a dictionary of annotation properties
    :type data: dict

    :returns: the created annotation
    :rtype: dict
    """
    document_uri_dicts = data['document']['document_uri_dicts']
    document_meta_dicts = data['document']['document_meta_dicts']
    del data['document']

    # Replies must have the same group as their parent.
    if data['references']:
        top_level_annotation_id = data['references'][0]
        top_level_annotation = fetch_annotation(request.db,
                                                top_level_annotation_id)
        if top_level_annotation:
            data['groupid'] = top_level_annotation.groupid
        else:
            raise schemas.ValidationError(
                'references.0: ' +
                _('Annotation {id} does not exist').format(
                    id=top_level_annotation_id)
            )

    # The user must have permission to create an annotation in the group
    # they've asked to create one in.
    if data['groupid'] != '__world__':
        group_principal = 'group:{}'.format(data['groupid'])
        if group_principal not in request.effective_principals:
            raise schemas.ValidationError('group: ' +
                                          _('You may not create annotations '
                                            'in groups you are not a member '
                                            'of!'))

    annotation = models.Annotation(**data)
    request.db.add(annotation)

    # We need to flush the db here so that annotation.created and
    # annotation.updated get created.
    request.db.flush()

    models.update_document_metadata(
        request.db, annotation, document_meta_dicts, document_uri_dicts)

    return annotation
Ejemplo n.º 4
0
def create_annotation(request, data):
    """
    Create an annotation from passed data.

    :param request: the request object
    :type request: pyramid.request.Request

    :param data: a dictionary of annotation properties
    :type data: dict

    :returns: the created annotation
    :rtype: dict
    """
    document_uri_dicts = data['document']['document_uri_dicts']
    document_meta_dicts = data['document']['document_meta_dicts']
    del data['document']

    # Replies must have the same group as their parent.
    if data['references']:
        top_level_annotation_id = data['references'][0]
        top_level_annotation = fetch_annotation(request.db,
                                                top_level_annotation_id)
        if top_level_annotation:
            data['groupid'] = top_level_annotation.groupid
        else:
            raise schemas.ValidationError(
                'references.0: ' + _('Annotation {id} does not exist').format(
                    id=top_level_annotation_id))

    # The user must have permission to create an annotation in the group
    # they've asked to create one in.
    if data['groupid'] != '__world__':
        group_principal = 'group:{}'.format(data['groupid'])
        if group_principal not in request.effective_principals:
            raise schemas.ValidationError('group: ' +
                                          _('You may not create annotations '
                                            'in groups you are not a member '
                                            'of!'))

    annotation = models.Annotation(**data)
    request.db.add(annotation)

    # We need to flush the db here so that annotation.created and
    # annotation.updated get created.
    request.db.flush()

    models.update_document_metadata(request.db, annotation,
                                    document_meta_dicts, document_uri_dicts)

    return annotation
Ejemplo n.º 5
0
def create_annotation(request, data, group_service):
    """
    Create an annotation from passed data.

    :param request: the request object
    :type request: pyramid.request.Request

    :param data: a dictionary of annotation properties
    :type data: dict

    :param group_service: a service object that adheres to ``memex.interfaces.IGroupService``
    :type group_service: memex.interfaces.IGroupService

    :returns: the created and flushed annotation
    :rtype: dict
    """
    created = updated = datetime.utcnow()

    document_uri_dicts = data['document']['document_uri_dicts']
    document_meta_dicts = data['document']['document_meta_dicts']
    del data['document']

    # Replies must have the same group as their parent.
    if data['references']:
        top_level_annotation_id = data['references'][0]
        top_level_annotation = fetch_annotation(request.db,
                                                top_level_annotation_id)
        if top_level_annotation:
            data['groupid'] = top_level_annotation.groupid
        else:
            raise schemas.ValidationError(
                'references.0: ' + _('Annotation {id} does not exist').format(
                    id=top_level_annotation_id))

    # The user must have permission to create an annotation in the group
    # they've asked to create one in. If the application didn't configure
    # a groupfinder we will allow writing this annotation without any
    # further checks.
    group = group_service.find(data['groupid'])
    if group is None or not request.has_permission('write', context=group):
        raise schemas.ValidationError('group: ' +
                                      _('You may not create annotations '
                                        'in the specified group!'))

    annotation = models.Annotation(**data)
    annotation.created = created
    annotation.updated = updated

    document = models.update_document_metadata(request.db,
                                               annotation.target_uri,
                                               document_meta_dicts,
                                               document_uri_dicts,
                                               created=created,
                                               updated=updated)
    annotation.document = document

    request.db.add(annotation)
    request.db.flush()

    return annotation
Ejemplo n.º 6
0
def create_annotation(request, data):
    """
    Create an annotation from passed data.

    :param request: the request object
    :type request: pyramid.request.Request

    :param data: a dictionary of annotation properties
    :type data: dict

    :returns: the created and flushed annotation
    :rtype: dict
    """
    created = updated = datetime.utcnow()

    document_uri_dicts = data['document']['document_uri_dicts']
    document_meta_dicts = data['document']['document_meta_dicts']
    del data['document']

    # Replies must have the same group as their parent.
    if data['references']:
        top_level_annotation_id = data['references'][0]
        top_level_annotation = fetch_annotation(request.db,
                                                top_level_annotation_id)
        if top_level_annotation:
            data['groupid'] = top_level_annotation.groupid
        else:
            raise schemas.ValidationError(
                'references.0: ' +
                _('Annotation {id} does not exist').format(
                    id=top_level_annotation_id)
            )

    # The user must have permission to create an annotation in the group
    # they've asked to create one in. If the application didn't configure
    # a groupfinder we will allow writing this annotation without any
    # further checks.
    group = groups.find(request, data['groupid'])
    if group is None or not request.has_permission('write', context=group):
        raise schemas.ValidationError('group: ' +
                                      _('You may not create annotations '
                                        'in the specified group!'))

    annotation = models.Annotation(**data)
    annotation.created = created
    annotation.updated = updated

    document = models.update_document_metadata(
        request.db,
        annotation.target_uri,
        document_meta_dicts,
        document_uri_dicts,
        created=created,
        updated=updated)
    annotation.document = document

    request.db.add(annotation)
    request.db.flush()

    return annotation
Ejemplo n.º 7
0
def update_annotation(session, id_, data):
    """
    Update an existing annotation and its associated document metadata.

    Update the annotation identified by id_ with the given
    data. Create, delete and update document metadata as appropriate.

    :param session: the database session
    :type session: sqlalchemy.orm.session.Session

    :param id_: the ID of the annotation to be updated, this is assumed to be a
        validated ID of an annotation that does already exist in the database
    :type id_: string

    :param data: the validated data with which to update the annotation
    :type data: dict

    :returns: the updated annotation
    :rtype: memex.models.Annotation

    """
    # Remove any 'document' field first so that we don't try to save it on the
    # annotation object.
    document = data.pop('document', None)

    annotation = session.query(models.Annotation).get(id_)
    annotation.updated = datetime.utcnow()

    annotation.extra.update(data.pop('extra', {}))

    for key, value in data.items():
        setattr(annotation, key, value)

    if document:
        document_uri_dicts = document['document_uri_dicts']
        document_meta_dicts = document['document_meta_dicts']
        models.update_document_metadata(session, annotation,
                                        document_meta_dicts,
                                        document_uri_dicts)

    return annotation
Ejemplo n.º 8
0
def update_annotation(session, id_, data):
    """
    Update an existing annotation and its associated document metadata.

    Update the annotation identified by id_ with the given
    data. Create, delete and update document metadata as appropriate.

    :param session: the database session
    :type session: sqlalchemy.orm.session.Session

    :param id_: the ID of the annotation to be updated, this is assumed to be a
        validated ID of an annotation that does already exist in the database
    :type id_: string

    :param data: the validated data with which to update the annotation
    :type data: dict

    :returns: the updated annotation
    :rtype: memex.models.Annotation

    """
    # Remove any 'document' field first so that we don't try to save it on the
    # annotation object.
    document = data.pop('document', None)

    annotation = session.query(models.Annotation).get(id_)
    annotation.updated = datetime.utcnow()

    annotation.extra.update(data.pop('extra', {}))

    for key, value in data.items():
        setattr(annotation, key, value)

    if document:
        document_uri_dicts = document['document_uri_dicts']
        document_meta_dicts = document['document_meta_dicts']
        models.update_document_metadata(
            session, annotation, document_meta_dicts, document_uri_dicts)

    return annotation