Commit 7d4cb51b authored by Jérome Perrin's avatar Jérome Perrin

use pysvn in TemplateTool.download to download from svn repositories directly



git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@17505 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent ca8991d7
...@@ -30,6 +30,7 @@ from webdav.client import Resource ...@@ -30,6 +30,7 @@ from webdav.client import Resource
from App.config import getConfiguration from App.config import getConfiguration
import os, tarfile import os, tarfile
import shutil
from Acquisition import Implicit from Acquisition import Implicit
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
...@@ -51,11 +52,11 @@ try: ...@@ -51,11 +52,11 @@ try:
except ImportError: except ImportError:
from base64 import encodestring as b64encode, decodestring as b64decode from base64 import encodestring as b64encode, decodestring as b64decode
from Products.ERP5Type.Message import Message from Products.ERP5Type.Message import Message
from zLOG import LOG, INFO
N_ = lambda msgid, **kw: Message('ui', msgid, **kw) N_ = lambda msgid, **kw: Message('ui', msgid, **kw)
WIN = False WIN = os.name == 'nt'
if os.name == 'nt':
WIN = True
class BusinessTemplateUnknownError(Exception): class BusinessTemplateUnknownError(Exception):
""" Exception raised when the business template """ Exception raised when the business template
...@@ -322,30 +323,11 @@ class TemplateTool (BaseTool): ...@@ -322,30 +323,11 @@ class TemplateTool (BaseTool):
REQUEST.RESPONSE.redirect("%s?portal_status_message=%s" REQUEST.RESPONSE.redirect("%s?portal_status_message=%s"
% (ret_url, psm)) % (ret_url, psm))
security.declareProtected( 'Import/Export objects', 'download' ) def _download_local(self, path, bt_id):
def download(self, url, id=None, REQUEST=None): """Download Business Template from local directory or file
""" """
Download Business Template from url, can be file or local directory if os.path.isdir(os.path.normpath(path)):
""" path = os.path.normpath(path)
# For backward compatibility: If REQUEST is passed, it is likely that we
# come from the management interface.
if REQUEST is not None:
return self.manage_download(url, id=id, REQUEST=REQUEST)
if id is None:
id = self.generateNewId()
urltype, name = splittype(url)
# Windows compatibility
if WIN:
if os.path.isdir(os.path.normpath(url)):
name = os.path.normpath(url)
elif os.path.isfile(os.path.normpath(url)):
url = 'file:///%s' % os.path.normpath(url)
# new version of business template in plain format (folder)
if os.path.isdir(os.path.normpath(name)):
name = os.path.normpath(name)
def callback(file_list, directory, files): def callback(file_list, directory, files):
for excluded_directory in ('CVS', '.svn'): for excluded_directory in ('CVS', '.svn'):
try: try:
...@@ -358,12 +340,11 @@ class TemplateTool (BaseTool): ...@@ -358,12 +340,11 @@ class TemplateTool (BaseTool):
file_list.append(absolute_path) file_list.append(absolute_path)
file_list = [] file_list = []
os.path.walk(name, callback, file_list) os.path.walk(path, callback, file_list)
file_list.sort() file_list.sort()
# import bt object # import bt object
bt = self.newContent(portal_type='Business Template', id=id) bt = self.newContent(portal_type='Business Template', id=bt_id)
id = bt.getId() bt_path = os.path.join(path, 'bt')
bt_path = os.path.join(name, 'bt')
# import properties # import properties
prop_dict = {} prop_dict = {}
...@@ -381,19 +362,63 @@ class TemplateTool (BaseTool): ...@@ -381,19 +362,63 @@ class TemplateTool (BaseTool):
prop_dict.pop('id', '') prop_dict.pop('id', '')
bt.edit(**prop_dict) bt.edit(**prop_dict)
# import all others objects # import all others objects
bt.importFile(dir=1, file=file_list, root_path=name) bt.importFile(dir=1, file=file_list, root_path=path)
return bt
else: else:
# this should be a file
return self._importBT(path, bt_id)
def _download_url(self, url, bt_id):
tempid, temppath = mkstemp() tempid, temppath = mkstemp()
try: try:
os.close(tempid) # Close the opened fd as soon as possible. os.close(tempid) # Close the opened fd as soon as possible.
file, headers = urlretrieve(url, temppath) file_path, headers = urlretrieve(url, temppath)
if id is None: if re.search(r'<title>Revision \d+:', open(file_path, 'r').read()):
id = str(self.generateNewId()) # this looks like a subversion repository, try to check it out
bt = self._importBT(temppath, id) LOG('ERP5', INFO, 'TemplateTool doing a svn checkout of %s' % url)
return self._download_svn(url, bt_id)
return self._download_local(file_path, bt_id)
finally: finally:
os.remove(temppath) os.remove(temppath)
def _download_svn(self, url, bt_id):
svn_checkout_tmp_dir = mkdtemp()
svn_checkout_dir = os.path.join(svn_checkout_tmp_dir, 'bt')
try:
import pysvn
pysvn.Client().export(url, svn_checkout_dir)
return self._download_local(svn_checkout_dir, bt_id)
finally:
shutil.rmtree(svn_checkout_tmp_dir)
security.declareProtected( 'Import/Export objects', 'download' )
def download(self, url, id=None, REQUEST=None):
"""
Download Business Template from url, can be file or local directory
"""
# For backward compatibility: If REQUEST is passed, it is likely that we
# come from the management interface.
if REQUEST is not None:
return self.manage_download(url, id=id, REQUEST=REQUEST)
if id is None:
id = self.generateNewId()
urltype, name = splittype(url)
# Windows compatibility
if WIN:
if os.path.isdir(os.path.normpath(url)) or \
os.path.isfile(os.path.normpath(url)):
urltype = 'file'
name = os.path.normpath(url)
if urltype and urltype != 'file':
bt = self._download_url(url, id)
else:
bt = self._download_local(name, id)
bt.build(no_action=1) bt.build(no_action=1)
bt.reindexObject()
return bt return bt
def importFile(self, import_file=None, id=None, REQUEST=None, def importFile(self, import_file=None, id=None, REQUEST=None,
......
...@@ -2091,6 +2091,7 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): ...@@ -2091,6 +2091,7 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
bt_title = pathname2url(template.getTitle()) bt_title = pathname2url(template.getTitle())
template_path = os.path.join(cfg.instancehome, 'tests', '%s' % (bt_title,)) template_path = os.path.join(cfg.instancehome, 'tests', '%s' % (bt_title,))
# remove previous version of bt it exists # remove previous version of bt it exists
if os.path.exists(template_path):
shutil.rmtree(template_path) shutil.rmtree(template_path)
template.export(path=template_path, local=1) template.export(path=template_path, local=1)
sequence.edit(template_path=template_path) sequence.edit(template_path=template_path)
...@@ -4421,6 +4422,22 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): ...@@ -4421,6 +4422,22 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor):
bt5.setDependencyList(['not_exists (= 1.0)']) bt5.setDependencyList(['not_exists (= 1.0)'])
self.assertRaises(BusinessTemplateMissingDependency, bt5.checkDependencies) self.assertRaises(BusinessTemplateMissingDependency, bt5.checkDependencies)
def test_download_http(self):
test_web = self.portal.portal_templates.download(
'http://www.erp5.org/dists/snapshot/test_bt5/test_web.bt5')
self.assertEquals(test_web.getPortalType(), 'Business Template')
self.assertEquals(test_web.getTitle(), 'test_web')
self.assertTrue(test_web.getRevision())
def test_download_svn(self):
# if the page looks like a svn repository, template tool will use pysvn to
# get the bt5.
test_web = self.portal.portal_templates.download(
'https://svn.erp5.org/repos/public/erp5/trunk/bt5/test_web')
self.assertEquals(test_web.getPortalType(), 'Business Template')
self.assertEquals(test_web.getTitle(), 'test_web')
self.assertTrue(test_web.getRevision())
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
......
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