+
+ meta_type = 'Attachment container'
+ security = ClassSecurityInfo()
+
+ def __init__(self):
+ self.id = 'attachments'
+
+ security.declarePrivate('checkIdAvailable')
+ def checkIdAvailable(self, id):
+ try:
+ self._checkId(id)
+ except BadRequest:
+ return False
+ else:
+ return True
+
+
+ security.declareProtected(ModifyPortalContent, 'put_upload')
+ def put_upload(self, REQUEST, RESPONSE):
+ """ Upload a content thru webdav put method.
+ The default behavior (NullRessource.PUT + PortalFolder.PUT_factory)
+ disallow files names with '_' at the begining.
+ """
+
+ self.dav__init(REQUEST, RESPONSE)
+ fileName = unquote(REQUEST.getHeader('X-File-Name', ''))
+ validId = makeValidId(self, fileName, allow_dup=True)
+
+ ifhdr = REQUEST.get_header('If', '')
+ if self.wl_isLocked():
+ if ifhdr:
+ self.dav__simpleifhandler(REQUEST, RESPONSE, col=1)
+ else:
+ raise Locked
+ elif ifhdr:
+ raise PreconditionFailed
+
+ if int(REQUEST.get('CONTENT_LENGTH') or 0) > LARGE_FILE_THRESHOLD:
+ file = REQUEST['BODYFILE']
+ body = file.read(LARGE_FILE_THRESHOLD)
+ file.seek(0)
+ else:
+ body = REQUEST.get('BODY', '')
+
+ typ=REQUEST.get_header('content-type', None)
+ if typ is None:
+ typ, enc=guess_content_type(validId, body)
+
+ if self.checkIdAvailable(validId) :
+ if typ.startswith('image/') :
+ utool = getUtilityByInterfaceName('Products.CMFCore.interfaces.IURLTool')
+ portal = utool.getPortalObject()
+ thumbSize = {'thumb_height' : portal.getProperty('thumb_size', 192),
+ 'thumb_width' : portal.getProperty('thumb_size', 192)}
+ ob = Photo(validId, fileName, '', **thumbSize)
+ else :
+ ob = File(validId, fileName, '')
+
+ self._setObject(validId, ob)
+ httpRespCode = 201
+ else :
+ httpRespCode = 200
+ ob = self._getOb(validId)
+
+ # We call _verifyObjectPaste with verify_src=0, to see if the
+ # user can create this type of object (and we don't need to
+ # check the clipboard.
+ try:
+ self._verifyObjectPaste(ob.__of__(self), 0)
+ except CopyError:
+ sMsg = 'Unable to create object of class %s in %s: %s' % \
+ (ob.__class__, repr(self), sys.exc_info()[1],)
+ raise Unauthorized, sMsg
+
+ ob.PUT(REQUEST, RESPONSE)
+ RESPONSE.setStatus(httpRespCode)
+ RESPONSE.setHeader('Content-Type', 'text/xml;;charset=utf-8')
+ if ob.meta_type == 'Blob File' :
+ return '<element id="%s" title="%s"/>' % (ob.getId(), escape(ob.title_or_id()))
+ elif ob.meta_type == 'Photo' :
+ width, height = ob.getResizedImageSize(size=(310, 310))
+ return '<element src="%(src)s" title="%(title)s" width="%(width)d" height="%(height)d"/>' % \
+ {'src' : 'attachments/%s/getResizedImage?size=%d_%d' % (ob.getId(), width, height),
+ 'title' : escape(ob.title_or_id()),
+ 'width' : width,
+ 'height' : height
+ }
+
+ security.declareProtected(ModifyPortalContent, 'removeUnusedAttachments')
+ def removeUnusedAttachments(self, html) :
+ html = '<div>%s</div>' % html
+ doc = htmlReadDoc(html, '', None, PARSE_OPTIONS)
+ used = {}
+
+ hrefs = doc.xpathEval('//a/@href')
+ for href in [a.get_content() for a in hrefs] :
+ if href.startswith('attachments/') :
+ used[href[len('attachments/'):]] = True
+
+ srcs = doc.xpathEval('//img/@src')
+ for src in [a.get_content() for a in srcs] :
+ if src.startswith('attachments/') :
+ parts = src.split('/')
+ if len(parts) >=2 :
+ used[parts[1]] = True
+
+ unused = [id for id in self.objectIds() if not used.has_key(id)]
+ if unused :
+ self.manage_delObjects(unused)