示例#1
0
    def updateObject(self, obj, filename, request, response, content_type):
        obj = obj.__of__(self.context)
        if content_type in ATOMPUB_CONTENT_TYPES:
            body = request.get('BODYFILE')
            body.seek(0)
            if self.action in ['derive', 'checkout']:
                self.mergeMetadata(obj, parse(body))
            else:
                self.updateMetadata(obj, parse(body))
        elif content_type == 'application/zip':
            body = request.get('BODYFILE')
            cksum = request.get_header('Content-MD5')
            body.seek(0)
            self.updateContent(obj, body, content_type, cksum)
        elif content_type.startswith('multipart/'):
            cksum = request.get_header('Content-MD5')
            atom_dom, payload, payload_type = splitMultipartRequest(request)
            self.updateMetadata(obj, atom_dom)
            self.updateContent(obj, StringIO(payload), payload_type, cksum)

        # blank the message on derive or checkout - see ticket 11879
        if self.action in ('derive', 'checkout'):
            obj.logAction(self.action, '')
        else:
            obj.logAction(self.action, obj.message)
        return obj
示例#2
0
    def _handlePost(self):
        """ A POST fo the Edit-IRI can do one of two things. You can either add
            more metadata by posting an atom entry, you can add more data and
            metadata with a multipart post, or you can publish the module with
            an empty request and In-Progress set to false.
        """
        context = aq_inner(self.context)
        content_type = self.request.get_header('Content-Type', '')
        content_type = getContentType(content_type)

        if content_type in ATOMPUB_CONTENT_TYPES:
            # Apply more metadata to the item
            adapter = getMultiAdapter((context.aq_parent, self.request),
                                      IRhaptosWorkspaceSwordAdapter)

            body = self.request.get('BODYFILE')
            body.seek(0)
            if context.state == 'published':
                context.checkout(self.context.objectId)
            adapter.updateMetadata(context, parse(body))
        elif content_type.startswith('multipart/'):
            checkUploadSize(context, self.request.stdin)
            atom_dom, payload, payload_type = splitMultipartRequest(
                self.request)

            cksum = self.request.get_header('Content-MD5')
            merge = self.request.get_header('Update-Semantics')
            adapter = getMultiAdapter((context.aq_parent, self.request),
                                      IRhaptosWorkspaceSwordAdapter)

            if context.state == 'published':
                context.checkout(self.context.objectId)

            adapter.updateMetadata(context, atom_dom)
            adapter.updateContent(
                context, StringIO(payload), payload_type, cksum,
                merge == 'http://purl.org/oerpub/semantics/Merge')
            context.logAction(adapter.action)
        elif content_type:
            # A content type is provided, and its not atom+xml or multipart
            raise BadRequest(
                "You cannot POST content of type %s to the SE-IRI" %
                content_type)

        # If In-Progress is set to false or omitted, try to publish
        in_progress = self.request.get_header('In-Progress', 'false')
        if in_progress == 'false':
            self._handlePublish()
            # We SHOULD return a deposit receipt, status code 200, and the
            # Edit-IRI in the Location header.
            self.request.response.setHeader(
                'Location', '%s/sword' % context.absolute_url())
            self.request.response.setStatus(200)

        view = context.unrestrictedTraverse('@@sword')
        return view._handleGet()
