From a82324ca88708dfdfb77587ec32cefc0b709a7f1 Mon Sep 17 00:00:00 2001 From: Julien Muchembled <jm@nexedi.com> Date: Fri, 5 Sep 2014 14:59:03 +0200 Subject: [PATCH] BT: read metadata (bt/* files) through BusinessTemplateArchive --- product/ERP5/Document/BusinessTemplate.py | 32 +++++++-- product/ERP5/Tool/TemplateTool.py | 87 +---------------------- 2 files changed, 30 insertions(+), 89 deletions(-) diff --git a/product/ERP5/Document/BusinessTemplate.py b/product/ERP5/Document/BusinessTemplate.py index 0394ae3647..932b0e4aa4 100644 --- a/product/ERP5/Document/BusinessTemplate.py +++ b/product/ERP5/Document/BusinessTemplate.py @@ -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. diff --git a/product/ERP5/Tool/TemplateTool.py b/product/ERP5/Tool/TemplateTool.py index bb77d2732f..1be6efdb76 100644 --- a/product/ERP5/Tool/TemplateTool.py +++ b/product/ERP5/Tool/TemplateTool.py @@ -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() -- 2.30.9