[Erp5-report] r12195 - /erp5/trunk/products/ERP5OOo/Document/OOoDocument.py

nobody at svn.erp5.org nobody at svn.erp5.org
Mon Jan 22 13:51:31 CET 2007


Author: bartek
Date: Mon Jan 22 13:51:26 2007
New Revision: 12195

URL: http://svn.erp5.org?rev=12195&view=rev
Log:
reformatted code, added more docstrings, fixed some minor issues

Modified:
    erp5/trunk/products/ERP5OOo/Document/OOoDocument.py

Modified: erp5/trunk/products/ERP5OOo/Document/OOoDocument.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5OOo/Document/OOoDocument.py?rev=12195&r1=12194&r2=12195&view=diff
==============================================================================
--- erp5/trunk/products/ERP5OOo/Document/OOoDocument.py (original)
+++ erp5/trunk/products/ERP5OOo/Document/OOoDocument.py Mon Jan 22 13:51:26 2007
@@ -25,6 +25,13 @@
 #
 ##############################################################################
 
+import xmlrpclib
+import base64
+import re
+import zipfile
+import cStringIO
+from DateTime import DateTime
+
 from AccessControl import ClassSecurityInfo
 from OFS.Image import Pdata
 from Products.CMFCore.utils import getToolByName
@@ -35,14 +42,17 @@
 from Products.ERP5Type.XMLObject import XMLObject
 from Products.ERP5.Document.File import File, stripHtml
 from Products.ERP5.Document.Document import ConversionCacheMixin
-from DateTime import DateTime
-import xmlrpclib, base64, re, zipfile, cStringIO
 from Products.CMFCore.utils import getToolByName
+from Products.DCWorkflow.DCWorkflow import ValidationFailed
 
 enc=base64.encodestring
 dec=base64.decodestring
 
+_MARKER = []
+
+
 class ConversionError(Exception):pass
+
 
 class OOoDocument(File, ConversionCacheMixin):
   """
@@ -128,48 +138,78 @@
   )
 
   # regexps for stripping xml from docs
-  rx_strip=re.compile('<[^>]*?>',re.DOTALL|re.MULTILINE)
-  rx_compr=re.compile('\s+')
+  rx_strip = re.compile('<[^>]*?>', re.DOTALL|re.MULTILINE)
+  rx_compr = re.compile('\s+')
 
   searchable_property_list = File.searchable_property_list + ('text_content', ) # XXX - good idea - should'n this be made more general ?
 
+  def index_html(self, REQUEST, RESPONSE, format=None, force=0):
+    """
+      Standard function - gets converted version (from cache or new)
+      sets headers and returns converted data.
+
+      Format can be only one string (because we are OOoDocument and do not
+      accept more formatting arguments).
+
+      Force can force conversion.
+    """
+    self.log(format, force)
+    if (not self.hasOOFile()) or force:
+      self.convertToBase()
+    if format is None:
+      result = self.getOOFile()
+      mime = self.getMimeType()
+      self.log(mime)
+    else:
+      try:
+        mime, result = self.convert(format=format, force=force)
+      except ConversionError, e:
+        raise # should we do something here?
+    #RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime)) XXX to be implemented
+    RESPONSE.setHeader('Content-Type', mime)
+    #RESPONSE.setHeader('Content-Length', self.size) XXX to be implemented
+    RESPONSE.setHeader('Accept-Ranges', 'bytes')
+    # XXX here we should find out extension for this mime type and append to filename
+    RESPONSE.setBase(None)
+    return result
+
   def _getServerCoordinate(self):
     """
-    Returns OOo conversion server data from 
-    preferences
-    """
-    pref=getToolByName(self,'portal_preferences')
-    adr=pref.getPreferredOoodocServerAddress()
-    nr=pref.getPreferredOoodocServerPortNumber()
+      Returns OOo conversion server data from 
+      preferences
+    """
+    pref = getToolByName(self,'portal_preferences')
+    adr = pref.getPreferredOoodocServerAddress()
+    nr = pref.getPreferredOoodocServerPortNumber()
     if adr is None or nr is None:
       raise Exception('you should set conversion server coordinates in preferences')
-    return adr,nr
+    return adr, nr
 
   def _mkProxy(self):
-    sp=xmlrpclib.ServerProxy('http://%s:%d' % self._getServerCoordinate(),allow_none=True)
+    sp=xmlrpclib.ServerProxy('http://%s:%d' % self._getServerCoordinate(), allow_none=True)
     return sp
 
