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

AttachmentField.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: AttachmentField.py 30579 2006-09-19 13:58:17Z manuco $
__docformat__ = 'restructuredtext'

import urllib
import string
import os
import os.path
import sys
from types import FileType, ListType, TupleType

import Acquisition
from Acquisition import aq_base
from Globals import Persistent
from Globals import MessageDialog, DTMLFile      # fakes a method from a DTML file
from Globals import InitializeClass
from AccessControl import Role
from AccessControl import ClassSecurityInfo
from AccessControl import Permissions
from AccessControl import Unauthorized
from AccessControl import getSecurityManager
from webdav.common import rfc1123_date
import OFS.SimpleItem
from OFS.ObjectManager import ObjectManager
from OFS.Traversable import Traversable
from OFS.Image import Pdata, File
from OFS.content_types import guess_content_type
from global_symbols import *
try:
    from Products.CMFCore.utils import getToolByName
except:
    pass                # No CMF -> no charset converting

from Products.Archetypes import Field
from Products.Archetypes.utils import shasattr
from Products.Archetypes.interfaces.base import IBaseUnit

from Products.AttachmentField.interfaces.attachmentfield import IAttachmentField
import AttachmentHandler

from FlexStorage import FlexStorage

##DEFAULT_ID = "attach"
##ZAA_READ_PERMISSION = Permissions.access_contents_information
##ZAA_WRITE_PERMISSION = Permissions.change_images_and_files

#if _AF_VOLATILE_:
#    _indexed_ = "_v_%s_AF_indexed"
#    _preview_ = "_v_%s_AF_preview"
#else:
#    _indexed_ = "_%s_AF_indexed"
#    _preview_ = "_%s_AF_preview"

_indexed_ = "_%s_AF_indexed"
_preview_ = "_%s_AF_preview"



def getContentTypesWithAttachmentFields(instance):
    """
        Look for all content types that use AttachmentField, and return
        a dictionnary with
        keys : all content type names that use AttachmentField
        values : a list of all fields name that are AttachementField in
            this content type
    """
    archetypeTool = getToolByName(instance, 'archetype_tool')
    types = archetypeTool.listRegisteredTypes()
    result = {}
    for type in types:
        fields = type["schema"].fields()
        typeName = type["name"]
        for field in fields:
            if isinstance(field, AttachmentField):
                if typeName in result.keys():
                    result[typeName].append(field.getName())
                else:
                    result[typeName] = [field.getName()]
    return result



00104 class AttachmentField(Field.FileField):
    """
    A base class to handle file fields. This is based on Archetypes.
    When the file is uploaded, it's stored, as the File field, as a File class.

    See FileField.set() :

        value = File(self.getName(), '', value, mimetype)
        setattr(value, 'filename', f_name or self.getName())
        ObjectField.set(self, instance, value, **kwargs)

    """
    __implements__ = (Field.FileField.__implements__, IAttachmentField)
    security = ClassSecurityInfo()


    _properties = Field.FileField._properties.copy()
    _properties.update({
            "storage": FlexStorage()
        })


00126     def get(self, instance, mimetype = None, **kwargs):
        """Get value. If mime_type is 'text/plain', we retreive the
        indexed string. If it's text/html, we get the preview back.
        """
        if mimetype == 'text/plain':
            return self.getIndexableValue(instance)
        if mimetype == 'text/html':
            return self.getPreview(instance)
        kwargs.update({'mimetype': mimetype})
        return Field.FileField.get(self, instance, **kwargs)

00137     def set(self, instance, value, **kwargs):
        """
        Assign input value to object. If mimetype is not specified,
        pass to processing method without one and add mimetype returned
        to kwargs. Assign kwargs to instance.
        """
        self._reset(instance)
        return Field.FileField.set(self, instance, value, **kwargs)

    security.declarePublic("getFilename")
00147     def getFilename(self, instance, fromBaseUnit=True):
        """
        getFilename(self, instance, ) => return the filename
        We split to return only a file name and not a whole path.
        """

        # Get object or data
        accessor = self.getAccessor(instance)

        if self.isEmpty(instance) or accessor is None:
            return ''

        obj = accessor()
        fn = ''

        if hasattr(obj.aq_explicit, 'filename'):
            fn = obj.filename
        elif hasattr(obj.aq_explicit, 'getFilename'):
            fn = obj.getFilename()
        else:
            fn = Field.FileField.getFilename(self, instance, fromBaseUnit)

        fn = string.split(fn, '/')[-1]
        fn = string.split(fn, '\\')[-1]
        return fn

