Commit efdd4b44 authored by Julien Muchembled's avatar Julien Muchembled

Improvements to [33393] (download built BT from a running ERP5 instance)

* Fix lookup of the BT with the highest revision (getRevision method does not
  return an integer).
* Automatically build a non-built BT before exporting it.
* Make template tool export BT like a classic HTTP file server.
* Unit tests: allow to specify in --bt5_path any HTTP url. Existence of a BT is
  done by a HEAD request to avoid downloading twice.

So now, the URL to specify in --bt5_path must be of the following form:
  http://.../erp5/portal_templates/asRepository
It could also be http://www.erp5.org/dists/snapshot/bt5/

A normal ERP5 instance can also import a BT from another instance:
  http://.../erp5/portal_templates/asRepository/erp5_base

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@33414 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 4e488308
......@@ -33,7 +33,7 @@ import os
import shutil
import sys
from Acquisition import Implicit
from Acquisition import Implicit, Explicit
from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Globals import InitializeClass, DTMLFile, PersistentMapping
from Products.ERP5Type.DiffUtils import DiffFile
......@@ -144,16 +144,38 @@ class TemplateTool (BaseTool):
built_bts.append(bt)
return built_bts
def getLastBusinessTemplateId(self, title):
"""Get the id of the business template with the highest revision number
"""
last_bt = None, None
for bt in self.contentValues(portal_type='Business Template'):
if bt.getTitle() == title and bt.getBuildingState() == 'built':
revision = bt.getRevision()
if last_bt[0] < revision and bt.getInstallationState() != 'deleted':
last_bt = revision, bt.getId()
return last_bt[1]
@property
def asRepository(self):
class asRepository(Explicit):
"""Export business template by their title
Provides a view of template tool allowing a user to download the last
revision of a business template with a URL like:
http://.../erp5/portal_templates/asRepository/erp5_core
"""
def __before_publishing_traverse__(self, self2, request):
path = request['TraversalRequestNameStack']
self.subpath = tuple(reversed(path))
del path[:]
def __call__(self, REQUEST, RESPONSE):
title, = self.subpath
last_bt = None, None
for bt in self.aq_parent.searchFolder(title=title):
bt = bt.getObject()
revision = int(bt.getRevision())
if last_bt[0] < revision and bt.getInstallationState() != 'deleted':
last_bt = revision, bt
if last_bt[1] is None:
return RESPONSE.notFoundError(title)
RESPONSE.setHeader('Content-type', 'application/data')
RESPONSE.setHeader('Content-Disposition',
'inline;filename=%s-%s.zexp' % (title, last_bt[0]))
if REQUEST['REQUEST_METHOD'] == 'GET':
bt = last_bt[1]
if bt.getBuildingState() != 'built':
bt.build()
return self.aq_parent.manage_exportObject(bt.getId(), download=1)
return asRepository().__of__(self)
security.declareProtected(Permissions.ManagePortal,
'getDefaultBusinessTemplateDownloadURL')
......@@ -412,7 +434,7 @@ class TemplateTool (BaseTool):
name = os.path.normpath(url)
if urltype and urltype != 'file':
if '/manage_exportObject?' in url:
if '/portal_templates/asRepository/' in url:
# In this case, the downloaded BT is already built.
bt = self._p_jar.importFile(urlopen(url))
bt.id = id
......
......@@ -9,6 +9,7 @@ __version__ = '0.3.0'
import base64
import errno
import httplib
import md5
import os
import random
......@@ -17,10 +18,10 @@ import socket
import sys
import time
import traceback
import urllib
from cStringIO import StringIO
from cPickle import dumps
from glob import glob
from urllib import urlopen
from warnings import warn
from ZTUtils import make_query
......@@ -398,20 +399,33 @@ class ERP5TypeTestCase(backportUnittest.TestCase, PortalTestCase):
bt5_path = os.path.join(os.environ['INSTANCE_HOME'], 'bt5')
bt5_path_list = bt5_path, os.path.join(bt5_path, '*')
def search(path, template):
urltype, url = urllib.splittype(path + '/' + template)
if urltype == 'http':
host, selector = urllib.splithost(url)
user_passwd, host = urllib.splituser(host)
host = urllib.unquote(host)
h = httplib.HTTP(host)
h.putrequest('HEAD', selector)
h.putheader('Host', host)
if user_passwd:
h.putheader('Authorization',
'Basic %s' % base64.b64encode(user_passwd).strip())
h.endheaders()
errcode, errmsg, headers = h.getreply()
if errcode == 200:
return urltype + ':' + url
else:
path_list = glob(os.path.join(path, template))
if path_list:
return path_list[0]
not_found_list = []
new_template_list = []
for template in template_list:
id = template.split('/')[-1]
for path in bt5_path_list:
if path.endswith('/portal_templates'):
bt_id = urlopen('%s/getLastBusinessTemplateId?title=%s'
% (path, template)).read()
path = bt_id and '%s/manage_exportObject?%s' % (path,
make_query(id=bt_id, download=1, to_xml=0))
else:
path = os.path.join(path, template)
path_list = glob(path) + glob(path + '.bt5')
path = path_list and path_list[0]
path = search(path, template) or search(path, template + '.bt5')
if path:
break
else:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment