def test_it_calls_first(self, annotation, session, Document): """If it finds only one document it calls first().""" Document.find_or_create_by_uris.return_value = mock.Mock( count=mock.Mock(return_value=1) ) document.update_document_metadata(session, annotation, [], []) Document.find_or_create_by_uris.return_value.first.assert_called_once_with()
def test_it_calls_first(self, annotation, session, Document): """If it finds only one document it calls first().""" Document.find_or_create_by_uris.return_value = mock.Mock( count=mock.Mock(return_value=1)) document.update_document_metadata(session, annotation, [], []) Document.find_or_create_by_uris.return_value.first.assert_called_once_with( )
def test_it_updates_document_web_uri(self, annotation, Document, factories, session): document_ = mock.Mock(web_uri=None) Document.find_or_create_by_uris.return_value.count.return_value = 1 Document.find_or_create_by_uris.return_value.first.return_value = document_ document.update_document_metadata(session, annotation.target_uri, [], [], annotation.created, annotation.updated) document_.update_web_uri.assert_called_once_with()
def test_it_updates_document_updated(self, annotation, Document, merge_documents, session): yesterday_ = "yesterday" document_ = merge_documents.return_value = mock.Mock( updated=yesterday_) Document.find_or_create_by_uris.return_value.first.return_value = ( document_) document.update_document_metadata(session, annotation.target_uri, [], [], annotation.created, annotation.updated) assert document_.updated == annotation.updated
def test_if_there_are_multiple_documents_it_merges_them_into_one( self, annotation, Document, merge_documents, session): """If it finds more than one document it calls merge_documents().""" Document.find_or_create_by_uris.return_value = mock.Mock( count=mock.Mock(return_value=3)) document.update_document_metadata(session, annotation.target_uri, [], [], annotation.created, annotation.updated) merge_documents.assert_called_once_with( session, Document.find_or_create_by_uris.return_value, updated=annotation.updated)
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 ``h.interfaces.IGroupService`` :type group_service: h.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 = 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
def update_annotation(request, id_, data, group_service): """ 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 request: the request object :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 :type group_service: :py:class:`h.interfaces.IGroupService` :returns: the updated annotation :rtype: h.models.Annotation """ updated = datetime.utcnow() # Remove any 'document' field first so that we don't try to save it on the # annotation object. document = data.pop("document", None) annotation = request.db.query(models.Annotation).get(id_) annotation.updated = updated group = group_service.find(annotation.groupid) if group is None: raise schemas.ValidationError( "group: " + _("Invalid group specified for annotation")) if data.get("target_uri", None): _validate_group_scope(group, data["target_uri"]) 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"] document = update_document_metadata( request.db, annotation.target_uri, document_meta_dicts, document_uri_dicts, updated=updated, ) annotation.document = document request.find_service(name="search_index")._queue.add_by_id( id_, tag="storage.update_annotation", schedule_in=60) return annotation
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(document=self.document, 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('document', self.document) 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')) self.document = update_document_metadata( orm.object_session(self), self.target_uri, document_meta_dicts=document_meta_dicts, document_uri_dicts=document_uri_dicts, created=self.created, updated=self.updated, )
def test_it_updates_document_updated( self, annotation, Document, merge_documents, session ): yesterday_ = "yesterday" document_ = merge_documents.return_value = mock.Mock(updated=yesterday_) Document.find_or_create_by_uris.return_value.first.return_value = document_ document.update_document_metadata( session, annotation.target_uri, [], [], annotation.created, annotation.updated, ) assert document_.updated == annotation.updated
def test_it_updates_document_web_uri( self, annotation, Document, factories, session ): document_ = mock.Mock(web_uri=None) Document.find_or_create_by_uris.return_value.count.return_value = 1 Document.find_or_create_by_uris.return_value.first.return_value = document_ document.update_document_metadata( session, annotation.target_uri, [], [], annotation.created, annotation.updated, ) document_.update_web_uri.assert_called_once_with()
def test_it_saves_all_the_document_uris( self, session, annotation, Document, create_or_update_document_uri ): """It creates or updates a DocumentURI for each document URI dict.""" Document.find_or_create_by_uris.return_value.count.return_value = 1 document_uri_dicts = [ { "uri": "http://example.com/example_1", "claimant": "http://example.com/claimant", "type": "type", "content_type": None, }, { "uri": "http://example.com/example_2", "claimant": "http://example.com/claimant", "type": "type", "content_type": None, }, { "uri": "http://example.com/example_3", "claimant": "http://example.com/claimant", "type": "type", "content_type": None, }, ] document.update_document_metadata( session, annotation.target_uri, [], document_uri_dicts, annotation.created, annotation.updated, ) assert create_or_update_document_uri.call_count == 3 for doc_uri_dict in document_uri_dicts: create_or_update_document_uri.assert_any_call( session=session, document=Document.find_or_create_by_uris.return_value.first.return_value, created=annotation.created, updated=annotation.updated, **doc_uri_dict )
def test_it_saves_all_the_document_uris(self, session, annotation, Document, create_or_update_document_uri): """It creates or updates a DocumentURI for each document URI dict.""" Document.find_or_create_by_uris.return_value.count.return_value = 1 document_uri_dicts = [ { "uri": "http://example.com/example_1", "claimant": "http://example.com/claimant", "type": "type", "content_type": None, }, { "uri": "http://example.com/example_2", "claimant": "http://example.com/claimant", "type": "type", "content_type": None, }, { "uri": "http://example.com/example_3", "claimant": "http://example.com/claimant", "type": "type", "content_type": None, }, ] document.update_document_metadata( session, annotation.target_uri, [], document_uri_dicts, annotation.created, annotation.updated, ) assert create_or_update_document_uri.call_count == 3 for doc_uri_dict in document_uri_dicts: create_or_update_document_uri.assert_any_call( session=session, document=Document.find_or_create_by_uris.return_value.first. return_value, created=annotation.created, updated=annotation.updated, **doc_uri_dict)
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(document=self.document, 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('document', self.document) 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')) self.document = update_document_metadata( orm.object_session(self), self.target_uri, document_meta_dicts=document_meta_dicts, document_uri_dicts=document_uri_dicts, created=self.created, updated=self.updated, )
def update_annotation(request, id_, data, group_service): """ 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 request: the request object :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 :type group_service: :py:class:`h.interfaces.IGroupService` :returns: the updated annotation :rtype: h.models.Annotation """ updated = datetime.utcnow() # Remove any 'document' field first so that we don't try to save it on the # annotation object. document = data.pop("document", None) annotation = request.db.query(models.Annotation).get(id_) annotation.updated = updated group = group_service.find(annotation.groupid) if group is None: raise schemas.ValidationError( "group: " + _("Invalid group specified for annotation") ) if data.get("target_uri", None): _validate_group_scope(group, data["target_uri"]) 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"] document = update_document_metadata( request.db, annotation.target_uri, document_meta_dicts, document_uri_dicts, updated=updated, ) annotation.document = document return annotation
def test_it_uses_the_target_uri_to_get_the_document( self, annotation, Document, session ): document_uri_dicts = [ { "uri": "http://example.com/example_1", "claimant": "http://example.com/claimant", "type": "type", "content_type": None, }, { "uri": "http://example.com/example_2", "claimant": "http://example.com/claimant", "type": "type", "content_type": None, }, { "uri": "http://example.com/example_3", "claimant": "http://example.com/claimant", "type": "type", "content_type": None, }, ] document.update_document_metadata( session, annotation.target_uri, [], document_uri_dicts, annotation.created, annotation.updated, ) Document.find_or_create_by_uris.assert_called_once_with( session, annotation.target_uri, [ "http://example.com/example_1", "http://example.com/example_2", "http://example.com/example_3", ], created=annotation.created, updated=annotation.updated, )
def test_it_uses_the_target_uri_to_get_the_document(self, annotation, Document, session): document_uri_dicts = [ { 'uri': 'http://example.com/example_1', 'claimant': 'http://example.com/claimant', 'type': 'type', 'content_type': None, }, { 'uri': 'http://example.com/example_2', 'claimant': 'http://example.com/claimant', 'type': 'type', 'content_type': None, }, { 'uri': 'http://example.com/example_3', 'claimant': 'http://example.com/claimant', 'type': 'type', 'content_type': None, }, ] document.update_document_metadata(session, annotation.target_uri, [], document_uri_dicts, annotation.created, annotation.updated) Document.find_or_create_by_uris.assert_called_once_with( session, annotation.target_uri, [ 'http://example.com/example_1', 'http://example.com/example_2', 'http://example.com/example_3', ], created=annotation.created, updated=annotation.updated, )
def test_it_uses_the_target_uri_to_get_the_document( self, annotation, Document, session): document_uri_dicts = [ { "uri": "http://example.com/example_1", "claimant": "http://example.com/claimant", "type": "type", "content_type": None, }, { "uri": "http://example.com/example_2", "claimant": "http://example.com/claimant", "type": "type", "content_type": None, }, { "uri": "http://example.com/example_3", "claimant": "http://example.com/claimant", "type": "type", "content_type": None, }, ] document.update_document_metadata( session, annotation.target_uri, [], document_uri_dicts, annotation.created, annotation.updated, ) Document.find_or_create_by_uris.assert_called_once_with( session, annotation.target_uri, [ "http://example.com/example_1", "http://example.com/example_2", "http://example.com/example_3", ], created=annotation.created, updated=annotation.updated, )
def test_it_saves_all_the_document_metas(self, annotation, create_or_update_document_meta, Document, session): """It creates or updates a DocumentMeta for each document meta dict.""" Document.find_or_create_by_uris.return_value.count\ .return_value = 1 document_meta_dicts = [ { 'claimant': 'http://example.com/claimant', 'type': 'title', 'value': 'foo', }, { 'type': 'article title', 'value': 'bar', 'claimant': 'http://example.com/claimant', }, { 'type': 'site title', 'value': 'gar', 'claimant': 'http://example.com/claimant', }, ] document.update_document_metadata(session, annotation.target_uri, document_meta_dicts, [], annotation.created, annotation.updated) assert create_or_update_document_meta.call_count == 3 for document_meta_dict in document_meta_dicts: create_or_update_document_meta.assert_any_call( session=session, document=Document.find_or_create_by_uris.return_value.first.return_value, created=annotation.created, updated=annotation.updated, **document_meta_dict )
def test_it_saves_all_the_document_metas(self, annotation, create_or_update_document_meta, Document, session): """It creates or updates a DocumentMeta for each document meta dict.""" Document.find_or_create_by_uris.return_value.count\ .return_value = 1 document_meta_dicts = [ { 'claimant': 'http://example.com/claimant', 'type': 'title', 'value': 'foo', }, { 'type': 'article title', 'value': 'bar', 'claimant': 'http://example.com/claimant', }, { 'type': 'site title', 'value': 'gar', 'claimant': 'http://example.com/claimant', }, ] document.update_document_metadata(session, annotation.target_uri, document_meta_dicts, [], annotation.created, annotation.updated) assert create_or_update_document_meta.call_count == 3 for document_meta_dict in document_meta_dicts: create_or_update_document_meta.assert_any_call( session=session, document=Document.find_or_create_by_uris.return_value.first.return_value, created=annotation.created, updated=annotation.updated, **document_meta_dict )
def test_it_uses_the_target_uri_to_get_the_document(self, annotation, Document, session): document_uri_dicts = [ { 'uri': 'http://example.com/example_1', 'claimant': 'http://example.com/claimant', 'type': 'type', 'content_type': None, }, { 'uri': 'http://example.com/example_2', 'claimant': 'http://example.com/claimant', 'type': 'type', 'content_type': None, }, { 'uri': 'http://example.com/example_3', 'claimant': 'http://example.com/claimant', 'type': 'type', 'content_type': None, }, ] document.update_document_metadata(session, annotation.target_uri, [], document_uri_dicts, annotation.created, annotation.updated) Document.find_or_create_by_uris.assert_called_once_with( session, annotation.target_uri, [ 'http://example.com/example_1', 'http://example.com/example_2', 'http://example.com/example_3', ], created=annotation.created, updated=annotation.updated, )
def update_annotation(request, id_, data, group_service): """ 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 request: the request object :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 :type group_service: :py:class:`h.interfaces.IGroupService` :returns: the updated annotation :rtype: h.models.Annotation """ updated = datetime.utcnow() # Remove any 'document' field first so that we don't try to save it on the # annotation object. document = data.pop('document', None) annotation = request.db.query(models.Annotation).get(id_) annotation.updated = updated group = group_service.find(annotation.groupid) if group is None: raise schemas.ValidationError( 'group: ' + _('Invalid group specified for annotation')) if request.feature('filter_groups_by_scope') and data.get( 'target_uri', None): _validate_group_scope(group, data['target_uri']) 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'] document = update_document_metadata(request.db, annotation.target_uri, document_meta_dicts, document_uri_dicts, updated=updated) annotation.document = document return annotation
def test_it_saves_all_the_document_metas( self, annotation, create_or_update_document_meta, Document, session ): """It creates or updates a DocumentMeta for each document meta dict.""" Document.find_or_create_by_uris.return_value.count.return_value = 1 document_meta_dicts = [ { "claimant": "http://example.com/claimant", "type": "title", "value": "foo", }, { "type": "article title", "value": "bar", "claimant": "http://example.com/claimant", }, { "type": "site title", "value": "gar", "claimant": "http://example.com/claimant", }, ] document.update_document_metadata( session, annotation.target_uri, document_meta_dicts, [], annotation.created, annotation.updated, ) assert create_or_update_document_meta.call_count == 3 for document_meta_dict in document_meta_dicts: create_or_update_document_meta.assert_any_call( session=session, document=Document.find_or_create_by_uris.return_value.first.return_value, created=annotation.created, updated=annotation.updated, **document_meta_dict )
def test_it_saves_all_the_document_metas(self, annotation, create_or_update_document_meta, Document, session): """It creates or updates a DocumentMeta for each document meta dict.""" Document.find_or_create_by_uris.return_value.count.return_value = 1 document_meta_dicts = [ { "claimant": "http://example.com/claimant", "type": "title", "value": "foo", }, { "type": "article title", "value": "bar", "claimant": "http://example.com/claimant", }, { "type": "site title", "value": "gar", "claimant": "http://example.com/claimant", }, ] document.update_document_metadata( session, annotation.target_uri, document_meta_dicts, [], annotation.created, annotation.updated, ) assert create_or_update_document_meta.call_count == 3 for document_meta_dict in document_meta_dicts: create_or_update_document_meta.assert_any_call( session=session, document=Document.find_or_create_by_uris.return_value.first. return_value, created=annotation.created, updated=annotation.updated, **document_meta_dict)
def test_it_returns_a_document(self, annotation, create_or_update_document_meta, Document, session): Document.find_or_create_by_uris.return_value.count.return_value = 1 result = document.update_document_metadata(session, annotation.target_uri, [], [], annotation.created, annotation.updated) assert result == Document.find_or_create_by_uris.return_value.first.return_value
def test_if_there_are_multiple_documents_it_merges_them_into_one( self, annotation, Document, merge_documents, session): """If it finds more than one document it calls merge_documents().""" Document.find_or_create_by_uris.return_value = mock.Mock( count=mock.Mock(return_value=3)) document.update_document_metadata(session, annotation.target_uri, [], [], annotation.created, annotation.updated) merge_documents.assert_called_once_with( session, Document.find_or_create_by_uris.return_value, updated=annotation.updated)
def test_it_returns_a_document( self, annotation, create_or_update_document_meta, Document, session ): Document.find_or_create_by_uris.return_value.count.return_value = 1 result = document.update_document_metadata( session, annotation.target_uri, [], [], annotation.created, annotation.updated, ) assert result == Document.find_or_create_by_uris.return_value.first.return_value
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: h.models.Annotation """ updated = datetime.utcnow() # 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 = updated 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'] document = update_document_metadata(session, annotation.target_uri, document_meta_dicts, document_uri_dicts, updated=updated) annotation.document = document return annotation
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: h.models.Annotation """ updated = datetime.utcnow() # 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 = updated 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'] document = update_document_metadata(session, annotation.target_uri, document_meta_dicts, document_uri_dicts, updated=updated) annotation.document = document return annotation
def create_annotation(request, data, group_service): """ Create an annotation from already-validated data. :param request: the request object :type request: pyramid.request.Request :param data: an annotation data dict that has already been validated by :py:class:`h.schemas.annotation.CreateAnnotationSchema` :type data: dict :param group_service: a service object that implements :py:class:`h.interfaces.IGroupService` :type group_service: :py:class:`h.interfaces.IGroupService` :returns: the created and flushed annotation :rtype: :py:class:`h.models.Annotation` """ 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!")) _validate_group_scope(group, data["target_uri"]) annotation = models.Annotation(**data) annotation.created = created annotation.updated = updated document = 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() request.find_service(name="search_index")._queue.add_by_id( annotation.id, tag="storage.create_annotation", schedule_in=60) return annotation
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 ``h.interfaces.IGroupService`` :type group_service: h.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 = 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
def create_annotation(request, data, group_service): """ Create an annotation from already-validated data. :param request: the request object :type request: pyramid.request.Request :param data: an annotation data dict that has already been validated by :py:class:`h.schemas.annotation.CreateAnnotationSchema` :type data: dict :param group_service: a service object that implements :py:class:`h.interfaces.IGroupService` :type group_service: :py:class:`h.interfaces.IGroupService` :returns: the created and flushed annotation :rtype: :py:class:`h.models.Annotation` """ 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!')) if request.feature('filter_groups_by_scope') and group.scopes: # The scope (origin) of the target URI must match at least one # of a group's defined scopes, if the group has any group_scopes = [scope.origin for scope in group.scopes] if not group_scope_match(data['target_uri'], group_scopes): raise schemas.ValidationError('group scope: ' + _('Annotations for this target URI ' 'are not allowed in this group')) annotation = models.Annotation(**data) annotation.created = created annotation.updated = updated document = 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
def create_annotation(request, data, group_service): """ Create an annotation from already-validated data. :param request: the request object :type request: pyramid.request.Request :param data: an annotation data dict that has already been validated by :py:class:`h.schemas.annotation.CreateAnnotationSchema` :type data: dict :param group_service: a service object that implements :py:class:`h.interfaces.IGroupService` :type group_service: :py:class:`h.interfaces.IGroupService` :returns: the created and flushed annotation :rtype: :py:class:`h.models.Annotation` """ 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!") ) _validate_group_scope(group, data["target_uri"]) annotation = models.Annotation(**data) annotation.created = created annotation.updated = updated document = 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
# The user must have permission to create an annotation in the group # they've asked to create one in. if not request.has_permission(Permission.Group.WRITE, context=GroupContext(group)): raise schemas.ValidationError( "group: " + _("You may not create annotations in the specified group!")) _validate_group_scope(group, data["target_uri"]) annotation.created = annotation.updated = datetime.utcnow() annotation.document = update_document_metadata( request.db, annotation.target_uri, document_data["document_meta_dicts"], document_data["document_uri_dicts"], created=annotation.created, updated=annotation.updated, ) request.db.add(annotation) request.db.flush() request.find_service( # pylint: disable=protected-access name="search_index")._queue.add_by_id(annotation.id, tag="storage.create_annotation", schedule_in=60) return annotation