Back to index

plone3  3.1.7
Public Member Functions | Static Public Attributes | Private Member Functions
ExternalEditor.ExternalEditor.ExternalEditor Class Reference

List of all members.

Public Member Functions

def __before_publishing_traverse__
def index_html

Static Public Attributes

tuple security = ClassSecurityInfo()

Private Member Functions

def _set_headers
def _write_metadata

Detailed Description

Create a response that encapsulates the data needed by the
   ZopeEdit helper application

Definition at line 80 of file ExternalEditor.py.


Member Function Documentation

Definition at line 88 of file ExternalEditor.py.

00088 
00089     def __before_publishing_traverse__(self, self2, request):
00090         path = request['TraversalRequestNameStack']
00091         if path:
00092             target = path[-1]
00093             if request.get('macosx') and target.endswith('.zem'):
00094                 # Remove extension added by EditLink() for Mac finder
00095                 # so we can traverse to the target in Zope
00096                 target = target[:-4]
00097             request.set('target', target)
00098             path[:] = []
00099         else:
00100             request.set('target', None)

def ExternalEditor.ExternalEditor.ExternalEditor._set_headers (   self,
  RESPONSE 
) [private]

Definition at line 235 of file ExternalEditor.py.

00235 
00236     def _set_headers(self, RESPONSE):
00237         # Using RESPONSE.setHeader('Pragma', 'no-cache') would be better, but
00238         # this chokes crappy most MSIE versions when downloads happen on SSL.
00239         # cf. http://support.microsoft.com/support/kb/articles/q316/4/31.asp
00240         RESPONSE.setHeader('Last-Modified', rfc1123_date())
00241         RESPONSE.setHeader('Content-Type', 'application/x-zope-edit')

Here is the caller graph for this function:

def ExternalEditor.ExternalEditor.ExternalEditor._write_metadata (   self,
  RESPONSE,
  metadata,
  length 
) [private]

Definition at line 242 of file ExternalEditor.py.

00242 
00243     def _write_metadata(self, RESPONSE, metadata, length):
00244         # Set response content-type so that the browser gets hinted
00245         # about what application should handle this.
00246         self._set_headers(RESPONSE)
00247 
00248         # Set response length and write our metadata. The '+1' on the
00249         # content-length is the '\n' after the metadata.
00250         RESPONSE.setHeader('Content-Length', length + 1)
00251         RESPONSE.write(metadata)
00252         RESPONSE.write('\n')
00253 
00254 InitializeClass(ExternalEditor)

Here is the call graph for this function:

Here is the caller graph for this function:

def ExternalEditor.ExternalEditor.ExternalEditor.index_html (   self,
  REQUEST,
  RESPONSE,
  path = None 
)
Publish the object to the external editor helper app

Definition at line 101 of file ExternalEditor.py.

