debian-python-odf/contrib/ODFFile/ODFFile.py

214 lines
7.2 KiB
Python

# -*- coding: utf-8 -*-
# Copyright (C) 2007-2008 Søren Roug, European Environment Agency
#
# This is free software. You may redistribute it under the terms
# of the Apache license and the GNU General Public License Version
# 2 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; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# Contributor(s):
#
#Python imports
import zipfile
from odf.odf2xhtml import ODF2XHTML
from odf.namespaces import OFFICENS, TEXTNS, XLINKNS
from odf.opendocument import odmimetypes
#Zope imports
from OFS.Image import File, cookId
from Globals import InitializeClass
from Globals import DTMLFile
from AccessControl import ClassSecurityInfo
from AccessControl.Permissions import view_management_screens, view, change_images_and_files
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
class ODF2XHTMLBody(ODF2XHTML):
def rewritelink(self, imghref):
imghref = imghref.replace("Pictures/","index_html?pict=")
return imghref
manage_addODFFileForm=DTMLFile('dtml/odffileAdd', globals())
def manage_addODFFile(self, id='', file='',title='', precondition='', content_type='', conversion='embedded',
REQUEST=None):
"""Add a new File object.
Creates a new File object 'id' with the contents of 'file'"""
id = str(id)
title = str(title)
conversion = str(conversion)
content_type = str(content_type)
precondition = str(precondition)
suffix = ''
newid, title = cookId(id, title, file)
if id == '' and newid[-4:-2]== '.o' and newid[-2] in ['d','t']:
id = newid[:-4]
suffix = id[-3:]
else:
id = newid
self = self.this()
# First, we create the file without data:
self._setObject(id, ODFFile(id, title, '', suffix, content_type, precondition, conversion))
# Now we "upload" the data. By doing this in two steps, we
# can use a database trick to make the upload more efficient.
if file:
self._getOb(id).manage_upload(file)
if content_type:
self._getOb(id).content_type = content_type
if REQUEST is not None:
REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')
class ODFFile(File):
""" ODFFile class """
meta_type = "OpenDocument File"
# icon = 'misc_/ODFFile/presentation'
# manage_options = (
# (File.manage_options[5],
# File.manage_options[3],
# File.manage_options[6],)
# )
security = ClassSecurityInfo()
def __init__(self, id, title, file, suffix, content_type='', precondition='', conversion='embedded'):
""" constructor """
self.xhtml = "<h1>Nothing uploaded</h1>"
self.conversion = conversion
self.suffix = suffix
self._pictures = {}
File.__dict__['__init__'](self, id, title, file, content_type, precondition)
###########################
# ZMI FORMS #
###########################
security.declareProtected(view, 'index_html')
def index_html(self, REQUEST=None, RESPONSE=None):
""" Show the HTML part """
if REQUEST.has_key('pict'):
return self.Pictures(REQUEST['pict'], REQUEST, RESPONSE)
rsp = []
if self.conversion == 'embedded':
rsp.append(self.standard_html_header(self, REQUEST, RESPONSE))
rsp.append(self.xhtml)
if self.conversion == 'embedded':
rsp.append(self.standard_html_footer(self, REQUEST, RESPONSE))
return(''.join(rsp))
manage_editForm = DTMLFile('dtml/odfEdit',globals())
manage_editForm._setName('manage_editForm')
manage=manage_main = manage_editForm
manage_uploadForm = manage_editForm
def manage_edit(self, title, content_type, precondition='',
filedata=None, conversion='none', REQUEST=None):
"""
Changes the title and content type attributes of the OpenDocument File.
"""
ODFFile.inheritedAttribute('manage_edit')(self, title, content_type, precondition, filedata)
conversion = str(conversion)
if self.conversion != conversion:
self.conversion = conversion
self.update_xhtml()
if REQUEST:
message="Saved changes."
return self.manage_main(self,REQUEST,manage_tabs_message=message)
security.declareProtected(change_images_and_files, 'uploadFile')
def uploadFile(self, file):
""" asociates a file to the ODFFile object """
data, size = self._read_data(file)
content_type = self._get_content_type(file, data, self.__name__, 'undefined')
self.update_data(data, content_type, size)
self._p_changed = 1
security.declareProtected(view, 'download')
def download(self, REQUEST, RESPONSE):
""" set for download asociated file """
self.REQUEST.RESPONSE.setHeader('Content-Type', self.content_type)
self.REQUEST.RESPONSE.setHeader('Content-Length', self.size)
self.REQUEST.RESPONSE.setHeader('Content-Disposition', 'attachment;filename="' + self.id() + self.suffix + '"')
return ODFFile.inheritedAttribute('index_html')(self, REQUEST, RESPONSE)
security.declareProtected(view, 'download')
def picture_list(self, REQUEST, RESPONSE):
""" Show list of pictures """
return "\n".join(self._pictures.keys())
security.declareProtected(view, 'download')
def Pictures(self, pict, REQUEST, RESPONSE):
""" set for download asociated file """
suffices = {
'wmf':'image/x-wmf',
'png':'image/png',
'gif':'image/gif',
'jpg':'image/jpeg',
'jpeg':'image/jpeg'
}
suffix = pict[pict.rfind(".")+1:]
ct = suffices.get(suffix,'application/octet-stream')
self.REQUEST.RESPONSE.setHeader('Content-Type', ct)
return self._pictures[pict]
def _save_pictures(self, fd):
self._pictures = {}
z = zipfile.ZipFile(fd)
for zinfo in z.infolist():
if zinfo.filename[0:9] == 'Pictures/':
pictname = zinfo.filename[9:]
self._pictures[pictname] = z.read(zinfo.filename)
z.close()
# private
update_xhtml__roles__=()
def update_xhtml(self):
if self.size == 0:
return
if self.conversion == 'embedded':
odhandler = ODF2XHTMLBody(embedable=True)
else:
odhandler = ODF2XHTMLBody(embedable=False)
fd = StringIO(str(self.data))
self._save_pictures(fd)
fd.seek(0)
self.xhtml = odhandler.odf2xhtml(fd).encode('us-ascii','xmlcharrefreplace')
self.title = odhandler.title
update_data__roles__=()
def update_data(self, data, content_type=None, size=None):
File.__dict__['update_data'](self, data, content_type, size)
suffix = odmimetypes.get(content_type)
if suffix:
self.suffix = suffix
self.update_xhtml()
InitializeClass(ODFFile)