Example #1
0
    def __setitem__(self, url_or_type, item_or_items):
        if isinstance(url_or_type, type):
            self[url_or_type][()] = item_or_items
            return

        psn = self._descend(url_or_type, self._set_op)

        if psn is None:
            extra = [i for i in self.itervalues()]
            new = _convert(item_or_items, self._schema)
            old_key = getattr(new, '_key_', None)
            self._top = new
        else:
            p, s, n = psn
            if n in p:
                extra = [
                    i for i in self._all_data_items(p[n], url_or_type,
                                                    self._items_op)
                    if i[0] != url_or_type
                ]
            else:
                extra = []
            new = _convert(item_or_items, s)
            old_key = getattr(new, '_key_', None)
            p[n] = new

        if type(p) == dict and new is not None:  # Have to take care of _key_
            new._set_key(
                tuple((_key_convert(val, typ) for typ, val in zip(
                    self._descend(url_or_type, self._schema_op)[1],
                    re.search(s._url.replace('%s', '([^/]+)'),
                              url_or_type).groups()))))

        if old_key is not None and len(old_key) == len(new._key_) and len(old_key)>0 and \
           _is_fake_key( old_key[-1] ) and not _is_fake_key( new._key_[-1] ):
            if new._ is None: new._ = s._(replaces=old_key[-1])
            else: new._.replaces = old_key[-1]

        if new is not None and new._ and getattr(new._, 'replaces', None):
            self.replaces[new._.replaces] = new._key_[-1]

        for k, v in extra:
            self[k] = v
	def __setitem__( self, url_or_type, item_or_items ):
		if isinstance( url_or_type, type ):
			self[url_or_type][()] = item_or_items
			return

		psn = self._descend( url_or_type, self._set_op )
				
		if psn is None:
			extra = [ i for i in self.itervalues() ]
			new = _convert( item_or_items, self._schema )
			old_key = getattr( new, '_key_', None )
			self._top = new
		else:
			p,s,n = psn
			if n in p:
				extra = [ i for i in self._all_data_items( p[n], url_or_type, self._items_op ) if i[0] != url_or_type ]
			else:
				extra = []
			new = _convert( item_or_items, s )
			old_key = getattr( new, '_key_', None )
			p[n] = new

		if type(p) == dict and new is not None: # Have to take care of _key_
			new._set_key( tuple( (
				_key_convert( val, typ )
				for typ, val in zip(
					self._descend( url_or_type, self._schema_op )[1],
					re.search( s._url.replace( '%s', '([^/]+)' ), url_or_type ).groups()
				)
			) ) )

		if old_key is not None and len(old_key) == len(new._key_) and len(old_key)>0 and \
		   _is_fake_key( old_key[-1] ) and not _is_fake_key( new._key_[-1] ):
			if new._ is None:	new._ = s._( replaces = old_key[-1] )
			else:				new._.replaces = old_key[-1]
		
		if new is not None and new._ and getattr( new._, 'replaces', None ):
			self.replaces[new._.replaces] = new._key_[-1]

		for k,v in extra:	self[k] = v
    def _modifyObject(self, t, key, request, response, add):

        queue = [(t.children, 0, True, True)] if add else [(t, 0, False,
                                                            False)]

        while len(queue) > 0:

            t, ignore, add, is_item = queue.pop(0)
            all_of_type = request[t.schema_type]
            if key not in all_of_type: continue
            all_of_type = all_of_type.slice(key)

            if ignore == 0:
                ignore = 1
                if add:
                    if 'create' in t.handlers:
                        ignore = t.handlers['create'].depth + 1
                        t.handlers['create'](
                            self, ((key + tuple(
                                (response.replaces[kpart]
                                 if schema._is_fake_key(kpart) else kpart
                                 for kpart in (k[:-1] if is_item else k))), v)
                                   for k, v in all_of_type.iteritems()
                                   if (schema._is_fake_key(k[-1])
                                       if is_item else _is_new_key(k))),
                            response, request)
                    elif is_item or schema.is_a(t.schema_type, schema.Object):
                        raise Error(
                            405,
                            '%s at "%s" does not have a create() method associated'
                            % ('Item' if is_item else 'Object',
                               t.schema_type._url.replace('%s', '*')))
                else:
                    if 'update' in t.handlers:
                        ignore = t.handlers['update'].depth + 1
                        t.handlers['update'](self, (
                            v for k, v in all_of_type.iteritems()
                            if not _is_new_key(k) and not _is_deleted_item(v)),
                                             response, request)
                    elif schema.is_a(t.schema_type, schema.Container):
                        all_of_type = request[t.children.schema_type].slice(
                            key)

                        # Process deleted items immediately
                        all_deleted = [(k, _version_of(v))
                                       for k, v in all_of_type.iteritems()
                                       if _is_deleted_item(v)]
                        if len(all_deleted) > 0:
                            if 'delete' in t.children.handlers:
                                t.children.handlers['delete'](self,
                                                              all_deleted,
                                                              response,
                                                              request)
                            else:
                                raise Error(
                                    405,
                                    'Item at "%s" does not have a delete() method associated'
                                    % t.children.schema_type._url.replace(
                                        '%s', '*'))

                        # Add processing of added items to the queue
                        if not packet._is_empty(
                            (k for k in all_of_type.iterkeys()
                             if _is_new_key(k))):
                            queue.append((t.children, 0, True, True))

                    elif schema.is_a(t.schema_type, schema.Object):
                        raise Error(
                            405,
                            'Object at "%s" does not have an update() method associated'
                            % t.schema_type._url.replace('%s', '*'))

            if t.children:
                if schema.is_a(t.schema_type, schema.Container):
                    queue.append((t.children, ignore - 1, add, add))
                else:
                    for child in t.children.itervalues():
                        queue.append((child, ignore - 1, add, False))
	def _modifyObject( self, t, key, request, response, add ):
		
		queue = [ ( t.children, 0, True, True ) ] if add else [ ( t, 0, False, False ) ]
	
		while len(queue) > 0:
			
			t, ignore, add, is_item = queue.pop(0)
			all_of_type = request[t.schema_type]
			if key not in all_of_type:	continue
			all_of_type = all_of_type.slice( key )
			
			if ignore == 0:
				ignore = 1
				if add:
					if 'create' in t.handlers:
						ignore = t.handlers['create'].depth + 1
						t.handlers['create']( self, (
							(
								key + tuple( (
									response.replaces[kpart] if schema._is_fake_key( kpart ) else kpart
									for kpart in ( k[:-1] if is_item else k )
								) ),
								v
							)
							for k,v in all_of_type.iteritems()
							if ( schema._is_fake_key( k[-1] ) if is_item else _is_new_key( k ) )
						), response, request )
					elif is_item or schema.is_a( t.schema_type, schema.Object ):
						raise Error( 405, '%s at "%s" does not have a create() method associated'  % (
							'Item' if is_item else 'Object',
							t.schema_type._url.replace( '%s', '*' )
						) )
				else:
					if 'update' in t.handlers:
						ignore = t.handlers['update'].depth + 1
						t.handlers['update']( self, (
							v for k,v in all_of_type.iteritems() if not _is_new_key( k ) and not _is_deleted_item( v )
						), response, request )
					elif schema.is_a( t.schema_type, schema.Container ):
						all_of_type = request[t.children.schema_type].slice( key )
						
						# Process deleted items immediately
						all_deleted = [ ( k, _version_of( v ) ) for k,v in all_of_type.iteritems() if _is_deleted_item( v ) ]
						if len( all_deleted ) > 0:
							if 'delete' in t.children.handlers:
								t.children.handlers['delete']( self, all_deleted, response, request )
							else:
								raise Error( 405, 'Item at "%s" does not have a delete() method associated'  % t.children.schema_type._url.replace( '%s', '*' ) )
								
						# Add processing of added items to the queue
						if not packet._is_empty( ( k for k in all_of_type.iterkeys() if _is_new_key( k ) ) ):
							queue.append( ( t.children, 0, True, True ) )
							
					elif schema.is_a( t.schema_type, schema.Object ):
						raise Error( 405, 'Object at "%s" does not have an update() method associated'  % t.schema_type._url.replace( '%s', '*' ) )

			if t.children:					
				if schema.is_a( t.schema_type, schema.Container ):
					queue.append( ( t.children, ignore-1, add, add ) )
				else:
					for child in t.children.itervalues():
						queue.append( ( child, ignore-1, add, False ) )