############################################################################## # Copyright (c) 2003 Zope Corporation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. ############################################################################## """HTTP `PUT` verb $Id: put.py 70434 2006-09-29 06:53:22Z ctheune $ """ __docformat__ = 'restructuredtext' from zope.component import queryAdapter from zope.event import notify from zope.lifecycleevent import ObjectCreatedEvent from zope.interface import implements from zope.filerepresentation.interfaces import IWriteFile from zope.filerepresentation.interfaces import \ IWriteDirectory, IReadDirectory, IFileFactory from zope.app.http.interfaces import INullResource from zope.app import zapi class NullResource(object): """Object representing objects to be created by a `PUT`. """ implements(INullResource) def __init__(self, container, name): self.container = container self.name = name class NullPUT(object): """Put handler for null resources (new file-like things) This view creates new objects in containers. """ def __init__(self, context, request): self.context = context self.request = request def PUT(self): request = self.request body = request.bodyStream name = self.context.name container = self.context.container # Find the extension ext_start = name.rfind('.') if ext_start > 0: ext = name[ext_start:] else: ext = "." # Get a "directory" surrogate for the container # TODO: Argh. Why don't we have a unioned Interface for that?!? dir_write = IWriteDirectory(container) dir_read = IReadDirectory(container) # Now try to get a custom factory for he container factory = queryAdapter(container, IFileFactory, ext) # Fall back to a non-custom one if factory is None: factory = IFileFactory(container) # TODO: Need to add support for large files data = body.read() newfile = factory(name, request.getHeader('content-type', ''), data) notify(ObjectCreatedEvent(newfile)) dir_write[name] = newfile # Ickyness with non-predictable support for containment: # make sure we get a containment proxy newfile = dir_read[name] request.response.setStatus(201) request.response.setHeader( 'Location', zapi.absoluteURL(newfile, request)) return '' class FilePUT(object): """Put handler for existing file-like things """ def __init__(self, context, request): self.context = context self.request = request def PUT(self): request = self.request body = self.request.bodyStream file = self.context adapter = IWriteFile(file) adapter.write(body.read()) return ''