00101 
00102     def index_html(self, REQUEST, RESPONSE, path=None):
00103         """Publish the object to the external editor helper app"""
00104 
00105         security = getSecurityManager()
00106         if path is None:
00107             parent = self.aq_parent
00108             try:
00109                 ob = parent[REQUEST['target']] # Try getitem
00110             except KeyError:
00111                 ob = getattr(parent, REQUEST['target']) # Try getattr
00112             except AttributeError:
00113                 # Handle objects that are methods in ZClasses
00114                 ob = parent.propertysheets.methods[REQUEST['target']]
00115         else:
00116             ob = self.restrictedTraverse( path )
00117 
00118         r = []
00119         r.append('url:%s' % ob.absolute_url())
00120         r.append('meta_type:%s' % ob.meta_type)
00121 
00122         title = getattr(Acquisition.aq_base(ob), 'title', None)
00123         if title is not None:
00124             if callable(title):
00125                 title = title()
00126             if isinstance(title, types.UnicodeType):
00127                 title = unicode.encode(title, 'utf-8')
00128             r.append('title:%s' % title)
00129 
00130         if hasattr(Acquisition.aq_base(ob), 'content_type'):
00131             if callable(ob.content_type):
00132                 r.append('content_type:%s' % ob.content_type())
00133             else:
00134                 r.append('content_type:%s' % ob.content_type)
00135 
00136         if REQUEST._auth:
00137             if REQUEST._auth[-1] == '\n':
00138                 auth = REQUEST._auth[:-1]
00139             else:
00140                 auth = REQUEST._auth
00141 
00142             r.append('auth:%s' % auth)
00143 
00144         r.append('cookie:%s' % REQUEST.environ.get('HTTP_COOKIE',''))
00145 
00146         if wl_isLocked(ob):
00147             # Object is locked, send down the lock token
00148             # owned by this user (if any)
00149             user_id = security.getUser().getId()
00150             for lock in ob.wl_lockValues():
00151                 if not lock.isValid():
00152                     continue # Skip invalid/expired locks
00153                 creator = lock.getCreator()
00154                 if creator and creator[1] == user_id:
00155                     # Found a lock for this user, so send it
00156                     r.append('lock-token:%s' % lock.getLockToken())
00157                     if REQUEST.get('borrow_lock'):
00158                         r.append('borrow_lock:1')
00159                     break
00160 
00161         # Apply any extra callbacks that might have been registered.
00162         applyCallbacks(ob, r, REQUEST, RESPONSE)
00163 
00164         # Finish metadata with an empty line.
00165         r.append('')
00166         metadata = join(r, '\n')
00167         metadata_len = len(metadata)
00168 
00169         # Check if we should send the file's data down the response.
00170         if REQUEST.get('skip_data'):
00171             # We've been requested to send only the metadata. The
00172             # client will presumably fetch the data itself.
00173             self._write_metadata(RESPONSE, metadata, metadata_len)
00174             return ''
00175 
00176         ob_data = getattr(Acquisition.aq_base(ob), 'data', None)
00177         if (ob_data is not None and isinstance(ob_data, Image.Pdata)):
00178             # We have a File instance with chunked data, lets stream it.
00179             #
00180             # Note we are setting the content-length header here. This
00181             # is a simplification. Read comment below.
00182             #
00183             # We assume that ob.get_size() will return the exact size
00184             # of the PData chain. If that assumption is broken we
00185             # might have problems. This is mainly an optimization. If
00186             # we read the whole PData chain just to compute the
00187             # correct size that could cause the whole file to be read
00188             # into memory.
00189             RESPONSE.setHeader('Content-Length', ob.get_size())
00190             # It is safe to use this PDataStreamIterator here because
00191             # it is consumed right below. This is only used to
00192             # simplify the code below so it only has to deal with
00193             # stream iterators or plain strings.
00194             body = PDataStreamIterator(ob.data)
00195         elif hasattr(ob, 'manage_FTPget'):
00196             # Calling manage_FTPget *might* have side-effects. For
00197             # example, in Archetypes it does set the 'content-type'
00198             # response header, which would end up overriding our own
00199             # content-type header because we've set it 'too
00200             # early'. We've moved setting the content-type header to
00201             # the '_write_metadata' method since, and any manipulation
00202             # of response headers should happen there, if possible.
00203             try:
00204                 body = ob.manage_FTPget()
00205             except TypeError: # some need the R/R pair!
00206                 body = ob.manage_FTPget(REQUEST, RESPONSE)
00207         elif hasattr(ob, 'EditableBody'):
00208             body = ob.EditableBody()
00209         elif hasattr(ob, 'document_src'):
00210             body = ob.document_src(REQUEST, RESPONSE)
00211         elif hasattr(ob, 'read'):
00212             body = ob.read()
00213         else:
00214             # can't read it!
00215             raise 'BadRequest', 'Object does not support external editing'
00216 
00217         if (IStreamIterator is not None and
00218             IStreamIterator.isImplementedBy(body)):
00219             # We need to manage our content-length because we're streaming.
00220             # The content-length should have been set in the response by
00221             # the method that returns the iterator, but we need to fix it up
00222             # here because we insert metadata before the body.
00223             clen = RESPONSE.headers.get('content-length', None)
00224             assert clen is not None
00225             self._write_metadata(RESPONSE, metadata, metadata_len + int(clen))
00226             for data in body:
00227                 RESPONSE.write(data)
00228             return ''
00229 
00230         # If we reached this point, body *must* be a string. We *must*
00231         # set the headers ourselves since _write_metadata won't get
00232         # called.
00233         self._set_headers(RESPONSE)
00234         return join((metadata, body), '\n')

Here is the call graph for this function:


Member Data Documentation

tuple ExternalEditor.ExternalEditor.ExternalEditor.security = ClassSecurityInfo() [static]

Definition at line 85 of file ExternalEditor.py.


The documentation for this class was generated from the following file: