summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/leap/base/constants.py2
-rw-r--r--src/leap/base/network.py55
-rw-r--r--src/leap/baseapp/mainwindow.py3
-rw-r--r--src/leap/baseapp/network.py56
4 files changed, 116 insertions, 0 deletions
diff --git a/src/leap/base/constants.py b/src/leap/base/constants.py
index 7a1415fb..8a76b6b4 100644
--- a/src/leap/base/constants.py
+++ b/src/leap/base/constants.py
@@ -28,3 +28,5 @@ DEFAULT_PROVIDER_DEFINITION = {
u'version': u'0.1.0'}
MAX_ICMP_PACKET_LOSS = 10
+
+ROUTE_CHECK_INTERVAL = 120
diff --git a/src/leap/base/network.py b/src/leap/base/network.py
new file mode 100644
index 00000000..58f903e1
--- /dev/null
+++ b/src/leap/base/network.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+from __future__ import (print_function)
+
+from leap.base.checks import LeapNetworkChecker
+from leap.base.constants import ROUTE_CHECK_INTERVAL
+from leap.util.coroutines import (launch_thread, process_events)
+
+from time import sleep
+
+class NetworkChecker(object):
+ """
+ Manages network checking thread that makes sure we have a working network
+ connection.
+ """
+ def __init__(self, *args, **kwargs):
+ self.status_signals = kwargs.pop('status_signals', None)
+ self.watcher_cb = kwargs.pop('status_signals', None)
+
+ def start(self):
+ self._launch_recurrent_network_checks((self.watcher_cb,))
+
+ def stop(self):
+ raise NotImplementedError
+
+ def run_checks(self):
+ pass
+
+ #private methods
+
+ #here all the observers in fail_callbacks expect one positional argument,
+ #which is exception so we can try by passing a lambda with logger to
+ #check it works.
+ def _network_checks_thread(self, fail_callbacks):
+ print('fail_callbacks: %s' % fail_callbacks)
+ print(len(fail_callbacks))
+ observer_dict = dict(((
+ observer, process_events(observer)) for observer in fail_callbacks))
+ netchecker = LeapNetworkChecker()
+ while True:
+ try:
+ netchecker.check_internet_connection()
+ sleep(ROUTE_CHECK_INTERVAL)
+ except Exception as exc:
+ for obs in observer_dict:
+ observer_dict[obs].send(exc)
+
+
+ def _launch_recurrent_network_checks(fail_callbacks):
+ print(type(fail_callbacks))
+ watcher = launch_thread(
+ network_checks_thread,
+ (fail_callbacks,))
+ return watcher
+
+
diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py
index 10b23d9a..7b2ecb1d 100644
--- a/src/leap/baseapp/mainwindow.py
+++ b/src/leap/baseapp/mainwindow.py
@@ -8,6 +8,7 @@ from PyQt4 import QtGui
from leap.baseapp.eip import EIPConductorAppMixin
from leap.baseapp.log import LogPaneMixin
from leap.baseapp.systray import StatusAwareTrayIconMixin
+from leap.baseapp.network import NetworkCheckerAppMixin
from leap.baseapp.leap_app import MainWindowMixin
logger = logging.getLogger(name=__name__)
@@ -16,6 +17,7 @@ logger = logging.getLogger(name=__name__)
class LeapWindow(QtGui.QMainWindow,
MainWindowMixin, EIPConductorAppMixin,
StatusAwareTrayIconMixin,
+ NetworkCheckerAppMixin,
LogPaneMixin):
"""
main window for the leap app.
@@ -36,6 +38,7 @@ class LeapWindow(QtGui.QMainWindow,
self.createLogBrowser()
EIPConductorAppMixin.__init__(self, opts=opts)
StatusAwareTrayIconMixin.__init__(self)
+ NetworkCheckerAppMixin.__init__(self)
MainWindowMixin.__init__(self)
# bind signals
diff --git a/src/leap/baseapp/network.py b/src/leap/baseapp/network.py
new file mode 100644
index 00000000..42a42fcd
--- /dev/null
+++ b/src/leap/baseapp/network.py
@@ -0,0 +1,56 @@
+from __future__ import print_function
+import logging
+import time
+logger = logging.getLogger(name=__name__)
+
+from leap.base.network import NetworkChecker
+from leap.baseapp.dialogs import ErrorDialog
+
+
+class NetworkCheckerAppMixin(object):
+ """
+ initialize an instance of the Network Checker,
+ which gathers error and passes them on.
+ """
+
+ def __init__(self, *args, **kwargs):
+ opts = kwargs.pop('opts', None)
+ config_file = getattr(opts, 'config_file', None)
+
+ self.network_checker_started = False
+
+ self.network_checker = NetworkChecker(
+ watcher_cb=self.newLogLine.emit,
+ status_signals=(self.statusChange.emit, ),
+ debug=self.debugmode)
+
+ self.network_checker.run_checks()
+ self.error_check()
+
+ def error_check(self):
+ """
+ consumes the conductor error queue.
+ pops errors, and acts accordingly (launching user dialogs).
+ """
+ logger.debug('error check')
+
+ errq = self.conductor.error_queue
+ while errq.qsize() != 0:
+ logger.debug('%s errors left in conductor queue', errq.qsize())
+ # we get exception and original traceback from queue
+ error, tb = errq.get()
+
+ # redundant log, debugging the loop.
+ logger.error('%s: %s', error.__class__.__name__, error.message)
+
+ if issubclass(error.__class__, eip_exceptions.EIPClientError):
+ self.handle_eip_error(error)
+
+ else:
+ # deprecated form of raising exception.
+ raise error, None, tb
+
+ if error.failfirst is True:
+ break
+
+