-  def returnMessage(self,msg,code=0):
-    """
-    code > 0 indicates a problem
-    we distinguish data return from message by checking if it is a tuple
-    """
-    m=Message(domain='ui',message=msg)
-    return (code,m)
-
-  security.declareProtected(Permissions.ModifyPortalContent,'convert')
-  def convert(self,force=0,REQUEST=None):
-    """
-    Converts from the initial format to OOo format;
-    communicates with the conversion server
-    and gets converted file as well as metadata
-    """
-    if force==0 and self.hasOOFile():
-      return self.returnMessage('OOo file is up do date',1)
+  def returnMessage(self, msg, code=0):
+    """
+      code > 0 indicates a problem
+      we distinguish data return from message by checking if it is a tuple
+    """
+    m = Message(domain='ui', message=msg)
+    return (code, m)
+
+  security.declareProtected(Permissions.View, 'convert')
+  def convertToBase(self, force=0, REQUEST=None):
+    """
+      Converts from the initial format to base format (ODF);
+      communicates with the conversion server
+      and gets converted file as well as metadata
+    """
+    if force == 0 and self.hasOOFile():
+      return self.returnMessage('OOo file is up do date', 1)
     try:
-      self._convert()
-    except xmlrpclib.Fault,e:
-      return self.returnMessage('Problem: %s' % (str(e) or 'undefined'),2)
+      self._convertToBase()
+    except xmlrpclib.Fault, e:
+      return self.returnMessage('Problem: %s' % (str(e) or 'undefined'), 2)
     return self.returnMessage('converted')
 
   security.declareProtected(Permissions.AccessContentsInformation,'getTargetFormatList')
@@ -189,178 +229,165 @@
 
     cached_getTargetFormatItemList = CachingMethod(cached_getTargetFormatItemList,
                                         id = "OOoDocument_getTargetFormatItemList" )
-
     return cached_getTargetFormatItemList(self.getContentType())
 
-
-  security.declareProtected(Permissions.AccessContentsInformation,'getTargetFormatList')
+  security.declareProtected(Permissions.AccessContentsInformation, 'getTargetFormatList')
   def getTargetFormatList(self):
     """
       Returns a list of acceptable formats for conversion
     """
     return map(lambda x: x[0], self.getTargetFormatItemList())
 
-
-  security.declareProtected(Permissions.ModifyPortalContent,'reset')
+  security.declareProtected(Permissions.ModifyPortalContent, 'reset')
   def reset(self):
-    '''reset'''
+    """
+      make the object a non-converted one, as if it was brand new
+    """
     self.clearCache()
-    self.oo_data=None
-    m=self.returnMessage('new')
+    self.oo_data = None
+    m = self.returnMessage('new')
     self.setExternalProcessingStatusMessage(str(m[1]))
 
   security.declareProtected(Permissions.ModifyPortalContent,'isAllowed')
   def isAllowed(self, format):
     """
-    Checks if the current document can be converted
-    into the specified format.
-
-    """
-    if not self.hasOOFile(): return False
-    allowed=self.getTargetFormatItemList()
+      Checks if the current document can be converted
+      into the specified format.
+    """
+    allowed = self.getTargetFormatItemList()
     if allowed is None: return False
     return (format in [x[1] for x in allowed])
 
   security.declareProtected(Permissions.ModifyPortalContent,'editMetadata')
-  def editMetadata(self,newmeta):
-    """
-    Updates metadata information in the converted OOo document
-    based on the values provided by the user. This is implemented
-    through the invocation of the conversion server.
-    """
-    sp=self._mkProxy()
-    kw=sp.run_setmetadata(self.getTitle(),enc(self._unpackData(self.oo_data)),newmeta)
-    self.oo_data=Pdata(dec(kw['data']))
+  def editMetadata(self, newmeta):
+    """
+      Updates metadata information in the converted OOo document
+      based on the values provided by the user. This is implemented
+      through the invocation of the conversion server.
+    """
+    sp = self._mkProxy()
+    kw = sp.run_setmetadata(self.getTitle(), enc(self._unpackData(self.oo_data)), newmeta)
+    self.oo_data = Pdata(dec(kw['data']))
     self._setMetaData(kw['meta'])
     return True # XXX why return ? - why not?
 
   security.declarePrivate('_convert')
-  def _convert(self):
-    """
-    Converts the original document into OOo document
-    by invoking the conversion server. Store the result
-    on the object. Update metadata information.
-    """
-    sp=self._mkProxy()
-    kw=sp.run_convert(self.getSourceReference(),enc(self._unpackData(self.data)))
-    self.oo_data=Pdata(dec(kw['data']))
+  def _convertToBase(self):
+    """
+      Converts the original document into ODF
+      by invoking the conversion server. Store the result
+      on the object. Update metadata information.
+    """
+    sp = self._mkProxy()
+    kw = sp.run_convert(self.getSourceReference(), enc(self._unpackData(self.data)))
+    self.oo_data = Pdata(dec(kw['data']))
     # now we get text content 
-    text_data=self.extractTextContent()
+    text_data = self.extractTextContent()
     self.setTextContent(text_data)
     self._setMetaData(kw['meta'])
 
   security.declareProtected(Permissions.View,'extractTextContent')
   def extractTextContent(self):
     """
