[Pkg-anonymity-tools] [onionshare] 42/140: added download progress bars to GUI, and made close automatically act as stop server automatically

Ulrike Uhlig u-guest at moszumanska.debian.org
Mon Sep 29 20:33:45 UTC 2014


This is an automated email from the git hooks/post-receive script.

u-guest pushed a commit to branch master
in repository onionshare.

commit fcdcfd7c39f642dfc2042031265a33da50cd2a7f
Author: Micah Lee <micah at micahflee.com>
Date:   Wed Aug 27 23:52:56 2014 -0700

    added download progress bars to GUI, and made close automatically act as stop server automatically
---
 onionshare/strings.json          | 11 +--------
 onionshare/web.py                | 22 ++++++++++++++----
 onionshare_gui/downloads.py      | 42 ++++++++++++++++++++++++++--------
 onionshare_gui/onionshare_gui.py | 49 ++++++++++++++++++++++++++++++++++++----
 onionshare_gui/options.py        | 13 +++++++++--
 onionshare_gui/server_status.py  |  2 +-
 6 files changed, 107 insertions(+), 32 deletions(-)

diff --git a/onionshare/strings.json b/onionshare/strings.json
index 8a72506..eb5be01 100644
--- a/onionshare/strings.json
+++ b/onionshare/strings.json
@@ -14,8 +14,7 @@
     "download_finished": "Download finished",
     "other_page_loaded": "Other page has been loaded",
     "tails_requires_root": "You must run OnionShare as root in Tails",
-    "close_on_finish": "Close automatically",
-    "close_countdown": "Closing in {0} seconds...",
+    "close_on_finish": "Stop server automatically",
     "choose_file": "Choose a file to share",
     "closing_automatically": "Closing automatically because download finished",
     "error_tails_invalid_port": "Invalid value, port must be an integer",
@@ -52,7 +51,6 @@
     "other_page_loaded": "En annen side har blitt lastet",
     "tails_requires_root": "OnionShare kan må kjøres som administrator i Tails",
     "close_on_finish": "Lukk automatisk",
-    "close_countdown": "Lukker om {0} sekunder",
     "choose_file": "Velg en fil å dele"
 }, "es": {
     "calculating_sha1": "Calculando suma de verificación SHA1.",
@@ -70,7 +68,6 @@
     "other_page_loaded": "Otra página se ha cargado",
     "tails_requires_root": "Debe ejecutar OnionShare como root en Tails",
     "close_on_finish": "Cerrar automáticamente.",
-    "close_countdown": "Cierre en {0} segundos...",
     "choose_file": "Elija un archivo para compartir"
  }, "fr": {
     "calculating_sha1": "Calculer un hachage SHA-1.",
@@ -97,7 +94,6 @@
     "other_page_loaded": "Un altra pagina é stata caricata",
     "tails_requires_root": "Con Tails devi avviare OnionShare come utente root",
     "close_on_finish": "Chiudi automaticamente",
-    "close_countdown": "Chiusura in {0} secondi...",
     "choose_file": "Scegli un file da condividere"
 }, "nl": {
     "calculating_sha1": "SHA1 controlecijfer berekenen.",
@@ -115,7 +111,6 @@
     "other_page_loaded": "Andere pagina is geladen",
     "tails_requires_root": "Je moet OnionShare als root draaien in Tails",
     "close_on_finish": "Sluit automatisch",
-    "close_countdown": "Sluit in {0} seconden...",
     "choose_file": "Kies betsand om te delen",
     "gui_copy_url": "Kopieer URL",
     "closing_automatically": "Sluit nu automatisch omdat download gereed is",
@@ -142,7 +137,6 @@
     "other_page_loaded": "Outra página tem sido carregada",
     "tails_requires_root": "Tem que rodar o OnionShare como root no Tails",
     "close_on_finish": "Fechar automaticamente",
-    "close_countdown": "Fechando em {0} segundos...",
     "choose_file": "Escolhe um arquivo para compartilhar"
 }, "ru": {
     "calculating_sha1": "Вычисляется SHA1 хешсумма.",
@@ -160,7 +154,6 @@
     "other_page_loaded": "Другая страница была загружена",
     "tails_requires_root": "Вы должны запустить OnionShare с правами root в Tails",
     "close_on_finish": "Закрыть автоматически",
-    "close_countdown": "Закроется через {0} секунд...",
     "choose_file": "Выберите файл",
     "gui_copy_url": "Скопировать ссылку"
 }, "de": {
@@ -179,7 +172,6 @@
     "other_page_loaded": "Andere Seite wurde geladen",
     "tails_requires_root": "Du musst Onionshare in Tails als root ausführen",
     "close_on_finish": "Beende automatisch",
-    "close_countdown": "Beende in {0} Sekunden...",
     "choose_file": "Wähle eine Datei zum teilen aus"
 },"tr": {
     "punching_a_hole": "Güvenlik duvarında bir yol açılıyor.",
@@ -199,7 +191,6 @@
     "other_page_loaded": "Diğer sayfa yüklendi",
     "tails_requires_root": "Tails'da OnionShare root olarak çalışır",
     "close_on_finish": "Kendiliğinden kapan",
-    "close_countdown": "Kapanıyor {0} saniye...",
     "choose_file": "Paylaşım için bir dosya seç",
     "gui_copy_url": "URL Kopyala"
 }}
