eggification
[Photo.git] / Products / Photo / static / gitweb.css
diff --git a/blobbases.py b/blobbases.py
deleted file mode 100755 (executable)
index 964ffe3..0000000
+++ /dev/null
@@ -1,819 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-# This module is based on OFS.Image originaly copyrighted as:
-#
-# Copyright (c) 2002 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
-#
-##############################################################################
-"""Image object
-
-"""
-
-from cgi import escape
-from cStringIO import StringIO
-from mimetools import choose_boundary
-import struct
-from warnings import warn
-
-from AccessControl.Permissions import change_images_and_files
-from AccessControl.Permissions import view_management_screens
-from AccessControl.Permissions import view as View
-from AccessControl.Permissions import ftp_access
-from AccessControl.Permissions import delete_objects
-from AccessControl.Role import RoleManager
-from AccessControl.SecurityInfo import ClassSecurityInfo
-from Acquisition import Implicit
-from App.class_init import InitializeClass
-from App.special_dtml import DTMLFile
-from DateTime.DateTime import DateTime
-from Persistence import Persistent
-from webdav.common import rfc1123_date
-from webdav.interfaces import IWriteLock
-from webdav.Lockable import ResourceLockedError
-from ZPublisher import HTTPRangeSupport
-from ZPublisher.HTTPRequest import FileUpload
-from ZPublisher.Iterators import filestream_iterator
-from zExceptions import Redirect
-from zope.contenttype import guess_content_type
-from zope.interface import implementedBy
-from zope.interface import implements
-
-from OFS.Cache import Cacheable
-from OFS.PropertyManager import PropertyManager
-from OFS.SimpleItem import Item_w__name__
-
-from zope.event import notify
-from zope.lifecycleevent import ObjectModifiedEvent
-from zope.lifecycleevent import ObjectCreatedEvent
-
-from ZODB.blob import Blob
-
-CHUNK_SIZE = 1 << 16
-
-
-manage_addFileForm = DTMLFile('dtml/imageAdd',
-                              globals(),
-                              Kind='File',
-                              kind='file',
-                             )
-def manage_addFile(self, id, file='', title='', precondition='',
-                   content_type='', REQUEST=None):
-    """Add a new File object.
-
-    Creates a new File object 'id' with the contents of 'file'"""
-
-    id = str(id)
-    title = str(title)
-    content_type = str(content_type)
-    precondition = str(precondition)
-
-    id, title = cookId(id, title, file)
-    
-    self=self.this()
-    self._setObject(id, File(id,title,file,content_type, precondition))
-
-    newFile = self._getOb(id)
-    notify(ObjectCreatedEvent(newFile))
-    
-    if REQUEST is not None:
-        REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')
-
-
-class File(Persistent, Implicit, PropertyManager,
-           RoleManager, Item_w__name__, Cacheable):
-    """A File object is a content object for arbitrary files."""
-
-    implements(implementedBy(Persistent),
-               implementedBy(Implicit),
-               implementedBy(PropertyManager),
-               implementedBy(RoleManager),
-               implementedBy(Item_w__name__),
-               implementedBy(Cacheable),
-               IWriteLock,
-               HTTPRangeSupport.HTTPRangeInterface,
-              )
-    meta_type='Blob File'
-
-    security = ClassSecurityInfo()
-    security.declareObjectProtected(View)
-
-    precondition=''
-    size=None
-
-    manage_editForm  =DTMLFile('dtml/fileEdit',globals(),
-                               Kind='File',kind='file')
-    manage_editForm._setName('manage_editForm')
-
-    security.declareProtected(view_management_screens, 'manage')
-    security.declareProtected(view_management_screens, 'manage_main')
-    manage=manage_main=manage_editForm
-    manage_uploadForm=manage_editForm
-
-    manage_options=(
-        (
-        {'label':'Edit', 'action':'manage_main',
-         'help':('OFSP','File_Edit.stx')},
-        {'label':'View', 'action':'',
-         'help':('OFSP','File_View.stx')},
-        )
-        + PropertyManager.manage_options
-        + RoleManager.manage_options
-        + Item_w__name__.manage_options
-        + Cacheable.manage_options
-        )
-
-    _properties=({'id':'title', 'type': 'string'},
-                 {'id':'content_type', 'type':'string'},
-                 )
-
-    def __init__(self, id, title, file, content_type='', precondition=''):
-        self.__name__=id
-        self.title=title
-        self.precondition=precondition
-        self.uploaded_filename = cookId('', '', file)[0]
-        self.bdata = Blob()
-
-        content_type=self._get_content_type(file, id, content_type)
-        self.update_data(file, content_type)
-
-    security.declarePrivate('save')
-    def save(self, file):
-        bf = self.bdata.open('w')
-        bf.write(file.read())
-        self.size = bf.tell()
-        bf.close()
-    
-    security.declarePrivate('open')
-    def open(self, mode='r'):
-        bf = self.bdata.open(mode)
-        return bf
-    
-    security.declarePrivate('updateSize')
-    def updateSize(self, size=None):
-        if size is None :
-            bf = self.open('r')
-            bf.seek(0,2)
-            self.size = bf.tell()
-            bf.close()
-        else :
-            self.size = size
-
-    def _getLegacyData(self) :
-        warn("Accessing 'data' attribute may be inefficient with "
-             "this blob based file. You should refactor your product "
-             "by accessing data like: "
-             "f = self.open('r') "
-             "data = f.read()",
-            DeprecationWarning, stacklevel=2)
-        f = self.open()
-        data = f.read()
-        f.close()
-        return data
-    
-    def _setLegacyData(self, data) :
-        warn("Accessing 'data' attribute may be inefficient with "
-             "this blob based file. You should refactor your product "
-             "by accessing data like: "
-             "f = self.save(data)",
-            DeprecationWarning, stacklevel=2)
-        if isinstance(data, str) :
-            sio = StringIO()
-            sio.write(data)
-            sio.seek(0)
-            data = sio
-        self.save(data)
-        
-    data = property(_getLegacyData, _setLegacyData,
-                    "Data Legacy attribute to ensure compatibility "
-                    "with derived classes that access data by this way.")
-
-    def id(self):
-        return self.__name__
-
-    def _if_modified_since_request_handler(self, REQUEST, RESPONSE):
-        # HTTP If-Modified-Since header handling: return True if
-        # we can handle this request by returning a 304 response
-        header=REQUEST.get_header('If-Modified-Since', None)
-        if header is not None:
-            header=header.split( ';')[0]
-            # Some proxies seem to send invalid date strings for this
-            # header. If the date string is not valid, we ignore it
-            # rather than raise an error to be generally consistent
-            # with common servers such as Apache (which can usually
-            # understand the screwy date string as a lucky side effect
-            # of the way they parse it).
-            # This happens to be what RFC2616 tells us to do in the face of an
-            # invalid date.
-            try:    mod_since=long(DateTime(header).timeTime())
-            except: mod_since=None
-            if mod_since is not None:
-                if self._p_mtime:
-                    last_mod = long(self._p_mtime)
-                else:
-                    last_mod = long(0)
-                if last_mod > 0 and last_mod <= mod_since:
-                    RESPONSE.setHeader('Last-Modified',
-                                       rfc1123_date(self._p_mtime))
-                    RESPONSE.setHeader('Content-Type', self.content_type)
-                    RESPONSE.setHeader('Accept-Ranges', 'bytes')
-                    RESPONSE.setStatus(304)
-                    return True
-
-    def _range_request_handler(self, REQUEST, RESPONSE):
-        # HTTP Range header handling: return True if we've served a range
-        # chunk out of our data.
-        range = REQUEST.get_header('Range', None)
-        request_range = REQUEST.get_header('Request-Range', None)
-        if request_range is not None:
-            # Netscape 2 through 4 and MSIE 3 implement a draft version
-            # Later on, we need to serve a different mime-type as well.
-            range = request_range
-        if_range = REQUEST.get_header('If-Range', None)
-        if range is not None:
-            ranges = HTTPRangeSupport.parseRange(range)
-
-            if if_range is not None:
-                # Only send ranges if the data isn't modified, otherwise send
-                # the whole object. Support both ETags and Last-Modified dates!
-                if len(if_range) > 1 and if_range[:2] == 'ts':
-                    # ETag:
-                    if if_range != self.http__etag():
-                        # Modified, so send a normal response. We delete
-                        # the ranges, which causes us to skip to the 200
-                        # response.
-                        ranges = None
-                else:
-                    # Date
-                    date = if_range.split( ';')[0]
-                    try: mod_since=long(DateTime(date).timeTime())
-                    except: mod_since=None
-                    if mod_since is not None:
-                        if self._p_mtime:
-                            last_mod = long(self._p_mtime)
-                        else:
-                            last_mod = long(0)
-                        if last_mod > mod_since:
-                            # Modified, so send a normal response. We delete
-                            # the ranges, which causes us to skip to the 200
-                            # response.
-                            ranges = None
-
-            if ranges:
-                # Search for satisfiable ranges.
-                satisfiable = 0
-                for start, end in ranges:
-                    if start < self.size:
-                        satisfiable = 1
-                        break
-
-                if not satisfiable:
-                    RESPONSE.setHeader('Content-Range',
-                        'bytes */%d' % self.size)
-                    RESPONSE.setHeader('Accept-Ranges', 'bytes')
-                    RESPONSE.setHeader('Last-Modified',
-                        rfc1123_date(self._p_mtime))
-                    RESPONSE.setHeader('Content-Type', self.content_type)
-                    RESPONSE.setHeader('Content-Length', self.size)
-                    RESPONSE.setStatus(416)
-                    return True
-
-                ranges = HTTPRangeSupport.expandRanges(ranges, self.size)
-
-                if len(ranges) == 1:
-                    # Easy case, set extra header and return partial set.
-                    start, end = ranges[0]
-                    size = end - start
-
-                    RESPONSE.setHeader('Last-Modified',
-                        rfc1123_date(self._p_mtime))
-                    RESPONSE.setHeader('Content-Type', self.content_type)
-                    RESPONSE.setHeader('Content-Length', size)
-                    RESPONSE.setHeader('Accept-Ranges', 'bytes')
-                    RESPONSE.setHeader('Content-Range',
-                        'bytes %d-%d/%d' % (start, end - 1, self.size))
-                    RESPONSE.setStatus(206) # Partial content
-                    
-                    bf = self.open('r')
-                    bf.seek(start)
-                    RESPONSE.write(bf.read(size))
-                    bf.close()
-                    return True
-
-                else:
-                    boundary = choose_boundary()
-
-                    # Calculate the content length
-                    size = (8 + len(boundary) + # End marker length
-                        len(ranges) * (         # Constant lenght per set
-                            49 + len(boundary) + len(self.content_type) +
-                            len('%d' % self.size)))
-                    for start, end in ranges:
-                        # Variable length per set
-                        size = (size + len('%d%d' % (start, end - 1)) +
-                            end - start)
-
-
-                    # Some clients implement an earlier draft of the spec, they
-                    # will only accept x-byteranges.
-                    draftprefix = (request_range is not None) and 'x-' or ''
-
-                    RESPONSE.setHeader('Content-Length', size)
-                    RESPONSE.setHeader('Accept-Ranges', 'bytes')
-                    RESPONSE.setHeader('Last-Modified',
-                        rfc1123_date(self._p_mtime))
-                    RESPONSE.setHeader('Content-Type',
-                        'multipart/%sbyteranges; boundary=%s' % (
-                            draftprefix, boundary))
-                    RESPONSE.setStatus(206) # Partial content
-
-
-                    bf = self.open('r')
-#                    data = self.data
-#                    # The Pdata map allows us to jump into the Pdata chain
-#                    # arbitrarily during out-of-order range searching.
-#                    pdata_map = {}
-#                    pdata_map[0] = data
-
-                    for start, end in ranges:
-                        RESPONSE.write('\r\n--%s\r\n' % boundary)
-                        RESPONSE.write('Content-Type: %s\r\n' %
-                            self.content_type)
-                        RESPONSE.write(
-                            'Content-Range: bytes %d-%d/%d\r\n\r\n' % (
-                                start, end - 1, self.size))
-
-                        
-                        size = end - start
-                        bf.seek(start)
-                        RESPONSE.write(bf.read(size))
-                    
-                    bf.close()
-
-                    RESPONSE.write('\r\n--%s--\r\n' % boundary)
-                    return True
-
-    security.declareProtected(View, 'index_html')
-    def index_html(self, REQUEST, RESPONSE):
-        """
-        The default view of the contents of a File or Image.
-
-        Returns the contents of the file or image.  Also, sets the
-        Content-Type HTTP header to the objects content type.
-        """
-
-        if self._if_modified_since_request_handler(REQUEST, RESPONSE):
-            # we were able to handle this by returning a 304
-            # unfortunately, because the HTTP cache manager uses the cache
-            # API, and because 304 responses are required to carry the Expires
-            # header for HTTP/1.1, we need to call ZCacheable_set here.
-            # This is nonsensical for caches other than the HTTP cache manager
-            # unfortunately.
-            self.ZCacheable_set(None)
-            return ''
-
-        if self.precondition and hasattr(self, str(self.precondition)):
-            # Grab whatever precondition was defined and then
-            # execute it.  The precondition will raise an exception
-            # if something violates its terms.
-            c=getattr(self, str(self.precondition))
-            if hasattr(c,'isDocTemp') and c.isDocTemp:
-                c(REQUEST['PARENTS'][1],REQUEST)
-            else:
-                c()
-
-        if self._range_request_handler(REQUEST, RESPONSE):
-            # we served a chunk of content in response to a range request.
-            return ''
-
-        RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime))
-        RESPONSE.setHeader('Content-Type', self.content_type)
-        RESPONSE.setHeader('Content-Length', self.size)
-        RESPONSE.setHeader('Accept-Ranges', 'bytes')
-
-        if self.ZCacheable_isCachingEnabled():
-            result = self.ZCacheable_get(default=None)
-            if result is not None:
-                # We will always get None from RAMCacheManager and HTTP
-                # Accelerated Cache Manager but we will get
-                # something implementing the IStreamIterator interface
-                # from a "FileCacheManager"
-                return result
-
-        self.ZCacheable_set(None)
-
-        bf = self.open('r')
-        chunk = bf.read(CHUNK_SIZE)
-        while chunk :
-            RESPONSE.write(chunk)
-            chunk = bf.read(CHUNK_SIZE)
-        bf.close()
-        return ''       
-
-    security.declareProtected(View, 'view_image_or_file')
-    def view_image_or_file(self, URL1):
-        """
-        The default view of the contents of the File or Image.
-        """
-        raise Redirect, URL1
-
-    security.declareProtected(View, 'PrincipiaSearchSource')
-    def PrincipiaSearchSource(self):
-        """ Allow file objects to be searched.
-        """
-        if self.content_type.startswith('text/'):
-            bf = self.open('r')
-            data = bf.read()
-            bf.close()
-            return data
-        return ''
-
-    security.declarePrivate('update_data')
-    def update_data(self, file, content_type=None):
-        if isinstance(file, unicode):
-            raise TypeError('Data can only be str or file-like.  '
-                            'Unicode objects are expressly forbidden.')
-        elif isinstance(file, str) :
-            sio = StringIO()
-            sio.write(file)
-            sio.seek(0)
-            file = sio
-
-        if content_type is not None: self.content_type=content_type
-        self.save(file)
-        self.ZCacheable_invalidate()
-        self.ZCacheable_set(None)
-        self.http__refreshEtag()
-
-    security.declareProtected(change_images_and_files, 'manage_edit')
-    def manage_edit(self, title, content_type, precondition='',
-                    filedata=None, REQUEST=None):
-        """
-        Changes the title and content type attributes of the File or Image.
-        """
-        if self.wl_isLocked():
-            raise ResourceLockedError, "File is locked via WebDAV"
-
-        self.title=str(title)
-        self.content_type=str(content_type)
-        if precondition: self.precondition=str(precondition)
-        elif self.precondition: del self.precondition
-        if filedata is not None:
-            self.update_data(filedata, content_type)
-        else:
-            self.ZCacheable_invalidate()
-        
-        notify(ObjectModifiedEvent(self))
-        
-        if REQUEST:
-            message="Saved changes."
-            return self.manage_main(self,REQUEST,manage_tabs_message=message)
-
-    security.declareProtected(change_images_and_files, 'manage_upload')
-    def manage_upload(self,file='',REQUEST=None):
-        """
-        Replaces the current contents of the File or Image object with file.
-
-        The file or images contents are replaced with the contents of 'file'.
-        """
-        if self.wl_isLocked():
-            raise ResourceLockedError, "File is locked via WebDAV"
-
-        content_type=self._get_content_type(file, self.__name__,
-                                            'application/octet-stream')
-        self.update_data(file, content_type)
-        notify(ObjectModifiedEvent(self))
-
-        if REQUEST:
-            message="Saved changes."
-            return self.manage_main(self,REQUEST,manage_tabs_message=message)
-
-    def _get_content_type(self, file, id, content_type=None):
-        headers=getattr(file, 'headers', None)
-        if headers and headers.has_key('content-type'):
-            content_type=headers['content-type']
-        else:
-            name = getattr(file, 'filename', self.uploaded_filename) or id
-            content_type, enc=guess_content_type(name, '', content_type)
-        return content_type
-
-    security.declareProtected(delete_objects, 'DELETE')
-
-    security.declareProtected(change_images_and_files, 'PUT')
-    def PUT(self, REQUEST, RESPONSE):
-        """Handle HTTP PUT requests"""
-        self.dav__init(REQUEST, RESPONSE)
-        self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
-        type=REQUEST.get_header('content-type', None)
-
-        file=REQUEST['BODYFILE']
-
-        content_type = self._get_content_type(file, self.__name__,
-                                              type or self.content_type)
-        self.update_data(file, content_type)
-
-        RESPONSE.setStatus(204)
-        return RESPONSE
-
-    security.declareProtected(View, 'get_size')
-    def get_size(self):
-        """Get the size of a file or image.
-
-        Returns the size of the file or image.
-        """
-        size=self.size
-        if size is None :
-            bf = self.open('r')
-            bf.seek(0,2)
-            self.size = size = bf.tell()
-            bf.close()
-        return size
-
-    # deprecated; use get_size!
-    getSize=get_size
-
-    security.declareProtected(View, 'getContentType')
-    def getContentType(self):
-        """Get the content type of a file or image.
-
-        Returns the content type (MIME type) of a file or image.
-        """
-        return self.content_type
-
-
-    def __str__(self): return str(self.data)
-    def __len__(self): return 1
-
-    security.declareProtected(ftp_access, 'manage_FTPstat')
-    security.declareProtected(ftp_access, 'manage_FTPlist')
-
-    security.declareProtected(ftp_access, 'manage_FTPget')
-    def manage_FTPget(self):
-        """Return body for ftp."""
-        RESPONSE = self.REQUEST.RESPONSE
-
-        if self.ZCacheable_isCachingEnabled():
-            result = self.ZCacheable_get(default=None)
-            if result is not None:
-                # We will always get None from RAMCacheManager but we will get
-                # something implementing the IStreamIterator interface
-                # from FileCacheManager.
-                # the content-length is required here by HTTPResponse, even
-                # though FTP doesn't use it.
-                RESPONSE.setHeader('Content-Length', self.size)
-                return result
-
-        bf = self.open('r')
-        data = bf.read()
-        bf.close()
-        RESPONSE.setBase(None)
-        return data
-
-manage_addImageForm=DTMLFile('dtml/imageAdd',globals(),
-                             Kind='Image',kind='image')
-def manage_addImage(self, id, file, title='', precondition='', content_type='',
-                    REQUEST=None):
-    """
-    Add a new Image object.
-
-    Creates a new Image object 'id' with the contents of 'file'.
-    """
-
-    id=str(id)
-    title=str(title)
-    content_type=str(content_type)
-    precondition=str(precondition)
-
-    id, title = cookId(id, title, file)
-
-    self=self.this()
-    self._setObject(id, Image(id,title,file,content_type, precondition))
-
-    newFile = self._getOb(id)
-    notify(ObjectCreatedEvent(newFile))
-    
-    if REQUEST is not None:
-        try:    url=self.DestinationURL()
-        except: url=REQUEST['URL1']
-        REQUEST.RESPONSE.redirect('%s/manage_main' % url)
-    return id
-
-
-def getImageInfo(file):
-    height = -1
-    width = -1
-    content_type = ''
-
-    # handle GIFs
-    data = file.read(24)
-    size = len(data)
-    if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'):
-        # Check to see if content_type is correct
-        content_type = 'image/gif'
-        w, h = struct.unpack("<HH", data[6:10])
-        width = int(w)
-        height = int(h)
-
-    # See PNG v1.2 spec (http://www.cdrom.com/pub/png/spec/)
-    # Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
-    # and finally the 4-byte width, height
-    elif ((size >= 24) and (data[:8] == '\211PNG\r\n\032\n')
-          and (data[12:16] == 'IHDR')):
-        content_type = 'image/png'
-        w, h = struct.unpack(">LL", data[16:24])
-        width = int(w)
-        height = int(h)
-
-    # Maybe this is for an older PNG version.
-    elif (size >= 16) and (data[:8] == '\211PNG\r\n\032\n'):
-        # Check to see if we have the right content type
-        content_type = 'image/png'
-        w, h = struct.unpack(">LL", data[8:16])
-        width = int(w)
-        height = int(h)
-
-    # handle JPEGs
-    elif (size >= 2) and (data[:2] == '\377\330'):
-        content_type = 'image/jpeg'
-        jpeg = file
-        jpeg.seek(0)
-        jpeg.read(2)
-        b = jpeg.read(1)
-        try:
-            while (b and ord(b) != 0xDA):
-                while (ord(b) != 0xFF): b = jpeg.read(1)
-                while (ord(b) == 0xFF): b = jpeg.read(1)
-                if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
-                    jpeg.read(3)
-                    h, w = struct.unpack(">HH", jpeg.read(4))
-                    break
-                else:
-                    jpeg.read(int(struct.unpack(">H", jpeg.read(2))[0])-2)
-                b = jpeg.read(1)
-            width = int(w)
-            height = int(h)
-        except: pass
-
-    return content_type, width, height
-
-
-class Image(File):
-    """Image objects can be GIF, PNG or JPEG and have the same methods
-    as File objects.  Images also have a string representation that
-    renders an HTML 'IMG' tag.
-    """
-    meta_type='Blob Image'
-
-    security = ClassSecurityInfo()
-    security.declareObjectProtected(View)
-
-    alt=''
-    height=''
-    width=''
-
-    # FIXME: Redundant, already in base class
-    security.declareProtected(change_images_and_files, 'manage_edit')
-    security.declareProtected(change_images_and_files, 'manage_upload')
-    security.declareProtected(change_images_and_files, 'PUT')
-    security.declareProtected(View, 'index_html')
-    security.declareProtected(View, 'get_size')
-    security.declareProtected(View, 'getContentType')
-    security.declareProtected(ftp_access, 'manage_FTPstat')
-    security.declareProtected(ftp_access, 'manage_FTPlist')
-    security.declareProtected(ftp_access, 'manage_FTPget')
-    security.declareProtected(delete_objects, 'DELETE')
-
-    _properties=({'id':'title', 'type': 'string'},
-                 {'id':'alt', 'type':'string'},
-                 {'id':'content_type', 'type':'string','mode':'w'},
-                 {'id':'height', 'type':'string'},
-                 {'id':'width', 'type':'string'},
-                 )
-
-    manage_options=(
-        ({'label':'Edit', 'action':'manage_main',
-         'help':('OFSP','Image_Edit.stx')},
-         {'label':'View', 'action':'view_image_or_file',
-         'help':('OFSP','Image_View.stx')},)
-        + PropertyManager.manage_options
-        + RoleManager.manage_options
-        + Item_w__name__.manage_options
-        + Cacheable.manage_options
-        )
-
-    manage_editForm  =DTMLFile('dtml/imageEdit',globals(),
-                               Kind='Image',kind='image')
-    manage_editForm._setName('manage_editForm')
-
-    security.declareProtected(View, 'view_image_or_file')
-    view_image_or_file =DTMLFile('dtml/imageView',globals())
-
-    security.declareProtected(view_management_screens, 'manage')
-    security.declareProtected(view_management_screens, 'manage_main')
-    manage=manage_main=manage_editForm
-    manage_uploadForm=manage_editForm
-
-    security.declarePrivate('update_data')
-    def update_data(self, file, content_type=None):
-        super(Image, self).update_data(file, content_type)
-        self.updateFormat(size=self.size, content_type=content_type)
-        
-    security.declarePrivate('updateFormat')
-    def updateFormat(self, size=None, dimensions=None, content_type=None):
-        self.updateSize(size=size)
-
-        if dimensions is None or content_type is None :
-            bf = self.open('r')
-            ct, width, height = getImageInfo(bf)
-            bf.close()
-            if ct:
-                content_type = ct
-            if width >= 0 and height >= 0:
-                self.width = width
-                self.height = height
-
-            # Now we should have the correct content type, or still None
-            if content_type is not None: self.content_type = content_type
-        else :
-            self.width, self.height = dimensions
-            self.content_type = content_type
-
-    def __str__(self):
-        return self.tag()
-
-    security.declareProtected(View, 'tag')
-    def tag(self, height=None, width=None, alt=None,
-            scale=0, xscale=0, yscale=0, css_class=None, title=None, **args):
-        """
-        Generate an HTML IMG tag for this image, with customization.
-        Arguments to self.tag() can be any valid attributes of an IMG tag.
-        'src' will always be an absolute pathname, to prevent redundant
-        downloading of images. Defaults are applied intelligently for
-        'height', 'width', and 'alt'. If specified, the 'scale', 'xscale',
-        and 'yscale' keyword arguments will be used to automatically adjust
-        the output height and width values of the image tag.
-
-        Since 'class' is a Python reserved word, it cannot be passed in
-        directly in keyword arguments which is a problem if you are
-        trying to use 'tag()' to include a CSS class. The tag() method
-        will accept a 'css_class' argument that will be converted to
-        'class' in the output tag to work around this.
-        """
-        if height is None: height=self.height
-        if width is None:  width=self.width
-
-        # Auto-scaling support
-        xdelta = xscale or scale
-        ydelta = yscale or scale
-
-        if xdelta and width:
-            width =  str(int(round(int(width) * xdelta)))
-        if ydelta and height:
-            height = str(int(round(int(height) * ydelta)))
-
-        result='<img src="%s"' % (self.absolute_url())
-
-        if alt is None:
-            alt=getattr(self, 'alt', '')
-        result = '%s alt="%s"' % (result, escape(alt, 1))
-
-        if title is None:
-            title=getattr(self, 'title', '')
-        result = '%s title="%s"' % (result, escape(title, 1))
-
-        if height:
-            result = '%s height="%s"' % (result, height)
-
-        if width:
-            result = '%s width="%s"' % (result, width)
-
-        # Omitting 'border' attribute (Collector #1557)
-#        if not 'border' in [ x.lower() for x in  args.keys()]:
-#            result = '%s border="0"' % result
-
-        if css_class is not None:
-            result = '%s class="%s"' % (result, css_class)
-
-        for key in args.keys():
-            value = args.get(key)
-            if value:
-                result = '%s %s="%s"' % (result, key, value)
-
-        return '%s />' % result
-
-
-def cookId(id, title, file):
-    if not id and hasattr(file,'filename'):
-        filename=file.filename
-        title=title or filename
-        id=filename[max(filename.rfind('/'),
-                        filename.rfind('\\'),
-                        filename.rfind(':'),
-                        )+1:]
-    return id, title