| 1 | ################################################################################
|
|---|
| 2 | # _exportable.py
|
|---|
| 3 | #
|
|---|
| 4 | # This program is free software; you can redistribute it and/or
|
|---|
| 5 | # modify it under the terms of the GNU General Public License
|
|---|
| 6 | # as published by the Free Software Foundation; either version 2
|
|---|
| 7 | # of the License, or (at your option) any later version.
|
|---|
| 8 | #
|
|---|
| 9 | # This program is distributed in the hope that it will be useful,
|
|---|
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 12 | # GNU General Public License for more details.
|
|---|
| 13 | #
|
|---|
| 14 | # You should have received a copy of the GNU General Public License
|
|---|
| 15 | # along with this program; if not, write to the Free Software
|
|---|
| 16 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|---|
| 17 | ################################################################################
|
|---|
| 18 |
|
|---|
| 19 | # Imports.
|
|---|
| 20 | from AccessControl import ClassSecurityInfo
|
|---|
| 21 | from App.Common import package_home
|
|---|
| 22 | from OFS.Image import Image
|
|---|
| 23 | import Globals
|
|---|
| 24 | import copy
|
|---|
| 25 | import urllib
|
|---|
| 26 | import tempfile
|
|---|
| 27 | import os
|
|---|
| 28 | import re
|
|---|
| 29 | import sys
|
|---|
| 30 | # Product Imports.
|
|---|
| 31 | import _blobfields
|
|---|
| 32 | import _fileutil
|
|---|
| 33 | import _filtermanager
|
|---|
| 34 | import _globals
|
|---|
| 35 | import _xmllib
|
|---|
| 36 |
|
|---|
| 37 |
|
|---|
| 38 | # ------------------------------------------------------------------------------
|
|---|
| 39 | # _exportable.exportFiles:
|
|---|
| 40 | # ------------------------------------------------------------------------------
|
|---|
| 41 | def exportFiles(self, root, id, path):
|
|---|
| 42 | if hasattr(root,id):
|
|---|
| 43 | folder = getattr(root,id)
|
|---|
| 44 | for ob in folder.objectValues(['File','Image']):
|
|---|
| 45 | try:
|
|---|
| 46 | ob_id = ob.id()
|
|---|
| 47 | except:
|
|---|
| 48 | ob_id = str(ob.id)
|
|---|
| 49 | _fileutil.exportObj(ob,'%s/%s'%(path,ob_id))
|
|---|
| 50 |
|
|---|
| 51 |
|
|---|
| 52 | # ------------------------------------------------------------------------------
|
|---|
| 53 | # _exportable.exportFolder:
|
|---|
| 54 | # ------------------------------------------------------------------------------
|
|---|
| 55 | def exportFolder(self, root, path, id, REQUEST, depth=0):
|
|---|
| 56 | if hasattr(root,id):
|
|---|
| 57 | folder = getattr(root,id)
|
|---|
| 58 | for ob in folder.objectValues():
|
|---|
| 59 | if ob.meta_type == 'Folder':
|
|---|
| 60 | ob_id = ob.id
|
|---|
| 61 | exportFolder(self, ob,'%s/%s'%(path,id),ob_id,REQUEST,depth+1)
|
|---|
| 62 | elif ob.meta_type not in [ 'User Folder'] and 'content' not in folder.objectIds(['ZMS']):
|
|---|
| 63 | try:
|
|---|
| 64 | ob_id = ob.id()
|
|---|
| 65 | except:
|
|---|
| 66 | ob_id = str(ob.id)
|
|---|
| 67 | if ob.meta_type in [ 'DTML Document', 'DTML Method']:
|
|---|
| 68 | try:
|
|---|
| 69 | html = ob.raw
|
|---|
| 70 | html = _globals.dt_html( self, html, REQUEST)
|
|---|
| 71 | html = localHtml( self, ob, html, REQUEST)
|
|---|
| 72 | html = localIndexHtml( self, ob, len(ob.absolute_url().split('/'))-len(root.absolute_url().split('/'))+depth, html)
|
|---|
| 73 | ob = html
|
|---|
| 74 | except:
|
|---|
| 75 | pass
|
|---|
| 76 | _fileutil.exportObj(ob,'%s/%s/%s'%(path,id,ob_id))
|
|---|
| 77 |
|
|---|
| 78 |
|
|---|
| 79 | # ------------------------------------------------------------------------------
|
|---|
| 80 | # _exportable.findDelimiter:
|
|---|
| 81 | # ------------------------------------------------------------------------------
|
|---|
| 82 | def findDelimiter(s, delimiters=['"',"'"]):
|
|---|
| 83 | rtn = -1
|
|---|
| 84 | for delimiter in delimiters:
|
|---|
| 85 | i = s.find(delimiter)
|
|---|
| 86 | if rtn == -1:
|
|---|
| 87 | rtn = i
|
|---|
| 88 | elif i >= 0:
|
|---|
| 89 | rtn = min(rtn,i)
|
|---|
| 90 | return rtn
|
|---|
| 91 |
|
|---|
| 92 |
|
|---|
| 93 | # ------------------------------------------------------------------------------
|
|---|
| 94 | # _exportable.rfindDelimiter:
|
|---|
| 95 | # ------------------------------------------------------------------------------
|
|---|
| 96 | def rfindDelimiter(s, delimiters=['"',"'"]):
|
|---|
| 97 | rtn = -1
|
|---|
| 98 | for delimiter in delimiters:
|
|---|
| 99 | i = s.rfind(delimiter)
|
|---|
| 100 | rtn = max(rtn,i)
|
|---|
| 101 | return rtn
|
|---|
| 102 |
|
|---|
| 103 |
|
|---|
| 104 | # ------------------------------------------------------------------------------
|
|---|
| 105 | # _exportable.localHtml:
|
|---|
| 106 | #
|
|---|
| 107 | # Process encoding.
|
|---|
| 108 | # ------------------------------------------------------------------------------
|
|---|
| 109 | def localHtml(self, obj, html, REQUEST):
|
|---|
| 110 | try:
|
|---|
| 111 | default_charset = 'utf-8'
|
|---|
| 112 | charset = REQUEST.get('ZMS_CHARSET', default_charset)
|
|---|
| 113 | if charset != default_charset:
|
|---|
| 114 | html = unicode( html, default_charset).encode( charset)
|
|---|
| 115 | except ( UnicodeDecodeError, UnicodeEncodeError):
|
|---|
| 116 | _globals.writeError( obj, "[localHtml]")
|
|---|
| 117 | v = str(sys.exc_value)
|
|---|
| 118 | STR_POSITION = ' position '
|
|---|
| 119 | i = v.find(STR_POSITION)
|
|---|
| 120 | if i > 0:
|
|---|
| 121 | v = v[i+len(STR_POSITION):]
|
|---|
| 122 | if v.find('-') > 0:
|
|---|
| 123 | l = int( v[:v.find('-')])
|
|---|
| 124 | h = int( v[v.find('-')+1:v.find(':')])
|
|---|
| 125 | else:
|
|---|
| 126 | l = int( v[:v.find(':')])
|
|---|
| 127 | h = l
|
|---|
| 128 | ln = max( l - 20, 0)
|
|---|
| 129 | hn = min( h + 20, len(html))
|
|---|
| 130 | print ">>>>>",html[ln:hn]
|
|---|
| 131 | print ">>>>>"," "*(l-ln)+"^"*(h-l+1)
|
|---|
| 132 | return html
|
|---|
| 133 |
|
|---|
| 134 |
|
|---|
| 135 | # ------------------------------------------------------------------------------
|
|---|
| 136 | # _exportable.localIndexHtml:
|
|---|
| 137 | # ------------------------------------------------------------------------------
|
|---|
| 138 | def localIndexHtml(self, obj, level, html, xhtml=False):
|
|---|
| 139 | REQUEST = self.REQUEST
|
|---|
| 140 |
|
|---|
| 141 | sRoot = ''
|
|---|
| 142 | for i in range(level):
|
|---|
| 143 | sRoot = '../%s'%sRoot
|
|---|
| 144 |
|
|---|
| 145 | # Process aliases.
|
|---|
| 146 | doc_url = self.getDocumentElement().absolute_url()
|
|---|
| 147 | url = doc_url
|
|---|
| 148 | url = url[url.find('://')+3:]
|
|---|
| 149 | url = url[url.find('/'):]
|
|---|
| 150 | base_url = doc_url
|
|---|
| 151 | base_url = base_url[ : base_url.find(url)]
|
|---|
| 152 | html = re.sub( '"([^("\')]*?)'+url+'([^("\')]*?)"', '"'+base_url+url+'\\2"', html)
|
|---|
| 153 |
|
|---|
| 154 | # Process absolute URLs.
|
|---|
| 155 | s_new = '%s'%sRoot
|
|---|
| 156 | s_old = '%s/'%self.absolute_url()
|
|---|
| 157 | if xhtml or level != 0:
|
|---|
| 158 | html = html.replace( s_old, s_new)
|
|---|
| 159 | if self.getConfProperty('ZMS.pathhandler',0) != 0:
|
|---|
| 160 | s_old = '%s/'%self.getDeclUrl( REQUEST)
|
|---|
| 161 | html = html.replace( s_old, s_new)
|
|---|
| 162 | s_old = '%s/'%self.getDocumentElement().absolute_url()
|
|---|
| 163 | html = html.replace( s_old, s_new)
|
|---|
| 164 | s_old = '%s/'%self.getHome().absolute_url()
|
|---|
| 165 | html = html.replace( s_old, s_new)
|
|---|
| 166 |
|
|---|
| 167 | # Process links to resource-folders: images and assets.
|
|---|
| 168 | for container in self.getResourceFolders():
|
|---|
| 169 | id = container.id
|
|---|
| 170 | s_new = '"%s%s/'%(sRoot,id)
|
|---|
| 171 | s_old = '"./%s/'%(id)
|
|---|
| 172 | html = html.replace(s_old,s_new)
|
|---|
| 173 | s_old = '"%s/'%(id)
|
|---|
| 174 | html = html.replace(s_old,s_new)
|
|---|
| 175 |
|
|---|
| 176 | # Process links to product-folder: images and assets.
|
|---|
| 177 | s_new = '"%smisc_/zms/'%sRoot
|
|---|
| 178 | s_old = '"/misc_/zms/'
|
|---|
| 179 | html = html.replace(s_old,s_new)
|
|---|
| 180 | s_old = '"misc_/zms/'
|
|---|
| 181 | html = html.replace(s_old,s_new)
|
|---|
| 182 | # starting with '(' (in styles)
|
|---|
| 183 | s_new = '(%smisc_/zms/'%sRoot
|
|---|
| 184 | s_old = '(/misc_/zms/'
|
|---|
| 185 | html = html.replace(s_old,s_new)
|
|---|
| 186 | s_old = '(misc_/zms/'
|
|---|
| 187 | html = html.replace(s_old,s_new)
|
|---|
| 188 |
|
|---|
| 189 | # Process preview parameters.
|
|---|
| 190 | if not REQUEST.get('ZMS_PREVIEW_PRESERVE',False):
|
|---|
| 191 | html = re.sub('(\?|&)preview=preview','',html)
|
|---|
| 192 |
|
|---|
| 193 | # Process declarative URLs
|
|---|
| 194 | if self.getConfProperty('ZMS.pathhandler',0):
|
|---|
| 195 | for x in html.split('href="./'):
|
|---|
| 196 | href = x[:x.find('"')]
|
|---|
| 197 | if href.endswith('.html'):
|
|---|
| 198 | href = href.split('/')
|
|---|
| 199 | new_href = []
|
|---|
| 200 | ob = self
|
|---|
| 201 | for ob_id in href[:-1]:
|
|---|
| 202 | if ob is not None:
|
|---|
| 203 | if ob_id == '..':
|
|---|
| 204 | ob = ob.getParentNode()
|
|---|
| 205 | if ob is not None:
|
|---|
| 206 | new_href.append(ob_id)
|
|---|
| 207 | else:
|
|---|
| 208 | ob = getattr(ob,ob_id,None)
|
|---|
| 209 | if ob is not None:
|
|---|
| 210 | new_href.append(ob.getDeclId(REQUEST))
|
|---|
| 211 | if ob is not None:
|
|---|
| 212 | new_href.append(href[-1])
|
|---|
| 213 | html = html.replace('"./%s"'%('/'.join(href)),'"./%s"'%('/'.join(new_href)))
|
|---|
| 214 | if self.getConfProperty('ZMS.export.pathhandler',0):
|
|---|
| 215 | newTmp = '..\\'
|
|---|
| 216 | oldTmp = '../'
|
|---|
| 217 | # Save links to root.
|
|---|
| 218 | html = html.replace( oldTmp, newTmp)
|
|---|
| 219 | # Replace 'index' in declarative URLs
|
|---|
| 220 | pageexts = ['.html']
|
|---|
| 221 | if 'attr_pageext' in self.getObjAttrs().keys():
|
|---|
| 222 | obj_attr = self.getObjAttr('attr_pageext')
|
|---|
| 223 | if obj_attr.has_key('keys') and len(obj_attr.get('keys')) > 0:
|
|---|
| 224 | pageexts = obj_attr.get('keys')
|
|---|
| 225 | for pageext in pageexts:
|
|---|
| 226 | s_new = pageext
|
|---|
| 227 | s_old = '/index_%s%s'%(REQUEST['lang'],pageext)
|
|---|
| 228 | html = html.replace( s_old, s_new)
|
|---|
| 229 | # Replace 'index_print' & 'sitemap' in declarative URLs
|
|---|
| 230 | if obj.getLevel() > 0:
|
|---|
| 231 | for key in [ 'index_print', 'sitemap']:
|
|---|
| 232 | s_old = '"%s_%s%s'%(key,REQUEST['lang'],pageext)
|
|---|
| 233 | s_new = '"%s/%s_%s%s'%(obj.getDeclId(REQUEST),key,REQUEST['lang'],pageext)
|
|---|
| 234 | html = html.replace( s_old, s_new)
|
|---|
| 235 | # Restore links to root.
|
|---|
| 236 | html = html.replace( newTmp, oldTmp)
|
|---|
| 237 |
|
|---|
| 238 | return html
|
|---|
| 239 |
|
|---|
| 240 |
|
|---|
| 241 | ################################################################################
|
|---|
| 242 | ################################################################################
|
|---|
| 243 | ###
|
|---|
| 244 | ### Class
|
|---|
| 245 | ###
|
|---|
| 246 | ################################################################################
|
|---|
| 247 | ################################################################################
|
|---|
| 248 | class Exportable(_filtermanager.FilterItem):
|
|---|
| 249 |
|
|---|
| 250 | # Create a SecurityInfo for this class. We will use this
|
|---|
| 251 | # in the rest of our class definition to make security
|
|---|
| 252 | # assertions.
|
|---|
| 253 | security = ClassSecurityInfo()
|
|---|
| 254 |
|
|---|
| 255 |
|
|---|
| 256 | ############################################################################
|
|---|
| 257 | # Exportable.manage_export:
|
|---|
| 258 | #
|
|---|
| 259 | # Exports ZMS-object.
|
|---|
| 260 | ############################################################################
|
|---|
| 261 | def manage_export(self, export_format, lang, REQUEST, RESPONSE):
|
|---|
| 262 | """ Exportable.manage_export """
|
|---|
| 263 |
|
|---|
| 264 | title = self.getHome().id + '_' + _globals.id_quote( self.getTitlealt( REQUEST))
|
|---|
| 265 |
|
|---|
| 266 | # Get export format.
|
|---|
| 267 | try:
|
|---|
| 268 | export_format = int( export_format)
|
|---|
| 269 | except:
|
|---|
| 270 | pass
|
|---|
| 271 |
|
|---|
| 272 | get_data = REQUEST.get( 'download', 1) == 1
|
|---|
| 273 |
|
|---|
| 274 | # ZEXP.
|
|---|
| 275 | if export_format == 0:
|
|---|
| 276 | filename = '%s.zexp'%self.id
|
|---|
| 277 | export = self.aq_parent.manage_exportObject( id=self.id, download=1)
|
|---|
| 278 | content_type = 'application/data'
|
|---|
| 279 |
|
|---|
| 280 | # HTML.
|
|---|
| 281 | elif export_format == 1:
|
|---|
| 282 | filename = '%s_html.zip'%title
|
|---|
| 283 | export = self.toZippedHtml( REQUEST, get_data)
|
|---|
| 284 | content_type = 'application/zip'
|
|---|
| 285 |
|
|---|
| 286 | # XML.
|
|---|
| 287 | elif export_format in [ 2, 4]:
|
|---|
| 288 | incl_embedded = export_format == 4
|
|---|
| 289 | filename = '%s_xml.zip'%title
|
|---|
| 290 | export = self.toZippedXml( REQUEST, get_data, incl_embedded)
|
|---|
| 291 | content_type = 'application/zip'
|
|---|
| 292 |
|
|---|
| 293 | # myXML.
|
|---|
| 294 | elif export_format == 3:
|
|---|
| 295 | instance_home = INSTANCE_HOME
|
|---|
| 296 | software_home = os.path.join(SOFTWARE_HOME, '..%s..' % os.sep)
|
|---|
| 297 | software_home = os.path.normpath(software_home)
|
|---|
| 298 | REQUEST.set( 'ZMS_FILTER_SOFTWARE_HOME', software_home)
|
|---|
| 299 | REQUEST.set( 'ZMS_FILTER_INSTANCE_HOME', instance_home)
|
|---|
| 300 | REQUEST.set( 'ZMS_FILTER_PACKAGE_HOME', package_home(globals()))
|
|---|
| 301 | filename = '%s.xml'%title
|
|---|
| 302 | export = self.getXmlHeader() + getattr( self, 'getObjToXml_DocElmnt')(context=self)
|
|---|
| 303 | content_type = 'text/xml'
|
|---|
| 304 |
|
|---|
| 305 | # Export Filter.
|
|---|
| 306 | elif export_format in self.getFilterIds():
|
|---|
| 307 | if REQUEST.get('debug'):
|
|---|
| 308 | url = self.url_append_params( 'manage_importexportDebugFilter', { 'lang': lang, 'filterId': export_format, 'debug': 1})
|
|---|
| 309 | return RESPONSE.redirect( url)
|
|---|
| 310 | else:
|
|---|
| 311 | filename, export, content_type = _filtermanager.exportFilter(self, export_format, REQUEST)
|
|---|
| 312 |
|
|---|
| 313 | # return export for download to browser
|
|---|
| 314 | if get_data:
|
|---|
| 315 | RESPONSE.setHeader('Content-Type',content_type)
|
|---|
| 316 | RESPONSE.setHeader('Content-Disposition','inline;filename="%s"'%filename)
|
|---|
| 317 | return export
|
|---|
| 318 | else:
|
|---|
| 319 | message = 'Exported to %s (%s)'%(export,content_type)
|
|---|
| 320 | url = '%s/manage_importexport'%self.absolute_url()
|
|---|
| 321 | url = self.url_append_params( url, { 'lang': lang, 'manage_tabs_message': message})
|
|---|
| 322 | RESPONSE.redirect( url)
|
|---|
| 323 |
|
|---|
| 324 |
|
|---|
| 325 | ############################################################################
|
|---|
| 326 | # Exportable.pub_export:
|
|---|
| 327 | #
|
|---|
| 328 | # Exports ZMS-object.
|
|---|
| 329 | ############################################################################
|
|---|
| 330 | security.declareProtected('View', 'pub_export')
|
|---|
| 331 | def pub_export(self, export_format, lang, REQUEST, RESPONSE):
|
|---|
| 332 | """ Exportable.pub_export """
|
|---|
| 333 | self.f_standard_html_request( self, REQUEST)
|
|---|
| 334 | return self.manage_export( export_format, lang, REQUEST, RESPONSE)
|
|---|
| 335 |
|
|---|
| 336 |
|
|---|
| 337 | # --------------------------------------------------------------------------
|
|---|
| 338 | # Exportable.getObjToXml:
|
|---|
| 339 | #
|
|---|
| 340 | # myXML
|
|---|
| 341 | # --------------------------------------------------------------------------
|
|---|
| 342 | def getObjToXml(self):
|
|---|
| 343 | xml = []
|
|---|
| 344 | method = getattr( self, 'getObjToXml_%s'%self.meta_id, None)
|
|---|
| 345 | if method is not None:
|
|---|
| 346 | xml.append( method( context=self))
|
|---|
| 347 | return ''.join(xml)
|
|---|
| 348 |
|
|---|
| 349 | # --------------------------------------------------------------------------
|
|---|
| 350 | # Exportable.getObjChildrenToXml:
|
|---|
| 351 | #
|
|---|
| 352 | # myXML
|
|---|
| 353 | # --------------------------------------------------------------------------
|
|---|
| 354 | def getObjChildrenToXml(self):
|
|---|
| 355 | REQUEST = self.REQUEST
|
|---|
| 356 | xml = []
|
|---|
| 357 | for context in self.filteredChildNodes(REQUEST):
|
|---|
| 358 | xml.append( context.getObjToXml())
|
|---|
| 359 | return ''.join(xml)
|
|---|
| 360 |
|
|---|
| 361 |
|
|---|
| 362 | # --------------------------------------------------------------------------
|
|---|
| 363 | # Exportable.toXhtml:
|
|---|
| 364 | #
|
|---|
| 365 | # (X)HTML
|
|---|
| 366 | # --------------------------------------------------------------------------
|
|---|
| 367 | def toXhtml(self, REQUEST, deep=True):
|
|---|
| 368 | _globals.writeLog( self, '[toXhtml]')
|
|---|
| 369 | level = 0
|
|---|
| 370 | html = ''
|
|---|
| 371 | if REQUEST.has_key( 'ZMS_PAGE_HTML_HEADER'):
|
|---|
| 372 | html += getattr( self, REQUEST.get( 'ZMS_PAGE_HTML_HEADER'))( self, REQUEST)
|
|---|
| 373 | else:
|
|---|
| 374 | html += '<html>\n'
|
|---|
| 375 | html += '<head>\n'
|
|---|
| 376 | html += self.f_headMeta_Locale( self, REQUEST)
|
|---|
| 377 | html += '<title>%s</title>\n'%self.getTitle(REQUEST)
|
|---|
| 378 | html += '</head>\n'
|
|---|
| 379 | html += '<body>\n'
|
|---|
| 380 | html += self.printHtml( level, _globals.MySectionizer(), REQUEST, deep)
|
|---|
| 381 | if REQUEST.has_key( 'ZMS_PAGE_HTML_FOOTER'):
|
|---|
| 382 | html += getattr( self, REQUEST.get( 'ZMS_PAGE_HTML_FOOTER'))( self, REQUEST)
|
|---|
| 383 | else:
|
|---|
| 384 | html += '</body>\n'
|
|---|
| 385 | html += '</html>\n'
|
|---|
| 386 | html = localHtml( self, self, html, REQUEST)
|
|---|
| 387 | html = localIndexHtml( self, self, level, html, xhtml=True)
|
|---|
| 388 | return html
|
|---|
| 389 |
|
|---|
| 390 |
|
|---|
| 391 | # --------------------------------------------------------------------------
|
|---|
| 392 | # Exportable.toXml:
|
|---|
| 393 | # --------------------------------------------------------------------------
|
|---|
| 394 | def toXml(self, REQUEST, incl_embedded=False, deep=True, data2hex=False):
|
|---|
| 395 | xml = ''
|
|---|
| 396 | xml += _xmllib.xml_header()
|
|---|
| 397 | xml += _xmllib.getObjToXml( self, REQUEST, incl_embedded, deep, base_path='', data2hex=data2hex)
|
|---|
| 398 | return xml
|
|---|
| 399 |
|
|---|
| 400 |
|
|---|
| 401 | # --------------------------------------------------------------------------
|
|---|
| 402 | # Exportable.exportRessources:
|
|---|
| 403 | #
|
|---|
| 404 | # Returns list of exported resources (Images, StyleSheets, etc.)
|
|---|
| 405 | # --------------------------------------------------------------------------
|
|---|
| 406 | def exportRessources(self, tempfolder, REQUEST, from_content=True, from_zms=False, from_home=False, incl_embedded=False):
|
|---|
| 407 | ressources = []
|
|---|
| 408 |
|
|---|
| 409 | if from_zms:
|
|---|
| 410 | folder = 'misc_/zms'
|
|---|
| 411 | for obj_id in self.misc_.zms._d.keys():
|
|---|
| 412 | _fileutil.exportObj(self.misc_.zms[obj_id],'%s/%s/%s'%(tempfolder,folder,obj_id))
|
|---|
| 413 | exportFiles( self, self.getDocumentElement(), 'metaobj_manager', '%s/metaobj_manager'%tempfolder)
|
|---|
| 414 |
|
|---|
| 415 | if from_home:
|
|---|
| 416 | root = self.getHome()
|
|---|
| 417 | exportFiles( self, root.aq_parent, root.id, tempfolder)
|
|---|
| 418 | for id in root.objectIds(['Folder']):
|
|---|
| 419 | exportFolder( self, root, tempfolder, id, REQUEST)
|
|---|
| 420 |
|
|---|
| 421 | if from_content:
|
|---|
| 422 | base_path = tempfolder+'/'
|
|---|
| 423 | ressources.extend( _blobfields.recurse_downloadRessources( self, base_path, REQUEST, incl_embedded))
|
|---|
| 424 |
|
|---|
| 425 | return ressources
|
|---|
| 426 |
|
|---|
| 427 |
|
|---|
| 428 | # --------------------------------------------------------------------------
|
|---|
| 429 | # Exportable.exportExternalResources
|
|---|
| 430 | # --------------------------------------------------------------------------
|
|---|
| 431 | def exportExternalResources(self, obj, html, path, REQUEST):
|
|---|
| 432 | domains = []
|
|---|
| 433 | for domain in self.getConfProperty('ZMS.export.domains','').split(','):
|
|---|
| 434 | domain = domain.strip()
|
|---|
| 435 | if len( domain) > 0:
|
|---|
| 436 | domains.append( domain)
|
|---|
| 437 | if len( domains) == 0:
|
|---|
| 438 | return html
|
|---|
| 439 | for http_prefix in [ 'http:']:
|
|---|
| 440 | i = html.find( http_prefix)
|
|---|
| 441 | while i > 0:
|
|---|
| 442 | d = rfindDelimiter(html[:i]) # search delimiter ' or "
|
|---|
| 443 | k = rfindDelimiter(html[:d],'=') # search equal-sign between attribute name
|
|---|
| 444 | t = rfindDelimiter(html[:k],'<') # search start of tag
|
|---|
| 445 | # <img src="url">
|
|---|
| 446 | # <a href='url'">
|
|---|
| 447 | if (html[ t + 1: t + 4].lower() == 'img' and html[ k - 3: k].lower() == 'src') \
|
|---|
| 448 | or (html[ t + 1].lower() == 'a' and html[ k - 4: k].lower() == 'href'):
|
|---|
| 449 | l = findDelimiter(html[ d + 1:])
|
|---|
| 450 | url = html[ d + 1: d + l + 1]
|
|---|
| 451 | for domain in domains:
|
|---|
| 452 | if domain in url:
|
|---|
| 453 | try:
|
|---|
| 454 | _globals.writeLog( self, '[exportExternalResources]: url=%s'%url)
|
|---|
| 455 | s_new = s_old = url
|
|---|
| 456 | for repl in ':/%&?;=':
|
|---|
| 457 | s_new = s_new.replace(repl, '_')
|
|---|
| 458 | # test if extension is a real extension at the end ?
|
|---|
| 459 | # http://host:port/uri.gif?a=x&b=k => http___host_port_uri.gif_a_x_b_k.gif
|
|---|
| 460 | # http://host:port/uri.gif => http__host_port_uri.gif
|
|---|
| 461 | # http://host:port/draw/ID/png => http__host_port_draw_ID_png.png
|
|---|
| 462 | # http://host:port/draw/ID?fmt=pdf&scale=2 => http__host_port_draw_ID_fmt_pdf_scale_2.pdf
|
|---|
| 463 | for ext in ['gif','jpg','png','pdf','csv','xls','doc','ppt']:
|
|---|
| 464 | if ext in url:
|
|---|
| 465 | if s_new[-len(ext)-1:] != '.%s' % ext:
|
|---|
| 466 | s_new = "%s.%s" %(s_new, ext)
|
|---|
| 467 | break
|
|---|
| 468 | ext_path = '%s/%s'%( path, s_new)
|
|---|
| 469 | if not os.path.exists( ext_path):
|
|---|
| 470 | data = self.http_import( url)
|
|---|
| 471 | f = open( ext_path, 'w')
|
|---|
| 472 | f.write( data)
|
|---|
| 473 | f.close()
|
|---|
| 474 | html = html.replace( s_old, s_new)
|
|---|
| 475 | except:
|
|---|
| 476 | _globals.writeError( self, '[exportExternalResources]: url=%s'%url)
|
|---|
| 477 | break
|
|---|
| 478 | i = html.find( http_prefix, i + len( http_prefix))
|
|---|
| 479 | return html
|
|---|
| 480 |
|
|---|
| 481 |
|
|---|
| 482 | # --------------------------------------------------------------------------
|
|---|
| 483 | # Exportable.recurse_downloadHtmlPages:
|
|---|
| 484 | # --------------------------------------------------------------------------
|
|---|
| 485 | def recurse_downloadHtmlPages(self, obj, path, lang, REQUEST):
|
|---|
| 486 | try:
|
|---|
| 487 | os.mkdir(path)
|
|---|
| 488 | except:
|
|---|
| 489 | pass
|
|---|
| 490 |
|
|---|
| 491 | level = obj.getLevel()
|
|---|
| 492 | dctOp = {}
|
|---|
| 493 | if obj.meta_id.find('ZMSSys') == 0:
|
|---|
| 494 | exportFolder( obj, obj.getParentNode(), path[:path.rfind('/')], obj.id, REQUEST)
|
|---|
| 495 | else:
|
|---|
| 496 | dctOp = REQUEST.get('ZMS_EXPORT_OP',{'index':'','index_print':'print','sitemap':'sitemap'})
|
|---|
| 497 |
|
|---|
| 498 | for key in dctOp.keys():
|
|---|
| 499 |
|
|---|
| 500 | # Get html.
|
|---|
| 501 | REQUEST.set('op',dctOp[key])
|
|---|
| 502 | REQUEST.set('ZMS_PATH_HANDLER', True)
|
|---|
| 503 | REQUEST.set('ZMS_FETCH_REQ_BUFF',False)
|
|---|
| 504 |
|
|---|
| 505 | try:
|
|---|
| 506 |
|
|---|
| 507 | # Remember others.
|
|---|
| 508 | others = copy.copy(REQUEST.other.keys())
|
|---|
| 509 |
|
|---|
| 510 | root = getattr( obj, '__root__', None)
|
|---|
| 511 | if root is not None:
|
|---|
| 512 | REQUEST.set('ZMS_PROXY_%s'%root.id,obj)
|
|---|
| 513 | html = root.f_index_html( root, REQUEST)
|
|---|
| 514 | else:
|
|---|
| 515 | html = obj.f_index_html( obj, REQUEST)
|
|---|
| 516 |
|
|---|
| 517 | # Remove new others.
|
|---|
| 518 | for rk in REQUEST.other.keys():
|
|---|
| 519 | if rk not in others:
|
|---|
| 520 | try:
|
|---|
| 521 | del REQUEST.other[rk]
|
|---|
| 522 | except:
|
|---|
| 523 | pass
|
|---|
| 524 |
|
|---|
| 525 | # Localize html.
|
|---|
| 526 | html = localHtml( self, obj, html, REQUEST)
|
|---|
| 527 |
|
|---|
| 528 | # Save html to file.
|
|---|
| 529 | if key == 'index' and \
|
|---|
| 530 | level > 0 and \
|
|---|
| 531 | self.getConfProperty('ZMS.pathhandler',0) != 0 and \
|
|---|
| 532 | self.getConfProperty('ZMS.export.pathhandler',0) == 1:
|
|---|
| 533 | html = localIndexHtml( self, obj, level - 1, html)
|
|---|
| 534 | filename = '%s/../%s%s'%( path, obj.getDeclId(REQUEST), obj.getPageExt(REQUEST))
|
|---|
| 535 | else:
|
|---|
| 536 | if key == 'sitemap':
|
|---|
| 537 | pageext = '.html'
|
|---|
| 538 | else:
|
|---|
| 539 | pageext = obj.getPageExt( REQUEST)
|
|---|
| 540 | html = localIndexHtml( self, obj, level - self.getLevel(), html)
|
|---|
| 541 | filename = '%s/%s_%s%s'%( path, key, lang, pageext)
|
|---|
| 542 |
|
|---|
| 543 | html = self.exportExternalResources( obj, html, path, REQUEST)
|
|---|
| 544 |
|
|---|
| 545 | # Blank lines in includes cause PHP session errors
|
|---|
| 546 | # @see http://bugs.php.net/bug.php?id=8974
|
|---|
| 547 | html = self.re_sub('^\s*', '', html)
|
|---|
| 548 |
|
|---|
| 549 | f = open( filename, 'w')
|
|---|
| 550 | f.write( html)
|
|---|
| 551 | f.close()
|
|---|
| 552 |
|
|---|
| 553 | # Root folder requires and defaults to "index.html" at most systems.
|
|---|
| 554 | if key == 'index' and lang == self.getPrimaryLanguage():
|
|---|
| 555 | filename = '%s/%s%s'%( path, key, obj.getPageExt( REQUEST))
|
|---|
| 556 | f = open(filename,'w')
|
|---|
| 557 | f.write(html)
|
|---|
| 558 | f.close()
|
|---|
| 559 |
|
|---|
| 560 | except:
|
|---|
| 561 | _globals.writeError( obj, "[recurse_downloadHtmlPages]: Can't get html '%s'"%key)
|
|---|
| 562 |
|
|---|
| 563 | # Process DTML-methods of meta-objects.
|
|---|
| 564 | for metadictAttrId in self.getMetaobjAttrIds( obj.meta_id):
|
|---|
| 565 | try:
|
|---|
| 566 | metadictAttr = self.getMetaobjAttr( obj.meta_id, metadictAttrId)
|
|---|
| 567 | if metadictAttr is not None and metadictAttr['meta_type'] and metadictAttr['type'] in self.getMetaobjIds( sort=0):
|
|---|
| 568 | metaObj = self.getMetaobj( metadictAttr['type'])
|
|---|
| 569 | if metaObj['type'] == 'ZMSResource':
|
|---|
| 570 | for metadictObj in obj.getObjChildren( metadictAttr['id'], REQUEST):
|
|---|
| 571 | for metaObjAttr in metaObj['attrs']:
|
|---|
| 572 | if metaObjAttr['type'] in [ 'DTML Document', 'DTML Method']:
|
|---|
| 573 | html = getattr( obj, metaObjAttr['id'])( obj, REQUEST)
|
|---|
| 574 | html = localHtml( self, obj, html, REQUEST)
|
|---|
| 575 | filename = '%s/%s'%( path, metaObjAttr['id'])
|
|---|
| 576 | f = open(filename,'w')
|
|---|
| 577 | f.write(html)
|
|---|
| 578 | f.close()
|
|---|
| 579 | except:
|
|---|
| 580 | _globals.writeError( self, "[recurse_downloadHtmlPages]: Can't process DTML-method '%s' of meta-object"%metadictAttr)
|
|---|
| 581 |
|
|---|
| 582 | # Process children.
|
|---|
| 583 | for child in obj.filteredChildNodes(REQUEST,self.PAGES):
|
|---|
| 584 | self.recurse_downloadHtmlPages(child,'%s/%s'%(path,child.getDeclId(REQUEST)),lang,REQUEST)
|
|---|
| 585 |
|
|---|
| 586 |
|
|---|
| 587 | # --------------------------------------------------------------------------
|
|---|
| 588 | # Exportable.toZippedHtml:
|
|---|
| 589 | # --------------------------------------------------------------------------
|
|---|
| 590 | def toZippedHtml(self, REQUEST, get_data=True):
|
|---|
| 591 | REQUEST.set('ZMS_INDEX_HTML',1)
|
|---|
| 592 | REQUEST.set('ZMS_HTML_EXPORT',1)
|
|---|
| 593 |
|
|---|
| 594 | #-- Create temporary folder.
|
|---|
| 595 | tempfolder = tempfile.mktemp()
|
|---|
| 596 | ressources = self.exportRessources( tempfolder, REQUEST, from_zms=self.getLevel()==0, from_home=True)
|
|---|
| 597 |
|
|---|
| 598 | #-- Download HTML-pages.
|
|---|
| 599 | for lang in self.getLangIds():
|
|---|
| 600 | REQUEST.set('lang',lang)
|
|---|
| 601 | REQUEST.set('preview',None)
|
|---|
| 602 | self.recurse_downloadHtmlPages( self, tempfolder, lang, REQUEST)
|
|---|
| 603 |
|
|---|
| 604 | #-- Get zip-file.
|
|---|
| 605 | zipfiles = _fileutil.getOSPath('%s/*'%tempfolder)
|
|---|
| 606 | rtn = _fileutil.buildZipArchive( zipfiles, get_data)
|
|---|
| 607 |
|
|---|
| 608 | #-- Remove temporary folder.
|
|---|
| 609 | if not _globals.debug( self):
|
|---|
| 610 | _fileutil.remove( tempfolder, deep=1)
|
|---|
| 611 |
|
|---|
| 612 | return rtn
|
|---|
| 613 |
|
|---|
| 614 |
|
|---|
| 615 | # --------------------------------------------------------------------------
|
|---|
| 616 | # Exportable.toZippedXml:
|
|---|
| 617 | # --------------------------------------------------------------------------
|
|---|
| 618 | def toZippedXml(self, REQUEST, get_data=True, incl_embedded=False):
|
|---|
| 619 |
|
|---|
| 620 | #-- Create temporary folder.
|
|---|
| 621 | tempfolder = tempfile.mktemp()
|
|---|
| 622 | ressources = self.exportRessources( tempfolder, REQUEST, incl_embedded=incl_embedded)
|
|---|
| 623 |
|
|---|
| 624 | #-- Get xml-export.
|
|---|
| 625 | xml = self.toXml(REQUEST,incl_embedded)
|
|---|
| 626 |
|
|---|
| 627 | #-- Write xml-export to file.
|
|---|
| 628 | xmlfilename = _fileutil.getOSPath('%s/%s_%s.xml'%(tempfolder,self.getHome().id,self.meta_id))
|
|---|
| 629 | _fileutil.exportObj(xml,xmlfilename)
|
|---|
| 630 |
|
|---|
| 631 | #-- Get zip-file.
|
|---|
| 632 | zipfiles = _fileutil.getOSPath('%s/*'%tempfolder)
|
|---|
| 633 | rtn = _fileutil.buildZipArchive( zipfiles, get_data)
|
|---|
| 634 |
|
|---|
| 635 | #-- Remove temporary folder.
|
|---|
| 636 | if not _globals.debug( self):
|
|---|
| 637 | _fileutil.remove( tempfolder, deep=1)
|
|---|
| 638 |
|
|---|
| 639 | return rtn
|
|---|
| 640 |
|
|---|
| 641 |
|
|---|
| 642 | # call this to initialize framework classes, which
|
|---|
| 643 | # does the right thing with the security assertions.
|
|---|
| 644 | Globals.InitializeClass(Exportable)
|
|---|
| 645 |
|
|---|
| 646 | ################################################################################
|
|---|