Commit ebbf73db authored by Łukasz Nowak's avatar Łukasz Nowak

Merge remote-tracking branch 'origin/master' into interaction-drop

Conflicts:
	bt5/erp5_promise/PathTemplateItem/portal_alarms/promise_conversion_server.xml
	bt5/erp5_promise/PathTemplateItem/portal_alarms/promise_install_bt5.xml
	bt5/erp5_promise/PathTemplateItem/portal_alarms/promise_kumofs_server.xml
	bt5/erp5_promise/PathTemplateItem/portal_alarms/promise_mailhost_configuration.xml
	bt5/erp5_promise/PathTemplateItem/portal_alarms/promise_memcached_server.xml
	bt5/erp5_promise/PathTemplateItem/portal_alarms/promise_template_tool_configuration.xml
	bt5/erp5_promise/SkinTemplateItem/portal_skins/erp5_promise/Alarm_checkPromiseMailServer.xml
	bt5/erp5_promise/bt/description
	bt5/erp5_promise/bt/revision
	product/ERP5/ERP5Site.py
parents 70ffb3f0 39125bfe
Changes Changes
======= =======
0.4.6 (2012-08-10)
------------------
* erp5.util.taskdistribution:
- set socket timeout for RPC calls to prevent a deadlock happens.
[Rafael Monnerat]
0.4.5 (2012-07-04) 0.4.5 (2012-07-04)
------------------ ------------------
......
...@@ -65,7 +65,6 @@ configuration_save.addConfigurationItem("Permission Configurator Item",\n ...@@ -65,7 +65,6 @@ configuration_save.addConfigurationItem("Permission Configurator Item",\n
\n \n
# Create ERP5Site_getSecurityCategoryMapping\n # Create ERP5Site_getSecurityCategoryMapping\n
configuration_save.addConfigurationItem("Security Category Mapping Configurator Item")\n configuration_save.addConfigurationItem("Security Category Mapping Configurator Item")\n
</string> </value> </string> </value>
</item> </item>
<item> <item>
......
...@@ -221,7 +221,7 @@ ...@@ -221,7 +221,7 @@
Tips: <br>\n Tips: <br>\n
<br>\n <br>\n
<li> You can use this sample file <a href="consulting_configurator_sample_categories.ods"> Consulting.Configurator.Sample.Categories.ods </a></li> <li> You can use this sample file <a href="standard_category.ods"> Standard Configurator Categories </a></li>
]]></string> </value> ]]></string> </value>
</item> </item>
......
639 640
\ No newline at end of file \ No newline at end of file
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
<key> <string>actbox_category</string> </key> <key> <string>actbox_category</string> </key>
<value> <string>global</string> </value> <value> <string>global</string> </value>
</item> </item>
<item>
<key> <string>actbox_icon</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>actbox_name</string> </key> <key> <string>actbox_name</string> </key>
<value> <string>Sale Opportunities to Validate (%(count)s)</string> </value> <value> <string>Sale Opportunities to Validate (%(count)s)</string> </value>
...@@ -18,7 +22,7 @@ ...@@ -18,7 +22,7 @@
<key> <string>actbox_url</string> </key> <key> <string>actbox_url</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
sale_opportunity_module/view?simulation_state=draft&local_roles=Owner sale_opportunity_module?reset:int=1&simulation_state=draft&local_roles=Owner
]]></string> </value> ]]></string> </value>
</item> </item>
...@@ -47,10 +51,7 @@ sale_opportunity_module/view?simulation_state=draft&local_roles=Owner ...@@ -47,10 +51,7 @@ sale_opportunity_module/view?simulation_state=draft&local_roles=Owner
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle> <pickle>
<tuple>
<global name="Guard" module="Products.DCWorkflow.Guard"/> <global name="Guard" module="Products.DCWorkflow.Guard"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -67,10 +68,7 @@ sale_opportunity_module/view?simulation_state=draft&local_roles=Owner ...@@ -67,10 +68,7 @@ sale_opportunity_module/view?simulation_state=draft&local_roles=Owner
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<tuple>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
......
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
<key> <string>actbox_category</string> </key> <key> <string>actbox_category</string> </key>
<value> <string>global</string> </value> <value> <string>global</string> </value>
</item> </item>
<item>
<key> <string>actbox_icon</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>actbox_name</string> </key> <key> <string>actbox_name</string> </key>
<value> <string>Submitted Sale Opportunities to Validate (%(count)s)</string> </value> <value> <string>Submitted Sale Opportunities to Validate (%(count)s)</string> </value>
...@@ -18,7 +22,7 @@ ...@@ -18,7 +22,7 @@
<key> <string>actbox_url</string> </key> <key> <string>actbox_url</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
sale_opportunity_module/view?simulation_state=submitted&local_roles=Assignor sale_opportunity_module?reset:int=1&simulation_state=submitted&local_roles=Assignor
]]></string> </value> ]]></string> </value>
</item> </item>
...@@ -47,10 +51,7 @@ sale_opportunity_module/view?simulation_state=submitted&local_roles=Assignor ...@@ -47,10 +51,7 @@ sale_opportunity_module/view?simulation_state=submitted&local_roles=Assignor
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle> <pickle>
<tuple>
<global name="Guard" module="Products.DCWorkflow.Guard"/> <global name="Guard" module="Products.DCWorkflow.Guard"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -67,10 +68,7 @@ sale_opportunity_module/view?simulation_state=submitted&local_roles=Assignor ...@@ -67,10 +68,7 @@ sale_opportunity_module/view?simulation_state=submitted&local_roles=Assignor
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<tuple>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
......
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
<key> <string>actbox_category</string> </key> <key> <string>actbox_category</string> </key>
<value> <string>global</string> </value> <value> <string>global</string> </value>
</item> </item>
<item>
<key> <string>actbox_icon</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>actbox_name</string> </key> <key> <string>actbox_name</string> </key>
<value> <string>Sale Opportunities to Qualify (%(count)s)</string> </value> <value> <string>Sale Opportunities to Qualify (%(count)s)</string> </value>
...@@ -18,7 +22,7 @@ ...@@ -18,7 +22,7 @@
<key> <string>actbox_url</string> </key> <key> <string>actbox_url</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
sale_opportunity_module/view?simulation_state=contacted&local_roles:list=Assignee&local_roles:list=Assignor sale_opportunity_module?reset:int=1&simulation_state=contacted&local_roles:list=Assignee&local_roles:list=Assignor
]]></string> </value> ]]></string> </value>
</item> </item>
...@@ -47,10 +51,7 @@ sale_opportunity_module/view?simulation_state=contacted&local_roles:list=Assigne ...@@ -47,10 +51,7 @@ sale_opportunity_module/view?simulation_state=contacted&local_roles:list=Assigne
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle> <pickle>
<tuple>
<global name="Guard" module="Products.DCWorkflow.Guard"/> <global name="Guard" module="Products.DCWorkflow.Guard"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -68,10 +69,7 @@ sale_opportunity_module/view?simulation_state=contacted&local_roles:list=Assigne ...@@ -68,10 +69,7 @@ sale_opportunity_module/view?simulation_state=contacted&local_roles:list=Assigne
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<tuple>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
......
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
<key> <string>actbox_category</string> </key> <key> <string>actbox_category</string> </key>
<value> <string>global</string> </value> <value> <string>global</string> </value>
</item> </item>
<item>
<key> <string>actbox_icon</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>actbox_name</string> </key> <key> <string>actbox_name</string> </key>
<value> <string>Offers to Send (%(count)s)</string> </value> <value> <string>Offers to Send (%(count)s)</string> </value>
...@@ -18,7 +22,7 @@ ...@@ -18,7 +22,7 @@
<key> <string>actbox_url</string> </key> <key> <string>actbox_url</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
sale_opportunity_module/view?simulation_state=enquired&local_roles:list=Assignee&local_roles:list=Assignor sale_opportunity_module?reset:int=1&simulation_state=enquired&local_roles:list=Assignee&local_roles:list=Assignor
]]></string> </value> ]]></string> </value>
</item> </item>
...@@ -47,10 +51,7 @@ sale_opportunity_module/view?simulation_state=enquired&local_roles:list=Assignee ...@@ -47,10 +51,7 @@ sale_opportunity_module/view?simulation_state=enquired&local_roles:list=Assignee
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle> <pickle>
<tuple>
<global name="Guard" module="Products.DCWorkflow.Guard"/> <global name="Guard" module="Products.DCWorkflow.Guard"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -68,10 +69,7 @@ sale_opportunity_module/view?simulation_state=enquired&local_roles:list=Assignee ...@@ -68,10 +69,7 @@ sale_opportunity_module/view?simulation_state=enquired&local_roles:list=Assignee
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<tuple>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
......
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
<key> <string>actbox_category</string> </key> <key> <string>actbox_category</string> </key>
<value> <string>global</string> </value> <value> <string>global</string> </value>
</item> </item>
<item>
<key> <string>actbox_icon</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>actbox_name</string> </key> <key> <string>actbox_name</string> </key>
<value> <string>Pending Offers (%(count)s)</string> </value> <value> <string>Pending Offers (%(count)s)</string> </value>
...@@ -18,7 +22,7 @@ ...@@ -18,7 +22,7 @@
<key> <string>actbox_url</string> </key> <key> <string>actbox_url</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
sale_opportunity_module/view?simulation_state=offered&local_roles:list=Assignee&local_roles:list=Assignor sale_opportunity_module?reset:int=1&simulation_state=offered&local_roles:list=Assignee&local_roles:list=Assignor
]]></string> </value> ]]></string> </value>
</item> </item>
...@@ -47,10 +51,7 @@ sale_opportunity_module/view?simulation_state=offered&local_roles:list=Assignee& ...@@ -47,10 +51,7 @@ sale_opportunity_module/view?simulation_state=offered&local_roles:list=Assignee&
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle> <pickle>
<tuple>
<global name="Guard" module="Products.DCWorkflow.Guard"/> <global name="Guard" module="Products.DCWorkflow.Guard"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -68,10 +69,7 @@ sale_opportunity_module/view?simulation_state=offered&local_roles:list=Assignee& ...@@ -68,10 +69,7 @@ sale_opportunity_module/view?simulation_state=offered&local_roles:list=Assignee&
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<tuple>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
......
596 597
\ No newline at end of file \ No newline at end of file
...@@ -97,7 +97,7 @@ ...@@ -97,7 +97,7 @@
<string>link</string> <string>link</string>
</tuple> </tuple>
<tuple> <tuple>
<string>description</string> <string>DiscussionPost_getDescription</string>
<string>description</string> <string>description</string>
</tuple> </tuple>
<tuple> <tuple>
......
...@@ -121,6 +121,10 @@ ...@@ -121,6 +121,10 @@
<string>title</string> <string>title</string>
<string>Title</string> <string>Title</string>
</tuple> </tuple>
<tuple>
<string>reference</string>
<string>Reference</string>
</tuple>
<tuple> <tuple>
<string>translated_validation_state_title</string> <string>translated_validation_state_title</string>
<string>State</string> <string>State</string>
...@@ -140,6 +144,10 @@ ...@@ -140,6 +144,10 @@
<string>title</string> <string>title</string>
<string>Title</string> <string>Title</string>
</tuple> </tuple>
<tuple>
<string>reference</string>
<string>Reference</string>
</tuple>
<tuple> <tuple>
<string>agent_value</string> <string>agent_value</string>
<string>Related</string> <string>Related</string>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>return context.getTextContent()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>DiscussionPost_getDescription</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
115 116
\ No newline at end of file \ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
2012-07-30 Kazuhiko
* jQuery Core 1.7.2.
2011-12-01 Kazuhiko 2011-12-01 Kazuhiko
* jQuery Core 1.7.1. * jQuery Core 1.7.1.
......
This Business Template contains jQuery Core. This Business Template contains jQuery Core.
Current version is jQuery 1.7.1. Current version is jQuery 1.7.2.
\ No newline at end of file \ No newline at end of file
14 15
\ No newline at end of file \ No newline at end of file
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts31202676.8</string> </value> <value> <string>ts43624880.19</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -24,8 +24,9 @@ ...@@ -24,8 +24,9 @@
</item> </item>
<item> <item>
<key> <string>data</string> </key> <key> <string>data</string> </key>
<value> <string encoding="base64">iVBORw0KGgoAAAANSUhEUgAAACgAAABkAQMAAADOquA5AAAAA1BMVEWqqqoRfvv5AAAAD0lEQVQY <value> <string encoding="base64">iVBORw0KGgoAAAANSUhEUgAAACgAAABkCAYAAAD0ZHJ6AAAAXElEQVRo3u3OMQ0AAAgDsPmXMpNg
GWNgGAWjgPoAAAJYAAHlK0hvAAAAAElFTkSuQmCC</string> </value> g5Ae/Zu2c1kEBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUF
BQUFBQUFBQUFBQUFvwQXQyiz05YjDDkAAAAASUVORK5CYII=</string> </value>
</item> </item>
<item> <item>
<key> <string>height</string> </key> <key> <string>height</string> </key>
...@@ -37,7 +38,7 @@ GWNgGAWjgPoAAAJYAAHlK0hvAAAAAElFTkSuQmCC</string> </value> ...@@ -37,7 +38,7 @@ GWNgGAWjgPoAAAJYAAHlK0hvAAAAAElFTkSuQmCC</string> </value>
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>87</int> </value> <value> <int>149</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts31202666.15</string> </value> <value> <string>ts43624890.48</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -24,8 +24,9 @@ ...@@ -24,8 +24,9 @@
</item> </item>
<item> <item>
<key> <string>data</string> </key> <key> <string>data</string> </key>
<value> <string encoding="base64">iVBORw0KGgoAAAANSUhEUgAAACgAAABkAQMAAADOquA5AAAAA1BMVEXj6vr1J1NHAAAAD0lEQVQY <value> <string encoding="base64">iVBORw0KGgoAAAANSUhEUgAAACgAAABkCAYAAAGDY0LsAAAAZ0lEQVRo3u3OoQ0AMAhFQfZfs44R
GWNgGAWjgPoAAAJYAAHlK0hvAAAAAElFTkSuQmCC</string> </value> alqPwBNOYMjPy8XJ++qFp2f7NDQ0NDRcOhQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUHBkEBAQEBAQE
BAQEBAQEBAQEBAQEBAQEBAQEBAQEBARcAfxPn/knx13hBgAAAABJRU5ErkJggg==</string> </value>
</item> </item>
<item> <item>
<key> <string>height</string> </key> <key> <string>height</string> </key>
...@@ -37,7 +38,7 @@ GWNgGAWjgPoAAAJYAAHlK0hvAAAAAElFTkSuQmCC</string> </value> ...@@ -37,7 +38,7 @@ GWNgGAWjgPoAAAJYAAHlK0hvAAAAAElFTkSuQmCC</string> </value>
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>87</int> </value> <value> <int>160</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts26730022.12</string> </value> <value> <string>ts43624907.99</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -24,9 +24,9 @@ ...@@ -24,9 +24,9 @@
</item> </item>
<item> <item>
<key> <string>data</string> </key> <key> <string>data</string> </key>
<value> <string encoding="base64">iVBORw0KGgoAAAANSUhEUgAAAAEAAAGQCAYAAABvWArbAAAAQ0lEQVQ4je3PoQ2AQABD0f+7/4oM <value> <string encoding="base64">iVBORw0KGgoAAAANSUhEUgAAAAEAAAGQCAYAAAEYXzpNAAAAZElEQVQ4y+3UOw6AIBgD4N7/dGqM
gEZwCjAcigEIqXlJm1SUZR1nAEopv2XbDyIQnV0CiZLIJDP6dOq9jX7hTCnljQtFvQnqrH32ZgAA McYHiBjxsQK61MUr6D/g8u1Nm6JzkZAiU55ol0jY4/oa0eSl8cS4n+klF6XQnqhtIIZVZnVSpNt5
AABJRU5ErkJggg==</string> </value> uuTKP5OvpkA0cyB6Fwm9RcIIvc/Pi9yoJuFbfrTHoAAAAABJRU5ErkJggg==</string> </value>
</item> </item>
<item> <item>
<key> <string>height</string> </key> <key> <string>height</string> </key>
...@@ -38,7 +38,7 @@ AABJRU5ErkJggg==</string> </value> ...@@ -38,7 +38,7 @@ AABJRU5ErkJggg==</string> </value>
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>124</int> </value> <value> <int>157</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts31202757.95</string> </value> <value> <string>ts43624922.02</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -30,74 +30,74 @@ IiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQk ...@@ -30,74 +30,74 @@ IiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQk
IiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQk IiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQk
IiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiTww4gUAAAA IiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiQkIiTww4gUAAAA
TnRSTlMAGBAyBAhQv4OZLiJUcEBmYBoSzQwgPBZCSEoeWiYwUiyFNIeBw2rJz8c4RBy9uXyrtaWN TnRSTlMAGBAyBAhQv4OZLiJUcEBmYBoSzQwgPBZCSEoeWiYwUiyFNIeBw2rJz8c4RBy9uXyrtaWN
qa2zKP2fJO8KBgKPo2KVoa9s351GPm5+kWho0kj9AAAO1UlEQVR42u1dC2PbthEGyIhq6JiSLWtp qa2zKP2fJO8KBgKPo2KVoa9s351GPm5+kWho0kj9AAAO1klEQVR42u1dC2PbthEGyIhq6JiSLWtJ
7FprMnvzkmxr126tmi2p3XRJ1/X+/88ZQIrE3eElWjItR/jk1xF84D4egLsDSAuRkJCwA5Ag91x/ 7FprMnvzkmxr126tmi2p3XRJ1+X+/88ZQIrE3eElWjIt2/jk1xF84D4egLsDSAuRkJCwA5AgH7j+
2HEGNq6ehLD+EjOgdx6WEGaBoEEJ4PUh5bpU4i0AtoqBC7Dj6z8HNQlugTYBkteHlPM7aBHAD7cv sOMMbFw9CWH9JWZA7zwsIcwCQYMSwOtDynWpxFsAbBUDF2DH138OahLcAm0CJK8PKed30CKAH25f
YO0sB2TAqr9bhUC5zaAIGhCEGsRqZxncabsNnFuwXUV+g20LCd5h2wICFRjeAtykBG5h0IKdO1h9 wNpZDsiAVX+3CoFym0ERNCAINYjVzjK403YbOLdgu4r8BtsWErzDtgUEKjC8BbhJCdzCoAU7d7D6
QMgEh+8D7nsU4E1o+FEgOUIJCQkJCQkJCffmCd6zHyStaA248y4DCgHwAF/2ygdYCSF19kEpcVTA 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</string> </value> R35ALzal+U5I2HH8H8nmcxxRUAcPAAAAAElFTkSuQmCC</string> </value>
</item> </item>
<item> <item>
<key> <string>height</string> </key> <key> <string>height</string> </key>
...@@ -109,7 +109,7 @@ BIEgi6ltGUSygNQHPCQC9n0USEhISEhISNg25MPxBKKrICHvv9BVsv8PtNP3SsiNCeD3+yHpvw0L ...@@ -109,7 +109,7 @@ BIEgi6ltGUSygNQHPCQC9n0USEhISEhISNg25MPxBKKrICHvv9BVsv8PtNP3SsiNCeD3+yHpvw0L
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>4193</int> </value> <value> <int>4194</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts31202787.39</string> </value> <value> <string>ts43624928.95</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -30,74 +30,74 @@ gvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvws ...@@ -30,74 +30,74 @@ gvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvws
gvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvws gvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvws
gvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvzLrJBNAAAA gvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvwsgvzLrJBNAAAA
TnRSTlMAGBAyBAhQv4OZLiJUcEBmYBoSzQwgPBZCSEoeWiYwUiyFNIeBw2rJz8c4RBy9uXyrtaWN TnRSTlMAGBAyBAhQv4OZLiJUcEBmYBoSzQwgPBZCSEoeWiYwUiyFNIeBw2rJz8c4RBy9uXyrtaWN
qa2zKP2fJO8KBgKPo2KVoa9s351GPm5+kWho0kj9AAAO1UlEQVR42u1dC2PbthEGyIhq6JiSLWtp qa2zKP2fJO8KBgKPo2KVoa9s351GPm5+kWho0kj9AAAO1klEQVR42u1dC2PbthEGyIhq6JiSLWtJ
7FprMnvzkmxr126tmi2p3XRJ1/X+/88ZQIrE3eElWjItR/jk1xF84D4egLsDSAuRkJCwA5Ag91x/ 7FprMnvzkmxr126tmi2p3XRJ1+X+/88ZQIrE3eElWjIt2/jk1xF84D4egLsDSAuRkJCwA5AgH7j+
2HEGNq6ehLD+EjOgdx6WEGaBoEEJ4PUh5bpU4i0AtoqBC7Dj6z8HNQlugTYBkteHlPM7aBHAD7cv sOMMbFw9CWH9JWZA7zwsIcwCQYMSwOtDynWpxFsAbBUDF2DH138OahLcAm0CJK8PKed30CKAH25f
YO0sB2TAqr9bhUC5zaAIGhCEGsRqZxncabsNnFuwXUV+g20LCd5h2wICFRjeAtykBG5h0IKdO1h9 wNpZDsiAVX+3CoFym0ERNCAINYjVzjK403YbOLdgu4r8BtsWErzDtgUEKjC8BbhJCdzCoAU7d7D6
QMgEh+8D7nsU4E1o+FEgOUIJCQkJCQkJCffmCd6zHyStaA248y4DCgHwAF/2ygdYCSF19kEpcVTA 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</string> </value> R35ALzal+U5I2HH8H8nmcxxRUAcPAAAAAElFTkSuQmCC</string> </value>
</item> </item>
<item> <item>
<key> <string>height</string> </key> <key> <string>height</string> </key>
...@@ -109,7 +109,7 @@ BIEgi6ltGUSygNQHPCQC9n0USEhISEhISNg25MPxBKKrICHvv9BVsv8PtNP3SsiNCeD3+yHpvw0L ...@@ -109,7 +109,7 @@ BIEgi6ltGUSygNQHPCQC9n0USEhISEhISNg25MPxBKKrICHvv9BVsv8PtNP3SsiNCeD3+yHpvw0L
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>4193</int> </value> <value> <int>4194</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts31202794.89</string> </value> <value> <string>ts43624935.34</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -30,74 +30,74 @@ RkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRE ...@@ -30,74 +30,74 @@ RkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRE
RkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRE RkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRE
RkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkQfbf86AAAA RkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkRERkQfbf86AAAA
TnRSTlMAGBAyBAhQv4OZLiJUcEBmYBoSzQwgPBZCSEoeWiYwUiyFNIeBw2rJz8c4RBy9uXyrtaWN TnRSTlMAGBAyBAhQv4OZLiJUcEBmYBoSzQwgPBZCSEoeWiYwUiyFNIeBw2rJz8c4RBy9uXyrtaWN
qa2zKP2fJO8KBgKPo2KVoa9s351GPm5+kWho0kj9AAAO1UlEQVR42u1dC2PbthEGyIhq6JiSLWtp qa2zKP2fJO8KBgKPo2KVoa9s351GPm5+kWho0kj9AAAO1klEQVR42u1dC2PbthEGyIhq6JiSLWtJ
7FprMnvzkmxr126tmi2p3XRJ1/X+/88ZQIrE3eElWjItR/jk1xF84D4egLsDSAuRkJCwA5Ag91x/ 7FprMnvzkmxr126tmi2p3XRJ1+X+/88ZQIrE3eElWjIt2/jk1xF84D4egLsDSAuRkJCwA5AgH7j+
2HEGNq6ehLD+EjOgdx6WEGaBoEEJ4PUh5bpU4i0AtoqBC7Dj6z8HNQlugTYBkteHlPM7aBHAD7cv sOMMbFw9CWH9JWZA7zwsIcwCQYMSwOtDynWpxFsAbBUDF2DH138OahLcAm0CJK8PKed30CKAH25f
YO0sB2TAqr9bhUC5zaAIGhCEGsRqZxncabsNnFuwXUV+g20LCd5h2wICFRjeAtykBG5h0IKdO1h9 wNpZDsiAVX+3CoFym0ERNCAINYjVzjK403YbOLdgu4r8BtsWErzDtgUEKjC8BbhJCdzCoAU7d7D6
QMgEh+8D7nsU4E1o+FEgOUIJCQkJCQkJCffmCd6zHyStaA248y4DCgHwAF/2ygdYCSF19kEpcVTA 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</string> </value> R35ALzal+U5I2HH8H8nmcxxRUAcPAAAAAElFTkSuQmCC</string> </value>
</item> </item>
<item> <item>
<key> <string>height</string> </key> <key> <string>height</string> </key>
...@@ -109,7 +109,7 @@ BIEgi6ltGUSygNQHPCQC9n0USEhISEhISNg25MPxBKKrICHvv9BVsv8PtNP3SsiNCeD3+yHpvw0L ...@@ -109,7 +109,7 @@ BIEgi6ltGUSygNQHPCQC9n0USEhISEhISNg25MPxBKKrICHvv9BVsv8PtNP3SsiNCeD3+yHpvw0L
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>4193</int> </value> <value> <int>4194</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts31202803.11</string> </value> <value> <string>ts43624942.05</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -30,74 +30,74 @@ ioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyM ...@@ -30,74 +30,74 @@ ioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyM
ioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyM ioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyM
ioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMiozJxoFPAAAA ioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMioyMiozJxoFPAAAA
TnRSTlMAGBAyBAhQv4OZLiJUcEBmYBoSzQwgPBZCSEoeWiYwUiyFNIeBw2rJz8c4RBy9uXyrtaWN TnRSTlMAGBAyBAhQv4OZLiJUcEBmYBoSzQwgPBZCSEoeWiYwUiyFNIeBw2rJz8c4RBy9uXyrtaWN
qa2zKP2fJO8KBgKPo2KVoa9s351GPm5+kWho0kj9AAAO1UlEQVR42u1dC2PbthEGyIhq6JiSLWtp qa2zKP2fJO8KBgKPo2KVoa9s351GPm5+kWho0kj9AAAO1klEQVR42u1dC2PbthEGyIhq6JiSLWtJ
7FprMnvzkmxr126tmi2p3XRJ1/X+/88ZQIrE3eElWjItR/jk1xF84D4egLsDSAuRkJCwA5Ag91x/ 7FprMnvzkmxr126tmi2p3XRJ1+X+/88ZQIrE3eElWjIt2/jk1xF84D4egLsDSAuRkJCwA5AgH7j+
2HEGNq6ehLD+EjOgdx6WEGaBoEEJ4PUh5bpU4i0AtoqBC7Dj6z8HNQlugTYBkteHlPM7aBHAD7cv sOMMbFw9CWH9JWZA7zwsIcwCQYMSwOtDynWpxFsAbBUDF2DH138OahLcAm0CJK8PKed30CKAH25f
YO0sB2TAqr9bhUC5zaAIGhCEGsRqZxncabsNnFuwXUV+g20LCd5h2wICFRjeAtykBG5h0IKdO1h9 wNpZDsiAVX+3CoFym0ERNCAINYjVzjK403YbOLdgu4r8BtsWErzDtgUEKjC8BbhJCdzCoAU7d7D6
QMgEh+8D7nsU4E1o+FEgOUIJCQkJCQkJCffmCd6zHyStaA248y4DCgHwAF/2ygdYCSF19kEpcVTA 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</string> </value> R35ALzal+U5I2HH8H8nmcxxRUAcPAAAAAElFTkSuQmCC</string> </value>
</item> </item>
<item> <item>
<key> <string>height</string> </key> <key> <string>height</string> </key>
...@@ -109,7 +109,7 @@ BIEgi6ltGUSygNQHPCQC9n0USEhISEhISNg25MPxBKKrICHvv9BVsv8PtNP3SsiNCeD3+yHpvw0L ...@@ -109,7 +109,7 @@ BIEgi6ltGUSygNQHPCQC9n0USEhISEhISNg25MPxBKKrICHvv9BVsv8PtNP3SsiNCeD3+yHpvw0L
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>4193</int> </value> <value> <int>4194</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts31202810.01</string> </value> <value> <string>ts43624952.15</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -30,74 +30,74 @@ CgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzM ...@@ -30,74 +30,74 @@ CgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzM
CgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzM CgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzM
CgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzrDkZjAAAA CgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzMCgzrDkZjAAAA
TnRSTlMAGBAyBAhQv4OZLiJUcEBmYBoSzQwgPBZCSEoeWiYwUiyFNIeBw2rJz8c4RBy9uXyrtaWN TnRSTlMAGBAyBAhQv4OZLiJUcEBmYBoSzQwgPBZCSEoeWiYwUiyFNIeBw2rJz8c4RBy9uXyrtaWN
qa2zKP2fJO8KBgKPo2KVoa9s351GPm5+kWho0kj9AAAO1UlEQVR42u1dC2PbthEGyIhq6JiSLWtp qa2zKP2fJO8KBgKPo2KVoa9s351GPm5+kWho0kj9AAAO1klEQVR42u1dC2PbthEGyIhq6JiSLWtJ
7FprMnvzkmxr126tmi2p3XRJ1/X+/88ZQIrE3eElWjItR/jk1xF84D4egLsDSAuRkJCwA5Ag91x/ 7FprMnvzkmxr126tmi2p3XRJ1+X+/88ZQIrE3eElWjIt2/jk1xF84D4egLsDSAuRkJCwA5AgH7j+
2HEGNq6ehLD+EjOgdx6WEGaBoEEJ4PUh5bpU4i0AtoqBC7Dj6z8HNQlugTYBkteHlPM7aBHAD7cv sOMMbFw9CWH9JWZA7zwsIcwCQYMSwOtDynWpxFsAbBUDF2DH138OahLcAm0CJK8PKed30CKAH25f
YO0sB2TAqr9bhUC5zaAIGhCEGsRqZxncabsNnFuwXUV+g20LCd5h2wICFRjeAtykBG5h0IKdO1h9 wNpZDsiAVX+3CoFym0ERNCAINYjVzjK403YbOLdgu4r8BtsWErzDtgUEKjC8BbhJCdzCoAU7d7D6
QMgEh+8D7nsU4E1o+FEgOUIJCQkJCQkJCffmCd6zHyStaA248y4DCgHwAF/2ygdYCSF19kEpcVTA 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</string> </value> R35ALzal+U5I2HH8H8nmcxxRUAcPAAAAAElFTkSuQmCC</string> </value>
</item> </item>
<item> <item>
<key> <string>height</string> </key> <key> <string>height</string> </key>
...@@ -109,7 +109,7 @@ BIEgi6ltGUSygNQHPCQC9n0USEhISEhISNg25MPxBKKrICHvv9BVsv8PtNP3SsiNCeD3+yHpvw0L ...@@ -109,7 +109,7 @@ BIEgi6ltGUSygNQHPCQC9n0USEhISEhISNg25MPxBKKrICHvv9BVsv8PtNP3SsiNCeD3+yHpvw0L
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>4193</int> </value> <value> <int>4194</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -30,10 +30,10 @@ ...@@ -30,10 +30,10 @@
<key> <string>raw</string> </key> <key> <string>raw</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
/*\n /*!\n
* jQuery UI CSS Framework 1.8.18\n * jQuery UI CSS Framework 1.8.22\n
*\n *\n
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
* http://jquery.org/license\n * http://jquery.org/license\n
*\n *\n
...@@ -70,16 +70,16 @@ ...@@ -70,16 +70,16 @@
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }\n .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }\n
\n \n
\n \n
/*\n /*!\n
* jQuery UI CSS Framework 1.8.18\n * jQuery UI CSS Framework 1.8.22\n
*\n *\n
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
* http://jquery.org/license\n * http://jquery.org/license\n
*\n *\n
* http://docs.jquery.com/UI/Theming/API\n * http://docs.jquery.com/UI/Theming/API\n
*\n *\n
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ctl=themeroller&ctl=themeroller&ctl=themeroller&ctl=themeroller&ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=DAE6F6&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=3D6474&fcHeader=222222&iconColorHeader=222222&bgColorContent=E3EAFA&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=3D6474&fcContent=222222&iconColorContent=222222&bgColorDefault=DAE6F6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=3D6474&fcDefault=555555&iconColorDefault=888888&bgColorHover=d0e0f6&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=4589a5&fcHover=212121&iconColorHover=454545&bgColorActive=E3EAFA&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=3D6474&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px\n * To view and modify this theme, visit http://jqueryui.com/themeroller/?ctl=themeroller&ctl=themeroller&ctl=themeroller&ctl=themeroller&ctl=themeroller&ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=DAE6F6&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=3D6474&fcHeader=222222&iconColorHeader=222222&bgColorContent=E3EAFA&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=3D6474&fcContent=222222&iconColorContent=222222&bgColorDefault=DAE6F6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=3D6474&fcDefault=555555&iconColorDefault=888888&bgColorHover=d0e0f6&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=4589a5&fcHover=212121&iconColorHover=454545&bgColorActive=E3EAFA&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=3D6474&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px\n
*/\n */\n
\n \n
\n \n
...@@ -316,17 +316,17 @@ ...@@ -316,17 +316,17 @@
\n \n
/* Overlays */\n /* Overlays */\n
.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }\n .ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }\n
.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*\n .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*!\n
* jQuery UI Resizable 1.8.18\n * jQuery UI Resizable 1.8.22\n
*\n *\n
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
* http://jquery.org/license\n * http://jquery.org/license\n
*\n *\n
* http://docs.jquery.com/UI/Resizable#theming\n * http://docs.jquery.com/UI/Resizable#theming\n
*/\n */\n
.ui-resizable { position: relative;}\n .ui-resizable { position: relative;}\n
.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; }\n .ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; }\n
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }\n .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }\n
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }\n .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }\n
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }\n .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }\n
...@@ -335,20 +335,20 @@ ...@@ -335,20 +335,20 @@
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }\n .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }\n
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }\n .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }\n
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }\n .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }\n
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*\n .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*!\n
* jQuery UI Selectable 1.8.18\n * jQuery UI Selectable 1.8.22\n
*\n *\n
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
* http://jquery.org/license\n * http://jquery.org/license\n
*\n *\n
* http://docs.jquery.com/UI/Selectable#theming\n * http://docs.jquery.com/UI/Selectable#theming\n
*/\n */\n
.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }\n .ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }\n
/*\n /*!\n
* jQuery UI Accordion 1.8.18\n * jQuery UI Accordion 1.8.22\n
*\n *\n
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
* http://jquery.org/license\n * http://jquery.org/license\n
*\n *\n
...@@ -364,10 +364,10 @@ ...@@ -364,10 +364,10 @@
.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }\n .ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }\n
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }\n .ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }\n
.ui-accordion .ui-accordion-content-active { display: block; }\n .ui-accordion .ui-accordion-content-active { display: block; }\n
/*\n /*!\n
* jQuery UI Autocomplete 1.8.18\n * jQuery UI Autocomplete 1.8.22\n
*\n *\n
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
* http://jquery.org/license\n * http://jquery.org/license\n
*\n *\n
...@@ -379,7 +379,7 @@ ...@@ -379,7 +379,7 @@
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */\n * html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */\n
\n \n
/*\n /*\n
* jQuery UI Menu 1.8.18\n * jQuery UI Menu 1.8.22\n
*\n *\n
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
...@@ -417,16 +417,16 @@ ...@@ -417,16 +417,16 @@
\tfont-weight: normal;\n \tfont-weight: normal;\n
\tmargin: -1px;\n \tmargin: -1px;\n
}\n }\n
/*\n /*!\n
* jQuery UI Button 1.8.18\n * jQuery UI Button 1.8.22\n
*\n *\n
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
* http://jquery.org/license\n * http://jquery.org/license\n
*\n *\n
* http://docs.jquery.com/UI/Button#theming\n * http://docs.jquery.com/UI/Button#theming\n
*/\n */\n
.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: hidden; *overflow: visible; } /* the overflow property removes extra width in IE */\n .ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */\n
.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */\n .ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */\n
button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */\n button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */\n
.ui-button-icons-only { width: 3.4em; } \n .ui-button-icons-only { width: 3.4em; } \n
...@@ -455,10 +455,10 @@ input.ui-button { padding: .4em 1em; }\n ...@@ -455,10 +455,10 @@ input.ui-button { padding: .4em 1em; }\n
\n \n
/* workarounds */\n /* workarounds */\n
button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */\n button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */\n
/*\n /*!\n
* jQuery UI Dialog 1.8.18\n * jQuery UI Dialog 1.8.22\n
*\n *\n
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
* http://jquery.org/license\n * http://jquery.org/license\n
*\n *\n
...@@ -476,10 +476,10 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad ...@@ -476,10 +476,10 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }\n .ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }\n
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }\n .ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }\n
.ui-draggable .ui-dialog-titlebar { cursor: move; }\n .ui-draggable .ui-dialog-titlebar { cursor: move; }\n
/*\n /*!\n
* jQuery UI Slider 1.8.18\n * jQuery UI Slider 1.8.22\n
*\n *\n
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
* http://jquery.org/license\n * http://jquery.org/license\n
*\n *\n
...@@ -499,10 +499,10 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad ...@@ -499,10 +499,10 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }\n .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }\n
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }\n .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }\n
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }\n .ui-slider-vertical .ui-slider-range-min { bottom: 0; }\n
.ui-slider-vertical .ui-slider-range-max { top: 0; }/*\n .ui-slider-vertical .ui-slider-range-max { top: 0; }/*!\n
* jQuery UI Tabs 1.8.18\n * jQuery UI Tabs 1.8.22\n
*\n *\n
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
* http://jquery.org/license\n * http://jquery.org/license\n
*\n *\n
...@@ -517,10 +517,10 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad ...@@ -517,10 +517,10 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad
.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */\n .ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */\n
.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }\n .ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }\n
.ui-tabs .ui-tabs-hide { display: none !important; }\n .ui-tabs .ui-tabs-hide { display: none !important; }\n
/*\n /*!\n
* jQuery UI Datepicker 1.8.18\n * jQuery UI Datepicker 1.8.22\n
*\n *\n
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
* http://jquery.org/license\n * http://jquery.org/license\n
*\n *\n
...@@ -575,8 +575,6 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad ...@@ -575,8 +575,6 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad
\n \n
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */\n /* IE6 IFRAME FIX (taken from datepicker 1.5.3 */\n
.ui-datepicker-cover {\n .ui-datepicker-cover {\n
display: none; /*sorry for IE5*/\n
display/**/: block; /*sorry for IE5*/\n
position: absolute; /*must have*/\n position: absolute; /*must have*/\n
z-index: -1; /*must have*/\n z-index: -1; /*must have*/\n
filter: mask(); /*must have*/\n filter: mask(); /*must have*/\n
...@@ -584,10 +582,10 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad ...@@ -584,10 +582,10 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad
left: -4px; /*must have*/\n left: -4px; /*must have*/\n
width: 200px; /*must have*/\n width: 200px; /*must have*/\n
height: 200px; /*must have*/\n height: 200px; /*must have*/\n
}/*\n }/*!\n
* jQuery UI Progressbar 1.8.18\n * jQuery UI Progressbar 1.8.22\n
*\n *\n
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)\n
* Dual licensed under the MIT or GPL Version 2 licenses.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n
* http://jquery.org/license\n * http://jquery.org/license\n
*\n *\n
......
2012-07-30 Kazuhiko
* jquery-ui 1.8.22.
2012-03-08 Kazuhiko 2012-03-08 Kazuhiko
* jquery-ui 1.8.18. * jquery-ui 1.8.18.
......
This Business Template contains only static files of jQuery UI. This Business Template contains only static files of jQuery UI.
Current version is jquery-ui-1.8.18. Current version is jquery-ui-1.8.22.
18 19
\ No newline at end of file \ No newline at end of file
...@@ -1350,6 +1350,12 @@ button.formbt > span{\n ...@@ -1350,6 +1350,12 @@ button.formbt > span{\n
.page ul li {\n .page ul li {\n
list-style: square outside none;\n list-style: square outside none;\n
}\n }\n
\n
/* contained inside content area images should be re-sized to fit in */\n
.content img {\n
max-width: 720px;\n
}\n
\n
</tal:block> </tal:block>
]]></unicode> </value> ]]></unicode> </value>
......
1870 1871
\ No newline at end of file \ 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>category</string> </key>
<value> <string>global</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>check_site_consistency</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>Manage portal</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.6</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Check Site Consistency</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}/ERP5Site_viewCheckConsistency?reset:int=1</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -39,7 +39,9 @@ ...@@ -39,7 +39,9 @@
<item> <item>
<key> <string>periodicity_hour</string> </key> <key> <string>periodicity_hour</string> </key>
<value> <value>
<tuple/> <tuple>
<int>0</int>
</tuple>
</value> </value>
</item> </item>
<item> <item>
......
...@@ -39,7 +39,9 @@ ...@@ -39,7 +39,9 @@
<item> <item>
<key> <string>periodicity_hour</string> </key> <key> <string>periodicity_hour</string> </key>
<value> <value>
<tuple/> <tuple>
<int>0</int>
</tuple>
</value> </value>
</item> </item>
<item> <item>
......
...@@ -39,7 +39,9 @@ ...@@ -39,7 +39,9 @@
<item> <item>
<key> <string>periodicity_hour</string> </key> <key> <string>periodicity_hour</string> </key>
<value> <value>
<tuple/> <tuple>
<int>0</int>
</tuple>
</value> </value>
</item> </item>
<item> <item>
......
...@@ -39,7 +39,9 @@ ...@@ -39,7 +39,9 @@
<item> <item>
<key> <string>periodicity_hour</string> </key> <key> <string>periodicity_hour</string> </key>
<value> <value>
<tuple/> <tuple>
<int>0</int>
</tuple>
</value> </value>
</item> </item>
<item> <item>
......
...@@ -39,7 +39,9 @@ ...@@ -39,7 +39,9 @@
<item> <item>
<key> <string>periodicity_hour</string> </key> <key> <string>periodicity_hour</string> </key>
<value> <value>
<tuple/> <tuple>
<int>0</int>
</tuple>
</value> </value>
</item> </item>
<item> <item>
......
...@@ -39,7 +39,9 @@ ...@@ -39,7 +39,9 @@
<item> <item>
<key> <string>periodicity_hour</string> </key> <key> <string>periodicity_hour</string> </key>
<value> <value>
<tuple/> <tuple>
<int>0</int>
</tuple>
</value> </value>
</item> </item>
<item> <item>
......
...@@ -54,7 +54,6 @@ ...@@ -54,7 +54,6 @@
\n \n
portal = context.getPortalObject()\n portal = context.getPortalObject()\n
mailhost = portal.MailHost\n mailhost = portal.MailHost\n
portal_preferences = portal.portal_preferences\n
promise_url = portal.getPromiseParameter(\'external_service\', \'smtp_url\')\n promise_url = portal.getPromiseParameter(\'external_service\', \'smtp_url\')\n
\n \n
if promise_url is None:\n if promise_url is None:\n
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
process_list = context.Alarm_getReportResultList()\n
if len(process_list) > 0:\n
return "%s (%s)" % (process_list[0].summary, process_list[0].detail)\n
\n
return "Unknown"\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_getLastActiveMessageText</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
"""\n
N_ = context.Base_translateString\n
if len(uids):\n
for alarm in context.portal_alarms.searchFolder(uid=uids):\n
alarm.solve()\n
# Invoke activiveSense a bit later\n
alarm.activate().activeSense()\n
portal_status_message = N_("Site Configuration is going to be fixed by Activities.")\n
else:\n
portal_status_message = N_("No Site Configuration fix was request.")\n
\n
if enable_alarm:\n
updated = False\n
for alarm in context.portal_alarms.searchFolder(id="promise_%"):\n
if not alarm.getEnabled():\n
alarm.setEnabled(1)\n
updated = True\n
if updated:\n
portal_status_message += N_("Consistency Check information will be periodically updated.")\n
\n
form_id = context.REQUEST.get("form_id", "")\n
\n
return context.Base_redirect(form_id, \n
keep_items=dict(portal_status_message=portal_status_message))\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>enable_alarm=True, uids=[], **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_fixConfigurationConsistency</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>alarm_tool = context.getPortalObject().portal_alarms\n
kw["id"] = "promise_%"\n
\n
alarm_list = []\n
for alarm in alarm_tool.searchFolder(**kw):\n
alarm.activeSense()\n
if alarm.sense():\n
alarm_list.append(alarm)\n
\n
return alarm_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_getPromiseAlarmList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>alarm_tool = context.getPortalObject().portal_alarms\n
N_ = context.Base_translateString\n
\n
for alarm in alarm_tool.searchFolder(id="promise_%"):\n
alarm.activeSense()\n
\n
portal_status_message = N_("Promises are been reloaded via activities, please wait for background activities finish.")\n
return context.Base_redirect("ERP5Site_viewCheckConsistency", \n
keep_items=dict(reset=1, \n
portal_status_message=portal_status_message))\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_updateConfigurationConsistency</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>ERP5Site_fixConfigurationConsistency</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>application/x-www-form-urlencoded</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>
<string>your_enable_alarm</string>
</list>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>your_information</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_viewCheckConsistency</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>ERP5Site_viewCheckConsistency</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_dialog</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Fix Site Configuration</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>ERP5Site_updateConfigurationConsistency</string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string>Force Reload Promises</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>selection_name</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>all_editable_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>title</string>
<string>Title</string>
</tuple>
<tuple>
<string>Alarm_getLastActiveMessageText</string>
<string>Configuration Status</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>count_method</string> </key>
<value> <string></string> </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">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string>erp5_site_check_consistency_selection</string> </value>
</item>
<item>
<key> <string>sort</string> </key>
<value>
<list>
<tuple>
<string>title</string>
<string>descending</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>Site Configuration Problems</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>ERP5Site_getPromiseAlarmList</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>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>your_enable_alarm</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>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> <int>1</int> </value>
</item>
<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>Do you want to enable Periodical Check?</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="EditorField" module="Products.ERP5Form.EditorField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>your_information</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>
<item>
<key> <string>line_too_long</string> </key>
<value> <string>A line was too long.</string> </value>
</item>
<item>
<key> <string>required_not_found</string> </key>
<value> <string>Input is required but no input given.</string> </value>
</item>
<item>
<key> <string>too_long</string> </key>
<value> <string>You entered too many characters.</string> </value>
</item>
<item>
<key> <string>too_many_lines</string> </key>
<value> <string>You entered too many lines.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>height</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_linelength</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_lines</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>text_editor</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>height</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_linelength</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_lines</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>text_editor</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string>You has activities running in background, it is hightly recommended wait them finish.</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>height</string> </key>
<value> <int>5</int> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_linelength</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_lines</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>text_editor</string> </key>
<value> <string>text_area</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string encoding="cdata"><![CDATA[
<b>WARNNING!</b>
]]></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>40</int> </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: context.portal_activities.getMessageList()</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
2012-07-17 rafael
* Initial Release
\ No newline at end of file
Copyright (c) 2012 Nexedi SA
\ No newline at end of file
erp5_core
\ No newline at end of file
Provide automated ERP5 configuration. Provide automated ERP5 setup configuration.
\ No newline at end of file \ No newline at end of file
GPL
\ No newline at end of file
rafael
romain
\ No newline at end of file
9 17
\ No newline at end of file \ No newline at end of file
portal_actions | check_site_consistency
\ No newline at end of file
...@@ -72,7 +72,7 @@ for result in result_list:\n ...@@ -72,7 +72,7 @@ for result in result_list:\n
if strict_check_mode and method() != kw[key]:\n if strict_check_mode and method() != kw[key]:\n
raise RuntimeError, "One property is not the same that you wanted : you asked \'%s\' and expecting \'%s\' but get \'%s\'" % (key, kw[key], method())\n raise RuntimeError, "One property is not the same that you wanted : you asked \'%s\' and expecting \'%s\' but get \'%s\'" % (key, kw[key], method())\n
# check that every object are owner by you\n # check that every object are owner by you\n
if strict_check_mode and object.Base_getOwnerId() not in [owner_id, functional_test_username, \'System Processes\', functional_another_test_username]:\n if strict_check_mode and object.Base_getOwnerId() not in [owner_id, functional_test_username, \'System Processes\',\'zope\', functional_another_test_username]:\n
raise RuntimeError, "You have try to clean an item who haven\'t you as owner : %s is owned by %s and you are %s" % \\\n raise RuntimeError, "You have try to clean an item who haven\'t you as owner : %s is owned by %s and you are %s" % \\\n
(object.getTitle(), object.Base_getOwnerId(), owner_id)\n (object.getTitle(), object.Base_getOwnerId(), owner_id)\n
\n \n
......
...@@ -97,6 +97,7 @@ return {\'now\': DateTime(),\n ...@@ -97,6 +97,7 @@ return {\'now\': DateTime(),\n
\'sale_howto_currency_title\': \'Euro\',\n \'sale_howto_currency_title\': \'Euro\',\n
\'sale_howto_currency_tag\': \'EUR\',\n \'sale_howto_currency_tag\': \'EUR\',\n
\'sale_howto_product_reference\': \'ZUITE-TEST-SALEORDER-RL01\',\n \'sale_howto_product_reference\': \'ZUITE-TEST-SALEORDER-RL01\',\n
\'sale_howto_trade_condition_title\': \'ZUITE-TEST-SALE-TRADE-CONDITION-001\',\n
\'campaign_howto_person_title\': \'ZUITE-TEST-CAMPAIGN-PERSON-SUPERVISOR\',\n \'campaign_howto_person_title\': \'ZUITE-TEST-CAMPAIGN-PERSON-SUPERVISOR\',\n
\'campaign_howto_person2_title\': \'ZUITE-TEST-CAMPAIGN-PERSON-OPERATION-MANAGER\',\n \'campaign_howto_person2_title\': \'ZUITE-TEST-CAMPAIGN-PERSON-OPERATION-MANAGER\',\n
\'campaign_howto_organisation_title\': \'ZUITE-TEST-CAMPAIGN-ORGANISATION-001\',\n \'campaign_howto_organisation_title\': \'ZUITE-TEST-CAMPAIGN-ORGANISATION-001\',\n
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>if clean:\n
context.Zuite_tearDownSaleTradeConditionTest()\n
\n
portal = context.getPortalObject()\n
howto_dict = context.Zuite_getHowToInfo()\n
isTransitionPossible = portal.portal_workflow.isTransitionPossible\n
\n
# check if there is already the euro curency on the instance\n
currency = context.portal_catalog.getResultValue(portal_type=\'Currency\',\n
title=howto_dict[\'sale_howto_currency_title\'])\n
\n
if currency is None:\n
currency = portal.currency_module.newContent(portal_type=\'Currency\',\n
title=howto_dict[\'sale_howto_currency_title\'],\n
reference=howto_dict[\'sale_howto_currency_tag\'],\n
id=howto_dict[\'sale_howto_currency_tag\'],\n
base_unit_quantity=0.01)\n
\n
if isTransitionPossible(currency, \'validate\'):\n
currency.validate()\n
\n
my_organisation = portal.organisation_module.newContent(portal_type=\'Organisation\',\n
title=howto_dict[\'sale_howto_organisation_title\'],\n
corporate_name=howto_dict[\'sale_howto_organisation_title\'])\n
my_organisation.setRole(\'supplier\')\n
my_organisation.setGroup(\'my_group\')\n
my_organisation.validate()\n
\n
organisation = portal.organisation_module.newContent(portal_type=\'Organisation\',\n
title=howto_dict[\'sale_howto_organisation2_title\'],\n
corporate_name=howto_dict[\'sale_howto_organisation2_title\'])\n
organisation.validate()\n
\n
person = portal.person_module.newContent(portal_type=\'Person\',\n
title=howto_dict[\'sale_howto_person_title\'],\n
career_subordination_title=howto_dict[\'sale_howto_organisation_title\'])\n
person.validate()\n
\n
pref = getattr(context.portal_preferences, howto_dict[\'howto_preference_id\'], None)\n
if pref is None:\n
pref = context.portal_preferences.newContent(portal_type="Preference",\n
id=howto_dict[\'howto_preference_id\'])\n
pref.setPreferredAccountingTransactionSectionCategory(\'group/my_group\')\n
if isTransitionPossible(pref, \'enable\'):\n
pref.enable()\n
\n
pref.setPreferredAccountingTransactionSourceSection(my_organisation.getRelativeUrl())\n
\n
# Disabling save form warning\n
# this is bad but needed quickly to disable save form warning \n
pref.setPreferredHtmlStyleUnsavedFormWarning(False)\n
\n
# Clear cache\n
portal.portal_caches.clearAllCache()\n
\n
return "Init Ok"\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>clean=True</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Zuite_setUpSaleTradeConditionTest</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
howto_dict = context.Zuite_getHowToInfo()\n
\n
# remove the currency if it was created by us before\n
currency = context.portal_catalog.getResultValue(portal_type=\'Currency\',\n
title=howto_dict[\'sale_howto_currency_title\'],\n
local_roles = \'Owner\')\n
if currency is not None:\n
context.currency_module.deleteContent(currency.getId())\n
\n
# remove the organisation of the test if existing\n
organisation_list = context.Zuite_checkPortalCatalog(portal_type=\'Organisation\', max_count=1,\n
title=howto_dict[\'sale_howto_organisation_title\'])\n
if organisation_list is not None:\n
portal.organisation_module.deleteContent(organisation_list[0].getId())\n
\n
# remove the second organisation of the test if existing\n
organisation_list2 = context.Zuite_checkPortalCatalog(portal_type=\'Organisation\', max_count=1,\n
title=howto_dict[\'sale_howto_organisation2_title\'])\n
if organisation_list2 is not None:\n
portal.organisation_module.deleteContent(organisation_list2[0].getId())\n
\n
# remove the organisation of the test if existing\n
person_list = context.Zuite_checkPortalCatalog(portal_type=\'Person\', max_count=1,\n
title=howto_dict[\'sale_howto_person_title\'])\n
if person_list is not None:\n
portal.person_module.deleteContent(person_list[0].getId())\n
\n
# remove related sale packing list and sale order\n
sale_order_list = context.Zuite_checkPortalCatalog(portal_type=\'Sale Order\', max_count=1,\n
title=howto_dict[\'sale_howto_product_title\'])\n
if sale_order_list is not None:\n
for applied_rule in sale_order_list[0].getCausalityRelatedValueList(portal_type=\'Applied Rule\'):\n
applied_rule.getParentValue().deleteContent(applied_rule.getId())\n
portal.sale_order_module.deleteContent(sale_order_list[0].getId())\n
\n
# remove related sale packing list and sale order\n
sale_trade_condition_list = context.Zuite_checkPortalCatalog(portal_type=\'Sale Trade Condition\', max_count=1,\n
title=howto_dict[\'sale_howto_trade_condition_title\'])\n
if sale_trade_condition_list is not None:\n
portal.sale_trade_condition_module.deleteContent(sale_trade_condition_list[0].getId())\n
\n
\n
pref = getattr(context.portal_preferences, howto_dict[\'howto_preference_id\'], None)\n
if pref is not None:\n
context.portal_preferences.deleteContent(howto_dict[\'howto_preference_id\'])\n
\n
portal.portal_caches.clearAllCache()\n
\n
return "Clean Ok"\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Zuite_tearDownSaleTradeConditionTest</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -50,8 +50,7 @@ ...@@ -50,8 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string> <value> <string>preference_tool = context.getPortalObject().portal_preferences\n
preference_tool = context.getPortalObject().portal_preferences\n
\n \n
preference = preference_tool.getActivePreference()\n preference = preference_tool.getActivePreference()\n
\n \n
......
30-06-2012 rafael
- Included Trade Condition related scripts
30-04-2012 rafael
- Major change, Tests were merged with the tutorials.
28-03-2011 lucas 28-03-2011 lucas
- Replaced the email for a valid one. - Replaced the email for a valid one.
......
TODO: This bt5 contains no tests, all tests are part of the documentation.
- testHowToSaleOrder must be refactored to use new simulation. \ No newline at end of file
\ No newline at end of file
Copyright 2010, Nexedi SA Copyright 2010-2012, Nexedi SA
\ No newline at end of file \ No newline at end of file
This contains zelenium tests for user Tutorials instances. This contains scripts related to the users tutorials.
\ No newline at end of file \ No newline at end of file
rafael rafael
lucas
\ No newline at end of file
787 788
\ No newline at end of file \ No newline at end of file
...@@ -9,8 +9,8 @@ portal_categories/gender/female ...@@ -9,8 +9,8 @@ portal_categories/gender/female
portal_categories/gender/male portal_categories/gender/male
portal_categories/group/my_group portal_categories/group/my_group
portal_categories/incoterm/cpt portal_categories/incoterm/cpt
portal_categories/nationality/french
portal_categories/marital_status/married portal_categories/marital_status/married
portal_categories/nationality/french
portal_categories/order/normal portal_categories/order/normal
portal_categories/payment_mode/credit_card portal_categories/payment_mode/credit_card
portal_categories/quantity_unit/time portal_categories/quantity_unit/time
......
...@@ -63,6 +63,11 @@ ...@@ -63,6 +63,11 @@
verified and opened by administrator first\n verified and opened by administrator first\n
- you need to adjust group, function and site to your needs\n - you need to adjust group, function and site to your needs\n
"""\n """\n
\n
# since the following code is just an example, we simply raise an exception so that\n
# it is not executed actually.\n
raise NotImplementedError\n
\n
from Products.Formulator.Errors import ValidationError, FormValidationError\n from Products.Formulator.Errors import ValidationError, FormValidationError\n
portal = context.getPortalObject()\n portal = context.getPortalObject()\n
translateString = context.Base_translateString\n translateString = context.Base_translateString\n
......
1088 1089
\ No newline at end of file \ No newline at end of file
...@@ -10,10 +10,6 @@ ...@@ -10,10 +10,6 @@
<role>Author</role> <role>Author</role>
<role>Manager</role> <role>Manager</role>
</permission> </permission>
<permission type='tuple'>
<name>Access arbitrary user session data</name>
<role>Manager</role>
</permission>
<permission type='tuple'> <permission type='tuple'>
<name>Access contents information</name> <name>Access contents information</name>
<role>Assignee</role> <role>Assignee</role>
...@@ -23,14 +19,6 @@ ...@@ -23,14 +19,6 @@
<role>Author</role> <role>Author</role>
<role>Manager</role> <role>Manager</role>
</permission> </permission>
<permission type='tuple'>
<name>Access future portal content</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Access inactive portal content</name>
<role>Manager</role>
</permission>
<permission type='tuple'> <permission type='tuple'>
<name>Access session data</name> <name>Access session data</name>
<role>Assignee</role> <role>Assignee</role>
...@@ -40,427 +28,23 @@ ...@@ -40,427 +28,23 @@
<role>Author</role> <role>Author</role>
<role>Manager</role> <role>Manager</role>
</permission> </permission>
<permission type='tuple'>
<name>Add Accelerated HTTP Cache Managers</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add BTreeFolder2s</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Browser Id Manager</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMF Action Icons Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMF Active Processs</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMF Caching Policy Managers</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMF Calendar Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMF Core Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMF Default Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMF Report Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMF Setup Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMF Sites</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMF Unique Id Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMFActivity Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMFCategory Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add CMFMailIn Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Configured CMF Sites</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Content Type Registrys</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Cookie Crumblers</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Database Methods</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Documents, Images, and Files</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5 Filesystem Formulator Forms</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5 Form Printouts</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5 Forms</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5 OOo Templates</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5 PDF Forms</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5 PDF Templates</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5 Publications</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5 Reports</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5 Sites</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5 Subscriptions</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5 Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5Catalog Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5Configurator Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5Form Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5SyncML Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5Type Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ERP5Wizard Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ExtFiles</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ExtImages</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add External Methods</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Filesystem Directory Views</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Folders</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Formulator Forms</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add HBTreeFolder2s</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add LocalContents</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add LocalFolders</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Localizers</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add MailHost objects</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add MessageCatalogs</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add MimetypesRegistry Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Page Templates</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Pluggable Index</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Plugin Registrys</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add PortalTransforms Tools</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Python Scripts</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add RAM Cache Managers</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ReStructuredText Documents</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Session Data Manager</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Site Roots</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Temporary Folder</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Transient Object Container</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add User Folders</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Virtual Host Monsters</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Vocabularies</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Z Gadfly Database Connections</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Z MySQL Database Connections</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Z MySQL Deferred Database Connections</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ZCatalogs</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ZMailIn Clients</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ZMailMessages</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add ZODB Mount Points</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add Zope Tutorials</name>
<role>Manager</role>
</permission>
<permission type='tuple'> <permission type='tuple'>
<name>Add portal content</name> <name>Add portal content</name>
<role>Assignor</role> <role>Assignor</role>
<role>Author</role> <role>Author</role>
<role>Manager</role> <role>Manager</role>
</permission> </permission>
<permission type='tuple'>
<name>Add portal events</name>
<role>Manager</role>
</permission>
<permission type='tuple'> <permission type='tuple'>
<name>Add portal folders</name> <name>Add portal folders</name>
<role>Assignor</role> <role>Assignor</role>
<role>Author</role> <role>Author</role>
<role>Manager</role> <role>Manager</role>
</permission> </permission>
<permission type='tuple'>
<name>Add portal member</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add portal topics</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change Browser Id Manager</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change DTML Documents</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change DTML Methods</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change Database Connections</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change Database Methods</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change ExtFile/ExtImage</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change External Methods</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change Formulator Fields</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change Formulator Forms</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change Images and Files</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change Lock Information</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change Page Templates</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change Python Scripts</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change Session Data Manager</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change Versions</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change ZMailIn</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change ZMailMessages</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change bindings</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change cache managers</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change cache settings</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change configuration</name>
<role>Manager</role>
</permission>
<permission type='tuple'> <permission type='tuple'>
<name>Change local roles</name> <name>Change local roles</name>
<role>Assignor</role> <role>Assignor</role>
<role>Manager</role> <role>Manager</role>
</permission> </permission>
<permission type='tuple'>
<name>Change permissions</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change portal events</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change portal topics</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change proxy roles</name>
<role>Manager</role>
</permission>
<permission type='tuple'> <permission type='tuple'>
<name>Copy or Move</name> <name>Copy or Move</name>
<role>Assignee</role> <role>Assignee</role>
...@@ -470,51 +54,11 @@ ...@@ -470,51 +54,11 @@
<role>Author</role> <role>Author</role>
<role>Manager</role> <role>Manager</role>
</permission> </permission>
<permission type='tuple'>
<name>Create Transient Objects</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Create class instances</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Define permissions</name>
<role>Manager</role>
</permission>
<permission type='tuple'> <permission type='tuple'>
<name>Delete objects</name> <name>Delete objects</name>
<role>Assignor</role> <role>Assignor</role>
<role>Manager</role> <role>Manager</role>
</permission> </permission>
<permission type='tuple'>
<name>Download ExtFile/ExtImage</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Edit Factories</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Edit ReStructuredText</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Edit target</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>FTP access</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Import/Export objects</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Join/leave Versions</name>
<role>Manager</role>
</permission>
<permission type='tuple'> <permission type='tuple'>
<name>List folder contents</name> <name>List folder contents</name>
<role>Assignee</role> <role>Assignee</role>
...@@ -524,167 +68,11 @@ ...@@ -524,167 +68,11 @@
<role>Author</role> <role>Author</role>
<role>Manager</role> <role>Manager</role>
</permission> </permission>
<permission type='tuple'>
<name>List portal members</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>List undoable changes</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Log Site Errors</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Log to the Event Log</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Mail forgotten password</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage Access Rules</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage Groups</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage Selenium test cases</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage Transient Object Container</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage Vocabulary</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage WebDAV Locks</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage Z Classes</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage ZCatalog Entries</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage ZCatalogIndex Entries</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage languages</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage messages</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage portal</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage properties</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Manage users</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Modify Cookie Crumblers</name>
<role>Manager</role>
</permission>
<permission type='tuple'> <permission type='tuple'>
<name>Modify portal content</name> <name>Modify portal content</name>
<role>Assignor</role> <role>Assignor</role>
<role>Manager</role> <role>Manager</role>
</permission> </permission>
<permission type='tuple'>
<name>Open/Close Database Connection</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Open/Close Database Connections</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Post mail to ZMailIn</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Query Vocabulary</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Reply to item</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Request review</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Review portal content</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Save/discard Version changes</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Search ZCatalog</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Search for principals</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Set own password</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Set own properties</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Take ownership</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Test Database Connections</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Translate Content</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Undo changes</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Use Database Methods</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Use Factories</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Use mailhost services</name>
<role>Manager</role>
</permission>
<permission type='tuple'> <permission type='tuple'>
<name>View</name> <name>View</name>
<role>Assignee</role> <role>Assignee</role>
...@@ -702,26 +90,6 @@ ...@@ -702,26 +90,6 @@
<role>Author</role> <role>Author</role>
<role>Manager</role> <role>Manager</role>
</permission> </permission>
<permission type='tuple'>
<name>View ZMailMessage</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>View management screens</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>WebDAV Lock items</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>WebDAV Unlock items</name>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>WebDAV access</name>
<role>Manager</role>
</permission>
</permission_list> </permission_list>
<portal_type>Workflow Module</portal_type> <portal_type>Workflow Module</portal_type>
<title>Workflows</title> <title>Workflows</title>
......
...@@ -51,6 +51,10 @@ ...@@ -51,6 +51,10 @@
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>type_class</string> </key>
<value> <string>State</string> </value>
</item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
......
...@@ -68,6 +68,10 @@ ...@@ -68,6 +68,10 @@
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Variable</string> </value>
</item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
......
...@@ -68,6 +68,10 @@ ...@@ -68,6 +68,10 @@
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Transition</string> </value>
</item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
......
...@@ -51,6 +51,10 @@ ...@@ -51,6 +51,10 @@
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Variable</string> </value>
</item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
......
...@@ -67,6 +67,10 @@ ...@@ -67,6 +67,10 @@
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Workflow</string> </value>
</item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
......
Copyright (c) 2008-2012 Nexedi SA
\ No newline at end of file
erp5_base
\ No newline at end of file
GPL
\ No newline at end of file
rafael
\ No newline at end of file
35 37
\ No newline at end of file \ No newline at end of file
...@@ -60,9 +60,9 @@ ...@@ -60,9 +60,9 @@
<!-- <span tal:replace="structure python: getattr(here.gadgets.form, field_type).gadget(field_name=field_name)"/> -->\n <!-- <span tal:replace="structure python: getattr(here.gadgets.form, field_type).gadget(field_name=field_name)"/> -->\n
\n \n
<!-- XXX: render gadget asynchronously -->\n <!-- XXX: render gadget asynchronously -->\n
<div tal:attributes="gadget string:gadgets/form/${field_type}/gadget?field_name=${field_name};\n <div tal:attributes="data-gadget string:gadgets/form/${field_type}/gadget?field_name=${field_name};\n
id string:${form_id}_${field_name};\n id string:${form_id}_${field_name};\n
gadget:property string: {&quot;cacheable&quot;: &quot;1&quot;, &quot;cache_id&quot;: &quot;${form_id}_${field_name}&quot;}"></div>\n data-gadget:property string: {&quot;cacheable&quot;: &quot;1&quot;, &quot;cache_id&quot;: &quot;${form_id}_${field_name}&quot;}"></div>\n
\n \n
</div>\n </div>\n
</div>\n </div>\n
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts37261735.49</string> </value> <value> <string>ts45811421.8</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
......
...@@ -89,10 +89,10 @@ ...@@ -89,10 +89,10 @@
\n \n
<!--Form render goes here -->\n <!--Form render goes here -->\n
<div id="form_gadget"\n <div id="form_gadget"\n
tal:attributes="gadget string:${current_form_id}/Form_asRenderJSGadget;\n tal:attributes="data-gadget string:${current_form_id}/Form_asRenderJSGadget;\n
gadget:data-source string:Form_asJSON?form_id=${current_form_id};\n data-gadget:data-source string:Form_asJSON?form_id=${current_form_id};\n
gadget:data-handler string:ERP5Form.update;\n data-gadget:data-handler string:ERP5Form.update;\n
gadget:property string: {&quot;cacheable&quot;: &quot;1&quot;, &quot;cache_id&quot;: &quot;${current_form_id}&quot;}">\n data-gadget:property string: {&quot;cacheable&quot;: &quot;1&quot;, &quot;cache_id&quot;: &quot;${current_form_id}&quot;}">\n
</div>\n </div>\n
\n \n
</div>\n </div>\n
......
...@@ -71,8 +71,8 @@ ...@@ -71,8 +71,8 @@
\074script src="erp5_form.js"\076\074/script\076\n \074script src="erp5_form.js"\076\074/script\076\n
\n \n
\074div id="content"\n \074div id="content"\n
gadget="gadgets/content/gadget"\n data-gadget="gadgets/content/gadget"\n
tal:attributes="gadget string:gadgets/tabular_gadget/gadget?object_path=${object_path}\046current_form_id=${form_id}"\076\074/div\076\n tal:attributes="data-gadget string:gadgets/tabular_gadget/gadget?object_path=${object_path}\046current_form_id=${form_id}"\076\074/div\076\n
\n \n
\074script type="text/javascript" language="javascript"\076\n \074script type="text/javascript" language="javascript"\076\n
//\074![CDATA[\n //\074![CDATA[\n
......
8 9
\ No newline at end of file \ No newline at end of file
...@@ -95,16 +95,22 @@ def patchRPCParser(error_handler): ...@@ -95,16 +95,22 @@ def patchRPCParser(error_handler):
parser_klass.feed = verbose_feed parser_klass.feed = verbose_feed
class RPCRetry(object): class RPCRetry(object):
def __init__(self, proxy, retry_time, logger): def __init__(self, proxy, retry_time, logger, timeout=120):
super(RPCRetry, self).__init__() super(RPCRetry, self).__init__()
self._proxy = proxy self._proxy = proxy
self._retry_time = retry_time self._retry_time = retry_time
self._logger = logger self._logger = logger
self.__rpc_lock = threading.Lock() self.__rpc_lock = threading.Lock()
self.timeout = timeout
def _RPC(self, func_id, args=()): def _RPC(self, func_id, args=()):
default_timeout = socket.getdefaulttimeout()
socket.setdefaulttimeout(self.timeout)
try:
with self.__rpc_lock: with self.__rpc_lock:
return getattr(self._proxy, func_id)(*args) return getattr(self._proxy, func_id)(*args)
finally:
socket.setdefaulttimeout(default_timeout)
def _retryRPC(self, func_id, args=()): def _retryRPC(self, func_id, args=()):
retry_time = self._retry_time retry_time = self._retry_time
...@@ -141,29 +147,32 @@ class TestResultLineProxy(RPCRetry): ...@@ -141,29 +147,32 @@ class TestResultLineProxy(RPCRetry):
def stop(self, test_count=None, error_count=None, failure_count=None, def stop(self, test_count=None, error_count=None, failure_count=None,
skip_count=None, duration=None, date=None, command=None, skip_count=None, duration=None, date=None, command=None,
stdout=None, stderr=None, html_test_result=None): stdout=None, stderr=None, html_test_result=None, **kw):
""" """
Notify server of test completion. Notify server of test completion.
Without any parameter, notifies of a test failure which prevents any Without any parameter, notifies of a test failure which prevents any
precise reading (step count, how many succeeded, etc). precise reading (step count, how many succeeded, etc).
BBB: extra named arguments are deprecated (if some are really needed,
they must be declared as explicit parameters, with proper default
value).
""" """
status_dict = { status_dict = dict(x for x in (
'test_count': test_count, ('test_count', test_count),
'error_count': error_count, ('error_count', error_count),
'failure_count': failure_count, ('failure_count', failure_count),
'skip_count': skip_count, ('skip_count', skip_count),
'duration': duration, ('duration', duration),
'date': date, ('date', date),
} ('command', command),
if command is not None: ('stdout', stdout),
status_dict['command'] = command ('stderr', stderr),
if stdout is not None: ('html_test_result', html_test_result),
status_dict['stdout'] = stdout ) if x[1] is not None)
if stderr is not None: if kw:
status_dict['stderr'] = stderr self._logger.info('Extra parameters provided: %r', kw)
if html_test_result is not None: status_dict.update(kw)
status_dict['html_test_result'] = html_test_result
self._retryRPC('stopUnitTest', (self._test_result_line_path, self._retryRPC('stopUnitTest', (self._test_result_line_path,
status_dict)) status_dict))
......
...@@ -36,7 +36,7 @@ import urllib ...@@ -36,7 +36,7 @@ import urllib
from urlparse import urljoin from urlparse import urljoin
from z3c.etestbrowser.browser import ExtendedTestBrowser from z3c.etestbrowser.browser import ExtendedTestBrowser
from zope.testbrowser.browser import onlyOne from zope.testbrowser.browser import onlyOne, fix_exception_name
def measurementMetaClass(prefix): def measurementMetaClass(prefix):
""" """
...@@ -424,9 +424,15 @@ class Browser(ExtendedTestBrowser): ...@@ -424,9 +424,15 @@ class Browser(ExtendedTestBrowser):
@raise LookupError: Not found @raise LookupError: Not found
""" """
try: try:
return self.etree.xpath('//div[@id="transition_message"]')[0].text transition_message = self.etree.xpath(
'//div[@id="transition_message"]')[0].text
except IndexError: except IndexError:
raise LookupError("Cannot find div with ID 'transition_message'") raise LookupError("Cannot find div with ID 'transition_message'")
else:
if isinstance(transition_message, unicode):
transition_message = transition_message.encode('utf-8')
return transition_message
def getInformationArea(self): def getInformationArea(self):
""" """
...@@ -987,7 +993,7 @@ class ContextMainForm(MainForm): ...@@ -987,7 +993,7 @@ class ContextMainForm(MainForm):
maximum_attempt_number=1, maximum_attempt_number=1,
sleep_between_attempt=0, sleep_between_attempt=0,
dialog_name=None, dialog_name=None,
dialog_expected_transition_message=None, expected_transition_message=None,
**kw): **kw):
""" """
Select and submit a workflow action, given either by its label Select and submit a workflow action, given either by its label
...@@ -1022,8 +1028,8 @@ class ContextMainForm(MainForm): ...@@ -1022,8 +1028,8 @@ class ContextMainForm(MainForm):
@type sleep_between_attempt: int @type sleep_between_attempt: int
@param dialog_name: Function to call after the workflow action ('cancel' or 'confirm') @param dialog_name: Function to call after the workflow action ('cancel' or 'confirm')
@type dialog_name: str @type dialog_name: str
@param dialog_expected_transition_message: Expected dialog transition message @param expected_transition_message: Expected dialog transition message
@type dialog_expected_transition_message: str @type expected_transition_message: str
""" """
url_before = self.browser.url url_before = self.browser.url
...@@ -1045,13 +1051,14 @@ class ContextMainForm(MainForm): ...@@ -1045,13 +1051,14 @@ class ContextMainForm(MainForm):
getattr(self.browser.mainForm, getattr(self.browser.mainForm,
'submitDialog' + dialog_name.capitalize())() 'submitDialog' + dialog_name.capitalize())()
if dialog_expected_transition_message: if expected_transition_message:
transition_message = self.browser.getTransitionMessage() transition_message = self.browser.getTransitionMessage()
if transition_message != dialog_expected_transition_message: if transition_message != expected_transition_message:
raise AssertionError("Expected transition message: %s, got: %s" % \ raise AssertionError("Expected transition message: %s, got: %s" % \
(dialog_expected_transition_message, (expected_transition_message,
transition_message)) transition_message))
if dialog_name:
return show_dialog_time return show_dialog_time
if maximum_attempt_number == 1: if maximum_attempt_number == 1:
......
import re, sys, threading, os, subprocess
import traceback
import errno
from pprint import pprint
_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))
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 Persistent(object):
"""Very simple persistent data storage for optimization purpose
This tool should become a standalone daemon communicating only with an ERP5
instance. But for the moment, it only execute 1 test suite and exists,
and test suite classes may want some information from previous runs.
"""
def __init__(self, filename):
self._filename = filename
def __getattr__(self, attr):
if attr == '_db':
try:
db = file(self._filename, 'r+')
except IOError, e:
if e.errno != errno.ENOENT:
raise
db = file(self._filename, 'w+')
else:
try:
self.__dict__.update(eval(db.read()))
except StandardError:
pass
self._db = db
return db
self._db
return super(Persistent, self).__getattribute__(attr)
def sync(self):
self._db.seek(0)
db = dict(x for x in self.__dict__.iteritems() if x[0][:1] != '_')
pprint.pprint(db, self._db)
self._db.truncate()
class TestSuite(object):
"""
Subclasses may redefine the following properties:
mysql_db_count (integer, >=1)
Maximum number of SQL databases connection strings needed by any tests ran
in this suite. Tests will get mysql_db_count - 1 connection strings in
extra_sql_connection_string_list environment variable.
"""
RUN_RE = re.compile(
r'Ran (?P<all_tests>\d+) tests? in (?P<seconds>\d+\.\d+)s',
re.DOTALL)
STATUS_RE = re.compile(r"""
(OK|FAILED)\s+\(
(failures=(?P<failures>\d+),?\s*)?
(errors=(?P<errors>\d+),?\s*)?
(skipped=(?P<skips>\d+),?\s*)?
(expected\s+failures=(?P<expected_failures>\d+),?\s*)?
(unexpected\s+successes=(?P<unexpected_successes>\d+),?\s*)?
\)
""", re.DOTALL | re.VERBOSE)
mysql_db_count = 1
allow_restart = False
realtime_output = True
stdin = file(os.devnull)
def __init__(self, max_instance_count, **kw):
self.__dict__.update(kw)
self._path_list = ['tests']
pool = threading.Semaphore(max_instance_count)
self.acquire = pool.acquire
self.release = pool.release
self._instance = threading.local()
self._pool = max_instance_count == 1 and [None] or \
range(1, max_instance_count + 1)
self._ready = set()
self.running = {}
if max_instance_count != 1:
self.realtime_output = False
elif os.isatty(1):
self.realtime_output = True
self.persistent = Persistent('run_test_suite-%s.tmp'
% self.__class__.__name__)
instance = property(lambda self: self._instance.id)
def start(self, test, on_stop=None):
assert test not in self.running
self.running[test] = instance = self._pool.pop(0)
def run():
try:
self._instance.id = instance
if instance not in self._ready:
self._ready.add(instance)
self.setup()
status_dict = self.run(test)
if on_stop is not None:
on_stop(status_dict)
self._pool.append(self.running.pop(test))
finally:
self.release()
thread = threading.Thread(target=run)
thread.setDaemon(True)
thread.start()
def update(self):
self.checkout() # by default, update everything
def setup(self):
pass
def run(self, test):
raise NotImplementedError
def getTestList(self):
raise NotImplementedError
def spawn(self, *args, **kw):
quiet = kw.pop('quiet', False)
env = kw and dict(os.environ, **kw) or None
command = format_command(*args, **kw)
print '\n$ ' + command
sys.stdout.flush()
try:
p = subprocess.Popen(args, stdin=self.stdin, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, env=env)
except Exception:
# Catch any exception here, to warn user instead of beeing silent,
# by generating fake error result
result = dict(status_code=-1,
command=command,
stderr=traceback.format_exc(),
stdout='')
raise SubprocessError(result)
if self.realtime_output:
stdout, stderr = subprocess_capture(p, quiet)
else:
stdout, stderr = p.communicate()
if not quiet:
sys.stdout.write(stdout)
sys.stderr.write(stderr)
result = dict(status_code=p.returncode, command=command,
stdout=stdout, stderr=stderr)
if p.returncode:
raise SubprocessError(result)
return result
# (XXX) The code bellow is an generic extension to run a test for any egg.
# The code above was moved from ERP5 code base, because it is generic
# Enough to be used by others.
# (FIXME) Imports should be reorganised in a better way
import argparse
import sys
import glob
import re
import os
import shlex
from erp5.util import taskdistribution
import re, os, shlex, glob
class EggTestSuite(TestSuite):
def run(self, test):
print test
original_dir = os.getcwd()
try:
os.chdir(test)
return self.runUnitTest(test)
finally:
os.chdir(original_dir)
def runUnitTest(self, *args, **kw):
try:
# (FIXME) The python should be provided by environment with
# appropriated configuration.
runUnitTest = "python setup.py test"
args = tuple(shlex.split(runUnitTest))
status_dict = self.spawn(*args, **kw)
except SubprocessError, e:
status_dict = e.status_dict
test_log = status_dict['stderr']
search = self.RUN_RE.search(test_log)
if search:
groupdict = search.groupdict()
status_dict.update(duration=float(groupdict['seconds']),
test_count=int(groupdict['all_tests']))
search = self.STATUS_RE.search(test_log)
if search:
groupdict = search.groupdict()
status_dict.update(error_count=int(groupdict['errors'] or 0),
failure_count=int(groupdict['failures'] or 0)
+int(groupdict['unexpected_successes'] or 0),
skip_count=int(groupdict['skips'] or 0)
+int(groupdict['expected_failures'] or 0))
return status_dict
def getTestList(self):
# (FIXME) The test name should be nicer in order to provide a good report.
# On task distribution.
source_code_to_test = os.environ.get("SOURCE_CODE_TO_TEST", '.')
return source_code_to_test.split(",")
def runTestSuite():
parser = argparse.ArgumentParser(description='Run a test suite.')
parser.add_argument('--test_suite', help='The test suite name')
parser.add_argument('--test_suite_title', help='The test suite title',
default=None)
parser.add_argument('--test_node_title', help='The test node title',
default=None)
parser.add_argument('--project_title', help='The project title',
default=None)
parser.add_argument('--revision', help='The revision to test',
default='dummy_revision')
parser.add_argument('--node_quantity', help='Number of parallel tests to run',
default=1, type=int)
parser.add_argument('--master_url',
help='The Url of Master controling many suites',
default=None)
parser.add_argument('--source_code_path_list',
help='List of Eggs folders to test, splited by commam',
default='.')
args = parser.parse_args()
master = taskdistribution.TaskDistributionTool(args.master_url)
os.environ.setdefault("SOURCE_CODE_TO_TEST", args.source_code_path_list)
test_suite_title = args.test_suite_title or args.test_suite
revision = args.revision
suite = EggTestSuite(1, test_suite=args.test_suite,
node_quantity=args.node_quantity,
revision=revision)
test_result = master.createTestResult(revision, suite.getTestList(),
args.test_node_title, suite.allow_restart, test_suite_title,
args.project_title)
if test_result is not None:
assert revision == test_result.revision, (revision, test_result.revision)
while suite.acquire():
test = test_result.start(suite.running.keys())
if test is not None:
suite.start(test.name, lambda status_dict, __test=test:
__test.stop(**status_dict))
elif not suite.running:
break
#!/usr/bin/python
##############################################################################
#
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
# Vincent Pelletier <vincent@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.
#
##############################################################################
import os
import sys
import imp
import gzip
import getopt
from time import time
PROFILING_ENABLED = False
if PROFILING_ENABLED:
from tiny_profiler import profiler_decorator, profiler_report
else:
def profiler_decorator(funct):
return funct
def profiler_report():
pass
usage = """
Usage:
parse_timing_log.py [--prefix <prefix>] --config <config> [--debug]
[--no-average] [--sum] [--load <file>] [--save <file>]
[--decimate <int>] [file_1 [file_2 [...]]]
Either --prefix or --save must be given.
--prefix <prefix>
<prefix> is a string which is used to prefix result file names.
If ommited, no CSV will be generated.
--no-average
Disable the generation of CSV files with average values.
--sum
Generate CSV files with time sum as values.
They use the same names as average files, suffixed with "_sum.csv"
Ignored if --prefix was not given.
--load <file>
Load internal data dict from given file before processing any given file.
If it's given multiple time, the content of all those files will be merged.
--save <file>
Save interal data dict to given file after processing all given files.
--config <config>
<config> is a python script defining 2 values:
- a method called "processLine"
- a compiled regex called "LINE_PATTERN"
- a date list sort key computation function called "date_key"
--debug
Display missed and skipped lines.
--decimate <int>
Instead of generating a line per measure, generate one line per <int>
measures.
Remain of the integer division of the number of measures per decimate value
are all put in latest output line.
file_1 ...
Log files to process.
Order in which files are given does not matter.
Files can be gzip or plain text.
Output files:
CSV, one file per distinct processLine return value, one line per log day,
one column per measure.
First line contains column titles.
First column contains measure date (first recognisable date in current file).
Each other cell contains:
=<value sum>/<value count>
Example:
=434/125
Which means an average of 3.472s over 125 values.
Empty clls means that there are no values for that measure in current file.
Strings are surrounded by double quotes (").
Fields are sparated by colons (,).
"""
@profiler_decorator
def parseFile(filename, measure_dict):
date = None
line_number = 0
match_count = 0
skip_count = 0
logfile = gzip.open(filename, 'r')
try:
line = logfile.readline()
except IOError:
logfile = open(filename, 'r')
line = logfile.readline()
begin = time()
while line != '':
line_number += 1
if line_number % 5000 == 0:
sys.stderr.write('%i\r' % (line_number, ))
sys.stderr.flush()
match_list = LINE_PATTERN.findall(line)
if len(match_list) != 1:
print >>sys.stderr, 'Unparseable line: %s:%i %r' % (filename, line_number, line)
else:
result, filter_id, date, duration = processLine(match_list[0], filename, line_number)
# Possible result values & meaning:
# False: try next filter_method
# True: ignore & skip to next line
# (string): use & skip to next line
if result is False:
if debug:
print >>sys.stderr, '? %s:%i %r' % (filename, line_number, match_list[0])
elif result is True:
if debug:
print >>sys.stderr, '- %s:%i %r' % (filename, line_number, match_list[0])
skip_count += 1
else:
measure_dict.setdefault(filter_id, {}).setdefault(result, {}).setdefault(date, []).append(int(duration))
match_count += 1
line = logfile.readline()
print >>sys.stderr, '%i' % (line_number, )
if line_number > 0:
duration = time() - begin
print >>sys.stderr, "Matched %i lines (%.2f%%), %i skipped (%.2f%%), %i unmatched (%.2f%%) in %.2fs (%i lines per second)." % \
(match_count, (float(match_count) / line_number) * 100, skip_count, (float(skip_count) / line_number) * 100, (line_number - match_count - skip_count), (1 - (float(match_count + skip_count) / line_number)) * 100, duration, line_number / duration)
debug = False
outfile_prefix = None
configuration = None
do_average = True
do_sum = False
load_file_name_list = []
save_file_name = None
decimate_count = 1
try:
opts, file_list = getopt.getopt(sys.argv[1:], '', ['debug', 'config=', 'prefix=', 'no-average', 'sum', 'load=', 'save=', 'decimate='])
except Exception, reason:
print >>sys.stderr, reason
print >>sys.stderr, usage
sys.exit(1)
for name, value in opts:
if name == '--debug':
debug = True
elif name == '--config':
configuration = value
elif name == '--prefix':
outfile_prefix = value
elif name == '--no-average':
do_average = False
elif name == '--sum':
do_sum = True
elif name == '--load':
load_file_name_list.append(value)
elif name == '--save':
save_file_name = value
elif name == '--decimate':
decimate_count = int(value)
if configuration is None:
raise ValueError, '--config is mandatory'
config_file = os.path.splitext(os.path.basename(configuration))[0]
config_path = [os.path.dirname(os.path.abspath(configuration))] + sys.path
file, path, description = imp.find_module(config_file, config_path)
module = imp.load_module(config_file, file, path, description)
file.close()
processLine = module.processLine
LINE_PATTERN = module.LINE_PATTERN
date_key = module.date_key
file_count = len(file_list)
file_number = 0
measure_dict = {}
if len(load_file_name_list):
for load_file_name in load_file_name_list:
load_file = open(load_file_name)
temp_measure_dict = eval(load_file.read(), {})
load_file.close()
assert isinstance(measure_dict, dict)
for filter_id, result_dict in temp_measure_dict.iteritems():
for result, date_dict in result_dict.iteritems():
for date, duration_list in date_dict.iteritems():
measure_dict.setdefault(filter_id, {}).setdefault(result, {}).setdefault(date, []).extend(duration_list)
print >>sys.stderr, 'Previous processing result restored from %r' % (load_file_name, )
for filename in file_list:
file_number += 1
print >>sys.stderr, 'Processing %s [%i/%i]...' % (filename, file_number, file_count)
parseFile(filename, measure_dict)
if save_file_name is not None:
save_file = open(save_file_name, 'w')
save_file.write(repr(measure_dict))
save_file.close()
print >>sys.stderr, 'Processing result saved to %r' % (save_file_name, )
if outfile_prefix is not None:
## Generate a list of all measures and a 2-levels dictionnary with date as key and measure dictionnary as value
measure_id_list = []
append = measure_id_list.append
sheet_dict = {}
line_dict = {}
for match_id, match_dict in measure_dict.iteritems():
for result_id, result_dict in match_dict.iteritems():
measure_id = (match_id, result_id)
sheet_dict.setdefault(match_id, []).append((result_id, measure_id))
append(measure_id)
for date, measure_list in result_dict.iteritems():
first_level_dict = line_dict.setdefault(date, {})
assert measure_id not in first_level_dict
first_level_dict[measure_id] = measure_list
date_list = line_dict.keys()
date_list.sort(key=date_key)
def render_cell(value_list, format):
if isinstance(value_list, (list, tuple)):
return format % {'sum': sum(value_list), 'count': len(value_list)}
else:
return value_list
def renderOutput(data_format, filename_suffix):
for sheet_id, sheet_column_list in sheet_dict.iteritems():
outfile_name = '%s_%s_%s.csv' % (outfile_prefix, sheet_id, filename_suffix)
print >>sys.stderr, 'Writing to %r...' % (outfile_name, )
outfile = open(outfile_name, 'w')
print >>outfile, '"date",%s' % (','.join(['"%s"' % (x[0], ) for x in sheet_column_list]), )
decimate_dict = {}
decimate = 0
for date in date_list:
for key, value in line_dict[date].iteritems():
decimate_dict.setdefault(key, []).extend(value)
decimate += 1
if decimate == decimate_count:
print >>outfile, '"%s",%s' % (date, ','.join([render_cell(decimate_dict.get(x[1], ''), data_format) for x in sheet_column_list]))
decimate_dict = {}
decimate = 0
if len(decimate_dict):
print >>outfile, '"%s",%s' % (date, ','.join([render_cell(decimate_dict.get(x[1], ''), data_format) for x in sheet_column_list]))
if do_average:
renderOutput('=%(sum)i/%(count)i', 'avg')
if do_sum:
renderOutput('=%(sum)i', 'sum')
profiler_report()
#!/usr/bin/python
##############################################################################
#
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
# Vincent Pelletier <vincent@nexedi.com>
# Sebastien Robin <seb@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 datetime import date
from os import path
import rpy2.robjects as robjects
import os
from optparse import OptionParser
r = robjects.r
usage = """
Usage:
%prog [OPTION] file1.csv [file2.csv [...]]
Result:
Generates, in current directory, a graph per csv column in out-type format.
Their name is composed of:
- csv file basename (without extension)
- csv column title
- the ratio of present points (100 to 000). The higher the number, the
more the plot will be complete (less holes, longer timespan coverage).
- out-type extension
CSV files must have been generated by parse_timing_log.py tool.
"""
class CSVFile(object):
def __init__(self, file_name, field_delim=','):
file = open(file_name, 'r')
self.column_dict = column_dict = {}
self.column_list = column_list = []
self.ratio_dict = ratio_dict = {}
line_num = 0
self.value_max = value_max = {}
next_ord = 0
for x, title in enumerate(file.readline().split(field_delim)):
title = title.strip()
title = title.strip('"')
if title in column_dict:
title = next_ord
while title in column_dict:
title += 1
next_ord = title + 1
title = str(title)
column_dict[title] = []
column_list.append(title)
for line in file.readlines():
line_num += 1
for x, cell in enumerate(line.split(field_delim)):
cell = cell.strip()
key = column_list[x]
if x != 0:
cell = computeExpr(cell)
if cell is not None:
ratio = ratio_dict.get(key, 0)
ratio_dict[key] = ratio + 1
if cell > value_max.get(key, 0):
value_max[key] = cell
column_dict[key].append(cell)
line_num = float(line_num) / 100
for key in ratio_dict:
ratio_dict[key] /= line_num
def getColumn(self, column_id):
return self.column_dict[self.column_list[column_id]]
def iterColumns(self, start=0, stop=None):
if stop is None:
column_list = self.column_list[start:]
else:
column_list = self.column_list[start:stop]
return ((x, self.column_dict[x], self.value_max.get(x, 0), self.ratio_dict.get(x, 0)) for x in column_list)
def computeExpr(expr):
# only supports '=x/y'
if expr:
assert expr[0] == '='
num, denom = expr[1:].split('/')
result = float(int(num)) / int(denom)
else:
result = None
return result
def main():
parser = OptionParser(usage)
parser.add_option("--with-regression", action="store_true",
dest="regression_enabled", help="enable B-spline regression")
parser.add_option("--ignored-quantity", type="int", dest="ignored_quantity",
help="ignore IGNORED_QUANTITY higher values that might make a graph totally unusable")
parser.add_option("--out-type", type="string", default="png",
help="can be %default (default) or svg")
parser.add_option("--minimal-non-empty-values-ratio", type="float",
dest="minimal_non_empty_ratio", default=None,
help="graph with ratio of non empty values with lesser than value, then graph is ignored")
(options, file_name_list) = parser.parse_args()
current_dir = os.getcwd()
for file_name in file_name_list:
print 'Loading %s...' % (file_name, )
file = CSVFile(file_name)
date_string_list = file.getColumn(0)
date_list = []
x_label_value_list = []
# plotting functionnalities does not select smartly
# a good number of x values to display, so we will display 20 dates
# in order to have good enough dates on the x axis.
# x_label_value_list will be like [1, 5, 10...]
# date_list will be like ['2009/07/01', '2009/07/05', '2009/07/10', ...]
factor = 1
if len(date_string_list) > 20:
factor = int(len(date_string_list) / 20)
i = 0
for date_string in date_string_list:
if i % factor == 0:
x_label_value_list.append(i)
date_split = date_string.replace('"','').split('/')
date_split.reverse()
new_date = '/'.join(date_split)
date_list.append(new_date)
i += 1
max_x = len(date_string_list)
# knots are used for B-spline regression
# We need to add three additional knots at the begin and end in
# order to have the right basis
knot_list = [x_label_value_list[0]] * 3 + x_label_value_list \
+ [max_x] * 4
r_x_label_value_list = robjects.FloatVector(x_label_value_list)
robjects.globalenv["x_label_value_list"] = r_x_label_value_list
robjects.globalenv["knot_list"] = knot_list
r("x_label <- c(%s)" % ','.join(['"%s"' % x for x in date_list]))
# import the splines library in R
if options.regression_enabled:
r("library(splines)")
# now parse all columns and store a out-type file
for title, column, value_max, ratio in file.iterColumns(start=1):
out_file, out_ext = path.splitext(path.basename(file_name))
if out_ext != '.csv':
out_file = '.'.join((out_file, out_ext))
out_file_name = '%s_%s_%03i.%s' % (out_file, title.replace('%',''),
ratio, options.out_type)
i = 0
x_data = []
y_data = []
# First parse the list to retrieve values that we might want to remove
ignored_value_set = set([])
max_y_data = []
if options.ignored_quantity not in (None, 0):
for value in column:
if value is not None:
max_y_data.append(value)
max_y_data.sort()
ignored_value_set = set(max_y_data[-options.ignored_quantity:])
# build list with all data that we want to display
for value in column:
if value is not None and not (value in ignored_value_set):
x_data.append(i)
y_data.append(value)
i += 1
if len(x_data) == 0:
print 'Nothing to plot for %s...' % (out_file_name, )
continue
if options.minimal_non_empty_ratio is not None:
column_len = len(column)
if column_len:
if float(len(x_data))/column_len < options.minimal_non_empty_ratio:
print 'Not enough values to plot for %s...' % (out_file_name, )
continue
r_y_data = robjects.FloatVector(y_data)
r_x_data = robjects.FloatVector(x_data)
robjects.globalenv["y_data"] = r_y_data
robjects.globalenv["x_data"] = r_x_data
display_column_regression = options.regression_enabled
# if there is no more than one unique point, regression is useless
if len(set([x for x in r_y_data])) <= 1:
display_column_regression = 0
regression_string = ''
# Calculate a B-spline regression in order to give clear overview
# about the direction of chaotics values.
if display_column_regression:
r("bx <- splineDesign(knot_list, x_data)")
r("fitted_model <- lm(y_data ~ bx)")
regression_string = ', fitted_model$fit'
# Define the place where to store the graphe and format of the image
r("""%s(file='%s/%s', width=800, height=600)""" % (options.out_type,
current_dir, out_file_name))
# Increase the size for the place of the bottom axis labels (x)
r("""par(mar=c(9, 4, 4, 2) + 0.1)""")
# Plot the graph itself
r("""matplot(x_data, cbind(y_data %s), type='ll',
lty=1, main='%s (average display time per day)',
xlab='', ylab='time (s)', xaxt='n')""" % (
regression_string, title))
r("""axis(1, at=x_label_value_list, lab=x_label, las=2)""")
# stop changing the out-type file
r("""dev.off()""")
print 'Saving %s...' % (out_file_name, )
if __name__ == '__main__':
main()
...@@ -4177,10 +4177,7 @@ class RoleTemplateItem(BaseTemplateItem): ...@@ -4177,10 +4177,7 @@ class RoleTemplateItem(BaseTemplateItem):
path = obsolete_key path = obsolete_key
bta.addObject(xml_data, name=path) bta.addObject(xml_data, name=path)
class CatalogSearchKeyTemplateItem(BaseTemplateItem): class CatalogKeyTemplateItemBase(BaseTemplateItem):
key_list_attr = 'sql_catalog_search_keys'
key_list_title = 'search_key_list'
key_title = 'Search key'
def build(self, context, **kw): def build(self, context, **kw):
catalog = _getCatalogValue(self) catalog = _getCatalogValue(self)
...@@ -4205,6 +4202,10 @@ class CatalogSearchKeyTemplateItem(BaseTemplateItem): ...@@ -4205,6 +4202,10 @@ class CatalogSearchKeyTemplateItem(BaseTemplateItem):
key_list = [key.text for key in xml.getroot()] key_list = [key.text for key in xml.getroot()]
self._objects[file_name[:-4]] = key_list self._objects[file_name[:-4]] = key_list
def _getUpdateDictAction(self, update_dict):
action = update_dict.get(self.key_list_title, 'nothing')
return action
def install(self, context, trashbin, **kw): def install(self, context, trashbin, **kw):
catalog = _getCatalogValue(self) catalog = _getCatalogValue(self)
if catalog is None: if catalog is None:
...@@ -4222,16 +4223,16 @@ class CatalogSearchKeyTemplateItem(BaseTemplateItem): ...@@ -4222,16 +4223,16 @@ class CatalogSearchKeyTemplateItem(BaseTemplateItem):
keys = self._archive.keys() keys = self._archive.keys()
update_dict = kw.get('object_to_update') update_dict = kw.get('object_to_update')
force = kw.get('force') force = kw.get('force')
# XXX same as related key if force or self._getUpdateDictAction(update_dict) != 'nothing':
if update_dict.has_key(self.key_list_title) or force: catalog_key_list = self._getUpdatedCatalogKeyList(catalog_key_list, keys)
if not force: setattr(catalog, self.key_list_attr, catalog_key_list)
action = update_dict[self.key_list_title]
if action == 'nothing': def _getUpdatedCatalogKeyList(self, catalog_key_list, new_key_list):
return catalog_key_list = list(catalog_key_list) # copy
for key in keys: for key in new_key_list:
if key not in catalog_key_list: if key not in catalog_key_list:
catalog_key_list.append(key) catalog_key_list.append(key)
setattr(catalog, self.key_list_attr, catalog_key_list) return catalog_key_list
def uninstall(self, context, **kw): def uninstall(self, context, **kw):
catalog = _getCatalogValue(self) catalog = _getCatalogValue(self)
...@@ -4267,100 +4268,99 @@ class CatalogSearchKeyTemplateItem(BaseTemplateItem): ...@@ -4267,100 +4268,99 @@ class CatalogSearchKeyTemplateItem(BaseTemplateItem):
xml_data = self.generateXml(path=path) xml_data = self.generateXml(path=path)
bta.addObject(xml_data, name=path) bta.addObject(xml_data, name=path)
class CatalogResultKeyTemplateItem(CatalogSearchKeyTemplateItem): class CatalogUniqueKeyTemplateItemBase(CatalogKeyTemplateItemBase):
# like CatalogKeyTemplateItemBase, but for keys which use
# "key | value" syntax to configure dictionaries.
# The keys (part before the pipe) must be unique.
def _getMapFromKeyList(self, key_list):
# in case of duplicates, only the last installed entry will survive
return dict(tuple(part.strip() for part in key.split('|', 1))
for key in key_list)
def _getListFromKeyMap(self, key_map):
return [" | ".join(item) for item in sorted(key_map.items())]
def _getUpdatedCatalogKeyList(self, catalog_key_list, new_key_list):
# treat key lists as dictionaries, parse and update:
catalog_key_map = self._getMapFromKeyList(catalog_key_list)
catalog_key_map.update(self._getMapFromKeyList(new_key_list))
return self._getListFromKeyMap(catalog_key_map)
class CatalogSearchKeyTemplateItem(CatalogUniqueKeyTemplateItemBase):
key_list_attr = 'sql_catalog_search_keys'
key_list_title = 'search_key_list'
key_title = 'Search key'
class CatalogResultKeyTemplateItem(CatalogKeyTemplateItemBase):
key_list_attr = 'sql_search_result_keys' key_list_attr = 'sql_search_result_keys'
key_list_title = 'result_key_list' key_list_title = 'result_key_list'
key_title = 'Result key' key_title = 'Result key'
class CatalogRelatedKeyTemplateItem(CatalogSearchKeyTemplateItem): class CatalogRelatedKeyTemplateItem(CatalogUniqueKeyTemplateItemBase):
key_list_attr = 'sql_catalog_related_keys' key_list_attr = 'sql_catalog_related_keys'
key_list_title = 'related_key_list' key_list_title = 'related_key_list'
key_title = 'Related key' key_title = 'Related key'
# override this method to support 'key_list' for backward compatibility. # override this method to support 'key_list' for backward compatibility.
def install(self, context, trashbin, **kw): def _getUpdateDictAction(self, update_dict):
catalog = _getCatalogValue(self) action = update_dict.get(self.key_list_title, _MARKER)
if catalog is None: if action is _MARKER:
LOG('BusinessTemplate', 0, 'no SQL catalog was available') action = update_dict.get('key_list', 'nothing')
return return action
catalog_key_list = list(getattr(catalog, self.key_list_attr, []))
if context.getTemplateFormatVersion() == 1:
if len(self._objects.keys()) == 0: # needed because of pop()
return
keys = []
for k in self._objects.values().pop(): # because of list of list
keys.append(k)
else:
keys = self._archive.keys()
update_dict = kw.get('object_to_update')
force = kw.get('force')
# XXX must a find a better way to manage related key
if update_dict.has_key(self.key_list_title) or update_dict.has_key('key_list') or force:
if not force:
if update_dict.has_key(self.key_list_title):
action = update_dict[self.key_list_title]
else: # XXX for backward compatibility
action = update_dict['key_list']
if action == 'nothing':
return
for key in keys:
if key not in catalog_key_list:
catalog_key_list.append(key)
setattr(catalog, self.key_list_attr, catalog_key_list)
class CatalogResultTableTemplateItem(CatalogSearchKeyTemplateItem): class CatalogResultTableTemplateItem(CatalogKeyTemplateItemBase):
key_list_attr = 'sql_search_tables' key_list_attr = 'sql_search_tables'
key_list_title = 'result_table_list' key_list_title = 'result_table_list'
key_title = 'Result table' key_title = 'Result table'
# keyword # keyword
class CatalogKeywordKeyTemplateItem(CatalogSearchKeyTemplateItem): class CatalogKeywordKeyTemplateItem(CatalogKeyTemplateItemBase):
key_list_attr = 'sql_catalog_keyword_search_keys' key_list_attr = 'sql_catalog_keyword_search_keys'
key_list_title = 'keyword_key_list' key_list_title = 'keyword_key_list'
key_title = 'Keyword key' key_title = 'Keyword key'
# datetime # datetime
class CatalogDateTimeKeyTemplateItem(CatalogSearchKeyTemplateItem): class CatalogDateTimeKeyTemplateItem(CatalogKeyTemplateItemBase):
key_list_attr = 'sql_catalog_datetime_search_keys' key_list_attr = 'sql_catalog_datetime_search_keys'
key_list_title = 'datetime_key_list' key_list_title = 'datetime_key_list'
key_title = 'DateTime key' key_title = 'DateTime key'
# full text # full text
class CatalogFullTextKeyTemplateItem(CatalogSearchKeyTemplateItem): class CatalogFullTextKeyTemplateItem(CatalogKeyTemplateItemBase):
key_list_attr = 'sql_catalog_full_text_search_keys' key_list_attr = 'sql_catalog_full_text_search_keys'
key_list_title = 'full_text_key_list' key_list_title = 'full_text_key_list'
key_title = 'Fulltext key' key_title = 'Fulltext key'
# request # request
class CatalogRequestKeyTemplateItem(CatalogSearchKeyTemplateItem): class CatalogRequestKeyTemplateItem(CatalogKeyTemplateItemBase):
key_list_attr = 'sql_catalog_request_keys' key_list_attr = 'sql_catalog_request_keys'
key_list_title = 'request_key_list' key_list_title = 'request_key_list'
key_title = 'Request key' key_title = 'Request key'
# multivalue # multivalue
class CatalogMultivalueKeyTemplateItem(CatalogSearchKeyTemplateItem): class CatalogMultivalueKeyTemplateItem(CatalogKeyTemplateItemBase):
key_list_attr = 'sql_catalog_multivalue_keys' key_list_attr = 'sql_catalog_multivalue_keys'
key_list_title = 'multivalue_key_list' key_list_title = 'multivalue_key_list'
key_title = 'Multivalue key' key_title = 'Multivalue key'
# topic # topic
class CatalogTopicKeyTemplateItem(CatalogSearchKeyTemplateItem): class CatalogTopicKeyTemplateItem(CatalogKeyTemplateItemBase):
key_list_attr = 'sql_catalog_topic_search_keys' key_list_attr = 'sql_catalog_topic_search_keys'
key_list_title = 'topic_key_list' key_list_title = 'topic_key_list'
key_title = 'Topic key' key_title = 'Topic key'
class CatalogScriptableKeyTemplateItem(CatalogSearchKeyTemplateItem): class CatalogScriptableKeyTemplateItem(CatalogUniqueKeyTemplateItemBase):
key_list_attr = 'sql_catalog_scriptable_keys' key_list_attr = 'sql_catalog_scriptable_keys'
key_list_title = 'scriptable_key_list' key_list_title = 'scriptable_key_list'
key_title = 'Scriptable key' key_title = 'Scriptable key'
class CatalogRoleKeyTemplateItem(CatalogSearchKeyTemplateItem): class CatalogRoleKeyTemplateItem(CatalogUniqueKeyTemplateItemBase):
key_list_attr = 'sql_catalog_role_keys' key_list_attr = 'sql_catalog_role_keys'
key_list_title = 'role_key_list' key_list_title = 'role_key_list'
key_title = 'Role key' key_title = 'Role key'
class CatalogLocalRoleKeyTemplateItem(CatalogSearchKeyTemplateItem): class CatalogLocalRoleKeyTemplateItem(CatalogUniqueKeyTemplateItemBase):
key_list_attr = 'sql_catalog_local_role_keys' key_list_attr = 'sql_catalog_local_role_keys'
key_list_title = 'local_role_key_list' key_list_title = 'local_role_key_list'
key_title = 'LocalRole key' key_title = 'LocalRole key'
......
...@@ -37,6 +37,7 @@ import tarfile ...@@ -37,6 +37,7 @@ import tarfile
from Acquisition import Implicit, Explicit from Acquisition import Implicit, Explicit
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from AccessControl.SecurityInfo import ModuleSecurityInfo
from Products.CMFActivity.ActiveResult import ActiveResult from Products.CMFActivity.ActiveResult import ActiveResult
from Products.ERP5Type.Globals import InitializeClass, DTMLFile, PersistentMapping from Products.ERP5Type.Globals import InitializeClass, DTMLFile, PersistentMapping
from Products.ERP5Type.DiffUtils import DiffFile from Products.ERP5Type.DiffUtils import DiffFile
...@@ -83,6 +84,8 @@ class BusinessTemplateIsMeta(Exception): ...@@ -83,6 +84,8 @@ class BusinessTemplateIsMeta(Exception):
""" """
pass pass
ModuleSecurityInfo(__name__).declarePublic('BusinessTemplateUnknownError')
class TemplateTool (BaseTool): class TemplateTool (BaseTool):
""" """
TemplateTool manages Business Templates. TemplateTool manages Business Templates.
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts83858910.0</string> </value> <value> <string>ts44338434.35</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -106,7 +106,7 @@ window.onload = function()\r\n ...@@ -106,7 +106,7 @@ window.onload = function()\r\n
\t\t\t\t\t\t\t\tborder-left: #000000 1px solid; border-bottom: #000000 1px solid">\r\n \t\t\t\t\t\t\t\tborder-left: #000000 1px solid; border-bottom: #000000 1px solid">\r\n
\t\t\t\t\t\t\t\t<span fcklang="DlgAboutVersion">version</span>\r\n \t\t\t\t\t\t\t\t<span fcklang="DlgAboutVersion">version</span>\r\n
\t\t\t\t\t\t\t\t<br />\r\n \t\t\t\t\t\t\t\t<br />\r\n
\t\t\t\t\t\t\t\t<b>2.6.6</b><br />\r\n \t\t\t\t\t\t\t\t<b>2.6.8</b><br />\r\n
\t\t\t\t\t\t\t\tBuild 25427</td>\r\n \t\t\t\t\t\t\t\tBuild 25427</td>\r\n
\t\t\t\t\t\t</tr>\r\n \t\t\t\t\t\t</tr>\r\n
\t\t\t\t\t</table>\r\n \t\t\t\t\t</table>\r\n
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts83858910.02</string> </value> <value> <string>ts44338467.6</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
</item> </item>
<item> <item>
<key> <string>content_type</string> </key> <key> <string>content_type</string> </key>
<value> <string>text/x-unknown-content-type</string> </value> <value> <string>application/octet-stream</string> </value>
</item> </item>
<item> <item>
<key> <string>data</string> </key> <key> <string>data</string> </key>
...@@ -93,7 +93,7 @@ others files in certain cases.\r\n ...@@ -93,7 +93,7 @@ others files in certain cases.\r\n
<!--- Generate Text Inputs --->\r\n <!--- Generate Text Inputs --->\r\n
<cfset i = 0>\r\n <cfset i = 0>\r\n
<cfloop list="#submitted_text#" index="textinput">\r\n <cfloop list="#submitted_text#" index="textinput">\r\n
<cfset texts.textinputs = ListAppend(texts.textinputs, \'textinputs[#i#] = decodeURIComponent("#textinput#");\', CRLF)>\r\n <cfset texts.textinputs = ListAppend(texts.textinputs, \'textinputs[#i#] = decodeURIComponent("\' & htmleditformat( textinput ) & \'");\', CRLF)>\r\n
<cfset i = i + 1>\r\n <cfset i = i + 1>\r\n
</cfloop>\r\n </cfloop>\r\n
\r\n \r\n
...@@ -184,7 +184,7 @@ wordWindowObj.writeBody();\r\n ...@@ -184,7 +184,7 @@ wordWindowObj.writeBody();\r\n
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>5538</int> </value> <value> <int>5562</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts83858910.02</string> </value> <value> <string>ts44338476.75</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
</item> </item>
<item> <item>
<key> <string>content_type</string> </key> <key> <string>content_type</string> </key>
<value> <string>text/x-unknown-content-type</string> </value> <value> <string>application/x-php</string> </value>
</item> </item>
<item> <item>
<key> <string>data</string> </key> <key> <string>data</string> </key>
...@@ -52,7 +52,7 @@ function print_textinputs_var() {\r\n ...@@ -52,7 +52,7 @@ function print_textinputs_var() {\r\n
\tglobal $textinputs;\r\n \tglobal $textinputs;\r\n
\tforeach( $textinputs as $key=>$val ) {\r\n \tforeach( $textinputs as $key=>$val ) {\r\n
\t\t# $val = str_replace( "\'", "%27", $val );\r\n \t\t# $val = str_replace( "\'", "%27", $val );\r\n
\t\techo "textinputs[$key] = decodeURIComponent(\\"" . $val . "\\");\\n";\r\n \t\techo "textinputs[$key] = decodeURIComponent(\\"" . htmlspecialchars($val, ENT_QUOTES) . "\\");\\n";\r\n
\t}\r\n \t}\r\n
}\r\n }\r\n
\r\n \r\n
...@@ -235,7 +235,7 @@ wordWindowObj.writeBody();\r\n ...@@ -235,7 +235,7 @@ wordWindowObj.writeBody();\r\n
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>5854</int> </value> <value> <int>5884</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts83858910.02</string> </value> <value> <string>ts44338484.34</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -20,193 +20,205 @@ ...@@ -20,193 +20,205 @@
</item> </item>
<item> <item>
<key> <string>content_type</string> </key> <key> <string>content_type</string> </key>
<value> <string>text/plain</string> </value> <value> <string>application/octet-stream</string> </value>
</item> </item>
<item> <item>
<key> <string>data</string> </key> <key> <string>data</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
#!/usr/bin/perl\r\n #!/usr/bin/perl\n
\r\n \n
use CGI qw/ :standard /;\r\n use CGI qw/ :standard /;\n
use File::Temp qw/ tempfile tempdir /;\r\n use File::Temp qw/ tempfile tempdir /;\n
\r\n \n
# my $spellercss = \'/speller/spellerStyle.css\';\t\t\t\t\t# by FredCK\r\n # my $spellercss = \'/speller/spellerStyle.css\';\t\t\t\t\t# by FredCK\n
my $spellercss = \'../spellerStyle.css\';\t\t\t\t\t\t\t# by FredCK\r\n my $spellercss = \'../spellerStyle.css\';\t\t\t\t\t\t\t# by FredCK\n
# my $wordWindowSrc = \'/speller/wordWindow.js\';\t\t\t\t\t# by FredCK\r\n # my $wordWindowSrc = \'/speller/wordWindow.js\';\t\t\t\t\t# by FredCK\n
my $wordWindowSrc = \'../wordWindow.js\';\t\t\t\t\t\t\t# by FredCK\r\n my $wordWindowSrc = \'../wordWindow.js\';\t\t\t\t\t\t\t# by FredCK\n
my @textinputs = param( \'textinputs[]\' ); # array\r\n my @textinputs = param( \'textinputs[]\' ); # array\n
# my $aspell_cmd = \'aspell\';\t\t\t\t\t\t\t\t\t# by FredCK (for Linux)\r\n # my $aspell_cmd = \'aspell\';\t\t\t\t\t\t\t\t\t# by FredCK (for Linux)\n
my $aspell_cmd = \'"C:\\Program Files\\Aspell\\bin\\aspell.exe"\';\t# by FredCK (for Windows)\r\n my $aspell_cmd = \'"C:\\Program Files\\Aspell\\bin\\aspell.exe"\';\t# by FredCK (for Windows)\n
my $lang = \'en_US\';\r\n my $lang = \'en_US\';\n
# my $aspell_opts = "-a --lang=$lang --encoding=utf-8";\t\t\t# by FredCK\r\n # my $aspell_opts = "-a --lang=$lang --encoding=utf-8";\t\t\t# by FredCK\n
my $aspell_opts = "-a --lang=$lang --encoding=utf-8 -H --rem-sgml-check=alt";\t\t# by FredCK\r\n my $aspell_opts = "-a --lang=$lang --encoding=utf-8 -H --rem-sgml-check=alt";\t\t# by FredCK\n
my $input_separator = "A";\r\n my $input_separator = "A";\n
\r\n \n
# set the \'wordtext\' JavaScript variable to the submitted text.\r\n # set the \'wordtext\' JavaScript variable to the submitted text.\n
sub printTextVar {\r\n sub printTextVar {\n
\tfor( my $i = 0; $i <= $#textinputs; $i++ ) {\r\n \tfor( my $i = 0; $i <= $#textinputs; $i++ ) {\n
\t print "textinputs[$i] = decodeURIComponent(\'" . escapeQuote( $textinputs[$i] ) . "\')\\n";\r\n \t print "textinputs[$i] = decodeURIComponent(\\"" . specialchar_cnv( $textinputs[$i] ) . "\\");\\n";\n
\t}\r\n \t}\n
}\r\n }\n
\r\n \n
sub printTextIdxDecl {\r\n sub printTextIdxDecl {\n
\tmy $idx = shift;\r\n \tmy $idx = shift;\n
\tprint "words[$idx] = [];\\n";\r\n \tprint "words[$idx] = [];\\n";\n
\tprint "suggs[$idx] = [];\\n";\r\n \tprint "suggs[$idx] = [];\\n";\n
}\r\n }\n
\r\n \n
sub printWordsElem {\r\n sub printWordsElem {\n
\tmy( $textIdx, $wordIdx, $word ) = @_;\r\n \tmy( $textIdx, $wordIdx, $word ) = @_;\n
\tprint "words[$textIdx][$wordIdx] = \'" . escapeQuote( $word ) . "\';\\n";\r\n \tprint "words[$textIdx][$wordIdx] = \'" . escapeQuote( $word ) . "\';\\n";\n
}\r\n }\n
\r\n \n
sub printSuggsElem {\r\n sub printSuggsElem {\n
\tmy( $textIdx, $wordIdx, @suggs ) = @_;\r\n \tmy( $textIdx, $wordIdx, @suggs ) = @_;\n
\tprint "suggs[$textIdx][$wordIdx] = [";\r\n \tprint "suggs[$textIdx][$wordIdx] = [";\n
\tfor my $i ( 0..$#suggs ) {\r\n \tfor my $i ( 0..$#suggs ) {\n
\t\tprint "\'" . escapeQuote( $suggs[$i] ) . "\'";\r\n \t\tprint "\'" . escapeQuote( $suggs[$i] ) . "\'";\n
\t\tif( $i < $#suggs ) {\r\n \t\tif( $i < $#suggs ) {\n
\t\t\tprint ", ";\r\n \t\t\tprint ", ";\n
\t\t}\r\n \t\t}\n
\t}\r\n \t}\n
\tprint "];\\n";\r\n \tprint "];\\n";\n
}\r\n }\n
\r\n \n
sub printCheckerResults {\r\n sub printCheckerResults {\n
\tmy $textInputIdx = -1;\r\n \tmy $textInputIdx = -1;\n
\tmy $wordIdx = 0;\r\n \tmy $wordIdx = 0;\n
\tmy $unhandledText;\r\n \tmy $unhandledText;\n
\t# create temp file\r\n \t# create temp file\n
\tmy $dir = tempdir( CLEANUP => 1 );\r\n \tmy $dir = tempdir( CLEANUP => 1 );\n
\tmy( $fh, $tmpfilename ) = tempfile( DIR => $dir );\r\n \tmy( $fh, $tmpfilename ) = tempfile( DIR => $dir );\n
\r\n \n
\t# temp file was created properly?\r\n \t# temp file was created properly?\n
\r\n \n
\t# open temp file, add the submitted text.\r\n \t# open temp file, add the submitted text.\n
\tfor( my $i = 0; $i <= $#textinputs; $i++ ) {\r\n \tfor( my $i = 0; $i <= $#textinputs; $i++ ) {\n
\t\t$text = url_decode( $textinputs[$i] );\r\n \t\t$text = url_decode( $textinputs[$i] );\n
\t\t# Strip all tags for the text. (by FredCK - #339 / #681)\r\n \t\t# Strip all tags for the text. (by FredCK - #339 / #681)\n
\t\t$text =~ s/<[^>]+>/ /g;\r\n \t\t$text =~ s/<[^>]+>/ /g;\n
\t\t@lines = split( /\\n/, $text );\r\n \t\t@lines = split( /\\n/, $text );\n
\t\tprint $fh "\\%\\n"; # exit terse mode\r\n \t\tprint $fh "\\%\\n"; # exit terse mode\n
\t\tprint $fh "^$input_separator\\n";\r\n \t\tprint $fh "^$input_separator\\n";\n
\t\tprint $fh "!\\n"; # enter terse mode\r\n \t\tprint $fh "!\\n"; # enter terse mode\n
\t\tfor my $line ( @lines ) {\r\n \t\tfor my $line ( @lines ) {\n
\t\t\t# use carat on each line to escape possible aspell commands\r\n \t\t\t# use carat on each line to escape possible aspell commands\n
\t\t\tprint $fh "^$line\\n";\r\n \t\t\tprint $fh "^$line\\n";\n
\t\t}\r\n \t\t}\n
\r\n \n
\t}\r\n \t}\n
\t# exec aspell command\r\n \t# exec aspell command\n
\tmy $cmd = "$aspell_cmd $aspell_opts < $tmpfilename 2>&1";\r\n \tmy $cmd = "$aspell_cmd $aspell_opts < $tmpfilename 2>&1";\n
\topen ASPELL, "$cmd |" or handleError( "Could not execute `$cmd`\\\\n$!" ) and return;\r\n \topen ASPELL, "$cmd |" or handleError( "Could not execute `$cmd`\\\\n$!" ) and return;\n
\t# parse each line of aspell return\r\n \t# parse each line of aspell return\n
\tfor my $ret ( <ASPELL> ) {\r\n \tfor my $ret ( <ASPELL> ) {\n
\t\tchomp( $ret );\r\n \t\tchomp( $ret );\n
\t\t# if \'&\', then not in dictionary but has suggestions\r\n \t\t# if \'&\', then not in dictionary but has suggestions\n
\t\t# if \'#\', then not in dictionary and no suggestions\r\n \t\t# if \'#\', then not in dictionary and no suggestions\n
\t\t# if \'*\', then it is a delimiter between text inputs\r\n \t\t# if \'*\', then it is a delimiter between text inputs\n
\t\tif( $ret =~ /^\\*/ ) {\r\n \t\tif( $ret =~ /^\\*/ ) {\n
\t\t\t$textInputIdx++;\r\n \t\t\t$textInputIdx++;\n
\t\t\tprintTextIdxDecl( $textInputIdx );\r\n \t\t\tprintTextIdxDecl( $textInputIdx );\n
\t\t\t$wordIdx = 0;\r\n \t\t\t$wordIdx = 0;\n
\r\n \n
\t\t} elsif( $ret =~ /^(&|#)/ ) {\r\n \t\t} elsif( $ret =~ /^(&|#)/ ) {\n
\t\t\tmy @tokens = split( " ", $ret, 5 );\r\n \t\t\tmy @tokens = split( " ", $ret, 5 );\n
\t\t\tprintWordsElem( $textInputIdx, $wordIdx, $tokens[1] );\r\n \t\t\tprintWordsElem( $textInputIdx, $wordIdx, $tokens[1] );\n
\t\t\tmy @suggs = ();\r\n \t\t\tmy @suggs = ();\n
\t\t\tif( $tokens[4] ) {\r\n \t\t\tif( $tokens[4] ) {\n
\t\t\t\t@suggs = split( ", ", $tokens[4] );\r\n \t\t\t\t@suggs = split( ", ", $tokens[4] );\n
\t\t\t}\r\n \t\t\t}\n
\t\t\tprintSuggsElem( $textInputIdx, $wordIdx, @suggs );\r\n \t\t\tprintSuggsElem( $textInputIdx, $wordIdx, @suggs );\n
\t\t\t$wordIdx++;\r\n \t\t\t$wordIdx++;\n
\t\t} else {\r\n \t\t} else {\n
\t\t\t$unhandledText .= $ret;\r\n \t\t\t$unhandledText .= $ret;\n
\t\t}\r\n \t\t}\n
\t}\r\n \t}\n
\tclose ASPELL or handleError( "Error executing `$cmd`\\\\n$unhandledText" ) and return;\r\n \tclose ASPELL or handleError( "Error executing `$cmd`\\\\n$unhandledText" ) and return;\n
}\r\n }\n
\r\n \n
sub escapeQuote {\r\n sub escapeQuote {\n
\tmy $str = shift;\r\n \tmy $str = shift;\n
\t$str =~ s/\'/\\\\\'/g;\r\n \t$str =~ s/\'/\\\\\'/g;\n
\treturn $str;\r\n \treturn $str;\n
}\r\n }\n
\r\n \n
sub handleError {\r\n sub specialchar_cnv\n
\tmy $err = shift;\r\n {\n
\tprint "error = \'" . escapeQuote( $err ) . "\';\\n";\r\n \tlocal($ch) = @_;\n
}\r\n \n
\r\n \t$ch =~ s/&/&amp;/g;\t\t# &\n
sub url_decode {\r\n \t$ch =~ s/\\"/&quot;/g;\t#"\n
\tlocal $_ = @_ ? shift : $_;\r\n \t$ch =~ s/\\\'/&#39;/g;\t# \'\n
\tdefined or return;\r\n \t$ch =~ s/</&lt;/g;\t\t# <\n
\t# change + signs to spaces\r\n \t$ch =~ s/>/&gt;/g;\t\t# >\n
\ttr/+/ /;\r\n \treturn($ch);\n
\t# change hex escapes to the proper characters\r\n }\n
\ts/%([a-fA-F0-9]{2})/pack "H2", $1/eg;\r\n \n
\treturn $_;\r\n sub handleError {\n
}\r\n \tmy $err = shift;\n
\r\n \tprint "error = \'" . escapeQuote( $err ) . "\';\\n";\n
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\r\n }\n
# Display HTML\r\n \n
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\r\n sub url_decode {\n
\r\n \tlocal $_ = @_ ? shift : $_;\n
print <<EOF;\r\n \tdefined or return;\n
Content-type: text/html; charset=utf-8\r\n \t# change + signs to spaces\n
\r\n \ttr/+/ /;\n
<html>\r\n \t# change hex escapes to the proper characters\n
<head>\r\n \ts/%([a-fA-F0-9]{2})/pack "H2", $1/eg;\n
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\r\n \treturn $_;\n
<link rel="stylesheet" type="text/css" href="$spellercss"/>\r\n }\n
<script src="$wordWindowSrc"></script>\r\n \n
<script type="text/javascript">\r\n # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\n
var suggs = new Array();\r\n # Display HTML\n
var words = new Array();\r\n # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\n
var textinputs = new Array();\r\n \n
var error;\r\n print <<EOF;\n
EOF\r\n Content-type: text/html; charset=utf-8\n
\r\n \n
printTextVar();\r\n <html>\n
\r\n <head>\n
printCheckerResults();\r\n <meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n
\r\n <link rel="stylesheet" type="text/css" href="$spellercss"/>\n
print <<EOF;\r\n <script src="$wordWindowSrc"></script>\n
var wordWindowObj = new wordWindow();\r\n <script type="text/javascript">\n
wordWindowObj.originalSpellings = words;\r\n var suggs = new Array();\n
wordWindowObj.suggestions = suggs;\r\n var words = new Array();\n
wordWindowObj.textInputs = textinputs;\r\n var textinputs = new Array();\n
\r\n var error;\n
\r\n EOF\n
function init_spell() {\r\n \n
\t// check if any error occured during server-side processing\r\n printTextVar();\n
\tif( error ) {\r\n \n
\t\talert( error );\r\n printCheckerResults();\n
\t} else {\r\n \n
\t\t// call the init_spell() function in the parent frameset\r\n print <<EOF;\n
\t\tif (parent.frames.length) {\r\n var wordWindowObj = new wordWindow();\n
\t\t\tparent.init_spell( wordWindowObj );\r\n wordWindowObj.originalSpellings = words;\n
\t\t} else {\r\n wordWindowObj.suggestions = suggs;\n
\t\t\terror = "This page was loaded outside of a frameset. ";\r\n wordWindowObj.textInputs = textinputs;\n
\t\t\terror += "It might not display properly";\r\n \n
\t\t\talert( error );\r\n \n
\t\t}\r\n function init_spell() {\n
\t}\r\n \t// check if any error occured during server-side processing\n
}\r\n \tif( error ) {\n
\r\n \t\talert( error );\n
</script>\r\n \t} else {\n
\r\n \t\t// call the init_spell() function in the parent frameset\n
</head>\r\n \t\tif (parent.frames.length) {\n
<body onLoad="init_spell();">\r\n \t\t\tparent.init_spell( wordWindowObj );\n
\r\n \t\t} else {\n
<script type="text/javascript">\r\n \t\t\terror = "This page was loaded outside of a frameset. ";\n
wordWindowObj.writeBody();\r\n \t\t\terror += "It might not display properly";\n
</script>\r\n \t\t\talert( error );\n
\r\n \t\t}\n
</body>\r\n \t}\n
</html>\r\n }\n
EOF\r\n \n
</script>\n
\n
</head>\n
<body onLoad="init_spell();">\n
\n
<script type="text/javascript">\n
wordWindowObj.writeBody();\n
</script>\n
\n
</body>\n
</html>\n
EOF\n
]]></string> </value> ]]></string> </value>
...@@ -217,7 +229,7 @@ EOF\r\n ...@@ -217,7 +229,7 @@ EOF\r\n
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>4927</int> </value> <value> <int>4939</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts83858910.28</string> </value> <value> <string>ts44338348.56</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -87,7 +87,7 @@ FCKeditor.MinHeight = 200 ;\r\n ...@@ -87,7 +87,7 @@ FCKeditor.MinHeight = 200 ;\r\n
*/\r\n */\r\n
FCKeditor.MinWidth = 750 ;\r\n FCKeditor.MinWidth = 750 ;\r\n
\r\n \r\n
FCKeditor.prototype.Version\t\t\t= \'2.6.6\' ;\r\n FCKeditor.prototype.Version\t\t\t= \'2.6.8\' ;\r\n
FCKeditor.prototype.VersionBuild\t= \'25427\' ;\r\n FCKeditor.prototype.VersionBuild\t= \'25427\' ;\r\n
\r\n \r\n
FCKeditor.prototype.Create = function()\r\n FCKeditor.prototype.Create = function()\r\n
......
2012-08-07 Kazuhiko
* update FCKeditor to 2.6.8.
2011-01-20 Ivan 2011-01-20 Ivan
* Remove contained MochiKit Javascript library * Remove contained MochiKit Javascript library
......
Copyright (c) 2006-2007 Nexedi SA Copyright (c) 2006-2012 Nexedi SA
\ No newline at end of file \ No newline at end of file
1084 1085
\ No newline at end of file \ No newline at end of file
...@@ -1898,6 +1898,66 @@ class BusinessTemplateMixin(TestDeveloperMixin, ERP5TypeTestCase, LogInterceptor ...@@ -1898,6 +1898,66 @@ class BusinessTemplateMixin(TestDeveloperMixin, ERP5TypeTestCase, LogInterceptor
self.failUnless('catalog.reference' self.failUnless('catalog.reference'
in catalog.sql_search_result_keys) in catalog.sql_search_result_keys)
def stepModifyRelatedKey(self, sequence):
catalog = self.getCatalogTool().getSQLCatalog()
related_key = sequence['related_key']
related_key_list = list(catalog.sql_catalog_related_keys)
related_key_list.remove(related_key)
# related_key_2 <- 'fake_id | category/catalog/z_fake_method_2':
related_key_2 = related_key + '_2'
related_key_list.append(related_key_2)
catalog.sql_catalog_related_keys = tuple(related_key_list)
sequence['related_key_2'] = related_key_2
# check related key column is not present twice:
self.assertTrue(related_key_2.startswith('fake_id |'), related_key_2)
self.assertEqual(len([key for key in related_key_list
if key.startswith('fake_id |')]), 1)
def stepCheckRelatedKeyNonDuplicated(self, sequence):
catalog = self.getCatalogTool().getSQLCatalog()
related_key = sequence['related_key']
related_key_2 = sequence['related_key_2']
related_key_list = list(catalog.sql_catalog_related_keys)
# stepModifyRelatedKey added related_key_2 and removed related_key
# but the reinstallation of the BT replaced related_key_2 with
# related_key:
self.assertTrue(related_key in related_key_list)
self.assertFalse(related_key_2 in related_key_list)
# make sure there's only one entry
self.assertTrue(related_key.startswith('fake_id |'), related_key)
self.assertEqual(len([key for key in related_key_list
if key.startswith('fake_id |')]), 1)
def stepDuplicateRelatedKeyColumn(self, sequence):
catalog = self.getCatalogTool().getSQLCatalog()
related_key = sequence['related_key']
related_key_2 = sequence['related_key_2']
related_key_list = list(catalog.sql_catalog_related_keys)
self.assertTrue(related_key in related_key_list)
self.assertFalse(related_key_2 in related_key_list)
# we manually duplicate the key in the list, creating an invalid situation
self.assertEqual(len([key for key in related_key_list
if key.startswith('fake_id |')]), 1)
related_key_list.append(related_key_2)
catalog.sql_catalog_related_keys = tuple(related_key_list)
self.assertEqual(len([key for key in related_key_list
if key.startswith('fake_id |')]), 2)
def stepCheckOnlyDuplicateRelatedKeyRemains(self, sequence):
catalog = self.getCatalogTool().getSQLCatalog()
related_key = sequence['related_key']
related_key_2 = sequence['related_key_2']
related_key_list = list(catalog.sql_catalog_related_keys)
# after the uninstallation of the BT, only the wrong/duplicated
# entry remains because the original was uninstalled with the BT.
# This also means that an uninstallation of a BT does not
# accidentally removes an overriding key from another BT that
# depends on it.
self.assertFalse(related_key in related_key_list)
self.assertTrue(related_key_2 in related_key_list)
self.assertEqual(len([key for key in related_key_list
if key.startswith('fake_id |')]), 1)
def stepRemoveCatalogLocalConfiguration(self, sequence, **kw): def stepRemoveCatalogLocalConfiguration(self, sequence, **kw):
""" """
Remove modification made in stepModifyCatalogConfiguration Remove modification made in stepModifyCatalogConfiguration
...@@ -1919,7 +1979,13 @@ class BusinessTemplateMixin(TestDeveloperMixin, ERP5TypeTestCase, LogInterceptor ...@@ -1919,7 +1979,13 @@ class BusinessTemplateMixin(TestDeveloperMixin, ERP5TypeTestCase, LogInterceptor
sql_search_tables.remove(result_table) sql_search_tables.remove(result_table)
sql_search_tables.sort() sql_search_tables.sort()
catalog.sql_search_tables = tuple(sql_search_tables) catalog.sql_search_tables = tuple(sql_search_tables)
self.failUnless(result_table not in catalog.sql_search_tables) self.assertFalse(result_table in catalog.sql_search_tables)
# related key
related_key_2 = sequence['related_key_2']
sql_catalog_related_keys = list(catalog.sql_catalog_related_keys)
sql_catalog_related_keys.remove(related_key_2)
catalog.sql_catalog_related_keys = tuple(sql_catalog_related_keys)
self.assertFalse(related_key_2 in catalog.sql_catalog_related_keys)
def stepAddKeysAndTableToBusinessTemplate(self, sequence=None, **kw): def stepAddKeysAndTableToBusinessTemplate(self, sequence=None, **kw):
""" """
...@@ -5250,7 +5316,10 @@ class TestBusinessTemplate(BusinessTemplateMixin): ...@@ -5250,7 +5316,10 @@ class TestBusinessTemplate(BusinessTemplateMixin):
sequence_list.play(self) sequence_list.play(self)
def test_30_CheckInstalledCatalogProperties(self): def test_30_CheckInstalledCatalogProperties(self):
"""Test if installing some new catalog properties overwrites existing ones""" """
Test if installing some new catalog properties do not overwrite existing ones
Also check that it doesn't install two keys for the same column"""
sequence_list = SequenceList() sequence_list = SequenceList()
sequence_string = '\ sequence_string = '\
CreateCatalogMethod \ CreateCatalogMethod \
...@@ -5262,12 +5331,16 @@ class TestBusinessTemplate(BusinessTemplateMixin): ...@@ -5262,12 +5331,16 @@ class TestBusinessTemplate(BusinessTemplateMixin):
BuildBusinessTemplate \ BuildBusinessTemplate \
SaveBusinessTemplate \ SaveBusinessTemplate \
ModifyCatalogConfiguration \ ModifyCatalogConfiguration \
ModifyRelatedKey \
ImportBusinessTemplate \ ImportBusinessTemplate \
UseImportBusinessTemplate \ UseImportBusinessTemplate \
InstallBusinessTemplate \ InstallBusinessTemplate \
Tic \ Tic \
CheckCatalogConfigurationKept \ CheckCatalogConfigurationKept \
CheckRelatedKeyNonDuplicated \
DuplicateRelatedKeyColumn \
UninstallBusinessTemplate \ UninstallBusinessTemplate \
CheckOnlyDuplicateRelatedKeyRemains \
CheckCatalogConfigurationKept \ CheckCatalogConfigurationKept \
RemoveCatalogLocalConfiguration \ RemoveCatalogLocalConfiguration \
' '
......
...@@ -33,6 +33,7 @@ import urllib ...@@ -33,6 +33,7 @@ import urllib
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import FileUpload from Products.ERP5Type.tests.utils import FileUpload
from Products.ERP5Type.tests.backportUnittest import skip
SESSION_ID = "12345678" SESSION_ID = "12345678"
LANGUAGE_LIST = ('en', 'fr', 'de', 'bg',) LANGUAGE_LIST = ('en', 'fr', 'de', 'bg',)
...@@ -825,6 +826,7 @@ class TestCommerce(ERP5TypeTestCase): ...@@ -825,6 +826,7 @@ class TestCommerce(ERP5TypeTestCase):
shoppping_cart_item_list = self.website.SaleOrder_getShoppingCartItemList() shoppping_cart_item_list = self.website.SaleOrder_getShoppingCartItemList()
self.assertEquals(1, len(shoppping_cart_item_list)) self.assertEquals(1, len(shoppping_cart_item_list))
@skip('WebSite_createWebSiteAccount is disabled by default.')
def test_22_createShoppingCartWithAnonymousAndLogin(self): def test_22_createShoppingCartWithAnonymousAndLogin(self):
""" """
Test adding an arbitrary resources to shopping cart with Anonymous user Test adding an arbitrary resources to shopping cart with Anonymous user
......
...@@ -36,7 +36,7 @@ from Products.ERP5Type.TransactionalVariable import getTransactionalVariable ...@@ -36,7 +36,7 @@ from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import DummyLocalizer from Products.ERP5Type.tests.utils import DummyLocalizer
from Products.ERP5Type.tests.utils import createZODBPythonScript from Products.ERP5Type.tests.utils import createZODBPythonScript
from Products.ERP5Type.tests.backportUnittest import expectedFailure from Products.ERP5Type.tests.backportUnittest import expectedFailure, skip
LANGUAGE_LIST = ('en', 'fr', 'de', 'bg', ) LANGUAGE_LIST = ('en', 'fr', 'de', 'bg', )
HTTP_OK = 200 HTTP_OK = 200
...@@ -194,6 +194,7 @@ class TestERP5Web(ERP5TypeTestCase): ...@@ -194,6 +194,7 @@ class TestERP5Web(ERP5TypeTestCase):
self.assertEquals("""Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé self.assertEquals("""Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé Hé
Hé Hé Hé!""", page.asText().strip()) Hé Hé Hé!""", page.asText().strip())
@skip('WebSite_createWebSiteAccount is disabled by default.')
def test_03_CreateWebSiteUser(self): def test_03_CreateWebSiteUser(self):
""" """
Create Web site User. Create Web site User.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -61,7 +61,7 @@ class TestFormPrintoutAsODG(TestFormPrintoutMixin): ...@@ -61,7 +61,7 @@ class TestFormPrintoutAsODG(TestFormPrintoutMixin):
self.setSystemPreference() self.setSystemPreference()
# XML validator # XML validator
v12schema_url = os.path.join(os.path.dirname(__file__), v12schema_url = os.path.join(os.path.dirname(__file__),
'OpenDocument-schema-v1.2-draft9.rng') 'OpenDocument-v1.2-os-schema.rng')
self.validator = Validator(schema_url=v12schema_url) self.validator = Validator(schema_url=v12schema_url)
foo_file_path = os.path.join(os.path.dirname(__file__), foo_file_path = os.path.join(os.path.dirname(__file__),
......
...@@ -55,7 +55,7 @@ class TestFormPrintoutAsODT(TestFormPrintoutMixin): ...@@ -55,7 +55,7 @@ class TestFormPrintoutAsODT(TestFormPrintoutMixin):
self.setSystemPreference() self.setSystemPreference()
# XML validator # XML validator
v12schema_url = os.path.join(os.path.dirname(__file__), v12schema_url = os.path.join(os.path.dirname(__file__),
'OpenDocument-schema-v1.2-draft9.rng') 'OpenDocument-v1.2-os-schema.rng')
self.validator = Validator(schema_url=v12schema_url) self.validator = Validator(schema_url=v12schema_url)
foo_file_path = os.path.join(os.path.dirname(__file__), foo_file_path = os.path.join(os.path.dirname(__file__),
......
...@@ -54,7 +54,7 @@ class TestOooDynamicStyle(ERP5TypeTestCase): ...@@ -54,7 +54,7 @@ class TestOooDynamicStyle(ERP5TypeTestCase):
self.login() self.login()
self.getPortal().Localizer = DummyLocalizer() self.getPortal().Localizer = DummyLocalizer()
v12schema_url = os.path.join(os.path.dirname(__file__), v12schema_url = os.path.join(os.path.dirname(__file__),
'OpenDocument-schema-v1.2-draft9.rng') 'OpenDocument-v1.2-os-schema.rng')
self.validator = Validator(schema_url=v12schema_url) self.validator = Validator(schema_url=v12schema_url)
en_file_path = os.path.join(os.path.dirname(__file__), en_file_path = os.path.join(os.path.dirname(__file__),
'test_document', 'test_document',
......
import re, imp, sys, threading, os, shlex, subprocess, shutil, glob, random import re, imp, sys, os, shlex, shutil, glob, random
import traceback try:
from erp5.util.testsuite import TestSuite, SubprocessError
# The content of this file might be partially moved to an egg except ImportError:
# in order to allows parallel tests without the code of ERP5 # erp5.util.testsuite should be updated
print "Please update erp5.util to version >= 0.4.3"
_format_command_search = re.compile("[[\\s $({?*\\`#~';<>&|]").search
_format_command_escape = lambda s: "'%s'" % r"'\''".join(s.split("'")) import threading, subprocess
def format_command(*args, **kw): import traceback
import errno
from pprint import pprint
_format_command_search = re.compile("[[\\s $({?*\\`#~';<>&|]").search
_format_command_escape = lambda s: "'%s'" % r"'\''".join(s.split("'"))
def format_command(*args, **kw):
cmdline = [] cmdline = []
for k, v in sorted(kw.items()): for k, v in sorted(kw.items()):
if _format_command_search(v): if _format_command_search(v):
...@@ -18,7 +24,7 @@ def format_command(*args, **kw): ...@@ -18,7 +24,7 @@ def format_command(*args, **kw):
cmdline.append(v) cmdline.append(v)
return ' '.join(cmdline) return ' '.join(cmdline)
def subprocess_capture(p, quiet=False): def subprocess_capture(p, quiet=False):
def readerthread(input, output, buffer): def readerthread(input, output, buffer):
while True: while True:
data = input.readline() data = input.readline()
...@@ -47,7 +53,15 @@ def subprocess_capture(p, quiet=False): ...@@ -47,7 +53,15 @@ def subprocess_capture(p, quiet=False):
return (p.stdout and ''.join(stdout), return (p.stdout and ''.join(stdout),
p.stderr and ''.join(stderr)) p.stderr and ''.join(stderr))
class Persistent(object): 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 Persistent(object):
"""Very simple persistent data storage for optimization purpose """Very simple persistent data storage for optimization purpose
This tool should become a standalone daemon communicating only with an ERP5 This tool should become a standalone daemon communicating only with an ERP5
...@@ -82,7 +96,7 @@ class Persistent(object): ...@@ -82,7 +96,7 @@ class Persistent(object):
pprint.pprint(db, self._db) pprint.pprint(db, self._db)
self._db.truncate() self._db.truncate()
class TestSuite(object): class TestSuite(object):
""" """
Subclasses may redefine the following properties: Subclasses may redefine the following properties:
mysql_db_count (integer, >=1) mysql_db_count (integer, >=1)
...@@ -91,6 +105,21 @@ class TestSuite(object): ...@@ -91,6 +105,21 @@ class TestSuite(object):
extra_sql_connection_string_list environment variable. extra_sql_connection_string_list environment variable.
""" """
RUN_RE = re.compile(
r'Ran (?P<all_tests>\d+) tests? in (?P<seconds>\d+\.\d+)s',
re.DOTALL)
STATUS_RE = re.compile(r"""
(OK|FAILED)\s+\(
(failures=(?P<failures>\d+),?\s*)?
(errors=(?P<errors>\d+),?\s*)?
(skipped=(?P<skips>\d+),?\s*)?
(expected\s+failures=(?P<expected_failures>\d+),?\s*)?
(unexpected\s+successes=(?P<unexpected_successes>\d+),?\s*)?
\)
""", re.DOTALL | re.VERBOSE)
mysql_db_count = 1 mysql_db_count = 1
allow_restart = False allow_restart = False
realtime_output = True realtime_output = True
...@@ -177,21 +206,8 @@ class TestSuite(object): ...@@ -177,21 +206,8 @@ class TestSuite(object):
raise SubprocessError(result) raise SubprocessError(result)
return result return result
class ERP5TypeTestSuite(TestSuite):
RUN_RE = re.compile(
r'Ran (?P<all_tests>\d+) tests? in (?P<seconds>\d+\.\d+)s',
re.DOTALL)
STATUS_RE = re.compile(r""" class ERP5TypeTestSuite(TestSuite):
(OK|FAILED)\s+\(
(failures=(?P<failures>\d+),?\s*)?
(errors=(?P<errors>\d+),?\s*)?
(skipped=(?P<skips>\d+),?\s*)?
(expected\s+failures=(?P<expected_failures>\d+),?\s*)?
(unexpected\s+successes=(?P<unexpected_successes>\d+),?\s*)?
\)
""", re.DOTALL | re.VERBOSE)
FTEST_PASS_FAIL_RE = re.compile( FTEST_PASS_FAIL_RE = re.compile(
".*Functional Tests (?P<total>\d+) Tests, (?P<failures>\d+) " + \ ".*Functional Tests (?P<total>\d+) Tests, (?P<failures>\d+) " + \
...@@ -321,14 +337,6 @@ class SavedTestSuite(ERP5TypeTestSuite): ...@@ -321,14 +337,6 @@ class SavedTestSuite(ERP5TypeTestSuite):
super(SavedTestSuite, self).setup() super(SavedTestSuite, self).setup()
self.__runUnitTest('--save', self._saved_test_id) self.__runUnitTest('--save', self._saved_test_id)
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
sys.modules['test_suite'] = module = imp.new_module('test_suite') sys.modules['test_suite'] = module = imp.new_module('test_suite')
for var in SubprocessError, TestSuite, ERP5TypeTestSuite, ProjectTestSuite, \ for var in SubprocessError, TestSuite, ERP5TypeTestSuite, ProjectTestSuite, \
SavedTestSuite: SavedTestSuite:
......
#!/usr/bin/env python2.6 #!/usr/bin/env python2.6
import argparse, pprint, socket, sys, time, xmlrpclib import argparse, sys
from DummyTaskDistributionTool import DummyTaskDistributionTool from erp5.util import taskdistribution
from ERP5TypeTestSuite import ERP5TypeTestSuite
# XXX: below section is shared with erp5/util/testnode/testnode.py . # XXX: This import is required, just to populate sys.modules['test_suite'].
# They are supposed to be merged into a common library/tool someday, until # Even if it's not used in this file. Yuck.
# then please keep them synchronised. import ERP5TypeTestSuite
# Depending on used xmlrpc backend, different exceptions can be thrown.
SAFE_RPC_EXCEPTION_LIST = [socket.error, xmlrpclib.ProtocolError, xmlrpclib.Fault] def _parsingErrorHandler(data, _):
parser, _ = xmlrpclib.getparser() print >> sys.stderr, 'Error parsing data:', repr(data)
if xmlrpclib.ExpatParser and isinstance(parser, xmlrpclib.ExpatParser): taskdistribution.patchRPCParser(_parsingErrorHandler)
SAFE_RPC_EXCEPTION_LIST.append(xmlrpclib.expat.ExpatError)
else:
print >>sys.stderr, 'Warning: unhandled xmlrpclib parser %r, some ' \
'exceptions might get through safeRpcCall' % (parser, )
SAFE_RPC_EXCEPTION_LIST = tuple(SAFE_RPC_EXCEPTION_LIST)
parser_klass = parser.__class__
__original_feed = parser_klass.feed
def verbose_feed(self, data):
try:
return __original_feed(self, data)
except Exception:
print >>sys.stderr, 'Error parsing data:', repr(data)
raise
try:
parser_klass.feed = verbose_feed
except TypeError:
print >>sys.stderr, 'Warning: could not monkey-patch %r.feed to output ' \
'parsed data on error, debugging in case of error will be more ' \
'difficult' % (parser_klass, )
del parser, verbose_feed, parser_klass, _
def makeSuite(node_quantity=None, test_suite=None, revision=None, def makeSuite(node_quantity=None, test_suite=None, revision=None,
db_list=None, **kwargs): db_list=None, **kwargs):
...@@ -56,23 +35,6 @@ def makeSuite(node_quantity=None, test_suite=None, revision=None, ...@@ -56,23 +35,6 @@ def makeSuite(node_quantity=None, test_suite=None, revision=None,
**kwargs) **kwargs)
return suite return suite
def safeRpcCall(function, *args):
retry = 64
xmlrpc_arg_list = []
for argument in args:
if isinstance(argument, dict):
argument = dict([(x, isinstance(y,str) and xmlrpclib.Binary(y) or y) \
for (x,y) in argument.iteritems()])
xmlrpc_arg_list.append(argument)
while True:
try:
return function(*xmlrpc_arg_list)
except SAFE_RPC_EXCEPTION_LIST, e:
print >>sys.stderr, e
pprint.pprint(args, file(function._Method__name, 'w'))
time.sleep(retry)
retry += retry >> 1
def main(): def main():
parser = argparse.ArgumentParser(description='Run a test suite.') parser = argparse.ArgumentParser(description='Run a test suite.')
parser.add_argument('--test_suite', help='The test suite name') parser.add_argument('--test_suite', help='The test suite name')
...@@ -102,16 +64,7 @@ def main(): ...@@ -102,16 +64,7 @@ def main():
args = parser.parse_args() args = parser.parse_args()
if args.bt5_path is not None: if args.bt5_path is not None:
sys.path[0:0] = args.bt5_path.split(",") sys.path[0:0] = args.bt5_path.split(",")
if args.master_url is not None: master = taskdistribution.TaskDistributionTool(args.master_url)
master_url = args.master_url
if master_url[-1] != '/':
master_url += '/'
master = xmlrpclib.ServerProxy("%s%s" %
(master_url, 'portal_task_distribution'),
allow_none=1)
assert master.getProtocolRevision() == 1
else:
master = DummyTaskDistributionTool()
test_suite_title = args.test_suite_title or args.test_suite test_suite_title = args.test_suite_title or args.test_suite
revision = args.revision revision = args.revision
suite = makeSuite(test_suite=args.test_suite, suite = makeSuite(test_suite=args.test_suite,
...@@ -119,17 +72,15 @@ def main(): ...@@ -119,17 +72,15 @@ def main():
revision=revision, revision=revision,
db_list=args.db_list, db_list=args.db_list,
bt5_path=args.bt5_path) bt5_path=args.bt5_path)
test_result = safeRpcCall(master.createTestResult, test_result = master.createTestResult(revision, suite.getTestList(),
args.test_suite, revision, suite.getTestList(), args.test_node_title, suite.allow_restart, test_suite_title,
suite.allow_restart, test_suite_title, args.test_node_title,
args.project_title) args.project_title)
if test_result: if test_result is not None:
test_result_path, test_revision = test_result assert revision == test_result.revision, (revision, test_result.revision)
while suite.acquire(): while suite.acquire():
test = safeRpcCall(master.startUnitTest, test_result_path, test = test_result.start(suite.running.keys())
suite.running.keys()) if test is not None:
if test: suite.start(test.name, lambda status_dict, __test=test:
suite.start(test[1], lambda status_dict, __test_path=test[0]: __test.stop(**status_dict))
safeRpcCall(master.stopUnitTest, __test_path, status_dict))
elif not suite.running: elif not suite.running:
break break
...@@ -34,21 +34,21 @@ from Products.ERP5Type.tests.ERP5TypeFunctionalTestCase import \ ...@@ -34,21 +34,21 @@ from Products.ERP5Type.tests.ERP5TypeFunctionalTestCase import \
ERP5TypeFunctionalTestCase ERP5TypeFunctionalTestCase
BASE_REMOTE_SELENIUM_TEST_URL_LIST = [ BASE_REMOTE_SELENIUM_TEST_URL_LIST = [
"http://www.erp5.com/user-Howto.Create.Person-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Create.Persons/TestPage_viewSeleniumTest",
"http://www.erp5.com/user-Howto.Create.Organisations-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Create.Organisations/TestPage_viewSeleniumTest",
"http://www.erp5.com/user-Howto.Link.Persons.and.Organisations-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Link.Persons.and.Organisations/TestPage_viewSeleniumTest",
"http://www.erp5.com/user-Howto.Create.Campaigns-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Create.Campaigns/TestPage_viewSeleniumTest",
"http://www.erp5.com/user-Howto.Create.Outgoing.Events-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Create.Outgoing.Events/TestPage_viewSeleniumTest",
"http://www.erp5.com/user-Howto.Post.Outgoing.Events-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Post.Outgoing.Events/TestPage_viewSeleniumTest",
"http://www.erp5.com/user-Howto.Manage.Support.Request-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Manage.Support.Request/TestPage_viewSeleniumTest",
# Part 2 - PDM, Trade and simulation related tests # Part 2 - PDM, Trade and simulation related tests
"http://www.erp5.com/user-Howto.Create.and.Manage.Products-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Create.and.Manage.Products/TestPage_viewSeleniumTest",
# DO NOT CONTAINS TEST YET "http://www.erp5.com/user-Howto.Create.Trade.Conditions-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Create.Trade.Conditions/TestPage_viewSeleniumTest",
"http://www.erp5.com/user-Howto.Create.Sale.Orders-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Create.Sale.Orders/TestPage_viewSeleniumTest",
"http://www.erp5.com/user-Howto.Manage.Packing.Lists-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Manage.Packing.Lists/TestPage_viewSeleniumTest",
"http://www.erp5.com/user-Howto.Manage.Invoices-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Manage.Invoices/TestPage_viewSeleniumTest",
"http://www.erp5.com/user-Howto.Create.A.Payment-HTML5/TestPage_viewSeleniumTest", "http://www.erp5.com/user-Howto.Create.A.Payment/TestPage_viewSeleniumTest",
# Extra Tests, Additional Tests not yet related to any previous tutorial # Extra Tests, Additional Tests not yet related to any previous tutorial
"http://www.erp5.com/user-HowTo.Use.FullText.Search-TESTONLY/TestPage_viewSeleniumTest", "http://www.erp5.com/user-HowTo.Use.FullText.Search-TESTONLY/TestPage_viewSeleniumTest",
......
...@@ -300,7 +300,7 @@ def parseListeningAddress(host_port=None, default_host='127.0.0.1'): ...@@ -300,7 +300,7 @@ def parseListeningAddress(host_port=None, default_host='127.0.0.1'):
raise raise
""" """
if host_port: if host_port:
host_port = host_port.rsplit(':', 1) host_port = tuple(host_port.rsplit(':', 1))
if len(host_port) == 1: if len(host_port) == 1:
host_port = default_host, host_port[0] host_port = default_host, host_port[0]
try: try:
......
...@@ -2,7 +2,7 @@ from setuptools import setup, find_packages ...@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
import glob import glob
import os import os
version = '0.4.5' version = '0.4.7'
name = 'erp5.util' name = 'erp5.util'
long_description = open("README.erp5.util.txt").read() + "\n" long_description = open("README.erp5.util.txt").read() + "\n"
......
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