diff --git a/onionshare/web.py b/onionshare/web.py
index 243c390..db5e7f5 100644
--- a/onionshare/web.py
+++ b/onionshare/web.py
@@ -62,6 +62,15 @@ def set_stay_open(new_stay_open):
 def get_stay_open():
     return stay_open
 
+gui_mode = False
+def set_gui_mode(new_gui_mode):
+    global gui_mode
+    gui_mode = new_gui_mode
+def get_gui_mode():
+    return gui_mode
+
+
+
 def debug_mode():
     import logging
 
@@ -135,14 +144,16 @@ def download(slug_candidate):
 
         # download is finished, close the server
         if not stay_open:
-            print strings._("closing_automatically")
-            if shutdown_func is None:
-                raise RuntimeError('Not running with the Werkzeug Server')
-            shutdown_func()
+            if not gui_mode:
+                print strings._("closing_automatically")
+                if shutdown_func is None:
+                    raise RuntimeError('Not running with the Werkzeug Server')
+                shutdown_func()
 
     r = Response(generate())
     r.headers.add('Content-Length', zip_filesize)
     r.headers.add('Content-Disposition', 'attachment', filename=basename)
+    
     # guess content type
     (content_type, _) = mimetypes.guess_type(basename, strict=False)
     if content_type is not None:
@@ -169,7 +180,8 @@ def shutdown(shutdown_slug_candidate):
 
     return ""
 
-def start(port, stay_open=False):
+def start(port, stay_open=False, gui_mode=False):
     set_stay_open(stay_open)
+    set_gui_mode(gui_mode)
     app.run(port=port)
 
diff --git a/onionshare_gui/downloads.py b/onionshare_gui/downloads.py
index de82a65..cae474f 100644
--- a/onionshare_gui/downloads.py
+++ b/onionshare_gui/downloads.py
@@ -8,19 +8,43 @@ class Downloads(QtGui.QVBoxLayout):
         super(Downloads, self).__init__()
         self.addSpacing(10)
 
+        self.progress_bars = {}
+
         # downloads label
         self.downloads_label = QtGui.QLabel(strings._('gui_downloads'))
-        """progress_bar = QtGui.QProgressBar()
-        progress_bar.setFormat("12.3 KiB, 17%")
-        progress_bar.setTextVisible(True)
-        progress_bar.setAlignment(QtCore.Qt.AlignHCenter)
-        progress_bar.setMinimum(0)
-        progress_bar.setMaximum(100)
-        progress_bar.setValue(17)"""
-        # hide downloads by default
         self.downloads_label.hide()
 
         # add the widgets
         self.addWidget(self.downloads_label)
-        #self.addWidget(progress_bar)
+
+    def add_download(self, download_id, total_bytes):
+        self.downloads_label.show()
+
+        # make a new progress bar
+        pb = QtGui.QProgressBar()
+        pb.setTextVisible(True)
+        pb.setAlignment(QtCore.Qt.AlignHCenter)
+        pb.setMinimum(0)
+        pb.setMaximum(total_bytes)
+        pb.setValue(0)
+        pb.setStyleSheet("QProgressBar::chunk { background-color: #05B8CC; }")
+        pb.total_bytes = total_bytes
+
+        # add it to the list
+        self.progress_bars[download_id] = pb
+        self.addWidget(pb)
+
+        # start at 0
+        self.update_download(download_id, total_bytes, 0)
+
+    def update_download(self, download_id, total_bytes, downloaded_bytes):
+        if download_id not in self.progress_bars:
+            self.add_download(download_id, total_bytes)
+
+        pb = self.progress_bars[download_id]
+        pb.setValue(downloaded_bytes)
+        if downloaded_bytes == pb.total_bytes:
+            pb.setFormat("%p%")
+        else:
+            pb.setFormat("{0}, %p%".format(helpers.human_readable_filesize(downloaded_bytes)))
 
diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py
index d60d95e..e498576 100644
--- a/onionshare_gui/onionshare_gui.py
+++ b/onionshare_gui/onionshare_gui.py
@@ -48,20 +48,25 @@ class OnionShareGui(QtGui.QWidget):
         self.file_selection.file_list.files_updated.connect(self.server_status.update)
 
         # downloads