-    extract plain text from ooo docs - the simplest way possible, works for all ODF formats
-    """
-    cs=cStringIO.StringIO()
+      extract plain text from ooo docs - the simplest way possible, works for all ODF formats
+    """
+    cs = cStringIO.StringIO()
     cs.write(self._unpackData(self.oo_data))
-    z=zipfile.ZipFile(cs)
-    s=z.read('content.xml')
-    s=self.rx_strip.sub(" ",s) # strip xml
-    s=self.rx_compr.sub(" ",s) # compress multiple spaces
+    z = zipfile.ZipFile(cs)
+    s = z.read('content.xml')
+    s = self.rx_strip.sub(" ", s) # strip xml
+    s = self.rx_compr.sub(" ", s) # compress multiple spaces
     cs.close()
     z.close()
     return s
 
-  security.declareProtected(Permissions.ModifyPortalContent,'setPropertyListFromContent')
-  def setPropertyListFromContent(self):
-    '''docstring'''
-    atrs=self.Document_getPropertyListFromContent(self,self.getTextContent(),self.getPortalType())
-    doctype=atrs.get('doctype','None')
-    if doctype!='None' and doctype!=self.getPortalType():
-      raise Exception('portal type mismatch - content gave %s, I have %s' % (doctype,self.getPortalType()))
-    for a in atrs:
-      self.setProperty(a,atrs[a])
 
   security.declarePrivate('_setMetaData')
   def _setMetaData(self,meta):
     """
-    Sets metadata properties of the ERP5 object.
-
-    XXX - please double check that some properties
-    are not already defined in the Document class (which is used
-    for Web Page in ERP5)
-
-    XXX - it would be quite nice if the metadata structure
-          could also support user fields in OOo
-          (user fields are so useful actually...)
-          XXX - I think it does (BG)
+      Sets metadata properties of the ERP5 object.
+
+      XXX - please double check that some properties
+      are not already defined in the Document class (which is used
+      for Web Page in ERP5)
+
+      XXX - it would be quite nice if the metadata structure
+            could also support user fields in OOo
+            (user fields are so useful actually...)
+            XXX - I think it does (BG)
     """
     for k,v in meta.items():
-      meta[k]=v.encode('utf-8')
-    self.setTitle(meta.get('title',''))
-    self.setSubject(meta.get('keywords','').split())
-    self.setDescription(meta.get('description',''))
+      meta[k] = v.encode('utf-8')
+    self.setTitle(meta.get('title', ''))
+    self.setSubject(meta.get('keywords', '').split())
+    self.setDescription(meta.get('description', ''))
     #self.setLanguage(meta.get('language',''))
-    if meta.get('MIMEType',False):
+    if meta.get('MIMEType', False):
       self.setContentType(meta['MIMEType'])
     #self.setReference(meta.get('reference',''))
 
-  security.declareProtected(Permissions.View,'getOOFile')
+  security.declareProtected(Permissions.View, 'getOOFile')
   def getOOFile(self):
     """
-    Return the converted OOo document.
-
-    XXX - use a propertysheet for this instead. We have a type
-          called data in property sheet. Look at File implementation
-    XXX - doesn't seem to be there...
-    """
-    data=self.oo_data
+      Return the converted OOo document.
+
+      XXX - use a propertysheet for this instead. We have a type
+            called data in property sheet. Look at File implementation
+      XXX - doesn't seem to be there...
+    """
+    data = self.oo_data
     return data
 
-  security.declareProtected(Permissions.View,'hasOOFile')
+  security.declareProtected(Permissions.View, 'hasOOFile')
   def hasOOFile(self):
     """
-    Checks whether we have an OOo converted file
-    """
-    _marker=[]
-    if getattr(self,'oo_data',_marker) is not _marker: # XXX - use propertysheet accessors
-      return getattr(self,'oo_data') is not None
+      Checks whether we have an OOo converted file
+    """
+    _marker = []
+    if getattr(self, 'oo_data',_marker) is not _marker: # XXX - use propertysheet accessors
+      return getattr(self, 'oo_data') is not None
     return False
 
