<?xml version="1.0"?>
<ZopeData>
  <record id="1" aka="AAAAAAAAAAE=">
    <pickle>
      <tuple>
        <tuple>
          <string>Products.PythonScripts.PythonScript</string>
          <string>PythonScript</string>
        </tuple>
        <none/>
      </tuple>
    </pickle>
    <pickle>
      <dictionary>
        <item>
            <key> <string>Python_magic</string> </key>
            <value> <string encoding="base64">O/INCg==</string> </value>
        </item>
        <item>
            <key> <string>Script_magic</string> </key>
            <value> <int>3</int> </value>
        </item>
        <item>
            <key> <string>__ac_local_roles__</string> </key>
            <value>
              <none/>
            </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[

from Products.ERP5OOo.OOoUtils import OOoParser\n
from Products.ERP5Type.Utils import convertToUpperCase\n
OOoParser = OOoParser()\n
\n
\n
def getIdFromString(string=None):\n
  """\n
    This function transform a string to a safe id.\n
    It is used here to create a safe category id from a string.\n
  """\n
  clean_id = \'\'\n
  if string == None:\n
    return None\n
  translation_map = { "a": [\'\\xe0\']\n
                    , "e": [\'\\xe9\', \'\\xe8\']\n
                    }\n
  string = string.lower()\n
  string = string.strip()\n
  # oocalc inserts some strange chars when you press - key in a text cell.\n
  # Following line is a workaround for this, because \\u2013 does not exist in latin1\n
  string = string.replace(u\'\\u2013\', \'-\')\n
  for char in string.encode(\'iso8859_1\'):\n
    if char == \'_\' or char.isalnum():\n
      clean_id += char\n
    elif char.isspace() or char in (\'+\', \'-\'):\n
      clean_id += \'_\'\n
    else:\n
      for (safe_char, char_list) in translation_map.items():\n
        if char in char_list:\n
          clean_id += safe_char\n
          break\n
  return clean_id\n
\n
\n
# Extract tables from the speadsheet file\n
OOoParser.openFile(import_file)\n
filename = OOoParser.getFilename()\n
spreadsheets = OOoParser.getSpreadsheetsMapping()\n
\n
\n
for table_name in spreadsheets.keys():\n
\n
  # Get the header of the table\n
  columns_header = spreadsheets[table_name][0]\n
  # Get the mapping to help us to know the property according a cell index\n
  property_map = {}\n
  column_index = 0\n
  path_index = 0\n
  for column in columns_header:\n
    column_id = getIdFromString(column)\n
    # This give us the information that the path definition has started\n
    path_def_started = \'path_0\' in property_map.values()\n
    # The path of the category has started to be expressed\n
    if column_id == \'path\':\n
      property_map[column_index] = \'path_\' + str(path_index)\n
      path_index += 1\n
    # The column has no header information\n
    elif column_id in (None, \'\'):\n
      # Are we in the middle of the path definition ?\n
      # If the path definition has started and not ended\n
      if path_def_started and path_index != None:\n
        property_map[column_index] = \'path_\' + str(path_index)\n
        path_index += 1\n
      # else : The path definition is not started or is finished, so ignore the column\n
    # The column has a normal header\n
    else:\n
      # If there is a new column with a header and the path definition has started, that seems the path definition has ended\n
      if \'path_0\' in property_map.values():\n
        path_index == None\n
      property_map[column_index] = column_id\n
    column_index += 1\n
\n
  # Construct categories data (with absolut path) from table lines\n
  categories = []\n
  # The first category is the Base category\n
  # 1 table = 1 base category\n
  base_category_name = table_name\n
  base_category_id = getIdFromString(base_category_name)\n
  categories.append({ \'path\'  : base_category_id\n
                    , \'title\' : base_category_name\n
                    })\n
  # This path_elements help us to reconstruct the absolute path\n
  path_elements = []\n
  for line in spreadsheets[table_name][1:]:\n
    category_properties = {}\n
    # Exclude empty lines\n
    if line.count(\'\') + line.count(None) == len(line):\n
      continue\n
    # Analyse every cells of the line\n
    cell_index = 0\n
    for cell in line:\n
      # Ignore empty cells, do the test on the generated id because getIdFromString() is more restrictive\n
      cell_id = getIdFromString(cell)\n
      if cell_id not in (\'\', None):\n
        # Get the property corresponding to the cell data\n
        property_id = property_map[cell_index]\n
        # Handle normal properties\n
        if not property_id.startswith(\'path_\'):\n
          category_properties[property_id] = cell\n
        # Handle \'path\' property\n
        else:\n
          path_element_id = cell_id\n
          # Initialize the list of path elements to the cell element\n
          absolut_path_element_list = [path_element_id,]\n
          # Get the depth of the current element\n
          element_depth = int(property_id[5:])\n
          # Get a path element for each depth level to reach the 0-level\n
          for searched_depth in range(element_depth)[::-1]:\n
            # Get the first path element that correspond to the searched depth\n
            for element in path_elements[::-1]:\n
              if element[\'depth\'] == searched_depth:\n
                # Element found, add it to the list\n
                absolut_path_element_list.append(element[\'value\'])\n
                # Get the next depth\n
                break\n
          category_properties[\'path\'] = \'/\'.join([base_category_id,] + absolut_path_element_list[::-1])\n
          # If no title, get it from raw cell value\n
          if \'title\' not in category_properties.keys():\n
            clean_title = cell.strip()\n
            if clean_title != cell_id:\n
              category_properties[\'title\'] = clean_title\n
          # Save the path element\n
          path_elements.append({ \'depth\' : element_depth\n
                               , \'value\' : path_element_id\n
                               })\n
      cell_index += 1\n
    if len(category_properties) > 0 and \'path\' in category_properties.keys():\n
      categories.append(category_properties)\n
\n
\n
  # Create categories\n
  for category in categories:\n
    keys = category.keys()\n
    if \'path\' in keys:\n
      base_path_obj = context.portal_categories\n
      is_base_category = True\n
      for category_id in category[\'path\'].split(\'/\'):\n
        # The current category is not existing\n
        if category_id not in base_path_obj.contentIds():\n
          # Create the category\n
          if is_base_category:\n
            category_type = \'Base Category\'\n
          else:\n
            category_type = \'Category\'\n
          base_path_obj.newContent( portal_type       = category_type\n
                                  , id                = category_id\n
                                  , immediate_reindex = 1\n
                                  )\n
        base_path_obj = base_path_obj[category_id]\n
        is_base_category = False\n
      new_category = base_path_obj\n
\n
      # Set the category properties\n
      for key in keys:\n
        if key != \'path\':\n
          method_id = "set" + convertToUpperCase(key)\n
          value = category[key]\n
          if value not in (\'\', None):\n
            if hasattr(new_category, method_id):\n
              method = getattr(new_category, method_id)\n
              # Convert the value to something like \'\\xc3\\xa9\' not \'\\xc3\\xa9\'\n
              method(value.encode(\'UTF-8\'))\n
\n
\n
# Import is a success, go back to the portal_categories tool\n
return context.REQUEST.RESPONSE.redirect(context.portal_categories.absolute_url() + \'/view?portal_status_message=\' + filename + \'+successfully+imported\')\n


]]></string> </value>
        </item>
        <item>
            <key> <string>_code</string> </key>
            <value>
              <none/>
            </value>
        </item>
        <item>
            <key> <string>_filepath</string> </key>
            <value> <string>Script (Python):/nexedi/portal_skins/erp5_core/CategoryTool_importCategoryFile</string> </value>
        </item>
        <item>
            <key> <string>_params</string> </key>
            <value> <string>import_file, **kw</string> </value>
        </item>
        <item>
            <key> <string>errors</string> </key>
            <value>
              <tuple/>
            </value>
        </item>
        <item>
            <key> <string>func_code</string> </key>
            <value>
              <object>
                <klass>
                  <global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
                </klass>
                <tuple/>
                <state>
                  <dictionary>
                    <item>
                        <key> <string>co_argcount</string> </key>
                        <value> <int>1</int> </value>
                    </item>
                    <item>
                        <key> <string>co_varnames</string> </key>
                        <value>
                          <tuple>
                            <string>import_file</string>
                            <string>kw</string>
                            <string>Products.ERP5OOo.OOoUtils</string>
                            <string>OOoParser</string>
                            <string>Products.ERP5Type.Utils</string>
                            <string>convertToUpperCase</string>
                            <string>None</string>
                            <string>getIdFromString</string>
                            <string>_getattr_</string>
                            <string>filename</string>
                            <string>spreadsheets</string>
                            <string>_getiter_</string>
                            <string>table_name</string>
                            <string>_getitem_</string>
                            <string>columns_header</string>
                            <string>property_map</string>
                            <string>column_index</string>
                            <string>path_index</string>
                            <string>column</string>
                            <string>column_id</string>
                            <string>path_def_started</string>
                            <string>str</string>
                            <string>_write_</string>
                            <string>categories</string>
                            <string>base_category_name</string>
                            <string>base_category_id</string>
                            <string>path_elements</string>
                            <string>line</string>
                            <string>category_properties</string>
                            <string>len</string>
                            <string>cell_index</string>
                            <string>cell</string>
                            <string>cell_id</string>
                            <string>property_id</string>
                            <string>path_element_id</string>
                            <string>absolut_path_element_list</string>
                            <string>int</string>
                            <string>element_depth</string>
                            <string>range</string>
                            <string>searched_depth</string>
                            <string>element</string>
                            <string>clean_title</string>
                            <string>category</string>
                            <string>keys</string>
                            <string>context</string>
                            <string>base_path_obj</string>
                            <string>True</string>
                            <string>is_base_category</string>
                            <string>category_id</string>
                            <string>category_type</string>
                            <string>False</string>
                            <string>new_category</string>
                            <string>key</string>
                            <string>method_id</string>
                            <string>value</string>
                            <string>hasattr</string>
                            <string>getattr</string>
                            <string>method</string>
                          </tuple>
                        </value>
                    </item>
                  </dictionary>
                </state>
              </object>
            </value>
        </item>
        <item>
            <key> <string>func_defaults</string> </key>
            <value>
              <none/>
            </value>
        </item>
        <item>
            <key> <string>id</string> </key>
            <value> <string>CategoryTool_importCategoryFile</string> </value>
        </item>
        <item>
            <key> <string>warnings</string> </key>
            <value>
              <tuple/>
            </value>
        </item>
      </dictionary>
    </pickle>
  </record>
</ZopeData>
