mirror of
https://github.com/onionshare/onionshare.git
synced 2024-12-26 15:59:48 -05:00
added download progress bars to GUI, and made close automatically act as stop server automatically
This commit is contained in:
parent
5325b7b173
commit
fcdcfd7c39
@ -14,8 +14,7 @@
|
|||||||
"download_finished": "Download finished",
|
"download_finished": "Download finished",
|
||||||
"other_page_loaded": "Other page has been loaded",
|
"other_page_loaded": "Other page has been loaded",
|
||||||
"tails_requires_root": "You must run OnionShare as root in Tails",
|
"tails_requires_root": "You must run OnionShare as root in Tails",
|
||||||
"close_on_finish": "Close automatically",
|
"close_on_finish": "Stop server automatically",
|
||||||
"close_countdown": "Closing in {0} seconds...",
|
|
||||||
"choose_file": "Choose a file to share",
|
"choose_file": "Choose a file to share",
|
||||||
"closing_automatically": "Closing automatically because download finished",
|
"closing_automatically": "Closing automatically because download finished",
|
||||||
"error_tails_invalid_port": "Invalid value, port must be an integer",
|
"error_tails_invalid_port": "Invalid value, port must be an integer",
|
||||||
@ -52,7 +51,6 @@
|
|||||||
"other_page_loaded": "En annen side har blitt lastet",
|
"other_page_loaded": "En annen side har blitt lastet",
|
||||||
"tails_requires_root": "OnionShare kan må kjøres som administrator i Tails",
|
"tails_requires_root": "OnionShare kan må kjøres som administrator i Tails",
|
||||||
"close_on_finish": "Lukk automatisk",
|
"close_on_finish": "Lukk automatisk",
|
||||||
"close_countdown": "Lukker om {0} sekunder",
|
|
||||||
"choose_file": "Velg en fil å dele"
|
"choose_file": "Velg en fil å dele"
|
||||||
}, "es": {
|
}, "es": {
|
||||||
"calculating_sha1": "Calculando suma de verificación SHA1.",
|
"calculating_sha1": "Calculando suma de verificación SHA1.",
|
||||||
@ -70,7 +68,6 @@
|
|||||||
"other_page_loaded": "Otra página se ha cargado",
|
"other_page_loaded": "Otra página se ha cargado",
|
||||||
"tails_requires_root": "Debe ejecutar OnionShare como root en Tails",
|
"tails_requires_root": "Debe ejecutar OnionShare como root en Tails",
|
||||||
"close_on_finish": "Cerrar automáticamente.",
|
"close_on_finish": "Cerrar automáticamente.",
|
||||||
"close_countdown": "Cierre en {0} segundos...",
|
|
||||||
"choose_file": "Elija un archivo para compartir"
|
"choose_file": "Elija un archivo para compartir"
|
||||||
}, "fr": {
|
}, "fr": {
|
||||||
"calculating_sha1": "Calculer un hachage SHA-1.",
|
"calculating_sha1": "Calculer un hachage SHA-1.",
|
||||||
@ -97,7 +94,6 @@
|
|||||||
"other_page_loaded": "Un altra pagina é stata caricata",
|
"other_page_loaded": "Un altra pagina é stata caricata",
|
||||||
"tails_requires_root": "Con Tails devi avviare OnionShare come utente root",
|
"tails_requires_root": "Con Tails devi avviare OnionShare come utente root",
|
||||||
"close_on_finish": "Chiudi automaticamente",
|
"close_on_finish": "Chiudi automaticamente",
|
||||||
"close_countdown": "Chiusura in {0} secondi...",
|
|
||||||
"choose_file": "Scegli un file da condividere"
|
"choose_file": "Scegli un file da condividere"
|
||||||
}, "nl": {
|
}, "nl": {
|
||||||
"calculating_sha1": "SHA1 controlecijfer berekenen.",
|
"calculating_sha1": "SHA1 controlecijfer berekenen.",
|
||||||
@ -115,7 +111,6 @@
|
|||||||
"other_page_loaded": "Andere pagina is geladen",
|
"other_page_loaded": "Andere pagina is geladen",
|
||||||
"tails_requires_root": "Je moet OnionShare als root draaien in Tails",
|
"tails_requires_root": "Je moet OnionShare als root draaien in Tails",
|
||||||
"close_on_finish": "Sluit automatisch",
|
"close_on_finish": "Sluit automatisch",
|
||||||
"close_countdown": "Sluit in {0} seconden...",
|
|
||||||
"choose_file": "Kies betsand om te delen",
|
"choose_file": "Kies betsand om te delen",
|
||||||
"gui_copy_url": "Kopieer URL",
|
"gui_copy_url": "Kopieer URL",
|
||||||
"closing_automatically": "Sluit nu automatisch omdat download gereed is",
|
"closing_automatically": "Sluit nu automatisch omdat download gereed is",
|
||||||
@ -142,7 +137,6 @@
|
|||||||
"other_page_loaded": "Outra página tem sido carregada",
|
"other_page_loaded": "Outra página tem sido carregada",
|
||||||
"tails_requires_root": "Tem que rodar o OnionShare como root no Tails",
|
"tails_requires_root": "Tem que rodar o OnionShare como root no Tails",
|
||||||
"close_on_finish": "Fechar automaticamente",
|
"close_on_finish": "Fechar automaticamente",
|
||||||
"close_countdown": "Fechando em {0} segundos...",
|
|
||||||
"choose_file": "Escolhe um arquivo para compartilhar"
|
"choose_file": "Escolhe um arquivo para compartilhar"
|
||||||
}, "ru": {
|
}, "ru": {
|
||||||
"calculating_sha1": "Вычисляется SHA1 хешсумма.",
|
"calculating_sha1": "Вычисляется SHA1 хешсумма.",
|
||||||
@ -160,7 +154,6 @@
|
|||||||
"other_page_loaded": "Другая страница была загружена",
|
"other_page_loaded": "Другая страница была загружена",
|
||||||
"tails_requires_root": "Вы должны запустить OnionShare с правами root в Tails",
|
"tails_requires_root": "Вы должны запустить OnionShare с правами root в Tails",
|
||||||
"close_on_finish": "Закрыть автоматически",
|
"close_on_finish": "Закрыть автоматически",
|
||||||
"close_countdown": "Закроется через {0} секунд...",
|
|
||||||
"choose_file": "Выберите файл",
|
"choose_file": "Выберите файл",
|
||||||
"gui_copy_url": "Скопировать ссылку"
|
"gui_copy_url": "Скопировать ссылку"
|
||||||
}, "de": {
|
}, "de": {
|
||||||
@ -179,7 +172,6 @@
|
|||||||
"other_page_loaded": "Andere Seite wurde geladen",
|
"other_page_loaded": "Andere Seite wurde geladen",
|
||||||
"tails_requires_root": "Du musst Onionshare in Tails als root ausführen",
|
"tails_requires_root": "Du musst Onionshare in Tails als root ausführen",
|
||||||
"close_on_finish": "Beende automatisch",
|
"close_on_finish": "Beende automatisch",
|
||||||
"close_countdown": "Beende in {0} Sekunden...",
|
|
||||||
"choose_file": "Wähle eine Datei zum teilen aus"
|
"choose_file": "Wähle eine Datei zum teilen aus"
|
||||||
},"tr": {
|
},"tr": {
|
||||||
"punching_a_hole": "Güvenlik duvarında bir yol açılıyor.",
|
"punching_a_hole": "Güvenlik duvarında bir yol açılıyor.",
|
||||||
@ -199,7 +191,6 @@
|
|||||||
"other_page_loaded": "Diğer sayfa yüklendi",
|
"other_page_loaded": "Diğer sayfa yüklendi",
|
||||||
"tails_requires_root": "Tails'da OnionShare root olarak çalışır",
|
"tails_requires_root": "Tails'da OnionShare root olarak çalışır",
|
||||||
"close_on_finish": "Kendiliğinden kapan",
|
"close_on_finish": "Kendiliğinden kapan",
|
||||||
"close_countdown": "Kapanıyor {0} saniye...",
|
|
||||||
"choose_file": "Paylaşım için bir dosya seç",
|
"choose_file": "Paylaşım için bir dosya seç",
|
||||||
"gui_copy_url": "URL Kopyala"
|
"gui_copy_url": "URL Kopyala"
|
||||||
}}
|
}}
|
||||||
|
@ -62,6 +62,15 @@ def set_stay_open(new_stay_open):
|
|||||||
def get_stay_open():
|
def get_stay_open():
|
||||||
return 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():
|
def debug_mode():
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -135,6 +144,7 @@ def download(slug_candidate):
|
|||||||
|
|
||||||
# download is finished, close the server
|
# download is finished, close the server
|
||||||
if not stay_open:
|
if not stay_open:
|
||||||
|
if not gui_mode:
|
||||||
print strings._("closing_automatically")
|
print strings._("closing_automatically")
|
||||||
if shutdown_func is None:
|
if shutdown_func is None:
|
||||||
raise RuntimeError('Not running with the Werkzeug Server')
|
raise RuntimeError('Not running with the Werkzeug Server')
|
||||||
@ -143,6 +153,7 @@ def download(slug_candidate):
|
|||||||
r = Response(generate())
|
r = Response(generate())
|
||||||
r.headers.add('Content-Length', zip_filesize)
|
r.headers.add('Content-Length', zip_filesize)
|
||||||
r.headers.add('Content-Disposition', 'attachment', filename=basename)
|
r.headers.add('Content-Disposition', 'attachment', filename=basename)
|
||||||
|
|
||||||
# guess content type
|
# guess content type
|
||||||
(content_type, _) = mimetypes.guess_type(basename, strict=False)
|
(content_type, _) = mimetypes.guess_type(basename, strict=False)
|
||||||
if content_type is not None:
|
if content_type is not None:
|
||||||
@ -169,7 +180,8 @@ def shutdown(shutdown_slug_candidate):
|
|||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def start(port, stay_open=False):
|
def start(port, stay_open=False, gui_mode=False):
|
||||||
set_stay_open(stay_open)
|
set_stay_open(stay_open)
|
||||||
|
set_gui_mode(gui_mode)
|
||||||
app.run(port=port)
|
app.run(port=port)
|
||||||
|
|
||||||
|
@ -8,19 +8,43 @@ class Downloads(QtGui.QVBoxLayout):
|
|||||||
super(Downloads, self).__init__()
|
super(Downloads, self).__init__()
|
||||||
self.addSpacing(10)
|
self.addSpacing(10)
|
||||||
|
|
||||||
|
self.progress_bars = {}
|
||||||
|
|
||||||
# downloads label
|
# downloads label
|
||||||
self.downloads_label = QtGui.QLabel(strings._('gui_downloads'))
|
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()
|
self.downloads_label.hide()
|
||||||
|
|
||||||
# add the widgets
|
# add the widgets
|
||||||
self.addWidget(self.downloads_label)
|
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)))
|
||||||
|
|
||||||
|
@ -48,20 +48,25 @@ class OnionShareGui(QtGui.QWidget):
|
|||||||
self.file_selection.file_list.files_updated.connect(self.server_status.update)
|
self.file_selection.file_list.files_updated.connect(self.server_status.update)
|
||||||
|
|
||||||
# downloads
|
# downloads
|
||||||
downloads = Downloads()
|
self.downloads = Downloads()
|
||||||
|
|
||||||
# options
|
# options
|
||||||
options = Options(web.stay_open)
|
self.options = Options(web)
|
||||||
|
|
||||||
# main layout
|
# main layout
|
||||||
self.layout = QtGui.QVBoxLayout()
|
self.layout = QtGui.QVBoxLayout()
|
||||||
self.layout.addLayout(self.file_selection)
|
self.layout.addLayout(self.file_selection)
|
||||||
self.layout.addLayout(self.server_status)
|
self.layout.addLayout(self.server_status)
|
||||||
self.layout.addLayout(downloads)
|
self.layout.addLayout(self.downloads)
|
||||||
self.layout.addLayout(options)
|
self.layout.addLayout(self.options)
|
||||||
self.setLayout(self.layout)
|
self.setLayout(self.layout)
|
||||||
self.show()
|
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):
|
def start_server(self):
|
||||||
# start the hidden service
|
# start the hidden service
|
||||||
try:
|
try:
|
||||||
@ -76,7 +81,7 @@ class OnionShareGui(QtGui.QWidget):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# start onionshare service in new thread
|
# 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.daemon = True
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
@ -93,6 +98,40 @@ class OnionShareGui(QtGui.QWidget):
|
|||||||
|
|
||||||
self.server_status.stop_server_finished()
|
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):
|
def alert(msg, icon=QtGui.QMessageBox.NoIcon):
|
||||||
dialog = QtGui.QMessageBox()
|
dialog = QtGui.QMessageBox()
|
||||||
dialog.setWindowTitle("OnionShare")
|
dialog.setWindowTitle("OnionShare")
|
||||||
|
@ -4,18 +4,27 @@ import common
|
|||||||
from onionshare import strings, helpers
|
from onionshare import strings, helpers
|
||||||
|
|
||||||
class Options(QtGui.QHBoxLayout):
|
class Options(QtGui.QHBoxLayout):
|
||||||
def __init__(self, stay_open=False):
|
def __init__(self, web):
|
||||||
super(Options, self).__init__()
|
super(Options, self).__init__()
|
||||||
self.addSpacing(10)
|
self.addSpacing(10)
|
||||||
|
|
||||||
|
self.web = web
|
||||||
|
|
||||||
# close automatically
|
# close automatically
|
||||||
self.close_automatically = QtGui.QCheckBox()
|
self.close_automatically = QtGui.QCheckBox()
|
||||||
if stay_open:
|
if self.web.stay_open:
|
||||||
self.close_automatically.setCheckState(QtCore.Qt.Unchecked)
|
self.close_automatically.setCheckState(QtCore.Qt.Unchecked)
|
||||||
else:
|
else:
|
||||||
self.close_automatically.setCheckState(QtCore.Qt.Checked)
|
self.close_automatically.setCheckState(QtCore.Qt.Checked)
|
||||||
self.close_automatically.setText(strings._("close_on_finish"))
|
self.close_automatically.setText(strings._("close_on_finish"))
|
||||||
|
self.connect(self.close_automatically, QtCore.SIGNAL('stateChanged(int)'), self.stay_open_changed)
|
||||||
|
|
||||||
# add the widgets
|
# add the widgets
|
||||||
self.addWidget(self.close_automatically)
|
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)
|
||||||
|
|
||||||
|
@ -47,7 +47,6 @@ class ServerStatus(QtGui.QVBoxLayout):
|
|||||||
self.url_label.setFont(url_font)
|
self.url_label.setFont(url_font)
|
||||||
self.url_label.setWordWrap(True)
|
self.url_label.setWordWrap(True)
|
||||||
self.url_label.setAlignment(QtCore.Qt.AlignCenter)
|
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 = QtGui.QPushButton(strings._('gui_copy_url'))
|
||||||
self.copy_url_button.clicked.connect(self.copy_url)
|
self.copy_url_button.clicked.connect(self.copy_url)
|
||||||
url_layout = QtGui.QHBoxLayout()
|
url_layout = QtGui.QHBoxLayout()
|
||||||
@ -97,6 +96,7 @@ class ServerStatus(QtGui.QVBoxLayout):
|
|||||||
|
|
||||||
def start_server_finished(self):
|
def start_server_finished(self):
|
||||||
self.status = self.STATUS_STARTED
|
self.status = self.STATUS_STARTED
|
||||||
|
self.copy_url()
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def stop_server(self):
|
def stop_server(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user