Commit 9e4c0be0 authored by Rafael Monnerat's avatar Rafael Monnerat

Refactor build process to use activities and move bt5 installation to StandardBT5ConfiguratorItem.

This changes permit each configurator workflow install his own bt5 dependencies for the build process, instead require install the business templates in advance.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@44325 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent bf4856f9
...@@ -74,7 +74,7 @@ class BusinessConfiguration(Item): ...@@ -74,7 +74,7 @@ class BusinessConfiguration(Item):
def isInitialConfigurationState(self): def isInitialConfigurationState(self):
""" Check if the Business Configuration is on initial workflow state """ Check if the Business Configuration is on initial workflow state
""" """
workflow = self.getResourceValue() workflow = self.getResourceValue()
if workflow is not None: if workflow is not None:
return self.getCurrentState() == workflow.getSource() return self.getCurrentState() == workflow.getSource()
return None return None
...@@ -103,7 +103,7 @@ class BusinessConfiguration(Item): ...@@ -103,7 +103,7 @@ class BusinessConfiguration(Item):
raise TypeError, "More than one transition is available." raise TypeError, "More than one transition is available."
elif transition_number == 0: elif transition_number == 0:
return None return None
return transition_list[0] return transition_list[0]
security.declarePrivate('_executeTransition') security.declarePrivate('_executeTransition')
...@@ -111,7 +111,6 @@ class BusinessConfiguration(Item): ...@@ -111,7 +111,6 @@ class BusinessConfiguration(Item):
form_kw=None, form_kw=None,
request_kw=None): request_kw=None):
""" Execute the transition. """ """ Execute the transition. """
root_conf_save = None
if form_kw is None: if form_kw is None:
form_kw = {} form_kw = {}
current_state = self.getCurrentStateValue() current_state = self.getCurrentStateValue()
...@@ -126,7 +125,7 @@ class BusinessConfiguration(Item): ...@@ -126,7 +125,7 @@ class BusinessConfiguration(Item):
else: else:
## we have already created configuration save for this state ## we have already created configuration save for this state
## so remove from it already existing configuration items ## so remove from it already existing configuration items
if configuration_save != self: ## don't delete ourselves if configuration_save != self: # don't delete ourselves
existing_conf_items = configuration_save.objectIds() existing_conf_items = configuration_save.objectIds()
existing_conf_items = map(None, existing_conf_items) existing_conf_items = map(None, existing_conf_items)
configuration_save.manage_delObjects(existing_conf_items) configuration_save.manage_delObjects(existing_conf_items)
...@@ -192,10 +191,10 @@ class BusinessConfiguration(Item): ...@@ -192,10 +191,10 @@ class BusinessConfiguration(Item):
template_html = form() template_html = form()
for form_counter in range(0, forms_number): for form_counter in range(0, forms_number):
form_html = self.Base_mainConfiguratorFormTemplate( form_html = self.Base_mainConfiguratorFormTemplate(
current_form_number = form_counter + 1, current_form_number=form_counter + 1,
max_form_numbers = forms_number, max_form_numbers=forms_number,
form_title = form.title, form_title=form.title,
form_html = template_html) form_html=template_html)
html_forms.append(form_html) html_forms.append(form_html)
else: else:
if not isMultiEntryTransition: if not isMultiEntryTransition:
...@@ -211,18 +210,18 @@ class BusinessConfiguration(Item): ...@@ -211,18 +210,18 @@ class BusinessConfiguration(Item):
for form_counter in range(0, forms_number): for form_counter in range(0, forms_number):
## fill REQUEST with data as it will be used to render form ## fill REQUEST with data as it will be used to render form
for field in field_ids: for field in field_ids:
field_value = getattr(context, "field_%s" %field.id, None) field_value = getattr(context, "field_%s" % field.id, None)
if field_value is not None and len(field_value) > form_counter: if field_value is not None and len(field_value) > form_counter:
field_value = field_value[form_counter] field_value = field_value[form_counter]
self.REQUEST.set(field.id, field_value) self.REQUEST.set(field.id, field_value)
else: else:
self.REQUEST.set(field.id, '') self.REQUEST.set(field.id, '')
form_html = self.Base_mainConfiguratorFormTemplate( \ form_html = self.Base_mainConfiguratorFormTemplate( \
current_form_number = form_counter +1, \ current_form_number=form_counter + 1,\
max_form_numbers = forms_number, \ max_form_numbers = forms_number, \
form_html = getattr(context, form_id)()) form_html = getattr(context, form_id)())
html_forms.append(form_html) html_forms.append(form_html)
if html_forms!=[]: if html_forms != []:
html = "\n".join(html_forms) html = "\n".join(html_forms)
title = form.title title = form.title
return html, title return html, title
...@@ -285,7 +284,8 @@ class BusinessConfiguration(Item): ...@@ -285,7 +284,8 @@ class BusinessConfiguration(Item):
for wh in workflow_history: for wh in workflow_history:
wh_state = self.unrestrictedTraverse(wh['current_state']) wh_state = self.unrestrictedTraverse(wh['current_state'])
for wh_transition in wh_state.getAvailableTransitionList(self): for wh_transition in wh_state.getAvailableTransitionList(self):
if wh_transition.getTransitionFormId() is not None and wh_transition!=transition: if wh_transition.getTransitionFormId() is not None and \
wh_transition != transition:
return True return True
return False return False
...@@ -353,7 +353,6 @@ class BusinessConfiguration(Item): ...@@ -353,7 +353,6 @@ class BusinessConfiguration(Item):
Get list of built business templates in a Wizard format. Get list of built business templates in a Wizard format.
""" """
bt5_file_list = [] bt5_file_list = []
portal = self.getPortalObject()
for bt_link in self.contentValues(portal_type="Link"): for bt_link in self.contentValues(portal_type="Link"):
bt5_item = dict(bt5_id = bt_link.getUrlString(), bt5_item = dict(bt5_id = bt_link.getUrlString(),
bt5_filedata = "") bt5_filedata = "")
...@@ -374,31 +373,24 @@ class BusinessConfiguration(Item): ...@@ -374,31 +373,24 @@ class BusinessConfiguration(Item):
This is the actual implementation which can be used from workflow This is the actual implementation which can be used from workflow
actions and Configurator requets actions and Configurator requets
""" """
bt5_file_list = [] kw = dict(tag="start")
start = time.time() start = time.time()
bc_id = self.getId()
LOG("CONFIGURATOR", INFO, LOG("CONFIGURATOR", INFO,
'Build process started for %s' % self.getRelativeUrl()) 'Build process started for %s' % self.getRelativeUrl())
conf_item_list = []
# build # build
for conf_save in self._getConfigurationStack(): for configuration_save in self._getConfigurationStack():
# XXX: check which items are configure-able # XXX: check which items are configure-able
conf_item_list = [x for x in conf_save.contentValues()] configuration_item_list = [x for x in configuration_save.contentValues()]
conf_item_list.sort(lambda x,y: cmp(x.getIntId(), y.getIntId())) configuration_item_list.sort(lambda x,y: cmp(x.getIntId(), y.getIntId()))
for conf_item in conf_item_list: for configurator_item in configuration_item_list:
conf_save_id = conf_save.getId() configurator_item.activate(**kw).buildItem(self.getRelativeUrl())
configuration_item_object = conf_item kw["after_tag"] = kw["tag"]
LOG('CONFIGURATOR', INFO, 'Building --> %s' % conf_item) kw["tag"] = "configurator_item_%s_%s" % (configurator_item.getId(),
start_build = time.time() configurator_item.getUid())
build_result = conf_item.build(self)
LOG('CONFIGURATOR', INFO, 'Built --> %s (%.02fs)' \
% (conf_item, time.time()-start_build))
# save list of generated or reused bt5 ids in bc
LOG('CONFIGURATOR', INFO, LOG('CONFIGURATOR', INFO,
'Build process started for %s ended after %.02fs' 'Build process started for %s ended after %.02fs' % (self.getRelativeUrl(),
%(self.getRelativeUrl(), time.time()-start)) time.time() - start))
return bt5_file_list
security.declareProtected(Permissions.ModifyPortalContent, 'resetBusinessConfiguration') security.declareProtected(Permissions.ModifyPortalContent, 'resetBusinessConfiguration')
def resetBusinessConfiguration(self): def resetBusinessConfiguration(self):
...@@ -429,35 +421,21 @@ class BusinessConfiguration(Item): ...@@ -429,35 +421,21 @@ class BusinessConfiguration(Item):
bt5_title_list.append(bt5.getTitle()) bt5_title_list.append(bt5.getTitle())
return bt5_title in bt5_title_list return bt5_title in bt5_title_list
def getPublicUrlForBT5Id(self, bt5_id):
""" Generate publicly accessible URL for business template """
portal = self.getPortalObject()
return portal.portal_templates.getBusinessTemplateUrl(None, bt5_id)
security.declareProtected(Permissions.ModifyPortalContent, 'installConfiguration') security.declareProtected(Permissions.ModifyPortalContent, 'installConfiguration')
def installConfiguration(self, execute_after_setup_script = 1): def installConfiguration(self, execute_after_setup_script = 1):
""" """
Install in remote instance already built list of business templates Install in remote instance already built list of business templates
which are saved in the Business Configuration. which are saved in the Business Configuration.
""" """
kw = dict(tag="start") kw = dict(tag="install_start")
bt5_file_list = []
portal = self.getPortalObject() portal = self.getPortalObject()
for bt_link in self.contentValues(portal_type="Link"):
portal.portal_templates.activate(**kw).updateBusinessTemplateFromUrl(
bt_link.getUrlString())
LOG("Business COnfiguration", INFO,
"Install %s to %s" % (bt_link.getUrlString(), self.getRelativeUrl()))
kw["after_tag"] = kw["tag"]
kw["tag"] = bt_link.getTitle()
for bt_file in self.contentValues(portal_type="File"): for bt_file in self.contentValues(portal_type="File"):
if bt_file.getTitle("").replace(".bt5", "") == self.getSpecialiseTitle(): # Only install business templates which are not the one created by
# Configuration.
if bt_file.getTitle("").replace(".bt5", "") != self.getSpecialiseTitle():
bt5_io = StringIO(str(bt_file.getData())) bt5_io = StringIO(str(bt_file.getData()))
# XXX FIXME (lucas): Why FAIL on the log message?
LOG("Business Configuration", INFO, LOG("Business Configuration", INFO,
"[FAIL] Import of bt5 file (%s - %s)" % \ "Import of bt5 file (%s - %s)" % \
(bt_file.getId(), bt_file.getTitle())) (bt_file.getId(), bt_file.getTitle()))
bc = portal.portal_templates.importFile(import_file=bt5_io, bc = portal.portal_templates.importFile(import_file=bt5_io,
...@@ -467,6 +445,7 @@ class BusinessConfiguration(Item): ...@@ -467,6 +445,7 @@ class BusinessConfiguration(Item):
kw["tag"] = bt_file.getTitle() kw["tag"] = bt_file.getTitle()
if execute_after_setup_script: if execute_after_setup_script:
kw["after_method_id"] = ["buildItem", 'recursiveReindexObject']
self.activate(**kw).ERP5Site_afterConfigurationSetup() self.activate(**kw).ERP5Site_afterConfigurationSetup()
LOG("Business Configuration", INFO, LOG("Business Configuration", INFO,
"After setup script called (force) for %s : %s" % "After setup script called (force) for %s : %s" %
......
...@@ -32,7 +32,7 @@ from AccessControl import ClassSecurityInfo ...@@ -32,7 +32,7 @@ from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, interfaces from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5Configurator.mixin.configurator_item import ConfiguratorItemMixin from Products.ERP5Configurator.mixin.configurator_item import ConfiguratorItemMixin
import transaction from zLOG import LOG, INFO
class StandardBT5ConfiguratorItem(ConfiguratorItemMixin, XMLObject): class StandardBT5ConfiguratorItem(ConfiguratorItemMixin, XMLObject):
""" This class will install standard ERP5 template from a repository to """ This class will install standard ERP5 template from a repository to
...@@ -61,51 +61,22 @@ class StandardBT5ConfiguratorItem(ConfiguratorItemMixin, XMLObject): ...@@ -61,51 +61,22 @@ class StandardBT5ConfiguratorItem(ConfiguratorItemMixin, XMLObject):
def build(self, business_configuration): def build(self, business_configuration):
bt5_id = self.getBt5Id() bt5_id = self.getBt5Id()
bt5_copy_id = '%s_copy' % bt5_id
portal = self.getPortalObject() portal = self.getPortalObject()
template_tool = getToolByName(portal, 'portal_templates') template_tool = getToolByName(portal, 'portal_templates')
## Is this standard template already gzipped? installed_bt_list = template_tool.getInstalledBusinessTemplateTitleList()
filename_bt5_id = '%s.bt5' % bt5_id filename_bt5_id = '%s.bt5' % bt5_id
if business_configuration.isStandardBT5(filename_bt5_id): if business_configuration.isStandardBT5(filename_bt5_id):
bt_url = business_configuration.getPublicUrlForBT5Id(filename_bt5_id) if bt5_id not in installed_bt_list:
bt_url = template_tool.getBusinessTemplateUrl(None, filename_bt5_id)
business_configuration.newContent(portal_type='Link', template_tool.updateBusinessTemplateFromUrl(bt_url)
url_string = bt_url, title = filename_bt5_id) LOG("StandardBT5ConfiguratorItem", INFO,
"Install %s for %s" % (bt_url, self.getRelativeUrl()))
else:
LOG("StandardBT5ConfiguratorItem", INFO,
"%s is already present. Ignore installation (%s)" \
% (bt5_id, self.getRelativeUrl()))
else: else:
## we need to make a copy of template to be able to export it raise ValueError("The business template %s was not found on available \
if not bt5_copy_id in template_tool.objectIds(): sources." % bt5_id)
bt5 = template_tool.getInstalledBusinessTemplate(bt5_id)
template_copy = template_tool.manage_copyObjects(ids=(bt5.getId(),))
new_id_list = template_tool.manage_pasteObjects(template_copy)
new_bt5_id = new_id_list[0]['new_id']
template_tool.manage_renameObject(new_bt5_id, bt5_copy_id)
## we are sure that we have this business template
self._current_bt_id = bt5_copy_id
return self.get_it_built(business_configuration)
def get_it_built(self, business_configuration):
portal = self.getPortalObject()
template_tool = getToolByName(portal, 'portal_templates')
bt5_obj = self._getCurrentBT(business_configuration)
if bt5_obj.getBuildingState() != 'built':
## build template so it can be exported
bt5_obj.edit()
bt5_obj.build()
# XXX Due a bug into Business Templates it is not possible build
# the business template and export when this have one
# ActionTemplateItem. This is a TEMPORARY CHANGE and it should be
# removed as soon as Business Template is FIXED.
transaction.savepoint(optimistic=True)
bt5_data = template_tool.export(bt5_obj)
business_configuration.newContent(portal_type='File',
title = '%s.bt5' % bt5_obj.getId(),
data = bt5_data)
def _getCurrentBT(self, business_configuration):
""" Return current bt5 file. """
portal = self.getPortalObject()
template_tool = portal.portal_templates
bt5_id = self._current_bt_id
bt5_obj = portal.portal_templates[bt5_id]
return bt5_obj
...@@ -27,24 +27,40 @@ ...@@ -27,24 +27,40 @@
# #
############################################################################## ##############################################################################
from zLOG import LOG, INFO
import time
class ConfiguratorItemMixin: class ConfiguratorItemMixin:
""" This is the base class for all configurator item. """ """ This is the base class for all configurator item. """
def install(self, object, business_configuration, prefix = ''): def install(self, document, business_configuration, prefix=''):
""" Add object to customer customization template. """ """ Add object to customer customization template. """
bt5_obj = business_configuration.getSpecialiseValue() bt5_obj = business_configuration.getSpecialiseValue()
if object.getPortalType() in ['Category', 'Base Category']: if document.getPortalType() in ['Category', 'Base Category']:
prefix = "portal_categories/" prefix = "portal_categories/"
template_path_list = ['%s%s' % (prefix, object.getRelativeUrl()), template_path_list = ['%s%s' % (prefix, document.getRelativeUrl()),
'%s%s/**' % (prefix, object.getRelativeUrl())] '%s%s/**' % (prefix, document.getRelativeUrl())]
current_template_path_list = list(bt5_obj.getTemplatePathList()) current_template_path_list = list(bt5_obj.getTemplatePathList())
current_template_path_list.extend(template_path_list) current_template_path_list.extend(template_path_list)
bt5_obj.edit(template_path_list=current_template_path_list) bt5_obj.edit(template_path_list=current_template_path_list)
def addToCustomerBT5ByRelativeUrl(self, business_configuration, relative_url_list): def addToCustomerBT5ByRelativeUrl(self, business_configuration,
""" Add object to customer customization template object by its relative url. """ relative_url_list):
""" Add object to customer customization template object by
its relative url. """
bt5_obj = business_configuration.getSpecialiseValue() bt5_obj = business_configuration.getSpecialiseValue()
current_template_path_list = list(bt5_obj.getTemplatePathList()) current_template_path_list = list(bt5_obj.getTemplatePathList())
current_template_path_list.extend(relative_url_list) current_template_path_list.extend(relative_url_list)
bt5_obj.edit(template_path_list=current_template_path_list) bt5_obj.edit(template_path_list=current_template_path_list)
def buildItem(self, business_configuration_relative_url):
""" Invoke build process """
business_configuration = self.getPortalObject().restrictedTraverse(\
business_configuration_relative_url)
LOG('CONFIGURATOR', INFO, 'Building --> %s' % self)
start_build = time.time()
result = self.build(business_configuration)
LOG('CONFIGURATOR', INFO, 'Built --> %s (%.02fs)' % (self,
time.time()-start_build))
return result
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