-        downloads = Downloads()
+        self.downloads = Downloads()
 
         # options
-        options = Options(web.stay_open)
+        self.options = Options(web)
 
         # main layout
         self.layout = QtGui.QVBoxLayout()
         self.layout.addLayout(self.file_selection)
         self.layout.addLayout(self.server_status)
-        self.layout.addLayout(downloads)
-        self.layout.addLayout(options)
+        self.layout.addLayout(self.downloads)
+        self.layout.addLayout(self.options)
         self.setLayout(self.layout)
         self.show()
 
+        # check for requests frequently
+        self.timer = QtCore.QTimer()
+        QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.check_for_requests)
+        self.timer.start(500)
+
     def start_server(self):
         # start the hidden service
         try:
@@ -76,7 +81,7 @@ class OnionShareGui(QtGui.QWidget):
             return
 
         # start onionshare service in new thread
-        t = threading.Thread(target=web.start, args=(self.app.port, self.app.stay_open))
+        t = threading.Thread(target=web.start, args=(self.app.port, self.app.stay_open, True))
         t.daemon = True
         t.start()
 
@@ -93,6 +98,40 @@ class OnionShareGui(QtGui.QWidget):
 
         self.server_status.stop_server_finished()
 
+    def check_for_requests(self):
+        self.update()
+        # only check for requests if the server is running
+        if self.server_status.status != self.server_status.STATUS_STARTED:
+            return
+
+        events = []
+
+        done = False
+        while not done:
+            try:
+                r = web.q.get(False)
+                events.append(r)
+            except web.Queue.Empty:
+                done = True
+
+        for event in events:
+            #if event["path"] != '/favicon.ico':
+            #    pass
+            #if event["type"] == web.REQUEST_LOAD:
+            #    pass
+
+            if event["type"] == web.REQUEST_DOWNLOAD:
+                self.downloads.add_download(event["data"]["id"], web.zip_filesize)
+
+            elif event["type"] == web.REQUEST_PROGRESS:
+                self.downloads.update_download(event["data"]["id"], web.zip_filesize, event["data"]["bytes"])
+
+                # is the download complete?
+                if event["data"]["bytes"] == web.zip_filesize:
+                    # close on finish?
+                    if not web.get_stay_open():
+                        self.server_status.stop_server()
+
 def alert(msg, icon=QtGui.QMessageBox.NoIcon):
     dialog = QtGui.QMessageBox()
     dialog.setWindowTitle("OnionShare")
diff --git a/onionshare_gui/options.py b/onionshare_gui/options.py
index 16e8a85..e0e3038 100644
--- a/onionshare_gui/options.py
+++ b/onionshare_gui/options.py
@@ -4,18 +4,27 @@ import common
 from onionshare import strings, helpers
 
 class Options(QtGui.QHBoxLayout):
-    def __init__(self, stay_open=False):
+    def __init__(self, web):
         super(Options, self).__init__()
         self.addSpacing(10)
+
+        self.web = web
         
         # close automatically
         self.close_automatically = QtGui.QCheckBox()
-        if stay_open:
+        if self.web.stay_open:
             self.close_automatically.setCheckState(QtCore.Qt.Unchecked)
         else:
             self.close_automatically.setCheckState(QtCore.Qt.Checked)
         self.close_automatically.setText(strings._("close_on_finish"))
+        self.connect(self.close_automatically, QtCore.SIGNAL('stateChanged(int)'), self.stay_open_changed)
 
         # add the widgets
         self.addWidget(self.close_automatically)
 
+    def stay_open_changed(self, state):
+        if state > 0:
+            self.web.set_stay_open(False)
+        else:
+            self.web.set_stay_open(True)
+
diff --git a/onionshare_gui/server_status.py b/onionshare_gui/server_status.py
index df372d6..b42caf8 100644
--- a/onionshare_gui/server_status.py
+++ b/onionshare_gui/server_status.py
@@ -47,7 +47,6 @@ class ServerStatus(QtGui.QVBoxLayout):
         self.url_label.setFont(url_font)
         self.url_label.setWordWrap(True)
         self.url_label.setAlignment(QtCore.Qt.AlignCenter)
-        self.url_label.setMargin(3)
         self.copy_url_button = QtGui.QPushButton(strings._('gui_copy_url'))
         self.copy_url_button.clicked.connect(self.copy_url)
         url_layout = QtGui.QHBoxLayout()
@@ -97,6 +96,7 @@ class ServerStatus(QtGui.QVBoxLayout):
 
     def start_server_finished(self):
         self.status = self.STATUS_STARTED
+        self.copy_url()
         self.update()
 
     def stop_server(self):

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/collab-maint/onionshare.git



More information about the Pkg-anonymity-tools mailing list