-  security.declareProtected(Permissions.View,'hasSnapshot')
+  security.declareProtected(Permissions.View, 'hasSnapshot')
   def hasSnapshot(self):
     """
-    Checks whether we have a snapshot.
-    """
-    _marker=[]
-    if getattr(self,'snapshot',_marker) is not _marker: # XXX - use propertysheet accessors
-      return getattr(self,'snapshot') is not None
+      Checks whether we have a snapshot.
+    """
+    _marker = []
+    if getattr(self, 'snapshot', _marker) is not _marker: # XXX - use propertysheet accessors
+      return getattr(self, 'snapshot') is not None
     return False
 
   security.declareProtected(Permissions.ModifyPortalContent,'createSnapshot')
   def createSnapshot(self,REQUEST=None):
     """
-    Create a PDF snapshot
-
-    XXX - we should not create a snapshot if some error happened at conversion
-          is this checked ?
-    XXX - error at conversion raises an exception, so it should be ok
+      Create a PDF snapshot
+
+      XXX - we should not create a snapshot if some error happened at conversion
+            is this checked ?
+      XXX - error at conversion raises an exception, so it should be ok
     """
     if self.hasSnapshot():
       if REQUEST is not None:
-        return self.returnMessage('already has a snapshot',1)
+        return self.returnMessage('already has a snapshot', 1)
       raise ConversionError('already has a snapshot')
     # making snapshot
     # we have to figure out which pdf format to use
-    tgts=[x[1] for x in self.getTargetFormatItemList() if x[1].endswith('pdf')]
-    if len(tgts)>1:
-      return self.returnMessage('multiple pdf formats found - this shouldnt happen',2)
+    tgts = [x[1] for x in self.getTargetFormatItemList() if x[1].endswith('pdf')]
+    if len(tgts) > 1:
+      return self.returnMessage('multiple pdf formats found - this shouldnt happen', 2)
     if len(tgts)==0:
       return self.returnMessage('no pdf format found',1)
-    fmt=tgts[0]
+    fmt = tgts[0]
     self.makeFile(fmt)
     self.snapshot = Pdata(self._unpackData(self.getConversion(format = fmt)[1]))
     return self.returnMessage('snapshot created')
 
   security.declareProtected(Permissions.View,'getSnapshot')
-  def getSnapshot(self,REQUEST=None):
-    """
-    Returns the snapshot.
-    """
-    '''getSnapshot'''
+  def getSnapshot(self, REQUEST=None):
+    """
+      Returns the snapshot.
+    """
     if not self.hasSnapshot():
       self.createSnapshot()
     return self.snapshot
@@ -368,7 +395,7 @@
   security.declareProtected(Permissions.ManagePortal,'deleteSnapshot')
   def deleteSnapshot(self):
     """
