Commit 7ab4b81d authored by Rafael Monnerat's avatar Rafael Monnerat

Solve merge conflicts on revision files modified at rafael and master branch

Merged master into rafael branch

Conflicts:
	bt5/erp5_ui_test/bt/revision
	product/ERP5/bootstrap/erp5_core/bt/revision
parents 8c6785a9 0b539231
Changes
=======
0.4.3 (2012-04-24)
----------------
* erp5.util.testnode:
- Improve detection of the cancellation of a test on the master
- better management of SIGTERM signal
- cleanup test instances to make sure nothing stay from a previous
test run
0.4.2 (2012-04-11)
----------------
* erp5.util.testnode:
- Improve testnode logs
- add a thread to upload ongoing logs to the master regularly
- if the software release is not built successfully after a
few time, totally erase software. This help unblocking if
buildout is unable to update software.
- check if the last test result was cancelled in order to
allow relaunching test without restarting testnode
0.4.1 (2012-02-29)
----------------
......
......@@ -18,6 +18,7 @@ def generateBarcodeImage(self, barcode_type, data):
elif barcode_type == 'code128':
from hubarcode.code128 import Code128Encoder
encoder = Code128Encoder(data)
encoder.text = '' # get barcode image only
output = encoder.get_imagedata()
elif barcode_type == 'qrcode':
import qrcode
......
......@@ -57,7 +57,10 @@ event = portal.restrictedTraverse(event_relative_url)\n
subject = event.getTitle()\n
body = event.getTextContent()\n
sender = event.getSourceValue()\n
if sender is not None:\n
if kw.get("from_url") is not None:\n
from_url = kw.get("from_url")\n
elif event.getSource() is not None:\n
sender = event.getSourceValue()\n
from_url = formataddr((sender.getTitle(), sender.getDefaultEmailText()))\n
else:\n
from_url = portal.portal_preferences.getPreferredEventSenderEmail()\n
......
1020
\ No newline at end of file
1022
\ No newline at end of file
......@@ -110,8 +110,15 @@ if portal_preferences.getPreferredCredentialAlarmAutomaticCall():\n
message_str = "Credential Request Created."\n
else:\n
if portal_preferences.isPreferredEmailVerificationCheck():\n
# Send email to subscriber in order to check email\'s address\n
credential_request.activate(activity=\'SQLQueue\').CredentialRequest_sendSubmittedNotification(\n
# after_path_and_method_id argument is used below to not activate when\n
# Crededial request object is not indexed yet. This is needed because when\n
# the method searchAndActivate from catalog is called, if the object is not\n
# indexed, the e-mail is not sent.\n
method_id_list = (\'immediateReindexObject\', \'recursiveImmediateReindexObject\')\n
path_and_method_id = (credential_request.getPath(), method_id_list)\n
activity_kw = dict(activity=\'SQLQueue\',\n
after_path_and_method_id=path_and_method_id)\n
credential_request.activate(**activity_kw).CredentialRequest_sendSubmittedNotification(\n
context_url=context.absolute_url(),\n
notification_reference=\'erp5-subscription.notification\')\n
message_str = "Thanks for your registration. You will be receive an email to activate your account."\n
......
412
\ No newline at end of file
413
\ No newline at end of file
......@@ -73,6 +73,10 @@
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Acknowledgement</string> </value>
</item>
</dictionary>
</pickle>
</record>
......
......@@ -80,6 +80,10 @@
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Event</string> </value>
</item>
</dictionary>
</pickle>
</record>
......
......@@ -80,6 +80,10 @@
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Event</string> </value>
</item>
</dictionary>
</pickle>
</record>
......
......@@ -80,6 +80,10 @@
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Event</string> </value>
</item>
</dictionary>
</pickle>
</record>
......
......@@ -75,6 +75,10 @@
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Ticket</string> </value>
</item>
</dictionary>
</pickle>
</record>
......
......@@ -80,6 +80,10 @@
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Event</string> </value>
</item>
</dictionary>
</pickle>
</record>
......
......@@ -80,6 +80,10 @@
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Event</string> </value>
</item>
</dictionary>
</pickle>
</record>
......
......@@ -99,22 +99,31 @@ elif direction == \'incoming\':\n
else:\n
raise NotImplementedError, \'The specified direction is not handled: %r\' % (direction,)\n
\n
event_kw = {}\n
event_kw[\'portal_type\'] = portal_type\n
event_kw[\'title\'] = title\n
event_kw[\'resource\'] = resource\n
event_kw[\'source\'] = source_url\n
event_kw[\'source_section\'] = source_section_url\n
event_kw[\'destination\'] = destination_url\n
event_kw[\'destination_section\'] = destination_section_url\n
event_kw[\'start_date\'] = start_date\n
event_kw[\'follow_up\'] = follow_up\n
event_kw[\'text_content\'] = text_content\n
event_kw[\'content_type\'] = portal.portal_preferences.getPreferredTextEditor() and \'text/html\' or \'text/plain\'\n
\n
event_kw = {\n
\'portal_type\' : portal_type,\n
\'title\' : title,\n
\'resource\' : resource,\n
\'source\' : source_url,\n
\'source_section\' : source_section_url,\n
\'destination\' : destination_url,\n
\'destination_section\' : destination_section_url,\n
\'start_date\' : start_date,\n
\'follow_up\' : follow_up,\n
\'text_content\' : text_content,\n
\'content_type\' : portal.portal_preferences.getPreferredTextEditor() and \'text/html\' or \'text/plain\',\n
}\n
# Create event\n
module = portal.getDefaultModule(portal_type=portal_type)\n
event = module.newContent(**event_kw)\n
if not keep_draft:\n
if direction == \'incoming\':\n
# Support event_workflow and event_simulation_workflow\n
if portal.portal_workflow.isTransitionPossible(event, \'receive\'):\n
event.receive()\n
if portal.portal_workflow.isTransitionPossible(event, \'stop\'):\n
event.stop()\n
else:\n
event.plan()\n
\n
if batch_mode:\n
return event\n
......@@ -126,7 +135,7 @@ event.Base_redirect(keep_items={\'portal_status_message\': message})\n
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>title, direction, portal_type, resource, text_content=None, batch_mode=False, **kw</string> </value>
<value> <string>title, direction, portal_type, resource, text_content=None, batch_mode=False, keep_draft=False, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -82,6 +82,7 @@
<value>
<list>
<string>your_text_content</string>
<string>your_keep_draft</string>
</list>
</value>
</item>
......@@ -99,6 +100,8 @@
<string>your_portal_type</string>
<string>your_resource</string>
<string>your_direction</string>
<string>your_source</string>
<string>your_destination</string>
</list>
</value>
</item>
......
<?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>items</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>your_destination</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>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>Recipient</string> </value>
</item>
<item>
<key> <string>view_separator</string> </key>
<value> <string encoding="cdata"><![CDATA[
<br />
]]></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: here.Ticket_getArrowItemList()+ [(here.getTitle(), here.getRelativeUrl())]</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>your_keep_draft</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>Keep in draft state</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>items</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>your_source</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>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>Sender or Caller</string> </value>
</item>
<item>
<key> <string>view_separator</string> </key>
<value> <string encoding="cdata"><![CDATA[
<br />
]]></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: here.Ticket_getArrowItemList() + [(here.getTitle(), here.getRelativeUrl())]</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -57,13 +57,24 @@ event = context\n
operator_list = event.getDestinationList()\n
try:\n
source_value = portal.ERP5Site_getAuthenticatedMemberPersonValue()\n
if source_value:\n
operator_list.append(source_value.getRelativeUrl())\n
except ValueError:\n
source_value = None\n
if source_value is not None:\n
source_section_value = source_value.getDefaultCareerSubordinationValue()\n
operator_list.append(source_value.getRelativeUrl())\n
else:\n
source_section_value = None\n
source_section = portal.portal_preferences.getPreferredSection(),\n
\n
\n
resource_kw = {\n
"Campaign" : "follow_up_campaign_resource",\n
"Meeting" : "follow_up_meeting_resource",\n
"Sale Opportunity" : "follow_up_sale_opportunity_resource",\n
"Support Request" : "follow_up_support_request_resource",\n
}\n
\n
resource = None\n
if follow_up_ticket_type in resource_kw:\n
resource = kw.get(resource_kw[follow_up_ticket_type], None)\n
\n
\n
module = portal.getDefaultModule(follow_up_ticket_type)\n
ticket = module.newContent(\n
......@@ -71,20 +82,25 @@ ticket = module.newContent(\n
title=follow_up_ticket_title,\n
start_date=event.getStartDate(),\n
destination_decision_list=event.getSourceList(),\n
destination_section=event.getSourceSection() or event.getSource(),\n
# destination_section=event.getSourceSection() or event.getSource(),\n
source_trade_set=operator_list,\n
source_value=source_value,\n
source_section_value=source_section_value,\n
source_section=source_section,\n
resource=resource,\n
)\n
\n
follow_up_list = event.getFollowUpList()\n
follow_up_list.append(ticket.getRelativeUrl())\n
event.edit(follow_up_list=follow_up_list)\n
\n
if portal.portal_workflow.isTransitionPossible(\n
ticket, \'submit\'):\n
ticket.submit()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>follow_up_ticket_title="Sale Opportunity", follow_up_ticket_type=None, follow_up_ticket_resource=None, **kw</string> </value>
<value> <string>follow_up_ticket_title="Sale Opportunity", follow_up_ticket_type=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -51,17 +51,22 @@
<item>
<key> <string>_body</string> </key>
<value> <string>context.Event_createFollowUpTicket(follow_up_ticket_type=follow_up_ticket_type,\n
follow_up_ticket_title=follow_up_ticket_title)\n
follow_up_ticket_title=follow_up_ticket_title,\n
follow_up_campaign_resource=follow_up_campaign_resource,\n
follow_up_meeting_resource=follow_up_meeting_resource,\n
follow_up_sale_opportunity_resource=follow_up_sale_opportunity_resource,\n
follow_up_support_request_resource=follow_up_support_request_resource,\n
**kw)\n
if context.getPortalObject().portal_workflow.isTransitionPossible(\n
context, \'deliver\'):\n
context.deliver()\n
return context.Base_redirect("", \n
return context.Base_redirect("",\n
keep_items={\'portal_status_message\':context.getPortalObject().Base_translateString("Follow Up Ticket Created.")})\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>follow_up_ticket_type=None, follow_up_ticket_title=None, **kw</string> </value>
<value> <string>follow_up_ticket_type=None, follow_up_ticket_title=None, follow_up_campaign_resource=None, follow_up_meeting_resource=None, follow_up_sale_opportunity_resource=None, follow_up_support_request_resource=None, **kw</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......
......@@ -95,6 +95,11 @@
<list>
<string>your_follow_up_ticket_title</string>
<string>your_follow_up_ticket_type</string>
<string>your_follow_up_campaign_resource</string>
<string>your_follow_up_support_request_resource</string>
<string>your_follow_up_meeting_resource</string>
<string>your_follow_up_sale_opportunity_resource</string>
<string>additionnal_javascript</string>
</list>
</value>
</item>
......
<?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>css_class</string>
<string>default</string>
<string>items</string>
<string>required</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>your_follow_up_campaign_resource</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>default</string> </key>
<value> <string></string> </value>
</item>
<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>required</string> </key>
<value> <string></string> </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>css_class</string> </key>
<value> <string>hidden</string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>your_list_field</string> </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>required</string> </key>
<value> <int>0</int> </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>Nature</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: here.Ticket_getResourceItemList(portal_type="Campaign", include_context=False)</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>css_class</string>
<string>default</string>
<string>items</string>
<string>required</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>your_follow_up_meeting_resource</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>default</string> </key>
<value> <string></string> </value>
</item>
<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>required</string> </key>
<value> <string></string> </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>css_class</string> </key>
<value> <string>hidden</string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>your_list_field</string> </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>required</string> </key>
<value> <int>0</int> </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>Nature</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: here.Ticket_getResourceItemList(portal_type="Meeting", include_context=False)</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>css_class</string>
<string>default</string>
<string>items</string>
<string>required</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>your_follow_up_sale_opportunity_resource</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>default</string> </key>
<value> <string></string> </value>
</item>
<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>required</string> </key>
<value> <string></string> </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>css_class</string> </key>
<value> <string>hidden</string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>your_list_field</string> </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>required</string> </key>
<value> <int>0</int> </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>Nature</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: here.Ticket_getResourceItemList(portal_type="Sale Opportunity", include_context=False)</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>default</string>
<string>items</string>
<string>required</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>your_follow_up_support_request_resource</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>default</string> </key>
<value> <string></string> </value>
</item>
<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>required</string> </key>
<value> <string></string> </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>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>your_list_field</string> </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>required</string> </key>
<value> <int>0</int> </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>Nature</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: here.Ticket_getResourceItemList(portal_type="Support Request", include_context=False)</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -10,6 +10,7 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>default</string>
<string>required</string>
</list>
</value>
......@@ -52,6 +53,12 @@
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
......@@ -60,6 +67,10 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
......@@ -71,6 +82,10 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>your_title</string> </value>
......@@ -93,4 +108,17 @@
</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>here/getTitle</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -148,7 +148,9 @@
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>external_validator</string> </key>
......@@ -304,4 +306,17 @@
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: here.getPortalType() == "Mail Message"</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -54,18 +54,21 @@
arrow = portal.portal_property_sheets.get("Arrow")\n
\n
value_list = [(\'\', \'\'),]\n
value_list_append = value_list.append\n
\n
# add current user\n
user = portal.ERP5Site_getAuthenticatedMemberPersonValue()\n
if user is not None:\n
value_list.append((user.getTitle(), user.getRelativeUrl()))\n
\n
for property in arrow.contentValues():\n
value = context.getProperty("%s_value" %property.getReference(), None)\n
if value is not None and value.getPortalType() in portal.getPortalNodeTypeList():\n
value_list.append((value.getTitle(), value.getRelativeUrl()))\n
value_list_append((user.getTitle(), user.getRelativeUrl()))\n
\n
for property_value in arrow.contentValues():\n
value = context.getProperty("%s_value" %property_value.getReference(), None)\n
if value and value.getPortalType() in portal.getPortalNodeTypeList():\n
value = (value.getTitle(), value.getRelativeUrl())\n
if value not in value_list:\n
value_list_append(value)\n
\n
value_list.sort(key=lambda x: x[0])\n
\n
return value_list\n
</string> </value>
......
......@@ -59,23 +59,26 @@ from zExceptions import Unauthorized\n
from Products.ERP5Type.Cache import CachingMethod\n
portal = context.getPortalObject()\n
\n
preference_id = \'preferred_%s_use\' % \'_\'.join(token.lower() for token in context.getPortalType().split(\' \'))\n
if not portal_type:\n
portal_type = context.getPortalType()\n
\n
preference_id = \'preferred_%s_use\' % \'_\'.join(token.lower() for token in portal_type.split(\' \'))\n
sql_kw = {\'portal_type\': portal.getPortalResourceTypeList(),\n
\'use_uid\': portal.portal_categories.getCategoryUid(portal.portal_preferences.getPreference(preference_id), base_category=\'use\'),\n
\'validation_state\': \'validated\',\n
\'sort_on\': \'title\'}\n
\n
def getResourceItemList():\n
def getResourceItemList(portal_type):\n
return [(\'\', \'\')] + [(result.getTitle(), result.getRelativeUrl()) for result in portal.portal_catalog(**sql_kw)]\n
\n
getResourceItemList = CachingMethod(getResourceItemList, \n
id=(script.id, context.Localizer.get_selected_language()), \n
cache_factory=\'erp5_ui_long\')\n
\n
result_list = getResourceItemList()[:]\n
result_list = getResourceItemList(portal_type)[:]\n
\n
# BBB returns actual value in list field\n
if context.getResource() and context.getResource() not in [result[1] for result in result_list]:\n
if include_context and context.getResource() and context.getResource() not in [result[1] for result in result_list]:\n
try:\n
resource_value = portal.portal_categories.getCategoryValue(context.getResource(), base_category=\'resource\')\n
if resource_value is not None:\n
......@@ -94,7 +97,7 @@ return result_list\n
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
<value> <string>portal_type=None, include_context=True</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -77,14 +77,15 @@ event = module.newContent(portal_type=portal_type, \n
follow_up=context.getRelativeUrl())\n
\n
# Trigger appropriate workflow action\n
if direction == \'incoming\':\n
# Support event_workflow and event_simulation_workflow\n
if portal.portal_workflow.isTransitionPossible(event, \'receive\'):\n
event.receive()\n
if portal.portal_workflow.isTransitionPossible(event, \'stop\'):\n
event.stop()\n
else:\n
event.plan()\n
if not keep_draft:\n
if direction == \'incoming\':\n
# Support event_workflow and event_simulation_workflow\n
if portal.portal_workflow.isTransitionPossible(event, \'receive\'):\n
event.receive()\n
if portal.portal_workflow.isTransitionPossible(event, \'stop\'):\n
event.stop()\n
else:\n
event.plan()\n
\n
# Redirect to event\n
portal_status_message = translateString(\n
......@@ -95,7 +96,7 @@ return event.Base_redirect(\'view\', keep_items = dict(portal_status_message=por
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>form_id=\'view\', portal_type=None, title=None, resource=None, text_content=None,direction=None, source=None, destination=None, **kw</string> </value>
<value> <string>form_id=\'view\', portal_type=None, title=None, resource=None, text_content=None,direction=None, source=None, destination=None, keep_draft=False, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -76,6 +76,7 @@
<value>
<list>
<string>your_text_content</string>
<string>your_keep_draft</string>
</list>
</value>
</item>
......
<?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>your_keep_draft</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>Keep in draft state</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
592
\ No newline at end of file
593
\ No newline at end of file
......@@ -68,6 +68,8 @@
<key> <string>Add portal content</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
......@@ -76,6 +78,8 @@
<key> <string>Delete objects</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
......@@ -84,6 +88,8 @@
<key> <string>Modify portal content</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
......
9
\ No newline at end of file
10
\ No newline at end of file
<?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_report</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_report</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>role_information_list_view</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>2.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Role Information List</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}/TypesTool_viewRoleInformationList</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></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>
<string>listbox_role_name_list</string>
<string>listbox_role_category_list</string>
<string>listbox_role_base_category_list</string>
</list>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>TypesTool_viewRoleInformationList</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>TypesTool_viewRoleInformationList</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_list</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></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>columns</string>
<string>count_method</string>
<string>list_method</string>
<string>portal_types</string>
<string>sort</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</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>columns</string> </key>
<value>
<list>
<tuple>
<string>parent_title</string>
<string>Portal Type</string>
</tuple>
<tuple>
<string>title</string>
<string>Title</string>
</tuple>
<tuple>
<string>role_name_list</string>
<string>Roles</string>
</tuple>
<tuple>
<string>condition_text</string>
<string>Condition</string>
</tuple>
<tuple>
<string>role_base_category_list</string>
<string>Base Categories</string>
</tuple>
<tuple>
<string>role_base_category_script_id</string>
<string>Base Category Script</string>
</tuple>
<tuple>
<string>role_category_list</string>
<string>Categories</string>
</tuple>
<tuple>
<string>description</string>
<string>Description</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>count_method</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_list_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>list_method</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value>
<list>
<tuple>
<string>Role Information</string>
<string>Role Information</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>sort</string> </key>
<value>
<list>
<tuple>
<string>parent_title</string>
<string>parent_title</string>
</tuple>
<tuple>
<string>title</string>
<string>title</string>
</tuple>
</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>Role Informations</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Method" module="Products.Formulator.MethodField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>method_name</string> </key>
<value> <string>countResults</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Method" module="Products.Formulator.MethodField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>method_name</string> </key>
<value> <string>portal_catalog</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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_role_base_category_list</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_lines_field</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>
</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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_role_category_list</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_lines_field</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>
</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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_role_name_list</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_lines_field</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>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
2012-04-19 Kazuhiko
* add TypesTool_viewRoleInformationList that lists all Role Informations.
2011-08-08 yusei
* Extract messages from constraints in ZODB property sheets for POT.
......
665
\ No newline at end of file
666
\ No newline at end of file
......@@ -34,4 +34,5 @@ Glossary Term | view
Preference | vcs
Template Tool | bt_vcs_history
Template Tool | search_portal_type
Types Tool | role_information_list_view
portal_actions | generate_pot_file
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Folder" module="OFS.Folder"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>jcarousel</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
2012-04-18 Ivan
* Initial commit
\ No newline at end of file
2012 (c) Nexedi SA
\ No newline at end of file
erp5_jquery
\ No newline at end of file
This Business Template contains only static files of jCarousel jQuery library.
\ No newline at end of file
GPL
\ No newline at end of file
portal_skins/erp5_jquery/jquery/plugin/jcarousel
portal_skins/erp5_jquery/jquery/plugin/jcarousel/**
\ No newline at end of file
erp5_jquery_plugin_jcarousel
\ No newline at end of file
5.4.7
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Cacheable__manager_id</string> </key>
<value> <string>http_cache</string> </value>
</item>
<item>
<key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts34648236.68</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
<value> <string>grid.locale-fr.js</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>application/javascript</string> </value>
</item>
<item>
<key> <string>data</string> </key>
<value> <string encoding="cdata"><![CDATA[
;(function($){\r\n
/**\r\n
* jqGrid French Translation\r\n
* Tony Tomov tony@trirand.com\r\n
* http://trirand.com/blog/ \r\n
* Dual licensed under the MIT and GPL licenses:\r\n
* http://www.opensource.org/licenses/mit-license.php\r\n
* http://www.gnu.org/licenses/gpl.html\r\n
**/\r\n
$.jgrid = $.jgrid || {};\r\n
$.extend($.jgrid,{\r\n
\tdefaults : {\r\n
\t\trecordtext: "Enregistrements {0} - {1} sur {2}",\r\n
\t\temptyrecords: "Aucun enregistrement à afficher",\r\n
\t\tloadtext: "Chargement...",\r\n
\t\tpgtext : "Page {0} sur {1}"\r\n
\t},\r\n
\tsearch : {\r\n
\t\tcaption: "Recherche...",\r\n
\t\tFind: "Chercher",\r\n
\t\tReset: "Annuler",\r\n
\t\todata : [\'égal\', \'différent\', \'inférieur\', \'inférieur ou égal\',\'supérieur\',\'supérieur ou égal\', \'commence par\',\'ne commence pas par\',\'est dans\',"n\'est pas dans",\'finit par\',\'ne finit pas par\',\'contient\',\'ne contient pas\'],\r\n
\t\tgroupOps: [\t{ op: "AND", text: "tous" },\t{ op: "OR", text: "aucun" }\t],\r\n
\t\tmatchText: " correspondance",\r\n
\t\trulesText: " règles"\r\n
\t},\r\n
\tedit : {\r\n
\t\taddCaption: "Ajouter",\r\n
\t\teditCaption: "Editer",\r\n
\t\tbSubmit: "Valider",\r\n
\t\tbCancel: "Annuler",\r\n
\t\tbClose: "Fermer",\r\n
\t\tsaveData: "Les données ont changé ! Enregistrer les modifications ?",\r\n
\t\tbYes: "Oui",\r\n
\t\tbNo: "Non",\r\n
\t\tbExit: "Annuler",\r\n
\t\tmsg: {\r\n
\t\t\trequired: "Champ obligatoire",\r\n
\t\t\tnumber: "Saisissez un nombre correct",\r\n
\t\t\tminValue: "La valeur doit être supérieure ou égale à",\r\n
\t\t\tmaxValue: "La valeur doit être inférieure ou égale à",\r\n
\t\t\temail: "n\'est pas un email correct",\r\n
\t\t\tinteger: "Saisissez un entier correct",\r\n
\t\t\turl: "n\'est pas une adresse correcte. Préfixe requis (\'http://\' or \'https://\')",\r\n
\t\t\tnodefined : " n\'est pas défini!",\r\n
\t\t\tnovalue : " la valeur de retour est requise!",\r\n
\t\t\tcustomarray : "Une fonction personnalisée devrait retourner un tableau (array)!",\r\n
\t\t\tcustomfcheck : "Une fonction personnalisée devrait être présente dans le cas d\'une vérification personnalisée!"\r\n
\t\t}\r\n
\t},\r\n
\tview : {\r\n
\t\tcaption: "Voir les enregistrement",\r\n
\t\tbClose: "Fermer"\r\n
\t},\r\n
\tdel : {\r\n
\t\tcaption: "Supprimer",\r\n
\t\tmsg: "Supprimer les enregistrements sélectionnés ?",\r\n
\t\tbSubmit: "Supprimer",\r\n
\t\tbCancel: "Annuler"\r\n
\t},\r\n
\tnav : {\r\n
\t\tedittext: " ",\r\n
\t\tedittitle: "Editer la ligne sélectionnée",\r\n
\t\taddtext:" ",\r\n
\t\taddtitle: "Ajouter une ligne",\r\n
\t\tdeltext: " ",\r\n
\t\tdeltitle: "Supprimer la ligne sélectionnée",\r\n
\t\tsearchtext: " ",\r\n
\t\tsearchtitle: "Chercher un enregistrement",\r\n
\t\trefreshtext: "",\r\n
\t\trefreshtitle: "Recharger le tableau",\r\n
\t\talertcap: "Avertissement",\r\n
\t\talerttext: "Veuillez sélectionner une ligne",\r\n
\t\tviewtext: "",\r\n
\t\tviewtitle: "Afficher la ligne sélectionnée"\r\n
\t},\r\n
\tcol : {\r\n
\t\tcaption: "Afficher/Masquer les colonnes",\r\n
\t\tbSubmit: "Valider",\r\n
\t\tbCancel: "Annuler"\r\n
\t},\r\n
\terrors : {\r\n
\t\terrcap : "Erreur",\r\n
\t\tnourl : "Aucune adresse n\'est paramétrée",\r\n
\t\tnorecords: "Aucun enregistrement à traiter",\r\n
\t\tmodel : "Nombre de titres (colNames) <> Nombre de données (colModel)!"\r\n
\t},\r\n
\tformatter : {\r\n
\t\tinteger : {thousandsSeparator: " ", defaultValue: \'0\'},\r\n
\t\tnumber : {decimalSeparator:",", thousandsSeparator: " ", decimalPlaces: 2, defaultValue: \'0,00\'},\r\n
\t\tcurrency : {decimalSeparator:",", thousandsSeparator: " ", decimalPlaces: 2, prefix: "", suffix:"", defaultValue: \'0,00\'},\r\n
\t\tdate : {\r\n
\t\t\tdayNames: [\r\n
\t\t\t\t"Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam",\r\n
\t\t\t\t"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"\r\n
\t\t\t],\r\n
\t\t\tmonthNames: [\r\n
\t\t\t\t"Jan", "Fév", "Mar", "Avr", "Mai", "Jui", "Jul", "Aou", "Sep", "Oct", "Nov", "Déc",\r\n
\t\t\t\t"Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Décembre"\r\n
\t\t\t],\r\n
\t\t\tAmPm : ["am","pm","AM","PM"],\r\n
\t\t\tS: function (j) {return j == 1 ? \'er\' : \'e\';},\r\n
\t\t\tsrcformat: \'Y-m-d\',\r\n
\t\t\tnewformat: \'d/m/Y\',\r\n
\t\t\tmasks : {\r\n
\t\t\t\tISO8601Long:"Y-m-d H:i:s",\r\n
\t\t\t\tISO8601Short:"Y-m-d",\r\n
\t\t\t\tShortDate: "n/j/Y",\r\n
\t\t\t\tLongDate: "l, F d, Y",\r\n
\t\t\t\tFullDateTime: "l, F d, Y g:i:s A",\r\n
\t\t\t\tMonthDay: "F d",\r\n
\t\t\t\tShortTime: "g:i A",\r\n
\t\t\t\tLongTime: "g:i:s A",\r\n
\t\t\t\tSortableDateTime: "Y-m-d\\\\TH:i:s",\r\n
\t\t\t\tUniversalSortableDateTime: "Y-m-d H:i:sO",\r\n
\t\t\t\tYearMonth: "F, Y"\r\n
\t\t\t},\r\n
\t\t\treformatAfterEdit : false\r\n
\t\t},\r\n
\t\tbaseLinkUrl: \'\',\r\n
\t\tshowAction: \'\',\r\n
\t\ttarget: \'\',\r\n
\t\tcheckbox : {disabled:true},\r\n
\t\tidName : \'id\'\r\n
\t}\r\n
});\r\n
})(jQuery);\r\n
]]></string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>size</string> </key>
<value> <int>4273</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>grid.locale-fr.js</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
1
\ No newline at end of file
2
\ No newline at end of file
......@@ -12,7 +12,7 @@
</item>
<item>
<key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts34058349.94</string> </value>
<value> <string>ts34651695.58</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
......@@ -75,6 +75,16 @@ var LocalStorageCachePlugin = {\n
}\n
\n
var Cache = {\n
\n
ROOT_CACHE_ID: \'APP_CACHE\',\n
\n
getCacheId: function(cache_id) {\n
/* We should have a way to \'purge\' localStorage by setting a ROOT_CACHE_ID in all browser\n
* instances\n
*/\n
return Cache.ROOT_CACHE_ID + cache_id; \n
\n
},\n
\n
hasLocalStorage: function() {\n
/*\n
......@@ -91,6 +101,7 @@ var Cache = {\n
\n
get: function(cache_id, default_value){\n
/* Get cache key value */\n
cache_id = Cache.getCacheId(cache_id);\n
if (Cache.hasLocalStorage()){\n
return LocalStorageCachePlugin.get(cache_id, default_value);}\n
else{\n
......@@ -99,6 +110,7 @@ var Cache = {\n
\n
set: function(cache_id, data){\n
/* Set cache key value */\n
cache_id = Cache.getCacheId(cache_id);\n
if (Cache.hasLocalStorage()){\n
LocalStorageCachePlugin.set(cache_id, data);}\n
else{\n
......@@ -300,8 +312,9 @@ var Form = {\n
column_title_list.push(title);\n
column = {\'name\': index,\n
\'index\': index,\n
\'width\': 150,\n
\'align\': \'left\'}\n
\'width\': 185,\n
\'align\': \'left\'\n
}\n
colModel.push(column);\n
});\n
\n
......@@ -314,6 +327,11 @@ var Form = {\n
sortname: \'id\',\n
viewrecords: true,\n
sortorder: "desc",\n
loadError : function(xhr, textStatus, errorThrown) {\n
// XXX: handle better than just alert.\n
alert("Error occurred during getting data from server.");\n
},\n
cmTemplate: {sortable:false}, // XXX: until we get list of sortable columns from server\n
caption: field_dict["title"] });\n
listbox_table.jqGrid(\'navGrid\', \'#\'+navigation_id, {edit:false,add:false,del:false});\n
return listbox_table;\n
......@@ -535,7 +553,7 @@ var RenderJs = {\n
</item>
<item>
<key> <string>size</string> </key>
<value> <int>18537</int> </value>
<value> <int>19314</int> </value>
</item>
<item>
<key> <string>title</string> </key>
......
2
\ No newline at end of file
5
\ No newline at end of file
......@@ -58,17 +58,20 @@
breadcrumb_list python: current_web_section.getBreadcrumbItemList(current_web_document);">\n
<ul class="breadcrumb">\n
<li tal:repeat="breadcrumb python:breadcrumb_list[:(is_web_section_default_document and -1 or None)]">\n
<a href="#" tal:attributes="href python:current_web_section.getPermanentURL(breadcrumb[1]);\n
title python:breadcrumb[2];"\n
tal:content="python:breadcrumb[0]">Title</a>\n
<tal:block tal:condition="not: repeat/breadcrumb/end">\n
<img class="breadcrumb_separator" src="../km_img/crumb.png" alt="&gt;"\n
tal:attributes="src string:${portal_path}/km_img/crumb.png"/>\n
<tal:block tal:define="is_last repeat/breadcrumb/end">\n
<a href="#"\n
tal:attributes="href python:current_web_section.getPermanentURL(breadcrumb[1]);\n
title python:breadcrumb[2];\n
class python: test(is_last, \'last-breadcrumb\', \'breadcrumb\')"\n
tal:content="python:breadcrumb[0]">Title</a>\n
<img tal:condition="not: is_last"\n
class="breadcrumb_separator"\n
src="../km_img/crumb.png" alt="&gt;"\n
tal:attributes="src string:${portal_path}/km_img/crumb.png"/>\n
</tal:block>\n
</li>\n
</ul>\n
</tal:block>\n
</tal:block>
]]></unicode> </value>
</item>
......@@ -86,7 +89,7 @@
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
<value> <string>iso-8859-15</string> </value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -122,6 +122,7 @@
<list>
<string>left_menu_widget</string>
<string>listbox_action_widget</string>
<string>analytics_widget</string>
</list>
</value>
</item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</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>
<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>_text</string> </key>
<value> <unicode encoding="cdata"><![CDATA[
<!--Place analytic code or any other tracking scripts which will not be displayed-->
]]></unicode> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebSite_viewAnalyticsWidget</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -79,7 +79,7 @@
<tal:block tal:repeat="menu_item menu_item_list">\n
\n
<li tal:define="sub_item_list menu_item/subsection"\n
tal:attributes="class python:(sub_item_list and \'collapse-menu \' or \'\') + \'menu_item_%s\' % repeat[\'menu_item\'].index">\n
tal:attributes="class python:\'menu_item_%s collapse-menu\' % repeat[\'menu_item\'].index + \' \' + (sub_item_list and \'collapse-able\' or \'\')">\n
<a tal:attributes="href menu_item/url" >\n
<tal:block tal:replace="menu_item/compact_translated_title | menu_item/translated_title">Menu</tal:block>\n
</a>\n
......
......@@ -90,6 +90,7 @@
<value>
<list>
<string>footer_widget</string>
<string>analytics_widget</string>
</list>
</value>
</item>
......
<?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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>analytics_widget</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>analytics_widget</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>WebSection_viewMinimalKMWidgetFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -88,6 +88,7 @@
<value>
<list>
<string>footer_widget</string>
<string>analytics_widget</string>
</list>
</value>
</item>
......
<?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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>analytics_widget</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>analytics_widget</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>WebSection_viewMinimalKMWidgetFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -99,6 +99,7 @@
<value>
<list>
<string>footer_widget</string>
<string>analytics_widget</string>
</list>
</value>
</item>
......
<?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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>analytics_widget</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>analytics_widget</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>WebSection_viewMinimalKMWidgetFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -70,7 +70,8 @@ It is possible to specify a group id and a group title by naming a group followi
<tal:block tal:condition="preferred_html_style_developper_mode">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/form" />\n
</tal:block>\n
\n
<div class="form"\n
tal:attributes="id form/getId">\n
<tal:block tal:repeat="group group_list">\n
<tal:block tal:define="gid group/gid;">\n
<fieldset tal:condition="python: gid.find(\'hidden\') &lt; 0"\n
......@@ -86,11 +87,11 @@ It is possible to specify a group id and a group title by naming a group followi
</fieldset>\n
</tal:block>\n
</tal:block>\n
</div>\n
<p class="clear"></p>\n
</tal:block>\n
</tal:block>\n
</tal:block>\n
</tal:block>
]]></unicode> </value>
</item>
......@@ -108,7 +109,7 @@ It is possible to specify a group id and a group title by naming a group followi
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
<value> <string>iso-8859-15</string> </value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -84,7 +84,6 @@ div {\n
margin:0;\n
padding:0;\n
float:none;\n
width:100%;\n
position:relative;\n
}\n
\n
......@@ -171,7 +170,11 @@ fieldset.hidden_fieldset { \n
padding-bottom:35px;\n
padding-top: 5px;\n
}\n
\n
#master,\n
.document,\n
.content{\n
width:100%;\n
}\n
#wrapper_right{\n
float: left;\n
width:22.5%;\n
......@@ -227,7 +230,7 @@ div#wrapper_headline div.header_title {\n
}\n
\n
#wrapper_path {\n
float:left;\n
/* float:left; */\n
width: 100%;\n
}\n
\n
......@@ -249,11 +252,14 @@ div#wrapper_headline div.header_title {\n
height:100%;\n
}\n
\n
#menu ul li.collapse-menu{\n
#menu ul li.collapse-able{\n
background: url(km_img/collapse-down-arrow.gif) no-repeat transparent right 10px;\n
padding-right: 0px;\n
}\n
\n
\n
\n
\n
#menu ul li.non-collapse-menu{\n
background: none;\n
padding-right: 0px;\n
......@@ -567,10 +573,12 @@ fieldset.right{\n
*/\n
\n
fieldset.registration {\n
width:36%;\n
width:auto;\n
background-color: #FFFFFF;\n
margin-right: 0.5%;\n
height: auto;\n
margin-bottom:2em;\n
padding:10px;\n
}\n
\n
\n
......@@ -934,7 +942,7 @@ fieldset.right h4 {\n
padding:5px;\n
}\n
\n
.document > .content ul li {\n
.content ul li {\n
background:transparent url(km_img/bg_bullet_square.gif) no-repeat scroll 0 0.5em;\n
margin:0 0 0.3em 2px;\n
padding:0 0 0 12px;\n
......@@ -1075,7 +1083,7 @@ table tbody tr td {\n
top:0;\n
padding-top:30px;\n
left:0;\n
width:205px;\n
width:auto;\n
opacity: <tal:block tal:replace="menu_opacity">0.80</tal:block>;\n
}\n
\n
......
1854
\ No newline at end of file
1860
\ No newline at end of file
......@@ -92,7 +92,7 @@
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>python: context.getTextContent() is None or not context.getTextContent()</string> </value>
<value> <string>python: context.getTextContent() is None or not context.getTextContent() or context.getValidationState() in context.getPortalObject().getPortalDraftOrderStateList()</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -11,7 +11,6 @@
<value>
<list>
<string>description</string>
<string>enabled</string>
<string>title</string>
<string>whitespace_preserve</string>
</list>
......@@ -56,10 +55,8 @@
<value>
<dictionary>
<item>
<key> <string>enabled</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
......@@ -96,10 +93,6 @@
<key> <string>description</string> </key>
<value> <string>Name of the Web Page you would like to review.</string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
......@@ -130,17 +123,4 @@
</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>not:here/isExternalDocument</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -82,6 +82,7 @@
<string>delivery_builder/portal_deliveries/internal_packing_list_builder</string>
<string>delivery_builder/portal_deliveries/purchase_packing_list_builder</string>
<string>delivery_builder/portal_deliveries/sale_packing_list_builder</string>
<string>delivery_builder/portal_deliveries/task_report_builder</string>
</tuple>
</value>
</item>
......
34
\ No newline at end of file
35
\ No newline at end of file
<module>
<id>foo_module</id>
<permission_list>
<permission type='tuple'>
<name>Access Transient Objects</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Access contents information</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Access session data</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add portal content</name>
<role>Assignor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add portal folders</name>
<role>Assignor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change local roles</name>
<role>Assignor</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Copy or Move</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Delete objects</name>
<role>Assignor</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>List folder contents</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Modify portal content</name>
<role>Assignor</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>View</name>
<role>Assignee</role>
......@@ -9,6 +81,15 @@
<role>Auditor</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>View History</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Author</role>
<role>Manager</role>
</permission>
</permission_list>
<portal_type>Foo Module</portal_type>
<title>Foos</title>
......
683
\ No newline at end of file
683
##############################################################################
#
# Copyright (c) 2011 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import re
import subprocess
import threading
import signal
import sys
class SubprocessError(EnvironmentError):
def __init__(self, status_dict):
self.status_dict = status_dict
def __getattr__(self, name):
return self.status_dict[name]
def __str__(self):
return 'Error %i' % self.status_code
class CancellationError(EnvironmentError):
pass
_format_command_search = re.compile("[[\\s $({?*\\`#~';<>&|]").search
_format_command_escape = lambda s: "'%s'" % r"'\''".join(s.split("'"))
def format_command(*args, **kw):
cmdline = []
for k, v in sorted(kw.items()):
if _format_command_search(v):
v = _format_command_escape(v)
cmdline.append('%s=%s' % (k, v))
for v in args:
if _format_command_search(v):
v = _format_command_escape(v)
cmdline.append(v)
return ' '.join(cmdline)
def subprocess_capture(p, log, log_prefix, get_output=True):
def readerthread(input, output, buffer):
while True:
data = input.readline()
if not data:
break
if get_output:
buffer.append(data)
if log_prefix:
data = "%s : " % log_prefix + data
data = data.rstrip('\n')
output(data)
if p.stdout:
stdout = []
stdout_thread = threading.Thread(target=readerthread,
args=(p.stdout, log, stdout))
stdout_thread.daemon = True
stdout_thread.start()
if p.stderr:
stderr = []
stderr_thread = threading.Thread(target=readerthread,
args=(p.stderr, log, stderr))
stderr_thread.daemon = True
stderr_thread.start()
p.wait()
if p.stdout:
stdout_thread.join()
if p.stderr:
stderr_thread.join()
return (p.stdout and ''.join(stdout),
p.stderr and ''.join(stderr))
class ProcessManager(object):
stdin = file(os.devnull)
def __init__(self, log, *args, **kw):
self.log = log
self.process_pid_set = set()
signal.signal(signal.SIGTERM, self.sigterm_handler)
self.under_cancellation = False
def spawn(self, *args, **kw):
if self.under_cancellation:
raise CancellationError("Test Result was cancelled")
get_output = kw.pop('get_output', True)
log_prefix = kw.pop('log_prefix', '')
new_session = kw.pop('new_session', True)
subprocess_kw = {}
cwd = kw.pop('cwd', None)
if cwd:
subprocess_kw['cwd'] = cwd
if new_session:
subprocess_kw['preexec_fn'] = os.setsid
raise_error_if_fail = kw.pop('raise_error_if_fail', True)
env = kw and dict(os.environ, **kw) or None
command = format_command(*args, **kw)
self.log('subprocess_kw : %r' % (subprocess_kw,))
self.log('$ ' + command)
sys.stdout.flush()
p = subprocess.Popen(args, stdin=self.stdin, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, env=env, **subprocess_kw)
self.process_pid_set.add(p.pid)
stdout, stderr = subprocess_capture(p, self.log, log_prefix,
get_output=get_output)
result = dict(status_code=p.returncode, command=command,
stdout=stdout, stderr=stderr)
self.process_pid_set.discard(p.pid)
if self.under_cancellation:
raise CancellationError("Test Result was cancelled")
if raise_error_if_fail and p.returncode:
raise SubprocessError(result)
return result
def killPreviousRun(self, cancellation=False):
self.log('ProcessManager killPreviousRun, going to kill %r' % (self.process_pid_set,))
if cancellation:
self.under_cancellation = True
for pgpid in self.process_pid_set:
try:
os.kill(pgpid, signal.SIGTERM)
except:
pass
try:
if os.path.exists(self.supervisord_pid_file):
supervisor_pid = int(open(self.supervisord_pid_file).read().strip())
self.log('ProcessManager killPreviousRun, going to kill supervisor with pid %r' % supervisor_pid)
os.kill(supervisor_pid, signal.SIGTERM)
except:
self.log('ProcessManager killPreviousRun, exception when killing supervisor')
pass
self.process_pid_set.clear()
def sigterm_handler(self, signal, frame):
self.log('SIGTERM_HANDLER')
sys.exit(1)
......@@ -36,10 +36,12 @@ MAX_SR_RETRIES = 3
class SlapOSControler(object):
def __init__(self, config, log, process_group_pid_set=None,
slapproxy_log=None):
def __init__(self, config, log,
slapproxy_log=None, process_manager=None, reset_software=False):
log('SlapOSControler, initialize, reset_software: %r' % reset_software)
self.log = log
self.config = config
self.process_manager = process_manager
# By erasing everything, we make sure that we are able to "update"
# existing profiles. This is quite dirty way to do updates...
if os.path.exists(config['proxy_database']):
......@@ -51,7 +53,7 @@ class SlapOSControler(object):
kwargs['stderr'] = slapproxy_log_fp
proxy = subprocess.Popen([config['slapproxy_binary'],
config['slapos_config']], **kwargs)
process_group_pid_set.add(proxy.pid)
process_manager.process_pid_set.add(proxy.pid)
# XXX: dirty, giving some time for proxy to being able to accept
# connections
time.sleep(10)
......@@ -63,21 +65,33 @@ class SlapOSControler(object):
self.software_profile,
computer_guid=config['computer_id'])
computer = slap.registerComputer(config['computer_id'])
# Reset all previously generated software if needed
if reset_software:
software_root = config['software_root']
log('SlapOSControler : GOING TO RESET ALL SOFTWARE')
if os.path.exists(software_root):
shutil.rmtree(software_root)
os.mkdir(software_root)
os.chmod(software_root, 0750)
instance_root = config['instance_root']
if os.path.exists(instance_root):
# delete old paritions which may exists in order to not get its data
# (ex. MySQL db content) from previous testnode's runs
# In order to be able to change partition naming scheme, do this at
# instance_root level (such change happened already, causing problems).
shutil.rmtree(instance_root)
os.mkdir(instance_root)
for i in range(0, MAX_PARTIONS):
# create partition and configure computer
# XXX: at the moment all partitions do share same virtual interface address
# this is not a problem as usually all services are on different ports
partition_reference = '%s-%s' %(config['partition_reference'], i)
partition_path = os.path.join(config['instance_root'], partition_reference)
if os.path.exists(partition_path):
# delete old paritions which may exists in order to not get its data (ex. MySQL db content)
# from previous testnode's runs
shutil.rmtree(partition_path)
partition_path = os.path.join(instance_root, partition_reference)
os.mkdir(partition_path)
os.chmod(partition_path, 0750)
computer.updateConfiguration(xml_marshaller.xml_marshaller.dumps({
'address': config['ipv4_address'],
'instance_root': config['instance_root'],
'instance_root': instance_root,
'netmask': '255.255.255.255',
'partition_list': [{'address_list': [{'addr': config['ipv4_address'],
'netmask': '255.255.255.255'},
......@@ -91,37 +105,23 @@ class SlapOSControler(object):
'reference': config['computer_id'],
'software_root': config['software_root']}))
def runSoftwareRelease(self, config, environment, process_group_pid_set=None,
stdout=None, stderr=None):
def spawn(self, *args, **kw):
return self.process_manager.spawn(*args, **kw)
def runSoftwareRelease(self, config, environment):
self.log("SlapOSControler.runSoftwareRelease")
cpu_count = os.sysconf("SC_NPROCESSORS_ONLN")
os.putenv('MAKEFLAGS', '-j%s' % cpu_count)
os.environ['PATH'] = environment['PATH']
command = [config['slapgrid_software_binary'], '-v', '-c',
#'--buildout-parameter',"'-U -N' -o",
config['slapos_config']]
# a SR may fail for number of reasons (incl. network failures)
# so be tolerant and run it a few times before giving up
for runs in range(0, MAX_SR_RETRIES):
slapgrid = subprocess.Popen(command,
stdout=stdout, stderr=stderr,
close_fds=True, preexec_fn=os.setsid)
process_group_pid_set.add(slapgrid.pid)
slapgrid.wait()
stdout.seek(0)
stderr.seek(0)
process_group_pid_set.remove(slapgrid.pid)
status_dict = {'status_code':slapgrid.returncode,
'command': repr(command),
'stdout':stdout.read(),
'stderr':stderr.read()}
stdout.close()
stderr.close()
status_dict = self.spawn(config['slapgrid_software_binary'], '-v', '-c',
config['slapos_config'], raise_error_if_fail=False,
log_prefix='slapgrid_sr', get_output=False)
return status_dict
def runComputerPartition(self, config, environment,
process_group_pid_set=None,
stdout=None, stderr=None):
self.log("SlapOSControler.runComputerPartition")
slap = slapos.slap.slap()
......@@ -130,26 +130,12 @@ class SlapOSControler(object):
slap.registerOpenOrder().request(self.software_profile,
partition_reference='testing partition',
partition_parameter_kw=config['instance_dict'])
command = [config['slapgrid_partition_binary'],
config['slapos_config'], '-c', '-v']
# try to run for all partitions as one partition may in theory request another one
# this not always is required but curently no way to know how "tree" of partitions
# may "expand"
for runs in range(0, MAX_PARTIONS):
slapgrid = subprocess.Popen(command,
stdout=stdout, stderr=stderr,
close_fds=True, preexec_fn=os.setsid)
process_group_pid_set.add(slapgrid.pid)
slapgrid.wait()
process_group_pid_set.remove(slapgrid.pid)
stdout.seek(0)
stderr.seek(0)
status_dict = {'status_code':slapgrid.returncode,
'command': repr(command),
'stdout':stdout.read(),
'stderr':stderr.read()}
stdout.close()
stderr.close()
status_dict = self.spawn(config['slapgrid_partition_binary'], '-v', '-c',
config['slapos_config'], raise_error_if_fail=False,
log_prefix='slapgrid_cp', get_output=False)
return status_dict
......@@ -36,48 +36,6 @@ from testnode import SubprocessError
SVN_UP_REV = re.compile(r'^(?:At|Updated to) revision (\d+).$')
SVN_CHANGED_REV = re.compile(r'^Last Changed Rev.*:\s*(\d+)', re.MULTILINE)
_format_command_search = re.compile("[[\\s $({?*\\`#~';<>&|]").search
_format_command_escape = lambda s: "'%s'" % r"'\''".join(s.split("'"))
def format_command(*args, **kw):
cmdline = []
for k, v in sorted(kw.items()):
if _format_command_search(v):
v = _format_command_escape(v)
cmdline.append('%s=%s' % (k, v))
for v in args:
if _format_command_search(v):
v = _format_command_escape(v)
cmdline.append(v)
return ' '.join(cmdline)
def subprocess_capture(p, quiet=False):
def readerthread(input, output, buffer):
while True:
data = input.readline()
if not data:
break
output(data)
buffer.append(data)
if p.stdout:
stdout = []
output = quiet and (lambda data: None) or sys.stdout.write
stdout_thread = threading.Thread(target=readerthread,
args=(p.stdout, output, stdout))
stdout_thread.setDaemon(True)
stdout_thread.start()
if p.stderr:
stderr = []
stderr_thread = threading.Thread(target=readerthread,
args=(p.stderr, sys.stderr.write, stderr))
stderr_thread.setDaemon(True)
stderr_thread.start()
if p.stdout:
stdout_thread.join()
if p.stderr:
stderr_thread.join()
p.wait()
return (p.stdout and ''.join(stdout),
p.stderr and ''.join(stderr))
GIT_TYPE = 'git'
SVN_TYPE = 'svn'
......@@ -88,13 +46,14 @@ class Updater(object):
stdin = file(os.devnull)
def __init__(self, repository_path, log, revision=None, git_binary=None,
realtime_output=True):
realtime_output=True, process_manager=None):
self.log = log
self.revision = revision
self._path_list = []
self.repository_path = repository_path
self.git_binary = git_binary
self.realtime_output = realtime_output
self.process_manager = process_manager
def getRepositoryPath(self):
return self.repository_path
......@@ -128,25 +87,10 @@ class Updater(object):
raise
def spawn(self, *args, **kw):
quiet = kw.pop('quiet', False)
env = kw and dict(os.environ, **kw) or None
command = format_command(*args, **kw)
self.log('$ ' + command)
sys.stdout.flush()
p = subprocess.Popen(args, stdin=self.stdin, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, env=env,
cwd=self.getRepositoryPath())
if self.realtime_output:
stdout, stderr = subprocess_capture(p, quiet)
else:
stdout, stderr = p.communicate()
self.log(stdout)
self.log(stderr)
result = dict(status_code=p.returncode, command=command,
stdout=stdout, stderr=stderr)
if p.returncode:
raise SubprocessError(result)
return result
return self.process_manager.spawn(*args,
log_prefix='git',
cwd=self.getRepositoryPath(),
**kw)
def _git(self, *args, **kw):
return self.spawn(self.git_binary, *args, **kw)['stdout'].strip()
......
......@@ -30,12 +30,12 @@ import logging
import os
import pkg_resources
import testnode
from testnode import TestNode
CONFIG = dict(
computer_id='COMPUTER',
partition_reference='test0',
)
CONFIG = {
'computer_id': 'COMPUTER',
'partition_reference': 'test0',
}
def main(*args):
parser = argparse.ArgumentParser()
......@@ -48,15 +48,21 @@ def main(*args):
parsed_argument = parser.parse_args(list(args))
else:
parsed_argument = parser.parse_args()
logger_format = '%(asctime)s %(name)-13s: %(levelname)-8s %(message)s'
formatter = logging.Formatter(logger_format)
logging.basicConfig(level=logging.INFO,
format=logger_format)
logger = logging.getLogger('erp5testnode')
if parsed_argument.console or parsed_argument.logfile:
logger.setLevel(logging.INFO)
if parsed_argument.console:
logger.addHandler(logging.StreamHandler())
logger.info('Activated console output.')
if parsed_argument.logfile:
logger.addHandler(logging.FileHandler(filename=parsed_argument.logfile))
file_handler = logging.FileHandler(filename=parsed_argument.logfile)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.info('Activated logfile %r output' % parsed_argument.logfile)
CONFIG['log_file'] = parsed_argument.logfile
else:
logger.addHandler(logging.NullHandler())
CONFIG['logger'] = logger.info
......@@ -64,40 +70,33 @@ def main(*args):
# do not change case of option keys
config.optionxform = str
config.readfp(parsed_argument.configuration_file[0])
def geto(o):
return config.get('testnode', o)
CONFIG['slapos_directory'] = geto('slapos_directory')
CONFIG['working_directory'] = geto('working_directory')
CONFIG['test_suite_directory'] = geto('test_suite_directory')
CONFIG['log_directory'] = geto('log_directory')
CONFIG['run_directory'] = geto('run_directory')
for d in CONFIG['slapos_directory'], CONFIG['working_directory'], \
CONFIG['test_suite_directory'], CONFIG['log_directory'], \
CONFIG['run_directory']:
for key in ('slapos_directory', 'working_directory', 'test_suite_directory',
'log_directory', 'run_directory', 'proxy_host', 'proxy_port',
'git_binary', 'zip_binary', 'test_suite_title', 'test_node_title',
'test_suite', 'project_title', 'node_quantity', 'ipv4_address',
'ipv6_address', 'test_suite_master_url', 'slapgrid_partition_binary',
'slapgrid_software_binary', 'slapproxy_binary'):
CONFIG[key] = config.get('testnode', key)
for key in ('slapos_directory', 'working_directory', 'test_suite_directory',
'log_directory', 'run_directory'):
d = CONFIG[key]
if not os.path.isdir(d):
raise ValueError('Directory %r does not exists.' % d)
CONFIG['software_root'] = os.path.join(CONFIG['slapos_directory'],
'software')
CONFIG['instance_root'] = os.path.join(CONFIG['slapos_directory'],
'instance')
for d in CONFIG['software_root'], CONFIG['instance_root']:
if not os.path.lexists(d):
os.mkdir(d)
CONFIG['proxy_database'] = os.path.join(CONFIG['slapos_directory'],
'proxy.db')
CONFIG['proxy_host'] = geto('proxy_host')
CONFIG['proxy_port'] = geto('proxy_port')
slapos_directory = CONFIG['slapos_directory']
CONFIG['software_root'] = software_root = os.path.join(slapos_directory,
'software')
CONFIG['instance_root'] = instance_root = os.path.join(slapos_directory,
'instance')
CONFIG['proxy_database'] = os.path.join(slapos_directory, 'proxy.db')
CONFIG['slapos_config'] = slapos_config = os.path.join(slapos_directory,
'slapos.cfg')
if not os.path.lexists(software_root):
os.mkdir(software_root)
CONFIG['master_url'] = 'http://%s:%s' % (CONFIG['proxy_host'],
CONFIG['proxy_port'])
slapos_config = pkg_resources.resource_string('erp5.util.testnode',
'template/slapos.cfg.in')
slapos_config = slapos_config % CONFIG
CONFIG['slapos_config'] = os.path.join(CONFIG['slapos_directory'],
'slapos.cfg')
open(CONFIG['slapos_config'], 'w').write(slapos_config)
CONFIG['git_binary'] = geto('git_binary')
CONFIG['zip_binary'] = geto('zip_binary')
CONFIG['runTestSuite'] = os.path.join(CONFIG['instance_root'],
open(slapos_config, 'w').write(pkg_resources.resource_string(
'erp5.util.testnode', 'template/slapos.cfg.in') % CONFIG)
CONFIG['runTestSuite'] = os.path.join(instance_root,
CONFIG['partition_reference'], 'bin', 'runTestSuite')
# generate vcs_repository_list
......@@ -113,24 +112,16 @@ def main(*args):
CONFIG['bt5_path'] = bt5_path
CONFIG['vcs_repository_list'] = vcs_repository_list
CONFIG['test_suite_title'] = geto('test_suite_title')
CONFIG['test_node_title'] = geto('test_node_title')
CONFIG['test_suite'] = geto('test_suite')
CONFIG['project_title'] = geto('project_title')
CONFIG['node_quantity'] = geto('node_quantity')
CONFIG['ipv4_address'] = geto('ipv4_address')
CONFIG['ipv6_address'] = geto('ipv6_address')
CONFIG['test_suite_master_url'] = geto('test_suite_master_url')
CONFIG['slapgrid_partition_binary'] = geto('slapgrid_partition_binary')
CONFIG['slapgrid_software_binary'] = geto('slapgrid_software_binary')
bot_environment = {}
if 'bot_environment' in config.sections():
bot_environment = dict(config.items('bot_environment'))
else:
bot_environment = {}
CONFIG['bot_environment'] = bot_environment
CONFIG['environment'] = dict(config.items('environment'))
CONFIG['slapproxy_binary'] = geto('slapproxy_binary')
instance_dict = {}
if 'instance_dict' in config.sections():
instance_dict = dict(config.items('instance_dict'))
else:
instance_dict = {}
CONFIG['instance_dict'] = instance_dict
testnode.run(CONFIG)
testnode = TestNode(logger.info, CONFIG)
testnode.run()
This diff is collapsed.
......@@ -65,13 +65,7 @@ class SQLDict(SQLBase):
priority_list = [message.activity_kw.get('priority', 1) for message in registered_message_list]
dumped_message_list = [self.dumpMessage(message) for message in registered_message_list]
date_list = [message.activity_kw.get('at_date', None) for message in registered_message_list]
group_method_id_list = []
for m in registered_message_list:
group_method_id = m.activity_kw.get('group_method_id', '')
if group_method_id is None:
group_method_id = 'portal_activities/dummyGroupMethod/' + m.method_id
group_method_id_list.append(group_method_id + '\0' +
m.activity_kw.get('group_id', ''))
group_method_id_list = [m.getGroupId() for m in registered_message_list]
tag_list = [message.activity_kw.get('tag', '') for message in registered_message_list]
serialization_tag_list = [message.activity_kw.get('serialization_tag', '') for message in registered_message_list]
order_validation_text_list = [self.getOrderValidationText(message) for message in registered_message_list]
......
......@@ -66,13 +66,7 @@ class SQLQueue(SQLBase):
method_id_list = [m.method_id for m in registered_message_list]
priority_list = [m.activity_kw.get('priority', 1) for m in registered_message_list]
date_list = [m.activity_kw.get('at_date', None) for m in registered_message_list]
group_method_id_list = []
for m in registered_message_list:
group_method_id = m.activity_kw.get('group_method_id', '')
if group_method_id is None:
group_method_id = 'portal_activities/dummyGroupMethod/' + m.method_id
group_method_id_list.append(group_method_id + '\0' +
m.activity_kw.get('group_id', ''))
group_method_id_list = [m.getGroupId() for m in registered_message_list]
tag_list = [m.activity_kw.get('tag', '') for m in registered_message_list]
serialization_tag_list = [m.activity_kw.get('serialization_tag', '') for m in registered_message_list]
dumped_message_list = [self.dumpMessage(m) for m in registered_message_list]
......
......@@ -203,6 +203,13 @@ class Message(BaseMessage):
request.environ['HTTP_ACCEPT_LANGUAGE']
self.request_info['_script'] = list(request._script)
def getGroupId(self):
get = self.activity_kw.get
group_method_id = get('group_method_id', '')
if group_method_id is None:
group_method_id = 'portal_activities/dummyGroupMethod/' + self.method_id
return group_method_id + '\0' + get('group_id', '')
def getObject(self, activity_tool):
"""return the object referenced in this message."""
return activity_tool.unrestrictedTraverse(self.object_path)
......
......@@ -14,14 +14,6 @@ DeadlockDebugger can of course also be used in non-deadlock situations,
when a Zope process is taking a long time and you wish to know what code
is being executed.
Installation
------------
This product requires the 'threadframe' python module
(http://www.majid.info/mylos/stories/2004/06/10/threadframe.html).
When DeadlockDebugger starts, it verifies that threadframe is available,
please check the event.log for ERROR message.
Configuration
-------------
......
......@@ -28,24 +28,19 @@ You MUST configure zope.conf before use.
from zLOG import LOG, INFO, ERROR
from App.config import getConfiguration
try:
import threadframe
except ImportError:
LOG('DeadlockDebugger', ERROR, "Incorrectly installed threadframe module")
else:
config = getConfiguration()
if getattr(config, 'product_config', None) is not None:
deadlockdebugger = config.product_config.get('deadlockdebugger')
dump_url = ''
secret = ''
if deadlockdebugger is None:
LOG('DeadlockDebugger', ERROR, 'Missing configuration statement '
'<product-config deadlockdebugger>, not activated')
config = getConfiguration()
if getattr(config, 'product_config', None) is not None:
deadlockdebugger = config.product_config.get('deadlockdebugger')
dump_url = ''
secret = ''
if deadlockdebugger is None:
LOG('DeadlockDebugger', ERROR, 'Missing configuration statement '
'<product-config deadlockdebugger>, not activated')
else:
if not 'dump_url' in deadlockdebugger:
LOG('DeadlockDebugger', ERROR, 'Please configure dump_url and '
'optionally secret in <product-config deadlockdebugger>, not '
'activated')
else:
if not 'dump_url' in deadlockdebugger:
LOG('DeadlockDebugger', ERROR, 'Please configure dump_url and '
'optionally secret in <product-config deadlockdebugger>, not '
'activated')
else:
import dumper
LOG('DeadlockDebugger', INFO, "Installed")
import dumper
LOG('DeadlockDebugger', INFO, "Installed")
......@@ -23,7 +23,7 @@ ZServer hook to dump a traceback of the running python threads.
"""
import thread
import threadframe
from sys import _current_frames
import traceback
import time
from cStringIO import StringIO
......@@ -36,11 +36,10 @@ def dump_threads():
Returns a string with the tracebacks.
"""
frames = threadframe.dict()
this_thread_id = thread.get_ident()
now = time.strftime("%Y-%m-%d %H:%M:%S")
res = ["Threads traceback dump at %s\n" % now]
for thread_id, frame in frames.iteritems():
for thread_id, frame in _current_frames().iteritems():
if thread_id == this_thread_id:
continue
......@@ -68,7 +67,6 @@ def dump_threads():
res.append("Thread %s%s:\n%s" %
(thread_id, reqinfo, output.getvalue()))
frames = None
res.append("End of dump")
result = '\n'.join(res)
if isinstance(result, unicode):
......
......@@ -339,18 +339,12 @@ class Delivery(XMLObject, ImmobilisationDelivery,
security.declareProtected(Permissions.AccessContentsInformation, 'isSimulated')
def isSimulated(self):
"""
Returns 1 if all movements have a delivery or order counterpart
Returns 1 if all non-null movements have a delivery counterpart
in the simulation
"""
for m in self.getMovementList():
#LOG('Delivery.isSimulated m',0,m.getPhysicalPath())
#LOG('Delivery.isSimulated m.isSimulated',0,m.isSimulated())
if not m.isSimulated():
#LOG('Delivery.isSimulated m.getQuantity',0,m.getQuantity())
#LOG('Delivery.isSimulated m.getSimulationQuantity',0,m.getSimulationQuantity())
if m.getQuantity() != 0.0 or m.getSimulationQuantity() not in (0, None):
return 0
# else Do we need to create a simulation movement ? XXX probably not
if m.getQuantity() and not m.isSimulated():
return 0
return 1
security.declareProtected(Permissions.AccessContentsInformation, 'isDivergent')
......@@ -844,21 +838,21 @@ class Delivery(XMLObject, ImmobilisationDelivery,
This method will look at the causality and check if the
causality has already a causality
"""
causality_value_list = [x for x in self.getCausalityValueList()
if x is not self]
initial_list = []
if len(causality_value_list)==0:
initial_list = [self]
else:
causality_value_list = self.getCausalityValueList()
if causality_value_list:
initial_list = []
for causality in causality_value_list:
# The causality may be something which has not this method
# (e.g. item)
if hasattr(causality, 'getRootCausalityValueList'):
tmp_causality_list = causality.getRootCausalityValueList()
initial_list.extend([x for x in tmp_causality_list
if x not in initial_list])
return initial_list
try:
getRootCausalityValueList = causality.getRootCausalityValueList
except AttributeError:
continue
assert causality != self
initial_list += [x for x in getRootCausalityValueList()
if x not in initial_list]
return initial_list
return [self]
# XXX Temp hack, should be removed has soon as the structure of
# the order/delivery builder will be reviewed. It might
......@@ -982,6 +976,7 @@ class Delivery(XMLObject, ImmobilisationDelivery,
"""
divergent_tester_list = []
for simulation_movement in self._getAllRelatedSimulationMovementList():
simulation_movement = simulation_movement.getObject()
rule = simulation_movement.getParentValue().getSpecialiseValue()
for tester in rule._getDivergenceTesterList(exclude_quantity=False):
if tester.explain(simulation_movement) not in (None, []):
......
##############################################################################
#
# Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved.
# Yoshinori Okuji <yo@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5Type.XMLObject import XMLObject
from Products.ExtFile.ExtFile import ExtFile
from Products.ExtFile.ExtImage import ExtImage
import os
from App.config import getConfiguration
from Products.ERP5 import product_path
from Shared.DC.ZRDB.TM import TM
import shutil
from zLOG import LOG
class Deletion(TM):
"""Remove the directory at the end of a transaction.
"""
def __init__(self, path):
self.path = path
self._register()
def _finish(self):
try:
LOG('Deletion', 0, 'removing %s' % self.path)
shutil.rmtree(self.path)
except OSError:
pass
def _abort(self):
pass
class ExtFolder( XMLObject ):
"""
ExtFolder stores sub-objects as ExtFile or ExtImage.
"""
# Default Properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
)
# CMF Type Definition
meta_type='ERP5 External Folder'
portal_type='External Folder'
add_permission = Permissions.AddPortalContent
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
security.declarePrivate('PUT_factory')
def PUT_factory( self, name, typ, body ):
"""Return an ExtFile or ExtImage object.
"""
major, minor = typ.split('/', 1)
if major == 'image':
return ExtImage(name)
return ExtFile(name)
def _getRepositoryPath(self):
"""Return the path in the filesystem.
"""
instance_home = getConfiguration().instancehome
repository = os.path.join(*ExtFile._repository)
return os.path.sep.join((instance_home, repository, self.getPath()))
security.declareProtected('Manage portal', 'generateRpmHeaderList')
def generateRpmHeaderList(self):
"""Run genhdlist on the directory behind this object.
"""
status = os.system("/usr/bin/genhdlist -s %s" % self._getRepositoryPath())
if status != 0:
raise RuntimeError, "failed in executing genhdlist"
security.declareProtected('Manage portal', 'generateBt5HeaderList')
def generateBt5HeaderList(self):
"""Run genbt5list on the directory behind this object.
"""
status = os.system("%s/bin/genbt5list %s" % (product_path, self._getRepositoryPath()))
if status != 0:
raise RuntimeError, "failed in executing genbt5list"
def manage_beforeDelete(self, item, container):
"""Called before deleting this object.
"""
self._v_deletion = Deletion(self._getRepositoryPath())
XMLObject.manage_beforeDelete(self, item, container)
......@@ -348,11 +348,8 @@ class SimulatedDeliveryBuilder(BuilderMixin):
if old_delivery is None:
# from scratch
new_delivery_id = str(delivery_module.generateNewId())
delivery = delivery_module.newContent(
portal_type=self.getDeliveryPortalType(),
id=new_delivery_id,
created_by_builder=1,
activate_kw=activate_kw)
delivery = super(SimulatedDeliveryBuilder, self)._createDelivery(
delivery_module, movement_list, activate_kw)
else:
# from duplicated original delivery
cp = tryMethodCallWithTemporaryPermission(
......@@ -383,10 +380,8 @@ class SimulatedDeliveryBuilder(BuilderMixin):
old_delivery_line = None
if old_delivery_line is None:
# from scratch
new_delivery_line_id = str(delivery.generateNewId())
delivery_line = delivery.newContent(
portal_type=self.getDeliveryLinePortalType(),
id=new_delivery_line_id,
variation_category_list=[],
activate_kw=activate_kw)
else:
......
......@@ -193,7 +193,7 @@ class IdTool(BaseTool):
last_generator = self._getLatestGeneratorValue(id_generator)
new_id_list = last_generator.generateNewIdList(id_group=id_group,
id_count=id_count, default=default)
except KeyError:
except (KeyError, ValueError):
template_tool = getattr(self, 'portal_templates', None)
revision = template_tool.getInstalledBusinessTemplateRevision('erp5_core')
# XXX backward compatiblity
......
......@@ -256,3 +256,26 @@ class TaskDistributionTool(BaseTool):
break
else:
test_result.fail()
security.declarePublic('reportTaskStatus')
def reportTaskStatus(self, test_result_path, status_dict, node_title):
"""report status of node
"""
status_dict = self._extractXMLRPCDict(status_dict)
LOG("TaskDistributionTool.reportTaskStatus", 0, repr((test_result_path,
status_dict)))
portal = self.getPortalObject()
test_result = portal.restrictedTraverse(test_result_path)
node = self._getTestResultNode(test_result, node_title)
assert node is not None
node.edit(cmdline=status_dict['command'],
stdout=status_dict['stdout'], stderr=status_dict['stderr'])
security.declarePublic('isTaskAlive')
def isTaskAlive(self, test_result_path):
"""check status of a test suite
"""
LOG("TaskDistributionTool.checkTaskStatus", 0, repr(test_result_path))
portal = self.getPortalObject()
test_result = portal.restrictedTraverse(test_result_path)
return test_result.getSimulationState() == "started" and 1 or 0
......@@ -62,6 +62,7 @@
<value>
<list>
<string>listbox</string>
<string>listbox_modification_date</string>
</list>
</value>
</item>
......
......@@ -310,7 +310,12 @@
<item>
<key> <string>all_columns</string> </key>
<value>
<list/>
<list>
<tuple>
<string>modification_date</string>
<string>Modification Date</string>
</tuple>
</list>
</value>
</item>
<item>
......@@ -376,6 +381,10 @@
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default_display_style</string> </key>
<value> <string>table</string> </value>
</item>
<item>
<key> <string>default_params</string> </key>
<value>
......@@ -409,7 +418,12 @@
<item>
<key> <string>editable_columns</string> </key>
<value>
<list/>
<list>
<tuple>
<string>modification_date</string>
<string></string>
</tuple>
</list>
</value>
</item>
<item>
......@@ -430,6 +444,10 @@
<list/>
</value>
</item>
<item>
<key> <string>global_search_column</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>height</string> </key>
<value> <int>5</int> </value>
......@@ -477,6 +495,10 @@
</list>
</value>
</item>
<item>
<key> <string>page_navigation_template</string> </key>
<value> <string>ListBox_viewSliderPageNavigationRenderer</string> </value>
</item>
<item>
<key> <string>page_template</string> </key>
<value> <string></string> </value>
......@@ -584,6 +606,10 @@
<string>revision</string>
<string>Revision</string>
</tuple>
<tuple>
<string>modification_date</string>
<string>Modification Date</string>
</tuple>
</list>
</value>
</item>
......@@ -597,6 +623,12 @@
<key> <string>stat_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>style_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Business Templates</string> </value>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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