Commit 0cb750d8 authored by Jérome Perrin's avatar Jérome Perrin

- invalid_category_spreadsheet_handler now returns a boolean, telling if we...

- invalid_category_spreadsheet_handler now returns a boolean, telling if we should continue processing or not.
- Drop "simulation_mode" hack and use an invalid_category_spreadsheet_handler accumulating errors instead.
- Don't fail if some empty sheets are left in the spreadsheet


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@32183 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 939c9828
......@@ -60,9 +60,13 @@
`import_file` must be a spreadsheet in a format supported by openoffice\n
\n
`invalid_spreadsheet_error_handler` is the callback method that will be called if\n
the spreadsheet is invalid. The method must recieve as only parameter a string\n
explaining the error.\n
If no error_callback is given, the default action is to raise a ValueError.\n
the spreadsheet is invalid. The method must accept one parameter, an\n
explanation of the error.\n
The error handler can return a boolean, true meaning that the rest of the\n
spreadsheet have to be processed, false meaning that the processing should\n
stop.\n
If no error_callback is given, the default action is to raise a ValueError on\n
the first error encountered.\n
\n
The returned mapping has the following structure:\n
\n
......@@ -80,7 +84,6 @@ way that parent always precedes their children.\n
"""\n
from Products.ERP5Type.Message import translateString\n
from Products.ERP5OOo.OOoUtils import OOoParser\n
from Products.ERP5Type.Document import newTempBase\n
parser = OOoParser()\n
category_list_spreadsheet_mapping = dict()\n
error_list = []\n
......@@ -91,17 +94,16 @@ def default_invalid_spreadsheet_error_handler(error_message):\n
if invalid_spreadsheet_error_handler is None:\n
invalid_spreadsheet_error_handler = default_invalid_spreadsheet_error_handler\n
\n
try:\n
property_id_list = context.portal_classes.getPropertySheetPropertyIdList()\n
except AttributeError:\n
# Class tool is too old\n
property_id_list = []\n
# FIXME: we are actually only interested in properties defined on Category\n
# type information.\n
property_id_list = context.portal_classes.getPropertySheetPropertyIdList()\n
\n
\n
def getIDFromString(string=None):\n
"""\n
This function transform a string to a safe and beautiful ID.\n
It is used here to create a safe category ID from a string.\n
But the code is not really clever...\n
"""\n
if string is None:\n
return None\n
......@@ -156,8 +158,11 @@ spreadsheet_list = parser.getSpreadsheetsMapping(no_empty_lines=True)\n
\n
\n
for table_name in spreadsheet_list.keys():\n
sheet = spreadsheet_list[table_name]\n
if not sheet:\n
continue\n
# Get the header of the table\n
columns_header = spreadsheet_list[table_name][0]\n
columns_header = sheet[0]\n
# Get the mapping to help us know the property according a cell index\n
property_map = {}\n
column_index = 0\n
......@@ -204,8 +209,7 @@ for table_name in spreadsheet_list.keys():\n
# This path_element_list help us to reconstruct the absolute path\n
path_element_list = []\n
line_index = 2\n
for line in spreadsheet_list[table_name][1:]:\n
\n
for line in sheet[1:]:\n
# Exclude empty lines\n
if line.count(\'\') + line.count(None) == len(line):\n
continue\n
......@@ -218,7 +222,6 @@ for table_name in spreadsheet_list.keys():\n
property_id = property_map[cell_index]\n
line_data[property_id] = cell\n
cell_index += 1\n
\n
# Analyse every cell of the line\n
category_property_list = {}\n
cell_index = 0\n
......@@ -277,28 +280,23 @@ for table_name in spreadsheet_list.keys():\n
\n
# Detect invalid IDs\n
if path_element_id in property_id_list:\n
if simulation_mode:\n
error = newTempBase(context, \'item\')\n
error.edit(field_type = \'Invalid ID\', field_category = path_element_id, field_message = translateString("The ID ${id} in ${table} at line ${line} is invalid, it\'s a reserved property name",mapping=dict(id=path_element_id, table=table_name, line=line_index)))\n
error_list.append(error)\n
else:\n
return invalid_spreadsheet_error_handler(translateString("The ID ${id} in ${table} at line ${line} is invalid, it\'s a reserved property name",mapping=dict(id=path_element_id, table=table_name, line=line_index)))\n
\n
\n
cont = invalid_spreadsheet_error_handler(\n
translateString("The ID ${id} in ${table} at line ${line} is invalid, it\'s a reserved property name",\n
mapping=dict(id=path_element_id, table=table_name, line=line_index)))\n
if not cont:\n
return \n
\n
# Detect duplicate IDs\n
for element in path_element_list[::-1]:\n
if element[\'depth\'] != element_depth:\n
break\n
if element[\'value\'] == path_element_id:\n
if simulation_mode:\n
error = newTempBase(context, \'item\')\n
error.edit(field_type = \'Duplicate ID\', field_category = element[\'value\'], field_message = translateString("Duplicate ID ${id} found in ${table} at line ${line} ", mapping=dict(id=element[\'value\'], table=table_name, line=line_index)))\n
error_list.append(error)\n
else:\n
return invalid_spreadsheet_error_handler( \n
translateString("Duplicate id found in ${table} at line ${line} : ${id}",\n
cont = invalid_spreadsheet_error_handler(\n
translateString(\n
"Duplicate ID found in ${table} at line ${line} : ${id}",\n
mapping=dict(id=element[\'value\'], table=table_name, line=line_index)))\n
if not cont:\n
return\n
\n
\n
# Detect wrong hierarchy\n
......@@ -313,17 +311,13 @@ for table_name in spreadsheet_list.keys():\n
current_depth = element[\'depth\']\n
continue # we are on the direct parent (current level - 1)\n
else:\n
if simulation_mode:\n
error = newTempBase(context, \'item\')\n
error.edit(field_type = \'Wrong hierarchy\', field_category = path_element_id, field_message = translateString("Wrong hierarchy found for ID ${id} and ${depth} in ${table} at line ${line} " ,mapping=dict(id=path_element_id,depth=element_depth, table=table_name, line=line_index)))\n
error_list.append(error) \n
else: \n
return invalid_spreadsheet_error_handler(\n
cont = invalid_spreadsheet_error_handler(\n
translateString(\n
"Wrong hierarchy found for ID ${id} and depth ${depth} in ${table} at line ${line} ",\n
mapping=dict(id=path_element_id,\n
depth=element_depth, table=table_name, line=line_index)))\n
\n
if not cont:\n
return\n
\n
\n
# Save the path element\n
......@@ -352,7 +346,7 @@ else:\n
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>import_file, invalid_spreadsheet_error_handler=None, simulation_mode=False</string> </value>
<value> <string>import_file, invalid_spreadsheet_error_handler=None</string> </value>
</item>
<item>
<key> <string>errors</string> </key>
......@@ -372,7 +366,7 @@ else:\n
<dictionary>
<item>
<key> <string>co_argcount</string> </key>
<value> <int>3</int> </value>
<value> <int>2</int> </value>
</item>
<item>
<key> <string>co_varnames</string> </key>
......@@ -380,13 +374,10 @@ else:\n
<tuple>
<string>import_file</string>
<string>invalid_spreadsheet_error_handler</string>
<string>simulation_mode</string>
<string>Products.ERP5Type.Message</string>
<string>translateString</string>
<string>Products.ERP5OOo.OOoUtils</string>
<string>OOoParser</string>
<string>Products.ERP5Type.Document</string>
<string>newTempBase</string>
<string>parser</string>
<string>dict</string>
<string>category_list_spreadsheet_mapping</string>
......@@ -396,10 +387,10 @@ else:\n
<string>_getattr_</string>
<string>context</string>
<string>property_id_list</string>
<string>AttributeError</string>
<string>getIDFromString</string>
<string>content_type</string>
<string>hasattr</string>
<string>Products.ERP5Type.Document</string>
<string>newTempOOoDocument</string>
<string>tmp_ooo</string>
<string>_getiter_</string>
......@@ -411,6 +402,7 @@ else:\n
<string>spreadsheet_list</string>
<string>table_name</string>
<string>_getitem_</string>
<string>sheet</string>
<string>columns_header</string>
<string>property_map</string>
<string>column_index</string>
......@@ -445,7 +437,7 @@ else:\n
<string>element</string>
<string>path</string>
<string>clean_title</string>
<string>error</string>
<string>cont</string>
<string>current_depth</string>
</tuple>
</value>
......@@ -460,7 +452,6 @@ else:\n
<value>
<tuple>
<none/>
<int>0</int>
</tuple>
</value>
</item>
......
......@@ -62,15 +62,8 @@ detailed_report_append = detailed_report_result.append\n
base_category_id_list = []\n
category_path_dict = {}\n
simulation_new_category_id_list = []\n
try:\n
property_id_list = context.portal_classes.getPropertySheetPropertyIdList()\n
except AttributeError:\n
# Class tool is too old - use an empty list and warn used in detailed report\n
property_id_list = []\n
if \'warning\' in displayed_report:\n
report_line = newTempBase(context, \'item\')\n
report_line.edit(field_type = \'WARNING\', field_category = \'\', field_message = \'ERP5Type product needs to be upgraded so that portal_classes can supply getPropertySheetPropertyIdList\') \n
detailed_report_append(report_line)\n
\n
property_id_list = context.portal_classes.getPropertySheetPropertyIdList()\n
\n
def Object_hasRelation(obj):\n
# Check if there is some related objets.\n
......@@ -80,8 +73,6 @@ def Object_hasRelation(obj):\n
related_url = related.getRelativeUrl()\n
if related_url.startswith(obj.getRelativeUrl()):\n
continue\n
elif related_url.startswith(\'portal_simulation\'):\n
continue\n
elif related_url.startswith(\'portal_trash\'):\n
continue\n
else:\n
......@@ -104,19 +95,29 @@ expired_category_counter = 0\n
\n
filename = getattr(import_file, \'filename\', \'?\')\n
\n
def invalid_category_spreadsheet_handler(message):\n
# action taken when an invalid spreadsheet is provided.\n
# we *raise* a Redirect, because we don\'t want the transaction to succeed\n
# note, we could make a dialog parameter to allow import invalid spreadsheet:\n
raise \'Redirect\', \'%s/view?portal_status_message=%s\' % (\n
context.portal_categories.absolute_url(),\n
message)\n
# The list of error from simulation mode\n
error_list = []\n
if simulation_mode:\n
def invalid_category_spreadsheet_handler(message):\n
error = newTempBase(context, \'item\')\n
error.edit(field_type=\'Error\',\n
field_message=message)\n
error_list.append(error)\n
return True # means continue processing the rest of the document\n
else:\n
def invalid_category_spreadsheet_handler(error_type, path, message):\n
# action taken when an invalid spreadsheet is provided.\n
# we *raise* a Redirect, because we don\'t want the transaction to succeed\n
# note, we could make a dialog parameter to allow import invalid spreadsheet:\n
raise \'Redirect\', \'%s/view?portal_status_message=%s\' % (\n
context.portal_categories.absolute_url(),\n
message)\n
\n
category_list_spreadsheet_mapping = context.Base_getCategoriesSpreadSheetMapping(import_file,\n
invalid_spreadsheet_error_handler=invalid_category_spreadsheet_handler, simulation_mode=simulation_mode)\n
invalid_spreadsheet_error_handler=invalid_category_spreadsheet_handler)\n
\n
if category_list_spreadsheet_mapping.has_key(\'error_list\'):\n
context.REQUEST.other[\'category_import_report\'] = category_list_spreadsheet_mapping[\'error_list\']\n
if simulation_mode and error_list:\n
context.REQUEST.other[\'category_import_report\'] = error_list\n
return context.CategoryTool_viewImportReport()\n
\n
for base_category, category_list in \\\n
......@@ -147,7 +148,7 @@ for base_category, category_list in \\\n
simulation_new_category_id_list.append({\'category\':category_id,\'path\':parent_path})\n
if \'created\' in displayed_report:\n
report_line = newTempBase(context, \'item\')\n
report_line.edit(field_type = \'Creation\', field_category = category[\'path\'].split(category_id)[0]+category_id, field_message = translateString("Will be created new ${type}", mapping=dict(type=category_type))) \n
report_line.edit(field_type = \'Creation\', field_category = category[\'path\'].split(category_id)[0]+category_id, field_message = translateString("Will be created new ${type}", mapping=dict(type=category_type)))\n
detailed_report_append(report_line)\n
else:\n
base_path_obj.newContent( portal_type = category_type\n
......@@ -156,7 +157,7 @@ for base_category, category_list in \\\n
)\n
if \'created\' in displayed_report:\n
report_line = newTempBase(context, \'item\')\n
report_line.edit(field_type = \'Creation\', field_category = base_path_obj[category_id].getRelativeUrl(), field_message = translateString("Created new ${type}", mapping=dict(type=category_type))) \n
report_line.edit(field_type = \'Creation\', field_category = base_path_obj[category_id].getRelativeUrl(), field_message = translateString("Created new ${type}", mapping=dict(type=category_type)))\n
detailed_report_append(report_line)\n
else:\n
# The ID is invalid, we must break the loop\n
......@@ -164,7 +165,7 @@ for base_category, category_list in \\\n
is_valid_category = False\n
if \'warning\' in displayed_report:\n
report_line = newTempBase(context, \'item\')\n
report_line.edit(field_type = \'WARNING\', field_category = \'\', field_message = translateString("found invalid ID ${id} ", mapping=dict(id=category_id))) \n
report_line.edit(field_type = \'WARNING\', field_category = \'\', field_message = translateString("found invalid ID ${id} ", mapping=dict(id=category_id)))\n
detailed_report_append(report_line)\n
break\n
is_new_category = True\n
......@@ -251,23 +252,23 @@ for base_category_id in base_category_id_list:\n
# TODO: add a dialog parameter allowing to delete this path\n
if \'warning\' in displayed_report:\n
report_line = newTempBase(context, \'item\')\n
report_line.edit(field_type = \'Warning\', field_category = category.getRelativeUrl(), field_message = translateString("Category is used and can not be deleted or expired ", mapping=dict())) \n
report_line.edit(field_type = \'Warning\', field_category = category.getRelativeUrl(), field_message = translateString("Category is used and can not be deleted or expired ", mapping=dict()))\n
detailed_report_append(report_line)\n
else:\n
if existing_category_list == \'keep\' and \'kept\' in displayed_report:\n
report_line = newTempBase(context, \'item\')\n
report_line.edit(field_type = \'Keep\', field_category = category.getRelativeUrl(), field_message = translateString("Kept category", mapping=dict())) \n
report_line.edit(field_type = \'Keep\', field_category = category.getRelativeUrl(), field_message = translateString("Kept category", mapping=dict()))\n
detailed_report_append(report_line)\n
kept_category_counter += 1\n
else:\n
if existing_category_list == \'delete\' and \'deleted\' in displayed_report:\n
report_line = newTempBase(context, \'item\')\n
report_line.edit(field_type = \'Delete\', field_category = category.getRelativeUrl(), field_message = translateString("Deleted category", mapping=dict())) \n
report_line.edit(field_type = \'Delete\', field_category = category.getRelativeUrl(), field_message = translateString("Deleted category", mapping=dict()))\n
detailed_report_append(report_line)\n
deleted_category_counter += 1\n
if existing_category_list == \'expire\' and \'expired\' in displayed_report:\n
report_line = newTempBase(context, \'item\')\n
report_line.edit(field_type = \'Expire\', field_category = category.getRelativeUrl(), field_message = translateString("Expired category", mapping=dict())) \n
report_line.edit(field_type = \'Expire\', field_category = category.getRelativeUrl(), field_message = translateString("Expired category", mapping=dict()))\n
detailed_report_append(report_line)\n
expired_category_counter += 1\n
category_to_delete_list.append(category.getRelativeUrl())\n
......@@ -378,8 +379,6 @@ return context.REQUEST.RESPONSE.redirect(\n
<string>simulation_new_category_id_list</string>
<string>context</string>
<string>property_id_list</string>
<string>AttributeError</string>
<string>report_line</string>
<string>Object_hasRelation</string>
<string>isValidID</string>
<string>new_category_counter</string>
......@@ -391,9 +390,9 @@ return context.REQUEST.RESPONSE.redirect(\n
<string>expired_category_counter</string>
<string>getattr</string>
<string>filename</string>
<string>error_list</string>
<string>invalid_category_spreadsheet_handler</string>
<string>category_list_spreadsheet_mapping</string>
<string>_getitem_</string>
<string>_write_</string>
<string>_getiter_</string>
<string>base_category</string>
......@@ -405,6 +404,7 @@ return context.REQUEST.RESPONSE.redirect(\n
<string>is_new_category</string>
<string>key_list</string>
<string>base_path_obj</string>
<string>_getitem_</string>
<string>category_id_list</string>
<string>parent_path</string>
<string>True</string>
......@@ -413,6 +413,7 @@ return context.REQUEST.RESPONSE.redirect(\n
<string>category_id</string>
<string>str</string>
<string>category_type</string>
<string>report_line</string>
<string>dict</string>
<string>None</string>
<string>new_category</string>
......
1453
\ No newline at end of file
1455
\ No newline at end of file
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