partageweb2 : pré-calcul de la taille de l'archive tar transmise.
[progfou.git] / partageweb2 / partage-compta.py
index a3d3c89..b020006 100755 (executable)
@@ -40,7 +40,7 @@ def valid_path(path):
     return True
 
 def human_size(size):
-    if size <= 1: return "0 octet"
+    if size <= 1: return "%s octet" % size
     if size < 1024: return "%s octets" % size
     size /= 1024
     if size < 1024: return "%s Kio" % size
@@ -52,8 +52,8 @@ def human_size(size):
     return "%s Tio" % size
 
 def my_cmp(name1, name2):
-    m1 = re.match('[0-9]+', name1)
-    m2 = re.match('[0-9]+', name2)
+    m1 = re.match('[0-9]{1,8}', name1)
+    m2 = re.match('[0-9]{1,8}', name2)
     if not m1 or not m2:
         return cmp(name1, name2)
     n1 = int(m1.group())
@@ -83,6 +83,13 @@ def my_listdir(path):
     files.sort(cmp=my_cmp)
     return dirs, files
 
+def find_files(path):
+    files_list = []
+    for root, dirs, files in os.walk(path):
+        for a_file in files:
+            files_list.append(os.path.join(root, a_file))
+    return files_list
+
 
 id_number = 0
 
@@ -104,7 +111,7 @@ def dir_content(prefix, root, level=0):
             try:
                 name = name.decode('utf-8')
             except UnicodeDecodeError:
-                name = INVALID_NAME % name.decode('latin-1')
+                name = INVALID_NAME % name.decode('iso-8859-1')
             desc_file = '.' + path + '/' + dir_description_filename
             if os.path.isfile(desc_file):
                 desc = file(desc_file).read().strip().replace('\n',' ')
@@ -127,7 +134,7 @@ def dir_content(prefix, root, level=0):
             try:
                 name = name.decode('utf-8')
             except UnicodeDecodeError:
-                name = INVALID_NAME % name.decode('latin-1')
+                name = INVALID_NAME % name.decode('iso-8859-1')
             content.append( file_link_template % (space,
                 urllib.quote(prefix + path), name, human_size(file_size)) )
     return content, file_size_total
@@ -141,19 +148,29 @@ class FileBuffer():
         self._data.append(data)
     def read(self):
         return ''.join(self._data)
+    def length(self):
+        return sum([len(x) for x in self._data])
 
-def tar_generator(path, mode='w|', bufsize=65536):
+def tar_size(files, mode='w|', bufsize=65536):
+    size = 0
     buffer = FileBuffer()
-    #yield 'open()\n'
     tar = tarfile.open(mode=mode, fileobj=buffer, bufsize=bufsize)
-    for root, dirs, files in os.walk(path):
-        for name in files:
-            tar.add(os.path.join(root, name), recursive=False)
-            #yield '+ file: %s\n' % os.path.join(root, name)
-            yield buffer.read()
-            buffer.reset()
+    for a_file in files:
+        tar.add(a_file, recursive=False)
+        size += buffer.length()
+        buffer.reset()
+    tar.close()
+    size += buffer.length()
+    return size
+
+def tar_generator(files, mode='w|', bufsize=65536):
+    buffer = FileBuffer()
+    tar = tarfile.open(mode=mode, fileobj=buffer, bufsize=bufsize)
+    for a_file in files:
+        tar.add(a_file, recursive=False)
+        yield buffer.read()
+        buffer.reset()
     tar.close()
-    #yield 'close()\n'
     yield buffer.read()
 
 def application(environ, start_response):
@@ -181,10 +198,11 @@ def application(environ, start_response):
         start_response('200 OK', headers)
         return file('.' + path)
     if path.endswith('.tar') and os.path.isdir('.' + path[:-4]):
-        #headers = [('Content-Type', 'text/plain; charset=utf-8'), ]
-        headers = [('Content-Type', 'application/octet-stream'), ]
+        files = find_files('.' + path[:-4])
+        headers = [('Content-Type', 'application/octet-stream'),
+                   ('Content-Length', str(tar_size(files)) ), ]
         start_response('200 OK', headers)
-        return tar_generator('.' + path[:-4])
+        return tar_generator(files)
     content, size = dir_content(environ['SCRIPT_NAME'], environ['PATH_INFO'])
     environ.update({
         'page_title': PAGE_TITLE % human_size(size),