From 0c3f6870dd9e1fdced5ee57ca1519260048aba04 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Mon, 28 Sep 2020 13:22:19 +0300 Subject: [PATCH] added support for opening archives --- app/ui/app_menu_bar.ui | 4 +++ app/ui/main_app_window.py | 54 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 2 deletions(-) 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):