From c570d7ea77f5c766cccfe9d79e7e4c74658be35a Mon Sep 17 00:00:00 2001 From: Srinivas Devaki Date: Wed, 24 Aug 2016 01:43:21 +0530 Subject: [PATCH 1/2] added progress bar for zipping files --- onionshare/helpers.py | 11 +++++- onionshare/web.py | 4 +- onionshare_gui/onionshare_gui.py | 66 +++++++++++++++++++++++++++++++- resources/locale/cs.json | 3 +- resources/locale/en.json | 3 +- resources/locale/eo.json | 3 +- resources/locale/fi.json | 3 +- resources/locale/it.json | 5 ++- resources/locale/nl.json | 3 +- resources/locale/tr.json | 3 +- 10 files changed, 91 insertions(+), 13 deletions(-) diff --git a/onionshare/helpers.py b/onionshare/helpers.py index 814d0207..3ec785f2 100644 --- a/onionshare/helpers.py +++ b/onionshare/helpers.py @@ -176,19 +176,26 @@ class ZipWriter(object): with. If a zip_filename is not passed in, it will use the default onionshare filename. """ - def __init__(self, zip_filename=None): + def __init__(self, zip_filename=None, processed_size_callback=None): if zip_filename: self.zip_filename = zip_filename else: self.zip_filename = '{0:s}/onionshare_{1:s}.zip'.format(tempfile.mkdtemp(), random_string(4, 6)) self.z = zipfile.ZipFile(self.zip_filename, 'w', allowZip64=True) + self.processed_size_callback = processed_size_callback + if self.processed_size_callback is None: + self.processed_size_callback = lambda _: None + self._size = 0 + self.processed_size_callback(self._size) def add_file(self, filename): """ Add a file to the zip archive. """ self.z.write(filename, os.path.basename(filename), zipfile.ZIP_DEFLATED) + self._size += os.path.getsize(filename) + self.processed_size_callback(self._size) def add_dir(self, filename): """ @@ -201,6 +208,8 @@ class ZipWriter(object): if not os.path.islink(full_filename): arc_filename = full_filename[len(dir_to_strip):] self.z.write(full_filename, arc_filename, zipfile.ZIP_DEFLATED) + self._size += os.path.getsize(full_filename) + self.processed_size_callback(self._size) def close(self): """ diff --git a/onionshare/web.py b/onionshare/web.py index 958e8c3a..304c6148 100644 --- a/onionshare/web.py +++ b/onionshare/web.py @@ -31,7 +31,7 @@ zip_filename = None zip_filesize = None -def set_file_info(filenames): +def set_file_info(filenames, processed_size_callback=None): """ Using the list of filenames being shared, fill in details that the web page will need to display. This includes zipping up the file in order to @@ -58,7 +58,7 @@ def set_file_info(filenames): file_info['dirs'] = sorted(file_info['dirs'], key=lambda k: k['basename']) # zip up the files and folders - z = helpers.ZipWriter() + z = helpers.ZipWriter(processed_size_callback=processed_size_callback) for info in file_info['files']: z.add_file(info['filename']) for info in file_info['dirs']: diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 1eb508bc..d8ada3cf 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -110,6 +110,9 @@ class OnionShareGui(QtWidgets.QMainWindow): self.status_bar.addPermanentWidget(version_label) self.setStatusBar(self.status_bar) + # status bar, zip progress bar + self._zip_progress_bar = None + # main layout self.layout = QtWidgets.QVBoxLayout() self.layout.addLayout(self.file_selection) @@ -132,6 +135,9 @@ class OnionShareGui(QtWidgets.QMainWindow): Step 2 in starting the onionshare server. This displays the large filesize warning, if applicable. """ + if self._zip_progress_bar is not None: + self.status_bar.removeWidget(self._zip_progress_bar) + self._zip_progress_bar = None # warn about sending large files over Tor if web.zip_filesize >= 157286400: # 150mb self.filesize_warning.setText(strings._("large_filesize", True)) @@ -162,10 +168,22 @@ class OnionShareGui(QtWidgets.QMainWindow): t.daemon = True t.start() + self._zip_progress_bar = ZipProgressBar(0) + self.status_bar.clearMessage() + self.status_bar.insertWidget(0, self._zip_progress_bar) + # prepare the files for sending in a new thread def finish_starting_server(self): # prepare files to share - web.set_file_info(self.file_selection.file_list.filenames) + progress_bar = self._zip_progress_bar + progress_bar.total_files_size = OnionShareGui._compute_total_size( + self.file_selection.file_list.filenames) + + def _set_processed_size(x): + progress_bar.processed_size = x + + web.set_file_info(self.file_selection.file_list.filenames, processed_size_callback=_set_processed_size) + self.app.cleanup_filenames.append(web.zip_filename) self.starting_server_step2.emit() @@ -177,11 +195,20 @@ class OnionShareGui(QtWidgets.QMainWindow): # done self.start_server_finished.emit() - self.status_bar.showMessage(strings._('gui_starting_server2', True)) t = threading.Thread(target=finish_starting_server, kwargs={'self': self}) t.daemon = True t.start() + @staticmethod + def _compute_total_size(filenames): + total_size = 0 + for filename in filenames: + if os.path.isfile(filename): + total_size += os.path.getsize(filename) + if os.path.isdir(filename): + total_size += helpers.dir_size(filename) + return total_size + def stop_server(self): """ Stop the onionshare server. @@ -268,6 +295,41 @@ class OnionShareGui(QtWidgets.QMainWindow): e.ignore() +class ZipProgressBar(QtWidgets.QProgressBar): + def __init__(self, total_files_size): + super(ZipProgressBar, self).__init__() + self.setMaximumHeight(15) + self.setValue(0) + self.setFormat(strings._('zip_progress_bar_format')) + self.setStyleSheet( + "QProgressBar::chunk { background-color: #05B8CC; }") + + self._total_files_size = total_files_size + self._processed_size = 0 + + @property + def total_files_size(self): + return self._total_files_size + + @total_files_size.setter + def total_files_size(self, val): + self._total_files_size = val + + @property + def processed_size(self): + return self._processed_size + + @processed_size.setter + def processed_size(self, val): + self._processed_size = val + if self.processed_size < self.total_files_size: + self.setValue(int((self.processed_size * 100) / self.total_files_size)) + elif self.total_files_size != 0: + self.setValue(100) + else: + self.setValue(0) + + def alert(msg, icon=QtWidgets.QMessageBox.NoIcon): """ Pop up a message in a dialog window. diff --git a/resources/locale/cs.json b/resources/locale/cs.json index 8ac426e4..70b2a66f 100644 --- a/resources/locale/cs.json +++ b/resources/locale/cs.json @@ -41,5 +41,6 @@ "gui_please_wait": "Prosím čekejte...", "error_hs_dir_cannot_create": "Nejde vytvořit složka {0:s} pro hidden service", "error_hs_dir_not_writable": "Nejde zapisovat do složky {0:s} pro hidden service", - "using_ephemeral": "Staring ephemeral Tor hidden service and awaiting publication" + "using_ephemeral": "Staring ephemeral Tor hidden service and awaiting publication", + "zip_progress_bar_format": "Crunching files: %p%" } diff --git a/resources/locale/en.json b/resources/locale/en.json index 88a0cbb3..e6552878 100644 --- a/resources/locale/en.json +++ b/resources/locale/en.json @@ -49,5 +49,6 @@ "gui_quit_warning": "Are you sure you want to quit?\nThe URL you are sharing won't exist anymore.", "gui_quit_warning_quit": "Quit", "gui_quit_warning_dont_quit": "Don't Quit", - "error_rate_limit": "An attacker might be trying to guess your URL. To prevent this, OnionShare has automatically stopped the server. To share the files you must start it again and share the new URL." + "error_rate_limit": "An attacker might be trying to guess your URL. To prevent this, OnionShare has automatically stopped the server. To share the files you must start it again and share the new URL.", + "zip_progress_bar_format": "Crunching files: %p%" } diff --git a/resources/locale/eo.json b/resources/locale/eo.json index 5970ab95..2fd1a14f 100644 --- a/resources/locale/eo.json +++ b/resources/locale/eo.json @@ -41,5 +41,6 @@ "gui_please_wait": "Bonvolu atendi...", "error_hs_dir_cannot_create": "Ne eblas krei hidden-service-dosierujon {0:s}", "error_hs_dir_not_writable": "Ne eblas konservi dosierojn en hidden-service-dosierujo {0:s}", - "using_ephemeral": "Staring ephemeral Tor hidden service and awaiting publication" + "using_ephemeral": "Staring ephemeral Tor hidden service and awaiting publication", + "zip_progress_bar_format": "Crunching files: %p%" } diff --git a/resources/locale/fi.json b/resources/locale/fi.json index cad0ddf7..7e1fb1df 100644 --- a/resources/locale/fi.json +++ b/resources/locale/fi.json @@ -41,5 +41,6 @@ "gui_please_wait": "Odota...", "error_hs_dir_cannot_create": "Piilopalvelulle ei pystytty luomaan hakemistoa {0:s}", "error_hs_dir_not_writable": "Piilopalvelun hakemistoon {0:s} ei voi kirjoittaa", - "using_ephemeral": "Käynnistetään lyhytaikainen Tor piilopalvelu ja odotetaan julkaisua" + "using_ephemeral": "Käynnistetään lyhytaikainen Tor piilopalvelu ja odotetaan julkaisua", + "zip_progress_bar_format": "Tiivistän tiedostoja: %p%" } diff --git a/resources/locale/it.json b/resources/locale/it.json index 00388980..973a0576 100644 --- a/resources/locale/it.json +++ b/resources/locale/it.json @@ -41,5 +41,6 @@ "gui_please_wait": "Attendere prego...", "error_hs_dir_cannot_create": "Impossibile create la cartella per il servizio nascosto {0:s}", "error_hs_dir_not_writable": "La cartella per il servizio nascosto {0:s} non ha i permessi di scrittura", - "using_ephemeral": "Avviamento del servizio nascosto Tor ephemeral e attesa della pubblicazione" -} \ No newline at end of file + "using_ephemeral": "Avviamento del servizio nascosto Tor ephemeral e attesa della pubblicazione", + "zip_progress_bar_format": "Elaborazione files: %p%" +} diff --git a/resources/locale/nl.json b/resources/locale/nl.json index 5da91706..da7370cf 100644 --- a/resources/locale/nl.json +++ b/resources/locale/nl.json @@ -41,5 +41,6 @@ "gui_please_wait": "Moment geduld...", "error_hs_dir_cannot_create": "Kan verborgen service map {0:s} niet aanmaken", "error_hs_dir_not_writable": "Verborgen service map {0:s} is niet schrijfbaar", - "using_ephemeral": "Kortstondige Tor hidden service gestart en in afwachting van publicatie" + "using_ephemeral": "Kortstondige Tor hidden service gestart en in afwachting van publicatie", + "zip_progress_bar_format": "Bestanden verwerken: %p%" } diff --git a/resources/locale/tr.json b/resources/locale/tr.json index 242f5038..0a953269 100644 --- a/resources/locale/tr.json +++ b/resources/locale/tr.json @@ -41,5 +41,6 @@ "gui_please_wait": "Lütfen bekleyin...", "error_hs_dir_cannot_create": "Gizli hizmet klasörü {0:s} oluşturulamıyor", "error_hs_dir_not_writable": "Gizle hizmet klasörü {0:s} yazılabilir değil", - "using_ephemeral": "Geçici Tor gizli hizmetine bakılıyor ve yayımı bekleniyor" + "using_ephemeral": "Geçici Tor gizli hizmetine bakılıyor ve yayımı bekleniyor", + "zip_progress_bar_format": "Dosyalar hazırlanıyor: %p%" } From 3b11f4d38249823c56f3a4874c5e886ca2de3619 Mon Sep 17 00:00:00 2001 From: Srinivas Devaki Date: Wed, 24 Aug 2016 02:15:58 +0530 Subject: [PATCH 2/2] small refactoring --- onionshare_gui/onionshare_gui.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index d8ada3cf..149f7e87 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -168,20 +168,19 @@ class OnionShareGui(QtWidgets.QMainWindow): t.daemon = True t.start() + # add progress bar to the status bar, indicating the crunching of files. self._zip_progress_bar = ZipProgressBar(0) + self._zip_progress_bar.total_files_size = OnionShareGui._compute_total_size( + self.file_selection.file_list.filenames) self.status_bar.clearMessage() self.status_bar.insertWidget(0, self._zip_progress_bar) # prepare the files for sending in a new thread def finish_starting_server(self): - # prepare files to share - progress_bar = self._zip_progress_bar - progress_bar.total_files_size = OnionShareGui._compute_total_size( - self.file_selection.file_list.filenames) - def _set_processed_size(x): - progress_bar.processed_size = x + self._zip_progress_bar.processed_size = x + # prepare files to share web.set_file_info(self.file_selection.file_list.filenames, processed_size_callback=_set_processed_size) self.app.cleanup_filenames.append(web.zip_filename)