diff --git a/plugins/Sidebar/SidebarPlugin.py b/plugins/Sidebar/SidebarPlugin.py
index 4bf716f2..962edba0 100644
--- a/plugins/Sidebar/SidebarPlugin.py
+++ b/plugins/Sidebar/SidebarPlugin.py
@@ -17,6 +17,7 @@ from Plugin import PluginManager
from Debug import Debug
from Translate import Translate
from util import helper
+from ZipStream import ZipStream
plugin_dir = "plugins/Sidebar"
media_dir = plugin_dir + "/media"
@@ -62,6 +63,28 @@ class UiRequestPlugin(object):
for part in super(UiRequestPlugin, self).actionUiMedia(path):
yield part
+ def actionZip(self):
+ address = self.get["address"]
+ site = self.server.site_manager.get(address)
+ if not site:
+ return self.error404("Site not found")
+
+ title = site.content_manager.contents.get("content.json", {}).get("title", "").encode('ascii', 'ignore')
+ filename = "%s-backup-%s.zip" % (title, time.strftime("%Y-%m-%d_%H_%M"))
+ self.sendHeader(content_type="application/zip", extra_headers={'Content-Disposition': 'attachment; filename="%s"' % filename})
+
+ return self.streamZip(site.storage.getPath("."))
+
+ def streamZip(self, file_path):
+ zs = ZipStream(file_path)
+ while 1:
+ data = zs.read()
+ if not data:
+ break
+ yield data
+
+
+
@PluginManager.registerTo("UiWebsocket")
class UiWebsocketPlugin(object):
@@ -137,7 +160,15 @@ class UiWebsocketPlugin(object):
"""))
def sidebarRenderFileStats(self, body, site):
- body.append(_(u"
"))
+ body.append(_(u"""
+ -
+
+
+ """))
extensions = (
("html", "yellow"),
diff --git a/plugins/Sidebar/ZipStream.py b/plugins/Sidebar/ZipStream.py
new file mode 100644
index 00000000..a78eac2b
--- /dev/null
+++ b/plugins/Sidebar/ZipStream.py
@@ -0,0 +1,43 @@
+import cStringIO as StringIO
+import os
+import zipfile
+
+
+class ZipStream(file):
+ def __init__(self, dir_path):
+ self.dir_path = dir_path
+ self.pos = 0
+ self.zf = zipfile.ZipFile(self, 'w', zipfile.ZIP_DEFLATED)
+ self.buff = StringIO.StringIO()
+ self.file_list = self.getFileList()
+
+ def getFileList(self):
+ for root, dirs, files in os.walk(self.dir_path):
+ for file in files:
+ file_path = root + "/" + file
+ relative_path = os.path.join(os.path.relpath(root, self.dir_path), file)
+ yield file_path, relative_path
+ self.zf.close()
+
+ def read(self, size=60 * 1024):
+ for file_path, relative_path in self.file_list:
+ self.zf.write(file_path, relative_path)
+ if self.buff.tell() >= size:
+ break
+ self.buff.seek(0)
+ back = self.buff.read()
+ self.buff.truncate(0)
+ return back
+
+ def write(self, data):
+ self.pos += len(data)
+ self.buff.write(data)
+
+ def tell(self):
+ return self.pos
+
+ def seek(self, pos, type):
+ pass
+
+ def flush(self):
+ pass
diff --git a/src/Config.py b/src/Config.py
index 0de9c3bf..0c00c84d 100644
--- a/src/Config.py
+++ b/src/Config.py
@@ -10,7 +10,7 @@ class Config(object):
def __init__(self, argv):
self.version = "0.6.2"
- self.rev = 3465
+ self.rev = 3467
self.argv = argv
self.action = None
self.config_file = "zeronet.conf"