-    Deletes the snapshot - in theory this should never be done
+      Deletes the snapshot - in theory this should never be done
     """
     try:
       del(self.snapshot)
@@ -376,78 +403,91 @@
       pass
 
   def getHtmlRepresentation(self):
-    '''
-    get simplified html version to display
-    '''
+    """
+      get simplified html version to display
+    """
     # we have to figure out which html format to use
-    tgts=[x[1] for x in self.getTargetFormatItemList() if x[1].startswith('html')]
-    if len(tgts)==0:
+    tgts = [x[1] for x in self.getTargetFormatItemList() if x[1].startswith('html')]
+    if len(tgts) == 0:
       return 'no html representation available'
-    fmt=tgts[0]
-    fmt,data=self.getTargetFile(fmt)
-    cs=cStringIO.StringIO()
+    fmt = tgts[0]
+    fmt, data = self.convert(fmt)
+    cs = cStringIO.StringIO()
     cs.write(self._unpackData(data))
-    z=zipfile.ZipFile(cs)
-    h='could not extract anything'
+    z = zipfile.ZipFile(cs)
+    h = 'could not extract anything'
     for f in z.infolist():
-      fn=f.filename
+      fn = f.filename
       if fn.endswith('html'):
-        h=z.read(fn)
+        h = z.read(fn)
         break
     z.close()
     cs.close()
     return stripHtml(h)
 
-  security.declareProtected(Permissions.View,'getTargetFile')
-  def getTargetFile(self,format,REQUEST=None):
-    """
-    Get (possibly generate) file in a given format
-    """
+  security.declareProtected(Permissions.View, 'convert')
+  def convert(self, format, REQUEST=None, force=0):
+    """
+      Get file in a given format.
+      Runs makeFile to make sure we have the requested version cached,
+      then returns from cache.
+    """
+    # first check if we have base
+    if not self.hasOOFile():
+      self.convertToBase()
     if not self.isAllowed(format):
-      return self.returnMessage('can not convert to '+format+' for some reason',1)
+      if REQUEST is not None:
+        return self.returnMessage('can not convert to ' + format + ' for some reason',1)
+      else:
+        raise ConversionError, 'can not convert to ' + format + ' for some reason'
     try:
-      self.makeFile(format)
+      # make if necessary, return from cache
+      self.makeFile(format, force)
       return self.getConversion(format = format)
     except ConversionError,e:
-      return self.returnMessage(str(e),2)
-
-  security.declareProtected(Permissions.View,'isFileChanged')
-  def isFileChanged(self,format):
-    """
-    Checks whether the file was converted (or uploaded) after last generation of
-    the target format
-    """
-    return not self.hasConversion(format = format)
-
-  security.declareProtected(Permissions.ModifyPortalContent,'makeFile')
-  def makeFile(self,format,REQUEST=None):
-    """
-    This method implement the file conversion cache:
-      * check if the format is supported
-      * check date of last conversion to OOo, compare with date of last
-      * if necessary, create new file and cache
-      * update file generation time
-
-    TODO:
-      * support of images in html conversion (as subobjects for example)
+      if REQUEST is not None:
+        return self.returnMessage(str(e), 2)
+      raise
+
+  security.declareProtected(Permissions.View, 'isFileChanged')
+  def isFileChanged(self, format):
+    """
+      Checks whether the file was converted (or uploaded) after last generation of
+      the target format
+    """
+    return not self.hasConversion(format=format)
+
+  security.declareProtected(Permissions.ModifyPortalContent, 'makeFile')
+  def makeFile(self, format, force=0, REQUEST=None, **kw):
+    """
+      This method implement the file conversion cache:
+        * check if the format is supported
+        * check date of last conversion to OOo, compare with date of last
+        * if necessary, create new file and cache
+        * update file generation time
+
+      Fails silently if we have an up to date version.
+
+      TODO:
+        * support of images in html conversion (as subobjects for example)
     """
     if not self.isAllowed(format):
-      errstr='%s format is not supported' % format
-      if REQUEST is not None:
-        return self.returnMessage(errstr,2)
+      errstr = '%s format is not supported' % format
+      if REQUEST is not None:
+        return self.returnMessage(errstr, 2)
       raise ConversionError(errstr)
     if not self.hasOOFile():
       if REQUEST is not None:
-        return self.returnMessage('needs conversion',1)
+        return self.returnMessage('needs conversion', 1)
       raise ConversionError('needs conversion')
-    if self.isFileChanged(format):
+    if self.isFileChanged(format) or force:
       try:
-        mime,data=self._makeFile(format)
+        mime, data = self._makeFile(format)
         self.setConversion(data, mime, format = format)
-        self._p_changed=1 # XXX not sure it is necessary
-      except xmlrpclib.Fault,e:
+        self._p_changed = 1 # XXX not sure it is necessary
+      except xmlrpclib.Fault, e:
         if REQUEST is not None:
-          return self.returnMessage('Problem: %s' % str(e),2)
+          return self.returnMessage('Problem: %s' % str(e), 2)
         else:
           raise ConversionError(str(e))
       self.updateConversion(format = format)
@@ -455,25 +495,23 @@
         return self.returnMessage('%s created' % format)
     else:
       if REQUEST is not None:
-        return self.returnMessage('%s file is up to date' % format,1)
-      return ConversionError('%s file is up to date' % format)
+        return self.returnMessage('%s file is up to date' % format, 1)
 
   security.declarePrivate('_makeFile')
   def _makeFile(self,format):
     """
-    Communicates with server to convert a file
+      Communicates with server to convert a file
     """
     # real version:
-    sp=self._mkProxy()
-    kw=sp.run_generate(self.getSourceReference(),enc(self._unpackData(self.oo_data)),None,format)
-    return kw['mime'],Pdata(dec(kw['data']))
+    sp = self._mkProxy()
+    kw = sp.run_generate(self.getSourceReference(), enc(self._unpackData(self.oo_data)), None, format)
+    return kw['mime'], Pdata(dec(kw['data']))
 
   # make sure to call the right edit methods
-  _edit=File._edit
-  edit=File.edit
+  _edit = File._edit
+  edit = File.edit
 
   # BG copied from File in case
-  index_html = File.index_html
   security.declareProtected('FTP access', 'manage_FTPget', 'manage_FTPstat', 'manage_FTPlist')
   manage_FTPget = File.manage_FTPget
   manage_FTPlist = File.manage_FTPlist




More information about the Erp5-report mailing list