class OnionShareGui(QtGui.QWidget): start_server_finished = QtCore.pyqtSignal() stop_server_finished = QtCore.pyqtSignal() starting_server_step2 = QtCore.pyqtSignal() def __init__(self, qtapp, app): super(OnionShareGui, self).__init__() self.qtapp = qtapp self.app = app self.setWindowTitle('OnionShare') self.setWindowIcon(window_icon) def send_files(self, filenames=None): # file selection self.file_selection = FileSelection() if filenames: for filename in filenames: self.file_selection.file_list.add_file(filename) # server status self.server_status = ServerStatus(self.qtapp, self.app, web, self.file_selection) self.server_status.server_started.connect( self.file_selection.server_started) self.server_status.server_started.connect(self.start_server) self.server_status.server_stopped.connect( self.file_selection.server_stopped) self.server_status.server_stopped.connect(self.stop_server) self.start_server_finished.connect(self.clear_message) self.start_server_finished.connect( self.server_status.start_server_finished) self.stop_server_finished.connect( self.server_status.stop_server_finished) self.file_selection.file_list.files_updated.connect( self.server_status.update) self.server_status.url_copied.connect(self.copy_url) self.starting_server_step2.connect(self.start_server_step2) # filesize warning self.filesize_warning = QtGui.QLabel() self.filesize_warning.setStyleSheet( 'padding: 10px 0; font-weight: bold; color: #333333;') self.filesize_warning.hide() # downloads self.downloads = Downloads() # options self.options = Options(web) # status bar self.status_bar = QtGui.QStatusBar() self.status_bar.setSizeGripEnabled(False) # main layout self.layout = QtGui.QVBoxLayout() self.layout.addLayout(self.file_selection) self.layout.addLayout(self.server_status) self.layout.addWidget(self.filesize_warning) self.layout.addLayout(self.downloads) self.layout.addLayout(self.options) self.layout.addWidget(self.status_bar) 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_step2(self): self.status_bar.showMessage(strings._('gui_starting_server3', True)) # warn about sending large files over Tor if web.zip_filesize >= 157286400: # 150mb self.filesize_warning.setText(strings._("large_filesize", True)) self.filesize_warning.show() def start_server(self): # start the hidden service self.status_bar.showMessage(strings._('gui_starting_server1', True)) try: self.app.choose_port() print strings._("connecting_ctrlport").format(self.app.port) self.app.start_hidden_service(gui=True) except onionshare.NoTor as e: alert(e.args[0], QtGui.QMessageBox.Warning) self.server_status.stop_server() self.status_bar.clearMessage() return except onionshare.TailsError as e: alert(e.args[0], QtGui.QMessageBox.Warning) self.server_status.stop_server() self.status_bar.clearMessage() return # start onionshare service in new thread t = threading.Thread(target=web.start, args=(self.app.port, self.app.stay_open)) t.daemon = True t.start() # 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) self.app.cleanup_filenames.append(web.zip_filename) self.starting_server_step2.emit() # wait for hs self.app.wait_for_hs() # 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() def stop_server(self): if self.server_status.status == self.server_status.STATUS_STARTED: web.stop(self.app.port) self.app.cleanup() self.filesize_warning.hide() self.stop_server_finished.emit() 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["type"] == web.REQUEST_LOAD: self.status_bar.showMessage( strings._('download_page_loaded', True)) elif 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() elif event["type"] == web.REQUEST_CANCELED: self.downloads.cancel_download(event["data"]["id"]) elif event["path"] != '/favicon.ico': self.status_bar.showMessage('{0}: {1}'.format( strings._('other_page_loaded', True), event["path"])) def copy_url(self): self.status_bar.showMessage(strings._('gui_copied_url', True), 2000) def clear_message(self): self.status_bar.clearMessage()
class OnionShareGui(QtGui.QWidget): """ OnionShareGui is the main window for the GUI that contains all of the GUI elements. """ start_server_finished = QtCore.pyqtSignal() stop_server_finished = QtCore.pyqtSignal() starting_server_step2 = QtCore.pyqtSignal() def __init__(self, qtapp, app): super(OnionShareGui, self).__init__() self.qtapp = qtapp self.app = app self.setWindowTitle('OnionShare') self.setWindowIcon(window_icon) def send_files(self, filenames=None): """ Build the GUI in send files mode. Note that this is the only mode currently implemented. """ # file selection self.file_selection = FileSelection() if filenames: for filename in filenames: self.file_selection.file_list.add_file(filename) # server status self.server_status = ServerStatus(self.qtapp, self.app, web, self.file_selection) self.server_status.server_started.connect(self.file_selection.server_started) self.server_status.server_started.connect(self.start_server) self.server_status.server_stopped.connect(self.file_selection.server_stopped) self.server_status.server_stopped.connect(self.stop_server) self.start_server_finished.connect(self.clear_message) self.start_server_finished.connect(self.server_status.start_server_finished) self.stop_server_finished.connect(self.server_status.stop_server_finished) self.file_selection.file_list.files_updated.connect(self.server_status.update) self.server_status.url_copied.connect(self.copy_url) self.starting_server_step2.connect(self.start_server_step2) # filesize warning self.filesize_warning = QtGui.QLabel() self.filesize_warning.setStyleSheet('padding: 10px 0; font-weight: bold; color: #333333;') self.filesize_warning.hide() # downloads self.downloads = Downloads() # options self.options = Options(web, self.app) # status bar self.status_bar = QtGui.QStatusBar() self.status_bar.setSizeGripEnabled(False) # main layout self.layout = QtGui.QVBoxLayout() self.layout.addLayout(self.file_selection) self.layout.addLayout(self.server_status) self.layout.addWidget(self.filesize_warning) self.layout.addLayout(self.downloads) self.layout.addLayout(self.options) self.layout.addWidget(self.status_bar) 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_step2(self): """ Step 2 in starting the onionshare server. This displays the large filesize warning, if applicable. """ # warn about sending large files over Tor if web.zip_filesize >= 157286400: # 150mb self.filesize_warning.setText(strings._("large_filesize", True)) self.filesize_warning.show() def start_server(self): """ Start the onionshare server. This uses multiple threads to start the Tor hidden server and the web app. """ # start the hidden service self.status_bar.showMessage(strings._('gui_starting_server1', True)) self.app.choose_port() try: self.status_bar.showMessage(strings._('gui_starting_server1', True)) self.app.start_hidden_service(gui=True) except onionshare.hs.NoTor as e: alert(e.args[0], QtGui.QMessageBox.Warning) self.server_status.stop_server() self.status_bar.clearMessage() return # start onionshare service in new thread t = threading.Thread(target=web.start, args=(self.app.port, self.app.stay_open, self.app.transparent_torification)) t.daemon = True t.start() # 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) self.app.cleanup_filenames.append(web.zip_filename) self.starting_server_step2.emit() # wait for hs if not self.app.hs.supports_ephemeral: if not self.app.local_only: self.status_bar.showMessage(strings._('gui_starting_server3', True)) self.app.hs.wait_for_hs(self.app.onion_host) # 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() def stop_server(self): """ Stop the onionshare server. """ if self.server_status.status == self.server_status.STATUS_STARTED: web.stop(self.app.port) self.app.cleanup() self.filesize_warning.hide() self.stop_server_finished.emit() def check_for_requests(self): """ Check for messages communicated from the web app, and update the GUI accordingly. """ 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["type"] == web.REQUEST_LOAD: self.status_bar.showMessage(strings._('download_page_loaded', True)) elif 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() elif event["type"] == web.REQUEST_CANCELED: self.downloads.cancel_download(event["data"]["id"]) elif event["path"] != '/favicon.ico': self.status_bar.showMessage('{0:s}: {1:s}'.format(strings._('other_page_loaded', True), event["path"])) def copy_url(self): """ When the URL gets copied to the clipboard, display this in the status bar. """ self.status_bar.showMessage(strings._('gui_copied_url', True), 2000) def clear_message(self): """ Clear messages from the status bar. """ self.status_bar.clearMessage()
class OnionShareGui(QtGui.QWidget): """ OnionShareGui is the main window for the GUI that contains all of the GUI elements. """ start_server_finished = QtCore.pyqtSignal() stop_server_finished = QtCore.pyqtSignal() starting_server_step2 = QtCore.pyqtSignal() def __init__(self, qtapp, app): super(OnionShareGui, self).__init__() self.qtapp = qtapp self.app = app self.setWindowTitle('OnionShare') self.setWindowIcon(window_icon) def send_files(self, filenames=None): """ Build the GUI in send files mode. Note that this is the only mode currently implemented. """ # file selection self.file_selection = FileSelection() if filenames: for filename in filenames: self.file_selection.file_list.add_file(filename) # server status self.server_status = ServerStatus(self.qtapp, self.app, web, self.file_selection) self.server_status.server_started.connect( self.file_selection.server_started) self.server_status.server_started.connect(self.start_server) self.server_status.server_stopped.connect( self.file_selection.server_stopped) self.server_status.server_stopped.connect(self.stop_server) self.start_server_finished.connect(self.clear_message) self.start_server_finished.connect( self.server_status.start_server_finished) self.stop_server_finished.connect( self.server_status.stop_server_finished) self.file_selection.file_list.files_updated.connect( self.server_status.update) self.server_status.url_copied.connect(self.copy_url) self.starting_server_step2.connect(self.start_server_step2) # filesize warning self.filesize_warning = QtGui.QLabel() self.filesize_warning.setStyleSheet( 'padding: 10px 0; font-weight: bold; color: #333333;') self.filesize_warning.hide() # downloads self.downloads = Downloads() # options self.options = Options(web, self.app) # status bar self.status_bar = QtGui.QStatusBar() self.status_bar.setSizeGripEnabled(False) # main layout self.layout = QtGui.QVBoxLayout() self.layout.addLayout(self.file_selection) self.layout.addLayout(self.server_status) self.layout.addWidget(self.filesize_warning) self.layout.addLayout(self.downloads) self.layout.addLayout(self.options) self.layout.addWidget(self.status_bar) 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_step2(self): """ Step 2 in starting the onionshare server. This displays the large filesize warning, if applicable. """ # warn about sending large files over Tor if web.zip_filesize >= 157286400: # 150mb self.filesize_warning.setText(strings._("large_filesize", True)) self.filesize_warning.show() def start_server(self): """ Start the onionshare server. This uses multiple threads to start the Tor hidden server and the web app. """ # start the hidden service self.status_bar.showMessage(strings._('gui_starting_server1', True)) self.app.choose_port() try: self.status_bar.showMessage(strings._('gui_starting_server1', True)) self.app.start_hidden_service(gui=True) except onionshare.hs.NoTor as e: alert(e.args[0], QtGui.QMessageBox.Warning) self.server_status.stop_server() self.status_bar.clearMessage() return # start onionshare service in new thread t = threading.Thread(target=web.start, args=(self.app.port, self.app.stay_open, self.app.transparent_torification)) t.daemon = True t.start() # 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) self.app.cleanup_filenames.append(web.zip_filename) self.starting_server_step2.emit() # wait for hs if not self.app.local_only: if not self.app.hs.supports_ephemeral: self.status_bar.showMessage( strings._('gui_starting_server3', True)) self.app.hs.wait_for_hs(self.app.onion_host) # 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() def stop_server(self): """ Stop the onionshare server. """ if self.server_status.status != self.server_status.STATUS_STOPPED: web.stop(self.app.port) self.app.cleanup() self.filesize_warning.hide() self.stop_server_finished.emit() def check_for_requests(self): """ Check for messages communicated from the web app, and update the GUI accordingly. """ 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["type"] == web.REQUEST_LOAD: self.status_bar.showMessage( strings._('download_page_loaded', True)) elif 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() elif event["type"] == web.REQUEST_CANCELED: self.downloads.cancel_download(event["data"]["id"]) elif event["path"] != '/favicon.ico': self.status_bar.showMessage('{0:s}: {1:s}'.format( strings._('other_page_loaded', True), event["path"])) def copy_url(self): """ When the URL gets copied to the clipboard, display this in the status bar. """ self.status_bar.showMessage(strings._('gui_copied_url', True), 2000) def clear_message(self): """ Clear messages from the status bar. """ self.status_bar.clearMessage()