summaryrefslogtreecommitdiff
path: root/src/leap/bitmask/gui/mainwindow.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/bitmask/gui/mainwindow.py')
-rw-r--r--src/leap/bitmask/gui/mainwindow.py98
1 files changed, 32 insertions, 66 deletions
diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py
index 885cb792..03c29d0e 100644
--- a/src/leap/bitmask/gui/mainwindow.py
+++ b/src/leap/bitmask/gui/mainwindow.py
@@ -18,12 +18,10 @@
Main window for Bitmask.
"""
import logging
-import socket
from datetime import datetime
from PySide import QtCore, QtGui
-from twisted.internet import reactor, threads
from leap.bitmask import __version__ as VERSION
from leap.bitmask import __version_hash__ as VERSION_HASH
@@ -177,8 +175,8 @@ class MainWindow(QtGui.QMainWindow):
# Set used to track the services being stopped and need wait.
self._services_being_stopped = {}
- # timeout object used to trigger quit
- self._quit_timeout_callater = None
+ # used to know if we are in the final steps of quitting
+ self._finally_quitting = False
self._backend_connected_signals = []
self._backend_connect()
@@ -403,6 +401,8 @@ class MainWindow(QtGui.QMainWindow):
sig.eip_can_start.connect(self._backend_can_start_eip)
sig.eip_cannot_start.connect(self._backend_cannot_start_eip)
+ sig.eip_dns_error.connect(self._eip_dns_error)
+
# ==================================================================
# Soledad signals
@@ -897,7 +897,7 @@ class MainWindow(QtGui.QMainWindow):
self.tr('Hello!'),
self.tr('Bitmask has started in the tray.'))
# we wait for the systray to be ready
- reactor.callLater(1, hello)
+ QtDelayedCall(1, hello)
@QtCore.Slot(int)
def _tray_activated(self, reason=None):
@@ -1461,55 +1461,25 @@ class MainWindow(QtGui.QMainWindow):
self._already_started_eip = True
# check for connectivity
- # we might want to leave a little time here...
- self._check_name_resolution(domain)
-
- def _check_name_resolution(self, domain):
- # FIXME this has to be moved to backend !!!
- # Should move to netchecks module.
- # and separate qt from reactor...
- """
- Check if we can resolve the given domain name.
-
- :param domain: the domain to check.
- :type domain: str
- """
- def do_check():
- """
- Try to resolve the domain name.
- """
- socket.gethostbyname(domain.encode('idna'))
-
- def check_err(failure):
- """
- Errback handler for `do_check`.
-
- :param failure: the failure that triggered the errback.
- :type failure: twisted.python.failure.Failure
- """
- logger.error(repr(failure))
- logger.error("Can't resolve hostname.")
-
- msg = self.tr(
- "The server at {0} can't be found, because the DNS lookup "
- "failed. DNS is the network service that translates a "
- "website's name to its Internet address. Either your computer "
- "is having trouble connecting to the network, or you are "
- "missing some helper files that are needed to securely use "
- "DNS while {1} is active. To install these helper files, quit "
- "this application and start it again."
- ).format(domain, self._eip_conductor.eip_name)
-
- show_err = lambda: QtGui.QMessageBox.critical(
- self, self.tr("Connection Error"), msg)
- reactor.callLater(0, show_err)
-
- # python 2.7.4 raises socket.error
- # python 2.7.5 raises socket.gaierror
- failure.trap(socket.gaierror, socket.error)
-
- d = threads.deferToThread(do_check)
- d.addErrback(check_err)
+ self._backend.eip_check_dns(domain)
+
+ @QtCore.Slot()
+ def _eip_dns_error(self):
+ """
+ Trigger this if we don't have a working DNS resolver.
+ """
+ domain = self._login_widget.get_selected_provider()
+ msg = self.tr(
+ "The server at {0} can't be found, because the DNS lookup "
+ "failed. DNS is the network service that translates a "
+ "website's name to its Internet address. Either your computer "
+ "is having trouble connecting to the network, or you are "
+ "missing some helper files that are needed to securely use "
+ "DNS while {1} is active. To install these helper files, quit "
+ "this application and start it again."
+ ).format(domain, self._eip_conductor.eip_name)
+
+ QtGui.QMessageBox.critical(self, self.tr("Connection Error"), msg)
def _try_autostart_eip(self):
"""
@@ -1768,8 +1738,7 @@ class MainWindow(QtGui.QMainWindow):
# call final quit when all the services are stopped
self.all_services_stopped.connect(self.final_quit)
# or if we reach the timeout
- self._quit_timeout_callater = reactor.callLater(
- self.SERVICES_STOP_TIMEOUT, self.final_quit)
+ QtDelayedCall(self.SERVICES_STOP_TIMEOUT, self.final_quit)
@QtCore.Slot()
def _remove_service(self, service):
@@ -1795,16 +1764,13 @@ class MainWindow(QtGui.QMainWindow):
"""
logger.debug('Final quit...')
- try:
- # disconnect signal if we get here due a timeout.
- self.all_services_stopped.disconnect(self.final_quit)
- except RuntimeError:
- pass # Signal was not connected
+ # We can reach here because all the services are stopped or because a
+ # timeout was triggered. Since we want to run this only once, we exit
+ # if this is called twice.
+ if self._finally_quitting:
+ return
- # Cancel timeout to avoid being called if we reached here through the
- # signal
- if self._quit_timeout_callater.active():
- self._quit_timeout_callater.cancel()
+ self._finally_quitting = True
# Remove lockfiles on a clean shutdown.
logger.debug('Cleaning pidfiles')
@@ -1814,4 +1780,4 @@ class MainWindow(QtGui.QMainWindow):
self._backend.stop()
self.close()
- reactor.callLater(1, twisted_main.quit)
+ QtDelayedCall(1, twisted_main.quit)