00173     def guessMimeTypeFromContent(self, instance, ):
        """
        guessMimeType(self, instance) => guess a mime type using mimetypes registry,
        based on the content itself.
        """
        value = str(self.get(instance))
        mtr = getToolByName(instance, 'mimetypes_registry')
        mimetype = mtr.classify(value, filename=self.getFilename(instance).lower())
        if not mimetype:
            return self.default_content_type
        return str(mimetype)

00185     def getSize(self, instance):
        """
        getSize(self, instance) => return file size
        """
        if self.isEmpty(instance):
            return 0
        return self.get(instance).get_size()    # This is cached by OFS.File

00193     def isEmpty(self, instance):
        """
        return true if empty
        """
        instance = self.get(instance)
        if instance is None:
            return True
        if type(instance) in (type(''), type(u'')):
            return not len(instance)
        size = 0
        try:
            size = instance.get_size()
        except:
            pass
        return not size

00209     def getIndexableValue(self, instance):
        """
        getIndexableValue(self, instance) => Return the value we have to index
        """
        # Emptyness check
        if self.isEmpty(instance):
            return ""

        # Is the indexing up-to-date ?
        name = self.getName()
        if not getattr(instance, _indexed_ % name, None):
            handler = self._getHandler(instance)
            try:
                idx = handler.getIndexableValue(self, instance)
            except:
                self._logException(instance)
                idx = None
            setattr(instance, _indexed_ % name, idx)

        # Return the index
        ret = getattr(instance, _indexed_ % name, None)
        return ret

00232     def isIndexed(self, instance):
        """return true if the document is indexed properly.
        """
        if self.isEmpty(instance):
            return None
        return not not self.getIndexableValue(instance)

00239     def isPreviewAvailable(self, instance):
        """True if a preview is available for that
        (we can compute it immediately)
        """
        return not not self.getPreview(instance)

00245     def isMultiValued(self, instance):
        """True if field is multi valued
        """
        return isinstance(self.get(instance), (ListType, TupleType))

00250     def _getHandler(self, instance):
        """
        _getHandler(self, instance) => get the handler object
        """
        handler = AttachmentHandler.getAttachmentHandler(
            self.getContentType(instance, ),
            self, instance,
            )
        return handler


00261     def getPreview(self, instance):
        """Return the preview for this object
        """
        if self.isEmpty(instance):
            return ""

        # Compute it if necessary
        name = self.getName()
        if not getattr(instance, _preview_ % name, None):
            handler = self._getHandler(instance)
            try:
                preview = handler.getPreview(self, instance, )
            except:
                self._logException(instance)
                preview = None
            setattr(instance, _preview_ % name, preview, )

        # Return it
        return getattr(instance, _preview_ % name, None)

00281     def getIcon(self, instance):
        """
        getIcon(self, instance) => return the underlying file class icon (object)
        """
        handler = self._getHandler(instance)
        Log(LOG_DEBUG, "getIcon for", self.getFilename(instance), "/", handler.converter_type, )
        return getattr(instance, handler.getIconFile(self, instance))

00289     def getSmallIcon(self, instance):
        """
        getIcon(self, instance) => return the underlying file class icon (object)
        """
        handler = self._getHandler(instance)
        return getattr(instance, handler.getSmallIconFile(self, instance))

00296     def _reset(self, instance, ):
        """reset volatile stuff (indexation, preview)
        """
        name = self.getName()
        setattr(instance, _preview_ % name, None)
        setattr(instance, _indexed_ % name, None)

    def _logException(self, instance):
        if instance and hasattr(instance, 'getPhysicalPath'):
            path = '/'.join(instance.getPhysicalPath())
            filename = self.getFilename(instance)
            msg = 'EXCEPTION object: %s, file: %s: \n' % (path, filename)
            Log(LOG_NOTICE, msg)
        LogException()

InitializeClass(AttachmentField)

from Products.Archetypes.Registry import registerField

registerField(
    AttachmentField,
    title='Attachment',
    description='Used for storing files with advanced features.',
    )




Generated by  Doxygen 1.6.0   Back to index