Document ftp: improve exception handling, size may return 404
[odoo/odoo.git] / addons / document_ftp / ftpserver / abstracted_fs.py
index 7667b7e..ddd34e2 100644 (file)
@@ -34,29 +34,8 @@ def _get_month_name(month):
     elif month==11:return 'Nov'
     elif month==12:return 'Dec'
 
-def _to_unicode(s):
-    try:
-        return s.decode('utf-8')
-    except UnicodeError:
-        try:
-            return s.decode('latin')
-        except UnicodeError:
-            try:
-                return s.encode('ascii')
-            except UnicodeError:
-                return s
-
-def _to_decode(s):
-    try:
-        return s.encode('utf-8')
-    except UnicodeError:
-        try:
-            return s.encode('latin')
-        except UnicodeError:
-            try:
-                return s.decode('ascii')
-            except UnicodeError:
-                return s  
+from ftpserver import _to_decode, _to_unicode
+
 
 class abstracted_fs(object):
     """A class used to interact with the file system, providing a high
@@ -171,6 +150,7 @@ class abstracted_fs(object):
                     raise OSError(1, 'Operation not permited.')
 
                 ret = child.open_data(cr, mode)
+                cr.commit()
                 return ret
         except EnvironmentError:
             raise
@@ -180,7 +160,11 @@ class abstracted_fs(object):
 
         try:
             child = node.create_child(cr, objname, data=None)
-            return child.open_data(cr, mode)
+            ret = child.open_data(cr, mode)
+            cr.commit()
+            return ret
+        except EnvironmentError:
+            raise
         except Exception,e:
             self._log.exception('Cannot create item %s at node %s', objname, repr(node))
             raise OSError(1, 'Operation not permited.')
@@ -190,7 +174,11 @@ class abstracted_fs(object):
             raise OSError(1, 'Operation not permited.')
         # Reading operation
         cr, node, rem = datacr
-        res = node.open_data(cr, mode)
+        try:
+            res = node.open_data(cr, mode)
+            cr.commit()
+        except TypeError, e:
+            raise IOError(errno.EINVAL, "No data")
         return res
 
     # ok, but need test more
@@ -278,7 +266,7 @@ class abstracted_fs(object):
         if path == '/' and mode in ('list', 'cwd'):
             return (None, None, None )
 
-        path = os.path.normpath(path) # again, for '/db/../ss'
+        path = _to_unicode(os.path.normpath(path)) # again, for '/db/../ss'
         if path == '.': path = ''
 
         if os.path.isabs(path) and self.cwd_node is not None \
@@ -416,7 +404,7 @@ class abstracted_fs(object):
             assert (ret is True) or (ret is False)
             cr.commit()
         except Exception,err:
-            self._log.exception('Cannot rename "%s" to "%s" at "%s"', src, dst_basename, dst_basedir)
+            self._log.exception('Cannot rename "%s" to "%s" at "%s"', src, datacr[2], datacr[1])
             raise OSError(1,'Operation not permited.')
 
     def stat(self, node):
@@ -446,9 +434,9 @@ class abstracted_fs(object):
     def getsize(self, datacr):
         """Return the size of the specified file in bytes."""
         if not (datacr and datacr[1]):
-            return 0L
+            raise IOError(errno.ENOENT, "No such file or directory")
         if datacr[1].type in ('file', 'content'):
-            return datacr[1].content_length or 0L
+            return datacr[1].get_data_len(datacr[0]) or 0L
         return 0L
 
     # Ok
@@ -560,8 +548,8 @@ class abstracted_fs(object):
             perms = filemode(node.unixperms)  # permissions
             nlinks = 1
             size = node.content_length or 0L
-            uname = node.uuser
-            gname = node.ugroup
+            uname = _to_decode(node.uuser)
+            gname = _to_decode(node.ugroup)
             # stat.st_mtime could fail (-1) if last mtime is too old
             # in which case we return the local time as last mtime
             try:
@@ -658,9 +646,9 @@ class abstracted_fs(object):
             if 'unix.mode' in facts:
                 mode = 'unix.mode=%s;' %oct(node.unixperms & 0777)
             if 'unix.uid' in facts:
-                uid = 'unix.uid=%s;' % node.uuser
+                uid = 'unix.uid=%s;' % _to_decode(node.uuser)
             if 'unix.gid' in facts:
-                gid = 'unix.gid=%s;' % node.ugroup
+                gid = 'unix.gid=%s;' % _to_decode(node.ugroup)
             # We provide unique fact (see RFC-3659, chapter 7.5.2) on
             # posix platforms only; we get it by mixing st_dev and
             # st_ino values which should be enough for granting an