示例#3
0
    def createObject(self, context, name, content_type, request):
        # see if the request has a atompub payload that specifies,
        # module id in "source" or "mdml:derived_from" in ATOM entry.
        def _deriveOrCheckout(dom):
            # Check if this is a request to derive or checkout an item
            # 'item' could be a module or a collection at this point.
            elements = dom.getElementsByTagNameNS(
                "http://purl.org/dc/terms/", 'isVersionOf')
            if len(elements) > 0:
                item_id = \
                    elements[0].firstChild.toxml().encode(self.encoding)
                obj = self.checkoutItem(item_id)
                self.action = 'checkout'
                return obj
            elements = dom.getElementsByTagNameNS(
                "http://purl.org/dc/terms/", 'source')
            if len(elements) > 0:
                # now we can fork / derive the module
                item_id = \
                    elements[0].firstChild.toxml().encode(self.encoding)
                obj = self.deriveItem(item_id)
                self.action = 'derive'
                return obj

        if content_type in ATOMPUB_CONTENT_TYPES:
            # find our marker elements
            body = request.get('BODYFILE')

            # Check upload size
            checkUploadSize(context, body)

            body.seek(0)
            dom = parse(body)
            body.seek(0)

            # Derive or checkout, if the headers are right
            obj = _deriveOrCheckout(dom)
            if obj is not None:
                return obj
        elif content_type.startswith('multipart/'):
            # Check upload size
            checkUploadSize(context, request.stdin)
            atom_dom, payload, payload_type = splitMultipartRequest(request)
            obj = _deriveOrCheckout(atom_dom)
            if obj is not None:
                return obj

        checkUploadSize(context, request.stdin)
        # if none of the above is the case we let the ancestor to its thing
        # we set the action to 'create' since there is no more info to work
        # with.
        obj = super(RhaptosWorkspaceSwordAdapter, self).createObject(
            context, name, content_type, request)
        self.action = 'create'
        return obj
示例#4
0
    def _handlePost(self):
        """ A POST fo the Edit-IRI can do one of two things. You can either add
            more metadata by posting an atom entry, you can add more data and
            metadata with a multipart post, or you can publish the module with
            an empty request and In-Progress set to false.
        """
        context = aq_inner(self.context)
        content_type = self.request.get_header('Content-Type', '')
        content_type = getContentType(content_type)

        if content_type in ATOMPUB_CONTENT_TYPES:
            # Apply more metadata to the item
            adapter = getMultiAdapter(
                (context.aq_parent, self.request), IRhaptosWorkspaceSwordAdapter)

            body = self.request.get('BODYFILE')
            body.seek(0)
            if context.state == 'published':
                context.checkout(self.context.objectId)
            adapter.updateMetadata(context, parse(body))
        elif content_type.startswith('multipart/'):
            checkUploadSize(context, self.request.stdin)
            atom_dom, payload, payload_type = splitMultipartRequest(self.request)

            cksum = self.request.get_header('Content-MD5')
            merge = self.request.get_header('Update-Semantics')
            adapter = getMultiAdapter(
                (context.aq_parent, self.request), IRhaptosWorkspaceSwordAdapter)

            if context.state == 'published':
                context.checkout(self.context.objectId)

            adapter.updateMetadata(context, atom_dom)
            adapter.updateContent(context, StringIO(payload), payload_type,
                cksum, merge == 'http://purl.org/oerpub/semantics/Merge')
            context.logAction(adapter.action)
        elif content_type:
            # A content type is provided, and its not atom+xml or multipart
            raise BadRequest(
                "You cannot POST content of type %s to the SE-IRI" % content_type)

        # If In-Progress is set to false or omitted, try to publish
        in_progress = self.request.get_header('In-Progress', 'false')
        if in_progress == 'false':
            self._handlePublish()
            # We SHOULD return a deposit receipt, status code 200, and the
            # Edit-IRI in the Location header.
            self.request.response.setHeader('Location',
                '%s/sword' % context.absolute_url())
            self.request.response.setStatus(200)

        view = context.unrestrictedTraverse('@@sword')
        return view._handleGet()
