Commit a82324ca by Julien Muchembled

BT: read metadata (bt/* files) through BusinessTemplateArchive

1 parent b9483c71
......@@ -76,7 +76,6 @@ customImporters={
from zLOG import LOG, WARNING, INFO
from warnings import warn
from gzip import GzipFile
from lxml.etree import parse
from xml.sax.saxutils import escape
from Products.CMFCore.Expression import Expression
......@@ -360,7 +359,7 @@ class BusinessTemplateFolder(BusinessTemplateArchive):
d.setdefault(klass, []).append(f)
self.file_list_dict = d
def importFiles(self, item, **kw):
def importFiles(self, item):
"""
Import file from a local folder
"""
......@@ -415,7 +414,7 @@ class BusinessTemplateTarball(BusinessTemplateArchive):
return self.fobj
def _initImport(self, file, **kw):
self.tar = tarfile.TarFile(fileobj=StringIO(GzipFile(fileobj=file).read()))
self.tar = tarfile.open(file, 'r:gz')
self.item_dict = {}
setdefault = self.item_dict.setdefault
for info in self.tar.getmembers():
......@@ -428,7 +427,7 @@ class BusinessTemplateTarball(BusinessTemplateArchive):
file_name = unquote(file_name)
setdefault(path[1], []).append((file_name, info))
def importFiles(self, item, **kw):
def importFiles(self, item):
"""
Import all file from the archive to the site
"""
......@@ -535,7 +534,7 @@ class BaseTemplateItem(Implicit, Persistent):
return self._objects.keys()
def importFile(self, bta, **kw):
bta.importFiles(item=self)
bta.importFiles(self)
def removeProperties(self, obj, export, keep_workflow_history=False):
"""
......@@ -4704,6 +4703,13 @@ class LocalRolesTemplateItem(BaseTemplateItem):
delattr(obj, '__ac_local_roles_group_id_dict__')
obj.reindexObject()
class bt(dict):
"""Fake 'bt' item to read bt/* files through BusinessTemplateArchive"""
def _importFile(self, file_name, file):
self[file_name] = file.read()
class BusinessTemplate(XMLObject):
"""
A business template allows to construct ERP5 modules
......@@ -5615,6 +5621,22 @@ Business Template is a set of definitions, such as skins, portal types and categ
else:
bta = BusinessTemplateTarball(importing=1, file=file)
bt_item = bt()
bta.importFiles(bt_item)
prop_dict = {}
for prop in self.propertyMap():
pid = prop['id']
if pid != 'id':
prop_type = prop['type']
value = bt_item.get(pid)
if prop_type in ('text', 'string'):
prop_dict[pid] = value or ''
elif prop_type in ('int', 'boolean'):
prop_dict[pid] = value or 0
elif prop_type in ('lines', 'tokens'):
prop_dict[pid[:-5]] = (value or '').splitlines()
self._edit(**prop_dict)
self.storeTemplateItemData()
# Create temporary modules/classes for classes defined by this BT.
......
......@@ -33,7 +33,6 @@ from App.config import getConfiguration
import os
import shutil
import sys
import tarfile
from Acquisition import Implicit, Explicit
from AccessControl import ClassSecurityInfo
......@@ -56,7 +55,6 @@ from xml.dom.minidom import parse
from xml.parsers.expat import ExpatError
import struct
import cPickle
import posixpath
from base64 import b64encode, b64decode
from Products.ERP5Type.Message import translateString
from zLOG import LOG, INFO, WARNING
......@@ -298,58 +296,6 @@ class TemplateTool (BaseTool):
self.deleteContent(id)
self._importObjectFromFile(StringIO(export_string), id=id)
def _importBT(self, path=None, id=id):
"""
Import template from a temp file (as uploaded by the user)
"""
with open(path, 'rb') as file:
# read magic key to determine wich kind of bt we use
file.seek(0)
magic = file.read(5)
if magic == '<?xml': # old version
self._importObjectFromFile(path, id=id)
bt = self[id]
bt.id = id # Make sure id is consistent
bt.setProperty('template_format_version', 0, type='int')
else: # new version
# XXX: should really check for a magic and offer a falback if it
# doens't correspond to anything handled.
tar = tarfile.open(path, 'r:gz')
dir_name = tar.members[0].name.split(posixpath.sep, 1)[0]
try:
# create bt object
bt = self.newContent(portal_type='Business Template', id=id)
prop_dict = {}
for prop in bt.propertyMap():
prop_type = prop['type']
pid = prop['id']
prop_path = posixpath.join(dir_name, 'bt', pid)
try:
info = tar.getmember(prop_path)
value = tar.extractfile(info).read()
except KeyError:
value = None
if value is 'None':
# At export time, we used to export non-existent properties:
# str(obj.getProperty('non-existing')) == 'None'
# Discard them
continue
if prop_type in ('text', 'string'):
prop_dict[pid] = value or ''
elif prop_type in ('int', 'boolean'):
prop_dict[pid] = value or 0
elif prop_type in ('lines', 'tokens'):
prop_dict[pid[:-5]] = (value or '').splitlines()
prop_dict.pop('id', '')
bt.edit(**prop_dict)
# import all other files from bt
with open(path, 'rb') as fobj:
bt.importFile(file=fobj)
finally:
tar.close()
return bt
security.declareProtected( Permissions.ManagePortal, 'manage_download' )
def manage_download(self, url, id=None, REQUEST=None):
"""The management interface for download.
......@@ -368,6 +314,7 @@ class TemplateTool (BaseTool):
def _download_local(self, path, bt_id):
"""Download Business Template from local directory or file
"""
bt = self.newContent(portal_type='Business Template', id=bt_id)
if os.path.isdir(os.path.normpath(path)):
path = os.path.normpath(path)
def callback(file_list, directory, files):
......@@ -385,39 +332,11 @@ class TemplateTool (BaseTool):
os.path.walk(path, callback, file_list)
file_list.sort()
# import bt object
bt = self.newContent(portal_type='Business Template', id=bt_id)
bt_path = os.path.join(path, 'bt')
# import properties
prop_dict = {}
for prop in bt.propertyMap():
prop_type = prop['type']
pid = prop['id']
prop_path = os.path.join('.', bt_path, pid)
if not os.path.exists(prop_path):
value = None
else:
with open(prop_path, 'rb') as f:
value = f.read()
if value is 'None':
# At export time, we used to export non-existent properties:
# str(obj.getProperty('non-existing')) == 'None'
# Discard them
value = None
if prop_type in ('text', 'string'):
prop_dict[pid] = value or ''
elif prop_type in ('int', 'boolean'):
prop_dict[pid] = value or 0
elif prop_type in ('lines', 'tokens'):
prop_dict[pid[:-5]] = (value or '').splitlines()
prop_dict.pop('id', '')
bt.edit(**prop_dict)
# import all others objects
bt.importFile(dir=True, file=file_list, root_path=path)
return bt
else:
# this should be a file
return self._importBT(path, bt_id)
bt.importFile(file=path)
return bt
def _download_url(self, url, bt_id):
tempid, temppath = mkstemp()
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!