def post(self): """Create new resource and get response data. For :class:`adhocracy_core.interfaces.IItemVersion`: If a `new version` is already created in this transaction we don't want to create a new one. Instead we modify the existing one. This is needed to make :class:`adhocray_core.rest.batchview.BatchView` work. """ metric = self._get_post_metric_name() with statsd_timer(metric, rate=1, registry=self.registry): if is_batchmode(self.request) and self._creating_new_version(): last = self.registry.content.get_sheet_field(self.context, ITags, 'LAST') if is_created_in_current_transaction(last, self.registry): self._update_version(last) resource = last else: resource = self._create() else: resource = self._create() cstruct = self.build_post_response(resource) return cstruct
def test_post_copy_special_request__attributes_headers_to_subrequest( self, context, request_, mock_invoke_subrequest): from pyramid.traversal import resource_path from adhocracy_core.utils import is_batchmode request_.body = self._make_json_with_subrequest_cstructs( path='http://a.org/virtual/adhocracy/blah') request_.__cached_principals__ = [1] date = object() request_.headers['X-User-Path'] = 2 request_.headers['X-User-Token'] = 3 # Needed to stop the validator from complaining if these headers are # present request_.authenticated_userid = resource_path(context) request_.root = context request_.script_name = '/virtual' inst = self.make_one(context, request_) paths = { 'path': '/virtual/pool/item', 'first_version_path': '/virtual/pool/item/v1' } mock_invoke_subrequest.return_value = DummySubresponse( code=200, json=paths, ) inst.post() subrequest = mock_invoke_subrequest.call_args[0][0] assert is_batchmode(subrequest) assert subrequest.__cached_principals__ == [1] assert subrequest.headers.get('X-User-Path') == 2 assert subrequest.headers.get('X-User-Token') == 3 assert subrequest.script_name == '/virtual' assert subrequest.path_info == '/adhocracy/blah'
def test_post_copy_special_request__attributes_headers_to_subrequest( self, context, request_, mock_invoke_subrequest): from pyramid.traversal import resource_path from adhocracy_core.utils import is_batchmode request_.body = self._make_json_with_subrequest_cstructs( path='http://a.org/virtual/adhocracy/blah') request_.__cached_principals__ = [1] date = object() request_.headers['X-User-Path'] = 2 request_.headers['X-User-Token'] = 3 # Needed to stop the validator from complaining if these headers are # present request_.authenticated_userid = resource_path(context) request_.root = context request_.script_name = '/virtual' inst = self.make_one(context, request_) paths = {'path': '/virtual/pool/item', 'first_version_path': '/virtual/pool/item/v1'} mock_invoke_subrequest.return_value = DummySubresponse(code=200, json=paths,) inst.post() subrequest = mock_invoke_subrequest.call_args[0][0] assert is_batchmode(subrequest) assert subrequest.__cached_principals__ == [1] assert subrequest.headers.get('X-User-Path') == 2 assert subrequest.headers.get('X-User-Token') == 3 assert subrequest.script_name == '/virtual' assert subrequest.path_info == '/adhocracy/blah'
def test_post_empty(self, context, request_): from adhocracy_core.utils import is_batchmode inst = self.make_one(context, request_) assert inst.post() == {'responses': [], 'updated_resources': {'changed_descendants': [], 'created': [], 'modified': [], 'removed': []}} assert is_batchmode(request_)
def validate_linear_history(node, value): batchmode = is_batchmode(request) last = registry.content.get_sheet_field(context, ITags, 'LAST') if batchmode and is_created_in_current_transaction(last, registry): # In batchmode there is only one new last version created that is # updated by the following versions. See # func:`adhocracy_core.rest.views.IItemRestView.post` and # func:`adhocracy_core.resource.subscriber` for more information. return _assert_follows_last_version(node, value, last)
def _create(self) -> IResource: validated = self.request.validated kwargs = dict(parent=self.context, appstructs=validated.get('data', {}), creator=self.request.user, root_versions=validated.get('root_versions', []), request=self.request, is_batchmode=is_batchmode(self.request), ) iresource = validated['content_type'] return self.content.create(iresource.__identifier__, **kwargs)
def build_post_response(self, resource) -> dict: """Build response data structure for a POST request. """ appstruct = {} if IItem.providedBy(resource): appstruct["first_version_path"] = self._get_first_version(resource) schema = ItemResponseSchema().bind(request=self.request, context=resource) else: schema = ResourceResponseSchema().bind(request=self.request, context=resource) if not is_batchmode(self.request): appstruct["updated_resources"] = self._build_updated_resources_dict() return schema.serialize(appstruct)
def test_post_empty(self, context, request_): from adhocracy_core.utils import is_batchmode inst = self.make_one(context, request_) assert inst.post() == { 'responses': [], 'updated_resources': { 'changed_descendants': [], 'created': [], 'modified': [], 'removed': [] } } assert is_batchmode(request_)
def build_post_response(self, resource) -> dict: """Build response data structure for a POST request. """ appstruct = {} if IItem.providedBy(resource): appstruct['first_version_path'] = self._get_first_version(resource) schema = ItemResponseSchema().bind(request=self.request, context=resource) else: schema = ResourceResponseSchema().bind(request=self.request, context=resource) if not is_batchmode(self.request): appstruct[ 'updated_resources'] = self._build_updated_resources_dict() return schema.serialize(appstruct)
def put(self) -> dict: """Edit resource and get response data.""" sheets = self.registry.get_sheets_edit(self.context, self.request) appstructs = self.request.validated.get("data", {}) for sheet in sheets: name = sheet.meta.isheet.__identifier__ if name in appstructs: sheet.set(appstructs[name], request=self.request) appstruct = {} if not is_batchmode(self.request): # pragma: no branch appstruct["updated_resources"] = self._build_updated_resources_dict() schema = ResourceResponseSchema().bind(request=self.request, context=self.context) cstruct = schema.serialize(appstruct) return cstruct
def build_post_response(self, resource) -> dict: """Build response data structure for a POST request.""" appstruct = {} if IItem.providedBy(resource): first = get_sheet_field(resource, ITags, 'FIRST', registry=self.registry) appstruct['first_version_path'] = first schema = ItemResponseSchema().bind(request=self.request, context=resource) else: schema = ResourceResponseSchema().bind(request=self.request, context=resource) if not is_batchmode(self.request): appstruct[ 'updated_resources'] = self._build_updated_resources_dict() return schema.serialize(appstruct)
def put(self) -> dict: """Edit resource and get response data.""" sheets = self.registry.get_sheets_edit(self.context, self.request) appstructs = self.request.validated.get('data', {}) for sheet in sheets: name = sheet.meta.isheet.__identifier__ if name in appstructs: sheet.set(appstructs[name], request=self.request) appstruct = {} if not is_batchmode(self.request): # pragma: no branch appstruct[ 'updated_resources'] = self._build_updated_resources_dict() schema = ResourceResponseSchema().bind(request=self.request, context=self.context) cstruct = schema.serialize(appstruct) return cstruct
def build_post_response(self, resource) -> dict: """Build response data structure for a POST request.""" appstruct = {} if IItem.providedBy(resource): first = self.registry.content.get_sheet_field(resource, ITags, 'FIRST') appstruct['first_version_path'] = first schema = create_schema(ItemResponseSchema, resource, self.request) else: schema = create_schema(ResourceResponseSchema, resource, self.request) if not is_batchmode(self.request): updated = _build_updated_resources_dict(self.registry) appstruct['updated_resources'] = updated return schema.serialize(appstruct)
def put(self) -> dict: """Edit resource and get response data.""" with statsd_timer('process.put', rate=.1, registry=self.registry): sheets = self.content.get_sheets_edit(self.context, self.request) appstructs = self.request.validated.get('data', {}) for sheet in sheets: name = sheet.meta.isheet.__identifier__ if name in appstructs: sheet.set(appstructs[name]) appstruct = {} if not is_batchmode(self.request): # pragma: no branch updated = _build_updated_resources_dict(self.registry) appstruct['updated_resources'] = updated schema = create_schema(ResourceResponseSchema, self.context, self.request) cstruct = schema.serialize(appstruct) return cstruct
def post(self): """Create new resource and get response data. For :class:`adhocracy_core.interfaces.IItemVersion`: If a `new version` is already created in this transaction we don't want to create a new one. Instead we modify the existing one. This is needed to make :class:`adhocray_core.rest.batchview.BatchView` work. """ batchmode = is_batchmode(self.request) validated = self.request.validated iresource = validated['content_type'] resource_type = iresource.__identifier__ appstructs = validated.get('data', {}) creator = get_user(self.request) root_versions = validated.get('root_versions', []) last_new_version = validated.get('_last_new_version_in_transaction', None) metric = self._get_post_metric_name(iresource) with statsd_timer(metric, rate=1, registry=self.registry): if last_new_version is not None: # only happens in batch request sheets = self.content.get_sheets_create( last_new_version, self.request) appstructs = self.request.validated.get('data', {}) for sheet in sheets: name = sheet.meta.isheet.__identifier__ if name in appstructs: # pragma: no branch sheet.set(appstructs[name], request=self.request) resource = last_new_version else: resource = self.content.create( resource_type, self.context, appstructs=appstructs, creator=creator, root_versions=root_versions, request=self.request, is_batchmode=batchmode, ) return self.build_post_response(resource)
def post(self): """Create new resource and get response data. For :class:`adhocracy_core.interfaces.IItemVersion`: If a `new version` is already created in this transaction we don't want to create a new one. Instead we modify the existing one. This is needed to make :class:`adhocray_core.rest.batchview.BatchView` work. """ batchmode = is_batchmode(self.request) validated = self.request.validated iresource = validated['content_type'] resource_type = iresource.__identifier__ appstructs = validated.get('data', {}) creator = get_user(self.request) root_versions = validated.get('root_versions', []) last_new_version = validated.get('_last_new_version_in_transaction', None) metric = self._get_post_metric_name(iresource) with statsd_timer(metric, rate=1, registry=self.registry): if last_new_version is not None: # only happens in batch request sheets = self.content.get_sheets_create(last_new_version, self.request) appstructs = self.request.validated.get('data', {}) for sheet in sheets: name = sheet.meta.isheet.__identifier__ if name in appstructs: # pragma: no branch sheet.set(appstructs[name], request=self.request) resource = last_new_version else: resource = self.content.create(resource_type, self.context, appstructs=appstructs, creator=creator, root_versions=root_versions, request=self.request, is_batchmode=batchmode, ) return self.build_post_response(resource)
def validate_linear_history_no_fork(node: colander.SchemaNode, value: list): """Validate lineare history (no fork) for the follows field. :param:'value': list of one 'follows' resource. :raises colander.Invalid: if value does not reference the last version. """ from adhocracy_core.sheets.tags import ITags # prevent circle dependencies context = node.bindings['context'] request = node.bindings['request'] registry = node.bindings['registry'] batchmode = is_batchmode(request) last = get_sheet_field(context, ITags, 'LAST', registry=registry) if batchmode and is_created_in_current_transaction(last, registry): # In batchmode there is only one new last version created that is # updated by the following versions. See # func:`adhocracy_core.rest.views.IItemRestView.post` and # func:`adhocracy_core.resource.subscriber` for more information. return _assert_follows_last_version(node, value, last)
def validate_linear_history_no_fork(node: colander.SchemaNode, value: list): """Validate lineare history (no fork) for the follows field. :param:'value': list of one 'follows' resource. :raises colander.Invalid: if value does not reference the last version. """ context = node.bindings['context'] request = node.bindings['request'] if is_batchmode(request): last_new_version = get_last_new_version(request.registry, context) if last_new_version is not None: # Store ths last new version created in this transaction # so :func:`adhocracy_core.rest.views.ItemPoolView.post` # can do an put instead of post action in batch requests. request.validated['_last_new_version_in_transaction'] =\ last_new_version return last = get_last_version(context, request.registry) _assert_follows_eq_last_version(node, value, last)
def delete(self) -> dict: """Delete resource.""" parent = self.context.__parent__ name = self.context.__name__ parent.delete(name, self.registry) if is_batchmode(self.request): appstruct = {} else: updated = _build_updated_resources_dict(self.registry) appstruct = {'updated_resources': updated} schema = create_schema(DELETEResourceResponseSchema, self.context, self.request) # temporary undelete to make serialization work self.context.__parent__ = parent self.context.__name__ = name # serialize appstruct cstruct = schema.serialize(appstruct) del self.context.__parent__ del self.context.__name__ return cstruct