示例#5
0
    def _handlePut(self):
        """ PUT against an existing item should update it.
        """
        content_type = self.request.get_header('Content-Type')
        if content_type is None:
            raise BadRequest("You have no Content-Type header in your request")
        content_type = getContentType(content_type)

        if content_type in ATOMPUB_CONTENT_TYPES or \
          content_type.startswith('multipart/'):
            # If the module is published, do a transparent checkout
            if self.context.state == 'published':
                self.context.checkout(self.context.objectId)

            merge = self.request.get_header(
                'Update-Semantics') and True or False
            parent = self.context.aq_inner.aq_parent
            adapter = getMultiAdapter(
                (parent, self.request), IRhaptosWorkspaceSwordAdapter)

            if content_type.startswith('multipart/'):
                atom_dom, payload, payload_type = splitMultipartRequest(
                    self.request)
                checkUploadSize(self.context, payload)

                # Update Content
                cksum = self.request.get_header('Content-MD5')
                adapter.updateContent(self.context, StringIO(payload),
                    payload_type, cksum, merge)
                self.context.logAction(adapter.action)
            else:
                body = self.request.get('BODYFILE')
                checkUploadSize(self.context, body)
                atom_dom = parse(body)

            # update Metadata
            if merge:
                # merge the metadata on the request with what is on the
                # module (in this case 'self.context')
                adapter.mergeMetadata(self.context, atom_dom)
            else:
                # replace what is on the module with metadata on the request
                # in the process all fields not on the request will be reset
                # on the module (see METADATA_DEFAULTS) for the values used.
                adapter.replaceMetadata(self.context, atom_dom)

            # If In-Progress is set to false or omitted, try to publish
            if self.request.get_header('In-Progress', 'false') == 'false':
                self._handlePublish()

            # response code of 200 as required by SWORD spec:
            self.request.response.setStatus(200)
            # set the location header
            self.request.response.setHeader(
                'Location',
                '%s/sword' %self.context.absolute_url())

            view = self.__of__(self.context)
            pt = self.depositreceipt.__of__(view)
            return pt()
        else:
            # This will result in a 400 error
            raise ValueError(
                "%s is not a valid content type for this request" % content_type)
示例#6
0
    def _handlePut(self):
        """ PUT against an existing item should update it.
        """
        content_type = self.request.get_header('Content-Type')
        if content_type is None:
            raise BadRequest("You have no Content-Type header in your request")
        content_type = getContentType(content_type)

        if content_type in ATOMPUB_CONTENT_TYPES or \
          content_type.startswith('multipart/'):
            # If the module is published, do a transparent checkout
            if self.context.state == 'published':
                self.context.checkout(self.context.objectId)

            merge = self.request.get_header(
                'Update-Semantics') and True or False
            parent = self.context.aq_inner.aq_parent
            adapter = getMultiAdapter((parent, self.request),
                                      IRhaptosWorkspaceSwordAdapter)

            if content_type.startswith('multipart/'):
                atom_dom, payload, payload_type = splitMultipartRequest(
                    self.request)
                checkUploadSize(self.context, payload)

                # Update Content
                cksum = self.request.get_header('Content-MD5')
                adapter.updateContent(self.context, StringIO(payload),
                                      payload_type, cksum, merge)
                self.context.logAction(adapter.action)
            else:
                body = self.request.get('BODYFILE')
                checkUploadSize(self.context, body)
                atom_dom = parse(body)

            # update Metadata
            if merge:
                # merge the metadata on the request with what is on the
                # module (in this case 'self.context')
                adapter.mergeMetadata(self.context, atom_dom)
            else:
                # replace what is on the module with metadata on the request
                # in the process all fields not on the request will be reset
                # on the module (see METADATA_DEFAULTS) for the values used.
                adapter.replaceMetadata(self.context, atom_dom)

            # If In-Progress is set to false or omitted, try to publish
            if self.request.get_header('In-Progress', 'false') == 'false':
                self._handlePublish()

            # response code of 200 as required by SWORD spec:
            self.request.response.setStatus(200)
            # set the location header
            self.request.response.setHeader(
                'Location', '%s/sword' % self.context.absolute_url())

            view = self.__of__(self.context)
            pt = self.depositreceipt.__of__(view)
            return pt()
        else:
            # This will result in a 400 error
            raise ValueError(
                "%s is not a valid content type for this request" %
                content_type)