diff --git a/app/ui/app_menu_bar.ui b/app/ui/app_menu_bar.ui
index 44c4b42e..975ba663 100644
--- a/app/ui/app_menu_bar.ui
+++ b/app/ui/app_menu_bar.ui
@@ -47,6 +47,10 @@
Open
app.on_data_open
+ -
+ Extract...
+ app.on_archive_open
+
-
Save
app.on_data_save
diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py
index 32de2063..1578fa38 100644
--- a/app/ui/main_app_window.py
+++ b/app/ui/main_app_window.py
@@ -386,6 +386,7 @@ class Application(Gtk.Application):
set_action("on_download_data", self.on_download_data)
set_action("upload_all", lambda a, v: self.on_upload_data(DownloadType.ALL))
set_action("upload_bouquets", lambda a, v: self.on_upload_data(DownloadType.BOUQUETS))
+ set_action("on_archive_open", self.on_archive_open)
# Edit
set_action("on_edit", self.on_edit)
# Save
@@ -1236,14 +1237,63 @@ class Application(Gtk.Application):
self.show_error_dialog(str(e))
def on_data_open(self, action=None, value=None):
- response = show_dialog(DialogType.CHOOSER, self._main_window, settings=self._settings)
+ """ Opening data via "File/Open". """
+ response = show_dialog(DialogType.CHOOSER, self._main_window, settings=self._settings, title="Open folder")
+ if response in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT):
+ return
+ self.open_data(response)
+
+ def on_archive_open(self, action=None, value=None):
+ """ Opening the data archive via "File/Open archive". """
+ file_filter = Gtk.FileFilter()
+ file_filter.set_name("*.zip, *.gz")
+ file_filter.add_mime_type("application/zip")
+ file_filter.add_mime_type("application/gzip")
+
+ response = show_dialog(DialogType.CHOOSER, self._main_window,
+ action_type=Gtk.FileChooserAction.OPEN,
+ file_filter=file_filter,
+ settings=self._settings,
+ title="Open archive")
if response in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT):
return
self.open_data(response)
def open_data(self, data_path=None, callback=None):
""" Opening data and fill views. """
- gen = self.update_data(data_path, callback)
+ if data_path and os.path.isfile(data_path):
+ self.open_compressed_data(data_path)
+ else:
+ gen = self.update_data(data_path, callback)
+ GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
+
+ def open_compressed_data(self, data_path):
+ """ Opening archived data. """
+ import zipfile
+ import tarfile
+ import tempfile
+
+ tmp_path = tempfile.TemporaryDirectory()
+ tmp_path_name = str(tmp_path.name)
+
+ if zipfile.is_zipfile(data_path):
+ with zipfile.ZipFile(data_path) as zip_file:
+ for zip_info in zip_file.infolist():
+ if not zip_info.is_dir():
+ zip_info.filename = os.path.basename(zip_info.filename)
+ zip_file.extract(zip_info, path=tmp_path_name)
+ elif tarfile.is_tarfile(data_path):
+ with tarfile.open(data_path) as tar:
+ for mb in tar.getmembers():
+ if mb.isfile():
+ mb.name = os.path.basename(mb.name)
+ tar.extract(mb, path=tmp_path_name)
+ else:
+ self.show_error_dialog("Unsupported format!")
+ tmp_path.cleanup()
+ return
+
+ gen = self.update_data("{}{}".format(tmp_path_name, os.sep), callback=tmp_path.cleanup)
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
def update_data(self, data_path, callback=None):