Ignore:
Timestamp:
12 Dec 2014, 18:28:54 (10 years ago)
Author:
Henrik Bettermann
Message:

Add DocumentFileNameChooser? and DocumentFileStoreHandler? with functional tests.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.ikoba/trunk/src/waeup/ikoba/documents/document.py

    r12200 r12204  
    1919These are the document tickets.
    2020"""
     21import os
    2122import grok
    2223from time import time
     
    2829from zope.interface import implementedBy
    2930from zope.i18n import translate
    30 from waeup.ikoba.interfaces import IIkobaUtils, IObjectHistory
     31
     32from waeup.ikoba.image import IkobaImageFile
     33from waeup.ikoba.imagestorage import DefaultFileStoreHandler
     34from waeup.ikoba.interfaces import (
     35    IIkobaUtils, IObjectHistory,
     36    IFileStoreNameChooser, IFileStoreHandler, IExtFileStore)
    3137from waeup.ikoba.interfaces import MessageFactory as _
    3238from waeup.ikoba.utils.helpers import attrs_to_fields, get_current_principal
     
    163169        return implementedBy(HTMLDocument)
    164170
     171#: The file id marker for files
     172DOCUMENT_FILE_STORE_NAME = 'file-document'
     173
     174
     175class DocumentFileNameChooser(grok.Adapter):
     176    """A file id chooser for :class:`Document` objects.
     177
     178    `context` is an :class:`Document` instance.
     179
     180    The delivered file_id contains the file id marker for
     181    :class:`Document` objects in the central :class:`DocumentsContainer`.
     182
     183    This chooser is registered as an adapter providing
     184    :class:`waeup.ikoba.interfaces.IFileStoreNameChooser`.
     185
     186    File store name choosers like this one are only convenience
     187    components to ease the task of creating file ids for customer document
     188    objects. You are nevertheless encouraged to use them instead of
     189    manually setting up filenames for customer documents.
     190
     191    .. seealso:: :mod:`waeup.ikoba.imagestorage`
     192
     193    """
     194
     195    grok.context(IDocument)
     196    grok.implements(IFileStoreNameChooser)
     197
     198    def checkName(self, name=None, attr=None):
     199        """Check whether the given name is a valid file id for the context.
     200
     201        Returns ``True`` only if `name` equals the result of
     202        :meth:`chooseName`.
     203
     204        """
     205        return name == self.chooseName()
     206
     207    def chooseName(self, attr, name=None):
     208        """Get a valid file id for customer document context.
     209
     210        *Example:*
     211
     212        For document with id 'd123'
     213        with attr ``'nice_image.jpeg'`` stored in
     214        the documents container this chooser would create:
     215
     216          ``'__file-document__documents/nice_image_d123.jpeg'``
     217
     218        meaning that the nice image of this document would be
     219        stored in the site-wide file storage in path:
     220
     221          ``documents/nice_image_d123.jpeg``
     222
     223        """
     224        basename, ext = os.path.splitext(attr)
     225        doc_id = self.context.document_id
     226        marked_filename = '__%s__documents/%s_%s%s' % (
     227            DOCUMENT_FILE_STORE_NAME,
     228            basename, doc_id, ext)
     229        return marked_filename
     230
     231
     232class DocumentFileStoreHandler(DefaultFileStoreHandler, grok.GlobalUtility):
     233    """ Document specific file handling.
     234
     235    This handler knows in which path in a filestore to store document
     236    files and how to turn this kind of data into some (browsable)
     237    file object.
     238
     239    It is called from the global file storage, when it wants to
     240    get/store a file with a file id starting with
     241    ``__file-document__`` (the marker string for customer files).
     242
     243    Like each other file store handler it does not handle the files
     244    really (this is done by the global file store) but only computes
     245    paths and things like this.
     246    """
     247    grok.implements(IFileStoreHandler)
     248    grok.name(DOCUMENT_FILE_STORE_NAME)
     249
     250    def pathFromFileID(self, store, root, file_id):
     251        """All document files are put in directory ``documents``.
     252        """
     253        marker, filename, basename, ext = store.extractMarker(file_id)
     254        sub_root = os.path.join(root, 'documents')
     255        return super(DocumentFileStoreHandler, self).pathFromFileID(
     256            store, sub_root, basename)
     257
     258    def createFile(self, store, root, filename, file_id, file):
     259        """Create a browsable file-like object.
     260        """
     261        # call super method to ensure that any old files with
     262        # different filename extension are deleted.
     263        file, path, file_obj = super(
     264            DocumentFileStoreHandler, self).createFile(
     265            store, root,  filename, file_id, file)
     266        return file, path, IkobaImageFile(
     267            file_obj.filename, file_obj.data)
     268
    165269
    166270@grok.subscribe(IDocument, grok.IObjectAddedEvent)
Note: See TracChangeset for help on using the changeset viewer.