Add -n/--not-strict to igorbinarywave.py (currently for IBW files with non-empty...
[hooke.git] / hooke / driver / jpk.py
index 6fe84f01d3860e7b0df45a8b0e212448168ce228..2fd91c8b8d5ed3e557dd95e9928fc55cb4d1c3e1 100644 (file)
@@ -35,6 +35,46 @@ from ..util.si import join_data_label, split_data_label
 from . import Driver as Driver
 
 
+def slash_join(*args):
+    r"""Join path components with forward slashes regardless of OS.
+
+    Notes
+    -----
+    From the `PKZIP Application Note`_, section J (Explanation of fields):
+
+      file name: (Variable)
+
+        ... All slashes should be forward slashes ``/`` as opposed to
+        backwards slashes ``\`` for compatibility with Amiga and UNIX
+        file systems etc. ...
+
+    .. _PKZIP Application Note:
+      http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+
+    Examples
+    --------
+
+    >>> sep = os.path.sep
+    >>> os.path.sep = '/'
+    >>> print slash_join('abc', 'def/ghi', 'jkl\\mno')
+    abc/def/ghi/jkl\mno
+    >>> os.path.sep = '\\'
+    >>> print slash_join('abc', 'def/ghi', 'jkl\\mno')
+    abc/def/ghi/jkl\mno
+    >>> os.path.sep = sep
+
+    Note that when :const:`os.path.sep` is ``/`` (e.g. UNIX),
+    ``def/ghi`` is a compound segment, but when :const:`os.path.sep`
+    is ``\`` (e.g. Windows), ``def/ghi`` is a single segment.
+    """
+    sep = os.path.sep
+    try:
+        os.path.sep = '/'
+        return os.path.join(*args)
+    finally:
+        os.path.sep = sep
+
+
 class JPKDriver (Driver):
     """Handle JPK ForceRobot's data format.
     """
@@ -113,10 +153,10 @@ class JPKDriver (Driver):
             return info
 
     def _zip_segment(self, zipfile, path, info, zip_info, index, version):
-        prop_file = zipfile.open(os.path.join(
-                'segments', str(index), 'segment-header.properties'))
-        prop = self._parse_params(prop_file.readlines())
-        prop_file.close()
+        with Closing(zipfile.open(slash_join(
+                    'segments', str(index), 'segment-header.properties'))
+                     ) as f:
+            prop = self._parse_params(f.readlines())
         expected_shape = (int(prop['force-segment-header']['num-points']),)
         channels = []
         if 'list' not in prop['channels']:
@@ -147,7 +187,7 @@ class JPKDriver (Driver):
     def _zip_channel(self, zipfile, segment_index, channel_name, chan_info):
         if chan_info['data']['type'] in ['constant-data', 'raster-data']:
             return self._zip_calculate_channel(chan_info)
-        with Closing(zipfile.open(os.path.join(
+        with Closing(zipfile.open(slash_join(
                     'segments', str(segment_index),
                     chan_info['data']['file']['name']), 'r')) as f:
             assert chan_info['data']['file']['format'] == 'raw', \