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 ...@@ -33,7 +33,7 @@ import os
import shutil import shutil
import sys import sys
from Acquisition import Implicit from Acquisition import Implicit, Explicit
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Globals import InitializeClass, DTMLFile, PersistentMapping from Products.ERP5Type.Globals import InitializeClass, DTMLFile, PersistentMapping
from Products.ERP5Type.DiffUtils import DiffFile from Products.ERP5Type.DiffUtils import DiffFile
...@@ -144,16 +144,38 @@ class TemplateTool (BaseTool): ...@@ -144,16 +144,38 @@ class TemplateTool (BaseTool):
built_bts.append(bt) built_bts.append(bt)
return built_bts return built_bts
def getLastBusinessTemplateId(self, title): @property
"""Get the id of the business template with the highest revision number 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 last_bt = None, None
for bt in self.contentValues(portal_type='Business Template'): for bt in self.aq_parent.searchFolder(title=title):
if bt.getTitle() == title and bt.getBuildingState() == 'built': bt = bt.getObject()
revision = bt.getRevision() revision = int(bt.getRevision())
if last_bt[0] < revision and bt.getInstallationState() != 'deleted': if last_bt[0] < revision and bt.getInstallationState() != 'deleted':
last_bt = revision, bt.getId() last_bt = revision, bt
return last_bt[1] 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, security.declareProtected(Permissions.ManagePortal,
'getDefaultBusinessTemplateDownloadURL') 'getDefaultBusinessTemplateDownloadURL')
...@@ -412,7 +434,7 @@ class TemplateTool (BaseTool): ...@@ -412,7 +434,7 @@ class TemplateTool (BaseTool):
name = os.path.normpath(url) name = os.path.normpath(url)
if urltype and urltype != 'file': 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. # In this case, the downloaded BT is already built.
bt = self._p_jar.importFile(urlopen(url)) bt = self._p_jar.importFile(urlopen(url))
bt.id = id bt.id = id
......
...@@ -9,6 +9,7 @@ __version__ = '0.3.0' ...@@ -9,6 +9,7 @@ __version__ = '0.3.0'
import base64 import base64
import errno import errno
import httplib
import md5 import md5
import os import os
import random import random
...@@ -17,10 +18,10 @@ import socket ...@@ -17,10 +18,10 @@ import socket
import sys import sys
import time import time
import traceback import traceback
import urllib
from cStringIO import StringIO from cStringIO import StringIO
from cPickle import dumps from cPickle import dumps
from glob import glob from glob import glob
from urllib import urlopen
from warnings import warn from warnings import warn
from ZTUtils import make_query from ZTUtils import make_query
...@@ -398,20 +399,33 @@ class ERP5TypeTestCase(backportUnittest.TestCase, PortalTestCase): ...@@ -398,20 +399,33 @@ class ERP5TypeTestCase(backportUnittest.TestCase, PortalTestCase):
bt5_path = os.path.join(os.environ['INSTANCE_HOME'], 'bt5') bt5_path = os.path.join(os.environ['INSTANCE_HOME'], 'bt5')
bt5_path_list = bt5_path, os.path.join(bt5_path, '*') 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 = [] not_found_list = []
new_template_list = [] new_template_list = []
for template in template_list: for template in template_list:
id = template.split('/')[-1] id = template.split('/')[-1]
for path in bt5_path_list: for path in bt5_path_list:
if path.endswith('/portal_templates'): path = search(path, template) or search(path, template + '.bt5')
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]
if path: if path:
break break
else: 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