Commit 4cf40e3f authored by Arnaud Fontaine's avatar Arnaud Fontaine

Add Business Template action to import Document and Extensions automatically...

Add Business Template action to import Document and Extensions automatically after giving the version.

Migration is now performed at Business Template level as it makes more
sense rather than on Component Tool which would require specifying the
target Business Template to update Document Template Item and
Extension Template Item.
parent b53f29a3
......@@ -5741,6 +5741,61 @@ Business Template is a set of definitions, such as skins, portal types and categ
setattr(self, 'template_portal_type_base_category', ())
return
security.declareProtected(Permissions.ModifyPortalContent,
'migrateAllComponentFromFilesystem')
def migrateAllComponentFromFilesystem(self,
version_priority,
erase_existing=False,
**kw):
component_tool = self.getPortalObject().portal_components
failed_import_dict = {}
# XXX-arnau: dirty because of copy/paste but will be refactor
# later with Products anyway...
from Products.ERP5Type.Core.DocumentComponent import DocumentComponent
document_id_list = self.getTemplateDocumentIdList()
for i, reference in enumerate(document_id_list):
try:
obj = DocumentComponent.importFromFilesystem(component_tool,
reference,
version_priority,
erase_existing)
except Exception, e:
failed_import_dict[reference] = str(e)
else:
document_id_list[i] = obj.getId()
self.setTemplateDocumentIdList(document_id_list)
from Products.ERP5Type.Core.ExtensionComponent import ExtensionComponent
extension_id_list = self.getTemplateExtensionIdList()
for i, reference in enumerate(extension_id_list):
try:
obj = ExtensionComponent.importFromFilesystem(component_tool,
reference,
version_priority,
erase_existing)
except Exception, e:
failed_import_dict[reference] = str(e)
else:
extension_id_list[i] = obj.getId()
self.setTemplateExtensionIdList(extension_id_list)
if failed_import_dict:
failed_import_formatted_list = []
for name, error in failed_import_dict.iteritems():
failed_import_formatted_list.append("%s (%s)" % (name, error))
message = "The following component could not be imported: %s" % \
', '.join(failed_import_formatted_list)
else:
message = "All components were successfully imported " \
"from filesystem to ZODB."
return self.Base_redirect('view',
keep_items={'portal_status_message': message})
# Block acquisition on all _item_name_list properties by setting
# a default class value to None
for key in BusinessTemplate._item_name_list:
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>migrate_component_from_filesystem</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>Add portal content</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Action Information</string> </value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Migrate Components From Filesystem</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/BusinessTemplate_viewMigrateAllComponentFromFilesystemDialog</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>template_document_id_list = context.getTemplateDocumentIdList()\n
template_extension_id_list = context.getTemplateExtensionIdList()\n
if not (template_document_id_list or template_extension_id_list):\n
return []\n
\n
migrated_component_id_list = template_document_id_list + template_extension_id_list\n
portal = context.getPortalObject()\n
component_tool = portal.portal_components\n
\n
from Products.ERP5Type.Document import newTempBase\n
def addLineListByType(id_list, destination_portal_type, line_list):\n
for component_id in id_list:\n
if getattr(component_tool, component_id, None) is not None:\n
continue\n
\n
line = newTempBase(context,\n
\'tmp_migrate_%s_%s\' % (destination_portal_type, component_id),\n
uid=component_id,\n
name=component_id,\n
destination_portal_type=destination_portal_type)\n
\n
line_list.append(line)\n
\n
line_list = []\n
addLineListByType(template_document_id_list, \'Document Component\', line_list)\n
addLineListByType(template_extension_id_list, \'Extension Component\', line_list)\n
return line_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>*args, **kwargs</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>BusinessTemplate_getComponentMigratedFromFilesystemList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5Form" module="Products.ERP5Form.Form"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>migrateAllComponentFromFilesystem</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_version_priority</string>
<string>my_erase_existing</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>BusinessTemplate_viewMigrateAllComponentFromFilesystemDialog</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>BusinessTemplate_viewMigrateAllComponentFromFilesystem</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_dialog</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Migrate Components from filesystem to ZODB</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_erase_existing</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_checkbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Erase Existing</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>first_item</string>
<string>items</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_version_priority</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>items</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_list_field</string> </value>
</item>
<item>
<key> <string>first_item</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>items</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Version</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: [(v, v) for v in here.getPortalObject().getVersionPriority()]</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
2012-02-20 arnaud.fontaine
* Add Business Template action to import Document and Extensions automatically after giving the version.
2012-02-14 arnaud.fontaine
* Add component_interaction_workflow to Component Tool.
......
41002
\ No newline at end of file
41003
\ No newline at end of file
......@@ -29,6 +29,7 @@ Business Template | export
Business Template | get_portal_type_properties
Business Template | guess_portal_types
Business Template | jump_trash_bin
Business Template | migrate_component_from_filesystem
Business Template | save
Business Template | unittest_run
Business Template | view
......
......@@ -7063,7 +7063,8 @@ class TestDocumentTemplateItem(BusinessTemplateMixin):
document_object = self.importFromFilesystem(
component_tool,
os.path.join(sequence['document_path']))
sequence['document_title'],
'erp5')
sequence.edit(document_id=document_object.getId())
......
......@@ -215,30 +215,6 @@ class Component(Base):
def _getFilesystemPath():
raise NotImplementedError
security.declareProtected(Permissions.ModifyPortalContent,
'importAllFromFilesystem')
@classmethod
def importAllFromFilesystem(cls, context, erase_existing=False):
"""
Try to import all Components and returns error as a dict if any
"""
import os.path
path_pattern = "%s%s*.py" % (cls._getFilesystemPath(), os.path.sep)
LOG("ERP5Type.Core.Component", INFO, "Importing from %s" % path_pattern)
import glob
failed_import_dict = {}
for path in glob.iglob(path_pattern):
try:
cls.importFromFilesystem(context, path, erase_existing)
except Exception, e:
failed_import_dict[path] = str(e)
else:
LOG("ERP5Type.Core.Component", INFO, "Imported %s" % path)
return failed_import_dict
@staticmethod
def _getDynamicModuleNamespace():
raise NotImplementedError
......@@ -246,22 +222,25 @@ class Component(Base):
security.declareProtected(Permissions.ModifyPortalContent,
'importFromFilesystem')
@classmethod
def importFromFilesystem(cls, context, path, erase_existing=False):
def importFromFilesystem(cls, context, reference, version,
erase_existing=False):
"""
Import a Component from the given path into ZODB after checking that the
source code is valid
"""
import os.path
class_name = os.path.basename(path).replace('.py', '')
id = '%s.%s' % (cls._getDynamicModuleNamespace(), class_name)
object_id = '%s.%s.%s' % (cls._getDynamicModuleNamespace(), version,
reference)
# XXX-arnau: not efficient at all
if id in context:
obj = context._getOb(object_id, None)
if obj is not None:
if not erase_existing:
return
obj.validate()
return obj
context.deleteContent(id)
context.deleteContent(object_id)
import os.path
path = os.path.join(cls._getFilesystemPath(), reference + '.py')
with open(path) as f:
source_code = f.read()
......@@ -269,8 +248,9 @@ class Component(Base):
namespace_dict = {}
exec source_code in namespace_dict
new_component = context.newContent(id=id,
reference=class_name,
new_component = context.newContent(id=object_id,
reference=reference,
version=version,
text_content=source_code,
portal_type=cls.portal_type)
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2011 Nexedi SA and Contributors. All Rights Reserved.
# Jean-Paul Smets <jp@nexedi.com>
# Copyright (c) 2011-2012 Nexedi SA and Contributors. All Rights Reserved.
# Jean-Paul Smets <jp@nexedi.com>
# Arnaud Fontaine <arnaud.fontaine@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
......@@ -43,9 +44,9 @@ from zLOG import LOG, INFO, WARNING
_last_sync = -1
class ComponentTool(BaseTool):
"""
This tool provides methods to load the the different types
of components of the ERP5 framework: Document classes, interfaces,
mixin classes, fields, accessors, etc.
This tool provides methods to load the the different types of
components of the ERP5 framework: Document classes, interfaces,
mixin classes, fields, accessors, etc.
"""
id = "portal_components"
meta_type = "ERP5 Component Tool"
......@@ -129,43 +130,3 @@ class ComponentTool(BaseTool):
if key not in tv:
tv[key] = None
transaction.get().addBeforeCommitHook(self.reset)
security.declareProtected(Permissions.ModifyPortalContent,
'createAllComponentFromFilesystem')
def createAllComponentFromFilesystem(self, erase_existing=False,
REQUEST=None):
"""
XXX-arnau: only bt5 Extensions and Documents for now
"""
portal = self.getPortalObject()
import erp5.portal_type
type_tool = portal.portal_types
failed_import_dict = {}
for content_portal_type in getattr(type_tool,
self.portal_type).getTypeAllowedContentTypeList():
try:
failed_import_dict.update(
getattr(erp5.portal_type,
content_portal_type).importAllFromFilesystem(self,
erase_existing=erase_existing))
# XXX-arnau: NotImplementedErrror only until everything has been
# implemented
except (NotImplementedError, AttributeError):
LOG("ERP5Type.Tool.ComponentTool", WARNING, "Could not import %ss" % \
content_portal_type)
if REQUEST:
if failed_import_dict:
failed_import_formatted_list = []
for name, error in failed_import_dict.iteritems():
failed_import_formatted_list.append("%s (%s)" % (name, error))
message = "The following component could not be imported: %s" % \
', '.join(failed_import_formatted_list)
else:
message = "All components were successfully imported " \
"from filesystem to ZODB."
return self.Base_redirect('view',
keep_items={'portal_status_message': message})
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