def resource_create_object(request, resource_cls, uri, resource_name, obj_id): """In the default bucket, the bucket and collection are implicitly created. This helper instantiate the resource and simulate a request with its RootFactory on the instantiated resource. :returns: the created object :rtype: dict """ # Fake context to instantiate a resource. context = RouteFactory(request) context.get_permission_object_id = lambda r, i: uri resource = resource_cls(request, context) # Check that provided id is valid for this resource. if not resource.model.id_generator.match(obj_id): error_details = { 'location': 'path', 'description': "Invalid %s id" % resource_name } raise_invalid(resource.request, **error_details) data = {'id': obj_id} try: obj = resource.model.create_record(data) # Since the current request is not a resource (but a straight Service), # we simulate a request on a resource. # This will be used in the resource event payload. resource.request.current_resource_name = resource_name resource.postprocess(data, action=ACTIONS.CREATE) except storage_exceptions.UnicityError as e: obj = e.record return obj
def create_collection(request, bucket_id): # Do nothing if current request does not involve a collection. subpath = request.matchdict.get('subpath') if not (subpath and subpath.startswith('collections/')): return collection_id = subpath.split('/')[1] # Do nothing if current request will already create the collection. collection_put = (request.method.lower() == 'put' and request.path.endswith(collection_id)) if collection_put: return # Fake context to instantiate a Collection resource. context = RouteFactory(request) context.get_permission_object_id = ( lambda r, i: '/buckets/%s/collections/%s' % (bucket_id, collection_id)) backup = request.matchdict request.matchdict = dict(bucket_id=bucket_id, id=collection_id, **request.matchdict) resource = Collection(request, context) try: resource.collection.create_record({'id': collection_id}) except storage_exceptions.UnicityError: pass request.matchdict = backup
def create_collection(request, bucket_id): # Do nothing if current request does not involve a collection. subpath = request.matchdict.get('subpath') if not (subpath and subpath.startswith('collections/')): return collection_id = subpath.split('/')[1] collection_uri = '/buckets/%s/collections/%s' % (bucket_id, collection_id) # Do not intent to create multiple times per request (e.g. in batch). already_created = request.bound_data.setdefault('collections', {}) if collection_uri in already_created: return # Do nothing if current request will already create the collection. collection_put = (request.method.lower() == 'put' and request.path.endswith(collection_id)) if collection_put: return # Fake context to instantiate a Collection resource. context = RouteFactory(request) context.get_permission_object_id = lambda r, i: collection_uri backup = request.matchdict request.matchdict = dict(bucket_id=bucket_id, id=collection_id, **request.matchdict) resource = Collection(request, context) try: collection = resource.model.create_record({'id': collection_id}) except storage_exceptions.UnicityError as e: collection = e.record already_created[collection_uri] = collection request.matchdict = backup
def patch_record(record, request): # XXX: add util clone_request() backup_pattern = request.matched_route.pattern backup_body = request.body backup_validated = request.validated # Instantiate record resource with current request. context = RouteFactory(request) context.get_permission_object_id = lambda r, i: record_uri(r) record_pattern = request.matched_route.pattern.replace('/attachment', '') request.matched_route.pattern = record_pattern # Simulate update of fields. request.validated = record request.body = json.dumps(record).encode('utf-8') resource = Record(request, context) request.current_resource_name = 'record' try: saved = resource.patch() except httpexceptions.HTTPNotFound: saved = resource.put() request.matched_route.pattern = backup_pattern request.body = backup_body request.validated = backup_validated return saved
def resource_create_object(request, resource_cls, uri): """Implicitly create a resource (or fail silently). In the default bucket, the bucket and collection are implicitly created. This helper creates one of those resources using a simulated request and context that is appropriate for the resource. Also runs create events as though the resource were created in a subrequest. If the resource already exists, do nothing. """ resource_name, matchdict = view_lookup(request, uri) # Build a fake request, mainly used to populate the create events that # will be triggered by the resource. fakerequest = build_request(request, { 'method': 'PUT', 'path': uri, }) fakerequest.matchdict = matchdict fakerequest.bound_data = request.bound_data fakerequest.authn_type = request.authn_type fakerequest.selected_userid = request.selected_userid fakerequest.errors = request.errors fakerequest.current_resource_name = resource_name obj_id = matchdict['id'] # Fake context, required to instantiate a resource. context = RouteFactory(fakerequest) context.resource_name = resource_name resource = resource_cls(fakerequest, context) # Check that provided id is valid for this resource. if not resource.model.id_generator.match(obj_id): error_details = { 'location': 'path', 'description': 'Invalid {} id'.format(resource_name) } raise_invalid(resource.request, **error_details) data = {'id': obj_id} try: obj = resource.model.create_record(data) except UnicityError as e: # The record already exists; skip running events return e.record # Since the current request is not a resource (but a straight Service), # we simulate a request on a resource. # This will be used in the resource event payload. resource.postprocess(obj, action=ACTIONS.CREATE) return obj
def create_bucket(request, bucket_id): """Create a bucket if it doesn't exists.""" bucket_put = (request.method.lower() == 'put' and request.path.endswith('buckets/default')) # Do nothing if current request will already create the bucket. if bucket_put: return # Fake context to instantiate a Bucket resource. context = RouteFactory(request) context.get_permission_object_id = lambda r, i: '/buckets/%s' % bucket_id resource = Bucket(request, context) try: resource.collection.create_record({'id': bucket_id}) except storage_exceptions.UnicityError: pass
def resource_create_object(request, resource_cls, uri): """In the default bucket, the bucket and collection are implicitly created. This helper instantiate the resource and simulate a request with its RootFactory on the instantiated resource. :returns: the created object :rtype: dict """ resource_name, matchdict = view_lookup(request, uri) # Build a fake request, mainly used to populate the create events that # will be triggered by the resource. fakerequest = build_request(request, { 'method': 'PUT', 'path': uri, }) fakerequest.matchdict = matchdict fakerequest.bound_data = request.bound_data fakerequest.authn_type = request.authn_type fakerequest.selected_userid = request.selected_userid fakerequest.errors = request.errors fakerequest.current_resource_name = resource_name obj_id = matchdict['id'] # Fake context, required to instantiate a resource. context = RouteFactory(fakerequest) context.resource_name = resource_name resource = resource_cls(fakerequest, context) # Check that provided id is valid for this resource. if not resource.model.id_generator.match(obj_id): error_details = { 'location': 'path', 'description': "Invalid %s id" % resource_name } raise_invalid(resource.request, **error_details) data = {'id': obj_id} try: obj = resource.model.create_record(data) # Since the current request is not a resource (but a straight Service), # we simulate a request on a resource. # This will be used in the resource event payload. resource.postprocess(data, action=ACTIONS.CREATE) except storage_exceptions.UnicityError as e: obj = e.record return obj
def create_bucket(request, bucket_id): """Create a bucket if it doesn't exists.""" bucket_put = (request.method.lower() == 'put' and request.path.endswith('buckets/default')) # Do nothing if current request will already create the bucket. if bucket_put: return # Do not intent to create multiple times per request (e.g. in batch). already_created = request.bound_data.setdefault('buckets', {}) if bucket_id in already_created: return # Fake context to instantiate a Bucket resource. context = RouteFactory(request) context.get_permission_object_id = lambda r, i: '/buckets/%s' % bucket_id resource = Bucket(request, context) try: bucket = resource.model.create_record({'id': bucket_id}) except storage_exceptions.UnicityError as e: bucket = e.record already_created[bucket_id] = bucket