Logo Search packages:      
Sourcecode: zope-attachmentfield version File versions  Download package

AttachmentFieldTool.py

# -*- coding: utf-8 -*-
## AttchmentField
## Copyright (C)2006 Ingeniweb

## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.

## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.

## You should have received a copy of the GNU General Public License
## along with this program; see the file COPYING. If not, write to the
## Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
"""
AttchmentField
"""
__version__ = "$Revision: 30579 $"
# $Source: /cvsroot/ingeniweb/PloneSubscription/SubscriptionTool.py,v $
# $Id: AttachmentFieldTool.py 30579 2006-09-19 13:58:17Z manuco $
__docformat__ = 'restructuredtext'


# Python imports
from StringIO import StringIO
import os

# Zope imports
from AccessControl import ClassSecurityInfo
from OFS.PropertyManager import PropertyManager
from OFS.SimpleItem import SimpleItem
from Products.CMFCore.utils import UniqueObject
from Globals import InitializeClass
from zExceptions import BadRequest
from Products.PageTemplates.PageTemplateFile import PageTemplateFile

# CMF imports
from Products.CMFCore import CMFCorePermissions
from Products.CMFCore.utils import getToolByName
from Products.CMFCore.ActionProviderBase import ActionProviderBase

# Other imports
import AttachmentService
import AttachmentField
import FlexStorage

_www = os.path.join(os.path.dirname(__file__), 'www')

00052 class AttachmentFieldTool(
    UniqueObject,
    AttachmentService.AttachmentService,
    PropertyManager,
):
    """
    AttachmentFieldTool tool
    """

    id = 'portal_attachment'
    meta_type = 'AttachmentField Tool'
    security = ClassSecurityInfo()

    _properties = (
        {
            'id'  : 'contentDisposition',
            'type': 'selection',
            'mode': 'w',
            'select_variable' : 'getAvailableContentDisposition',
        },
    )

    manage_options = (
        AttachmentService.AttachmentService.manage_options +
        PropertyManager.manage_options
    )

    security.declarePrivate('manage_afterAdd')
    def manage_afterAdd(self, item, container):
        return self.migrate()


    security.declareProtected(CMFCorePermissions.ManagePortal, "migrate")
00085     def migrate(self):
        """
            Check that all properties are present and correctly initialized.
            If not, install them with a safe default value.
            It is safe to call it multiple times.
        """
        checkFor = [
            ("contentDisposition", self.getAvailableContentDisposition()[0]),
            ("currentFlexStorageBackend", "AttributeStorage"), ## ZODB
        ]
        rValue = ""
        for attr, default in checkFor:
            if not hasattr(self, attr):
                setattr(self, attr, default)
                rValue += "Added: %s\n" % attr
        if rValue == "":
            return "Tool was already up to date."
        return rValue + "\nTool succesfully updated!"


    def getAvailableContentDisposition(self):
        return [
            "attachment",
            "inline"
        ]

    def getAvailableFlexStorageBackends(self):
        ## FlexStorage object is not singleton and doesn't hold any properties
        ## of it's own. It is safe to build on the fly instances without damage.
        return FlexStorage.FlexStorage().getAvailableFlexStorages()

    def getSample(self, type):
        sampleLinks = {
            "attachment": self.absolute_url() + "/sample/contentDispositionAttachment",
            "inline": self.absolute_url() + "/sample/contentDispositionInline",
        }
        return sampleLinks[type]

    def getContentDisposition(self):
        return self.contentDisposition

    def getCurrentFlexStorageBackend(self):
        return self.currentFlexStorageBackend

    def setCurrentFlexStorageBackend(self, newStorageName):
        ## FlexStorage object is not singleton and doesn't hold any properties
        ## of it's own. It is safe to build on the fly instances without damage.
        FlexStorage.FlexStorage().changeFlexStorageBackend(
            self,
            newStorageName,
            AttachmentField.getContentTypesWithAttachmentFields(self)
        )

00138     def manageDownload(self, context, traverse_subpath):
        """
            Manage downlad mechanism (headers, etc)
        """

        request = context.REQUEST
        response = request.RESPONSE

        if len(traverse_subpath) != 1:
            raise BadRequest("Attachment download called with wrong reference.")

        fieldName = traverse_subpath[0]
        field = context.getField(fieldName)

        if not field:
            raise BadRequest("Attachment download called on unexistent field: %s" % fieldName)
        elif hasattr(field, 'getFields'):
            index = int(request.form.get(name))
            field = field.getFields()[index + 1]


        widget = field.widget
        if hasattr(widget, "contentDisposition"):
            if widget.contentDisposition in self.getAvailableContentDisposition():
                ## disposition is defined by widget
                disposition = widget.contentDisposition
            else:
                raise ValueError(
                    "contentDisposition %s is not in %s." % (
                        widget.contentDisposition, self.getAvailableContentDisposition()
                    )
                )
        else:
            ## default site wide choice
            disposition = self.getContentDisposition()

        ## We have to force disposition to "attachment" when content type is text/*
        ## Alexander Limi said:
        ## Crucially, absolutely NO files with the MIME type text/* should ever be  
        ## rendered inline, since this opens up for uploading HTML files and using  
        ## them as spam redirection URLs. Internet Explorer renders anything with  
        ## text/* as HTML, so it is not sufficient to just block text/html,  
        ## unfortunately.

        contentType = field.getContentType(context)
        if contentType.startswith("text/"):
            disposition = "attachment"

        result = field.download(context, request)

        response.setHeader(
            'Content-Disposition',
            '%s; filename="%s"' % (disposition, field.getFilename(context))
        )
        return result


InitializeClass(AttachmentFieldTool)

Generated by  Doxygen 1.6.0   Back to index