diff options
Diffstat (limited to 'src/leap/baseapp')
-rw-r--r-- | src/leap/baseapp/__init__.py | 0 | ||||
-rw-r--r-- | src/leap/baseapp/constants.py | 6 | ||||
-rw-r--r-- | src/leap/baseapp/dialogs.py | 61 | ||||
-rw-r--r-- | src/leap/baseapp/eip.py | 243 | ||||
-rw-r--r-- | src/leap/baseapp/leap_app.py | 153 | ||||
-rw-r--r-- | src/leap/baseapp/log.py | 69 | ||||
-rw-r--r-- | src/leap/baseapp/mainwindow.py | 191 | ||||
-rw-r--r-- | src/leap/baseapp/network.py | 63 | ||||
-rw-r--r-- | src/leap/baseapp/permcheck.py | 17 | ||||
-rw-r--r-- | src/leap/baseapp/systray.py | 268 |
10 files changed, 0 insertions, 1071 deletions
diff --git a/src/leap/baseapp/__init__.py b/src/leap/baseapp/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/src/leap/baseapp/__init__.py +++ /dev/null diff --git a/src/leap/baseapp/constants.py b/src/leap/baseapp/constants.py deleted file mode 100644 index e312be21..00000000 --- a/src/leap/baseapp/constants.py +++ /dev/null @@ -1,6 +0,0 @@ -# This timer used for polling vpn manager state. - -# XXX what is an optimum polling interval? -# too little will be overkill, too much will -# miss transition states. -TIMER_MILLISECONDS = 250.0 diff --git a/src/leap/baseapp/dialogs.py b/src/leap/baseapp/dialogs.py deleted file mode 100644 index d256fc99..00000000 --- a/src/leap/baseapp/dialogs.py +++ /dev/null @@ -1,61 +0,0 @@ -# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 -import logging - -from PyQt4.QtGui import (QDialog, QFrame, QPushButton, QLabel, QMessageBox) - -logger = logging.getLogger(name=__name__) - - -class ErrorDialog(QDialog): - def __init__(self, parent=None, errtype=None, msg=None, label=None): - super(ErrorDialog, self).__init__(parent) - frameStyle = QFrame.Sunken | QFrame.Panel - self.warningLabel = QLabel() - self.warningLabel.setFrameStyle(frameStyle) - self.warningButton = QPushButton("QMessageBox.&warning()") - - if msg is not None: - self.msg = msg - if label is not None: - self.label = label - if errtype == "critical": - self.criticalMessage(self.msg, self.label) - - def warningMessage(self, msg, label): - msgBox = QMessageBox(QMessageBox.Warning, - "LEAP Client Error", - msg, - QMessageBox.NoButton, self) - msgBox.addButton("&Ok", QMessageBox.AcceptRole) - if msgBox.exec_() == QMessageBox.AcceptRole: - pass - # do whatever we want to do after - # closing the dialog. we can pass that - # in the constructor - - def criticalMessage(self, msg, label): - msgBox = QMessageBox(QMessageBox.Critical, - "LEAP Client Error", - msg, - QMessageBox.NoButton, self) - msgBox.addButton("&Ok", QMessageBox.AcceptRole) - msgBox.exec_() - - # It's critical, so we exit. - # We should better emit a signal and connect it - # with the proper shutdownAndQuit method, but - # this suffices for now. - logger.info('Quitting') - import sys - sys.exit() - - def confirmMessage(self, msg, label, action): - msgBox = QMessageBox(QMessageBox.Critical, - self.tr("LEAP Client Error"), - msg, - QMessageBox.NoButton, self) - msgBox.addButton("&Ok", QMessageBox.AcceptRole) - msgBox.addButton("&Cancel", QMessageBox.RejectRole) - - if msgBox.exec_() == QMessageBox.AcceptRole: - action() diff --git a/src/leap/baseapp/eip.py b/src/leap/baseapp/eip.py deleted file mode 100644 index b34cc82e..00000000 --- a/src/leap/baseapp/eip.py +++ /dev/null @@ -1,243 +0,0 @@ -from __future__ import print_function -import logging -import time -#import sys - -from PyQt4 import QtCore - -from leap.baseapp.dialogs import ErrorDialog -from leap.baseapp import constants -from leap.eip import exceptions as eip_exceptions -from leap.eip.eipconnection import EIPConnection -from leap.base.checks import EVENT_CONNECT_REFUSED -from leap.util import geo - -logger = logging.getLogger(name=__name__) - - -class EIPConductorAppMixin(object): - """ - initializes an instance of EIPConnection, - gathers errors, and passes status-change signals - from Qt land along to the conductor. - Connects the eip connect/disconnect logic - to the switches in the app (buttons/menu items). - """ - ERR_DIALOG = False - - def __init__(self, *args, **kwargs): - opts = kwargs.pop('opts') - config_file = getattr(opts, 'config_file', None) - provider = kwargs.pop('provider') - - self.eip_service_started = False - - # conductor (eip connection) is in charge of all - # vpn-related configuration / monitoring. - # we pass a tuple of signals that will be - # triggered when status changes. - - self.conductor = EIPConnection( - watcher_cb=self.newLogLine.emit, - config_file=config_file, - checker_signals=(self.eipStatusChange.emit, ), - status_signals=(self.openvpnStatusChange.emit, ), - debug=self.debugmode, - ovpn_verbosity=opts.openvpn_verb, - provider=provider) - - # Do we want to enable the skip checks w/o being - # in debug mode?? - #self.skip_download = opts.no_provider_checks - #self.skip_verify = opts.no_ca_verify - self.skip_download = False - self.skip_verify = False - - def run_eip_checks(self): - """ - runs eip checks and - the error checking loop - """ - logger.debug('running EIP CHECKS') - self.conductor.run_checks( - skip_download=self.skip_download, - skip_verify=self.skip_verify) - self.error_check() - - self.start_eipconnection.emit() - - 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.triggerEIPError.emit(error) - - else: - # deprecated form of raising exception. - raise error, None, tb - - if error.failfirst is True: - break - - @QtCore.pyqtSlot(object) - def onEIPError(self, error): - """ - check severity and launches - dialogs informing user about the errors. - in the future we plan to derive errors to - our log viewer. - """ - if self.ERR_DIALOG: - logger.warning('another error dialog suppressed') - return - - # XXX this is actually a one-shot. - # On the dialog there should be - # a reset signal binded to the ok button - # or something like that. - self.ERR_DIALOG = True - - if getattr(error, 'usermessage', None): - message = error.usermessage - else: - message = error.message - - # XXX - # check headless = False before - # launching dialog. - # (so Qt tests can assert stuff) - - if error.critical: - logger.critical(error.message) - #critical error (non recoverable), - #we give user some info and quit. - #(critical error dialog will exit app) - ErrorDialog(errtype="critical", - msg=message, - label="critical error") - - elif error.warning: - logger.warning(error.message) - - else: - dialog = ErrorDialog() - dialog.warningMessage(message, 'error') - - @QtCore.pyqtSlot() - def statusUpdate(self): - """ - polls status and updates ui with real time - info about transferred bytes / connection state. - right now is triggered by a timer tick - (timer controlled by StatusAwareTrayIcon class) - """ - # TODO I guess it's too expensive to poll - # continously. move to signal events instead. - # (i.e., subscribe to connection status changes - # from openvpn manager) - - if not self.eip_service_started: - # there is a race condition - # going on here. Depending on how long we take - # to init the qt app, the management socket - # is not ready yet. - return - - #if self.conductor.with_errors: - #XXX how to wait on pkexec??? - #something better that this workaround, plz!! - #I removed the pkexec pass authentication at all. - #time.sleep(5) - #logger.debug('timeout') - #logger.error('errors. disconnect') - #self.start_or_stopVPN() # is stop - - state = self.conductor.poll_connection_state() - if not state: - return - - ts, con_status, ok, ip, remote = state - self.set_statusbarMessage(con_status) - self.setIconToolTip() - - ts = time.strftime("%a %b %d %X", ts) - if self.debugmode: - self.updateTS.setText(ts) - self.status_label.setText(con_status) - self.ip_label.setText(ip) - self.remote_label.setText(remote) - self.remote_country.setText( - geo.get_country_name(remote)) - - # status i/o - - status = self.conductor.get_status_io() - if status and self.debugmode: - #XXX move this to systray menu indicators - ts, (tun_read, tun_write, tcp_read, tcp_write, auth_read) = status - ts = time.strftime("%a %b %d %X", ts) - self.updateTS.setText(ts) - self.tun_read_bytes.setText(tun_read) - self.tun_write_bytes.setText(tun_write) - - # connection information via management interface - log = self.conductor.get_log() - error_matrix = [(EVENT_CONNECT_REFUSED, (self.start_or_stopVPN, ))] - if hasattr(self.network_checker, 'checker'): - self.network_checker.checker.parse_log_and_react(log, error_matrix) - - @QtCore.pyqtSlot() - def start_or_stopVPN(self, **kwargs): - """ - stub for running child process with vpn - """ - if self.conductor.has_errors(): - logger.debug('not starting vpn; conductor has errors') - return - - if self.eip_service_started is False: - try: - self.conductor.connect() - - except eip_exceptions.EIPNoCommandError as exc: - logger.error('tried to run openvpn but no command is set') - self.triggerEIPError.emit(exc) - - except Exception as err: - # raise generic exception (Bad Thing Happened?) - logger.exception(err) - else: - # no errors, so go on. - if self.debugmode: - self.startStopButton.setText(self.tr('&Disconnect')) - self.eip_service_started = True - self.toggleEIPAct() - - # XXX decouple! (timer is init by icons class). - # we could bring Timer Init to this Mixin - # or to its own Mixin. - self.timer.start(constants.TIMER_MILLISECONDS) - return - - if self.eip_service_started is True: - self.network_checker.stop() - self.conductor.disconnect() - if self.debugmode: - self.startStopButton.setText(self.tr('&Connect')) - self.eip_service_started = False - self.toggleEIPAct() - self.timer.stop() - return diff --git a/src/leap/baseapp/leap_app.py b/src/leap/baseapp/leap_app.py deleted file mode 100644 index 4d3aebd6..00000000 --- a/src/leap/baseapp/leap_app.py +++ /dev/null @@ -1,153 +0,0 @@ -import logging - -import sip -sip.setapi('QVariant', 2) - -from PyQt4 import QtCore -from PyQt4 import QtGui - -from leap.gui import mainwindow_rc - -logger = logging.getLogger(name=__name__) - - -APP_LOGO = ':/images/leap-color-small.png' - - -class MainWindowMixin(object): - """ - create the main window - for leap app - """ - - def __init__(self, *args, **kwargs): - # XXX set initial visibility - # debug = no visible - - widget = QtGui.QWidget() - self.setCentralWidget(widget) - - mainLayout = QtGui.QVBoxLayout() - # add widgets to layout - #self.createWindowHeader() - #mainLayout.addWidget(self.headerBox) - - # created in systray - mainLayout.addWidget(self.statusIconBox) - if self.debugmode: - mainLayout.addWidget(self.statusBox) - mainLayout.addWidget(self.loggerBox) - widget.setLayout(mainLayout) - - self.createMainActions() - self.createMainMenus() - - self.setWindowTitle("LEAP Client") - self.set_app_icon() - self.set_statusbarMessage('ready') - - def createMainActions(self): - #self.openAct = QtGui.QAction("&Open...", self, shortcut="Ctrl+O", - #triggered=self.open) - - self.firstRunWizardAct = QtGui.QAction( - "&First run wizard...", self, - triggered=self.stop_connection_and_launch_first_run_wizard) - self.aboutAct = QtGui.QAction("&About", self, triggered=self.about) - - #self.aboutQtAct = QtGui.QAction("About &Qt", self, - #triggered=QtGui.qApp.aboutQt) - - def createMainMenus(self): - self.connMenu = QtGui.QMenu("&Connections", self) - #self.viewMenu.addSeparator() - self.connMenu.addAction(self.quitAction) - - self.settingsMenu = QtGui.QMenu("&Settings", self) - self.settingsMenu.addAction(self.firstRunWizardAct) - - self.helpMenu = QtGui.QMenu("&Help", self) - self.helpMenu.addAction(self.aboutAct) - #self.helpMenu.addAction(self.aboutQtAct) - - self.menuBar().addMenu(self.connMenu) - self.menuBar().addMenu(self.settingsMenu) - self.menuBar().addMenu(self.helpMenu) - - def stop_connection_and_launch_first_run_wizard(self): - settings = QtCore.QSettings() - settings.setValue('FirstRunWizardDone', False) - logger.debug('should run first run wizard again...') - - status = self.conductor.get_icon_name() - if status != "disconnected": - self.start_or_stopVPN() - - self.launch_first_run_wizard() - #from leap.gui.firstrunwizard import FirstRunWizard - #wizard = FirstRunWizard( - #parent=self, - #success_cb=self.initReady.emit) - #wizard.show() - - def set_app_icon(self): - icon = QtGui.QIcon(APP_LOGO) - self.setWindowIcon(icon) - - #def createWindowHeader(self): - #""" - #description lines for main window - #""" - #self.headerBox = QtGui.QGroupBox() - #self.headerLabel = QtGui.QLabel( - #"<font size=40>LEAP Encryption Access Project</font>") - #self.headerLabelSub = QtGui.QLabel( - #"<br><i>your internet encryption toolkit</i>") -# - #pixmap = QtGui.QPixmap(APP_LOGO) - #leap_lbl = QtGui.QLabel() - #leap_lbl.setPixmap(pixmap) -# - #headerLayout = QtGui.QHBoxLayout() - #headerLayout.addWidget(leap_lbl) - #headerLayout.addWidget(self.headerLabel) - #headerLayout.addWidget(self.headerLabelSub) - #headerLayout.addStretch() - #self.headerBox.setLayout(headerLayout) - - def set_statusbarMessage(self, msg): - self.statusBar().showMessage(msg) - - def closeEvent(self, event): - """ - redefines close event (persistent window behaviour) - """ - if self.trayIcon.isVisible() and not self.debugmode: - QtGui.QMessageBox.information( - self, "Systray", - "The program will keep running " - "in the system tray. To " - "terminate the program, choose " - "<b>Quit</b> in the " - "context menu of the system tray entry.") - self.hide() - event.ignore() - return - self.cleanupAndQuit() - - def cleanupAndQuit(self): - """ - cleans state before shutting down app. - """ - # save geometry for restoring - settings = QtCore.QSettings() - geom_key = "DebugGeometry" if self.debugmode else "Geometry" - settings.setValue(geom_key, self.saveGeometry()) - - # TODO:make sure to shutdown all child process / threads - # in conductor - # XXX send signal instead? - logger.info('Shutting down') - self.conductor.disconnect(shutdown=True) - logger.info('Exiting. Bye.') - QtGui.qApp.quit() diff --git a/src/leap/baseapp/log.py b/src/leap/baseapp/log.py deleted file mode 100644 index 636e5bae..00000000 --- a/src/leap/baseapp/log.py +++ /dev/null @@ -1,69 +0,0 @@ -import logging - -from PyQt4 import QtGui -from PyQt4 import QtCore - -vpnlogger = logging.getLogger('leap.openvpn') - - -class LogPaneMixin(object): - """ - a simple log pane - that writes new lines as they come - """ - EXCLUDES = ('MANAGEMENT',) - - def createLogBrowser(self): - """ - creates Browser widget for displaying logs - (in debug mode only). - """ - self.loggerBox = QtGui.QGroupBox() - logging_layout = QtGui.QVBoxLayout() - self.logbrowser = QtGui.QTextBrowser() - - startStopButton = QtGui.QPushButton(self.tr("&Connect")) - self.startStopButton = startStopButton - - logging_layout.addWidget(self.logbrowser) - logging_layout.addWidget(self.startStopButton) - self.loggerBox.setLayout(logging_layout) - - # status box - - self.statusBox = QtGui.QGroupBox() - grid = QtGui.QGridLayout() - - self.updateTS = QtGui.QLabel('') - self.status_label = QtGui.QLabel(self.tr('Disconnected')) - self.ip_label = QtGui.QLabel('') - self.remote_label = QtGui.QLabel('') - self.remote_country = QtGui.QLabel('') - - tun_read_label = QtGui.QLabel("tun read") - self.tun_read_bytes = QtGui.QLabel("0") - tun_write_label = QtGui.QLabel("tun write") - self.tun_write_bytes = QtGui.QLabel("0") - - grid.addWidget(self.updateTS, 0, 0) - grid.addWidget(self.status_label, 0, 1) - grid.addWidget(self.ip_label, 1, 0) - grid.addWidget(self.remote_label, 1, 1) - grid.addWidget(self.remote_country, 2, 1) - grid.addWidget(tun_read_label, 3, 0) - grid.addWidget(self.tun_read_bytes, 3, 1) - grid.addWidget(tun_write_label, 4, 0) - grid.addWidget(self.tun_write_bytes, 4, 1) - - self.statusBox.setLayout(grid) - - @QtCore.pyqtSlot(str) - def onLoggerNewLine(self, line): - """ - simple slot: writes new line to logger Pane. - """ - msg = line[:-1] - if self.debugmode and all(map(lambda w: w not in msg, - LogPaneMixin.EXCLUDES)): - self.logbrowser.append(msg) - vpnlogger.info(msg) diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py deleted file mode 100644 index 91b0dc61..00000000 --- a/src/leap/baseapp/mainwindow.py +++ /dev/null @@ -1,191 +0,0 @@ -# vim: set fileencoding=utf-8 : -#!/usr/bin/env python -import logging - -import sip -sip.setapi('QString', 2) -sip.setapi('QVariant', 2) - -from PyQt4 import QtCore -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 -from leap.eip.checks import ProviderCertChecker -from leap.gui.threads import FunThread - -logger = logging.getLogger(name=__name__) - - -class LeapWindow(QtGui.QMainWindow, - MainWindowMixin, EIPConductorAppMixin, - StatusAwareTrayIconMixin, - NetworkCheckerAppMixin, - LogPaneMixin): - """ - main window for the leap app. - Initializes all of its base classes - We keep here some signal initialization - that gets tricky otherwise. - """ - - # signals - - newLogLine = QtCore.pyqtSignal([str]) - mainappReady = QtCore.pyqtSignal([]) - initReady = QtCore.pyqtSignal([]) - networkError = QtCore.pyqtSignal([object]) - triggerEIPError = QtCore.pyqtSignal([object]) - start_eipconnection = QtCore.pyqtSignal([]) - shutdownSignal = QtCore.pyqtSignal([]) - initNetworkChecker = QtCore.pyqtSignal([]) - - # this is status change got from openvpn management - openvpnStatusChange = QtCore.pyqtSignal([object]) - # this is global eip status - eipStatusChange = QtCore.pyqtSignal([str]) - - def __init__(self, opts): - logger.debug('init leap window') - self.debugmode = getattr(opts, 'debug', False) - super(LeapWindow, self).__init__() - if self.debugmode: - self.createLogBrowser() - - settings = QtCore.QSettings() - self.provider_domain = settings.value("provider_domain", None) - self.username = settings.value("username", None) - - logger.debug('provider: %s', self.provider_domain) - logger.debug('username: %s', self.username) - - provider = self.provider_domain - EIPConductorAppMixin.__init__( - self, opts=opts, provider=provider) - StatusAwareTrayIconMixin.__init__(self) - - # XXX network checker should probably not - # trigger run_checks on init... but wait - # for ready signal instead... - NetworkCheckerAppMixin.__init__(self, provider=provider) - MainWindowMixin.__init__(self) - - geom_key = "DebugGeometry" if self.debugmode else "Geometry" - geom = settings.value(geom_key) - if geom: - self.restoreGeometry(geom) - - # XXX check for wizard - self.wizard_done = settings.value("FirstRunWizardDone") - - self.initchecks = FunThread(self.run_eip_checks) - - # bind signals - self.initchecks.finished.connect( - lambda: logger.debug('Initial checks thread finished')) - self.trayIcon.activated.connect(self.iconActivated) - self.newLogLine.connect( - lambda line: self.onLoggerNewLine(line)) - self.timer.timeout.connect( - lambda: self.onTimerTick()) - self.networkError.connect( - lambda exc: self.onNetworkError(exc)) - self.triggerEIPError.connect( - lambda exc: self.onEIPError(exc)) - - if self.debugmode: - self.startStopButton.clicked.connect( - lambda: self.start_or_stopVPN()) - self.start_eipconnection.connect( - self.do_start_eipconnection) - self.shutdownSignal.connect( - self.cleanupAndQuit) - self.initNetworkChecker.connect( - lambda: self.init_network_checker(self.conductor.provider)) - - # status change. - # TODO unify - self.openvpnStatusChange.connect( - lambda status: self.onOpenVPNStatusChange(status)) - self.eipStatusChange.connect( - lambda newstatus: self.onEIPConnStatusChange(newstatus)) - self.eipStatusChange.connect( - lambda newstatus: self.toggleEIPAct()) - - # do first run wizard and init signals - self.mainappReady.connect(self.do_first_run_wizard_check) - self.initReady.connect(self.runchecks_and_eipconnect) - - # ... all ready. go! - # connected to do_first_run_wizard_check - self.mainappReady.emit() - - def do_first_run_wizard_check(self): - """ - checks whether first run wizard needs to be run - launches it if needed - and emits initReady signal if not. - """ - - logger.debug('first run wizard check...') - need_wizard = False - - # do checks (can overlap if wizard was interrupted) - if not self.wizard_done: - need_wizard = True - - if not self.provider_domain: - need_wizard = True - else: - pcertchecker = ProviderCertChecker(domain=self.provider_domain) - if not pcertchecker.is_cert_valid(do_raise=False): - logger.warning('missing valid client cert. need wizard') - need_wizard = True - - # launch wizard if needed - if need_wizard: - logger.debug('running first run wizard') - self.launch_first_run_wizard() - else: # no wizard needed - self.initReady.emit() - - def launch_first_run_wizard(self): - """ - launches wizard and blocks - """ - from leap.gui.firstrun.wizard import FirstRunWizard - wizard = FirstRunWizard( - self.conductor, - parent=self, - username=self.username, - start_eipconnection_signal=self.start_eipconnection, - eip_statuschange_signal=self.eipStatusChange, - quitcallback=self.onWizardCancel) - wizard.show() - - def onWizardCancel(self): - if not self.wizard_done: - logger.debug( - 'clicked on Cancel during first ' - 'run wizard. shutting down') - self.cleanupAndQuit() - - def runchecks_and_eipconnect(self): - """ - shows icon and run init checks - """ - self.show_systray_icon() - self.initchecks.begin() - - def do_start_eipconnection(self): - """ - shows icon and init eip connection - called from the end of wizard - """ - self.show_systray_icon() - # this will setup the command - self.conductor.run_openvpn_checks() - self.start_or_stopVPN() diff --git a/src/leap/baseapp/network.py b/src/leap/baseapp/network.py deleted file mode 100644 index dc5182a4..00000000 --- a/src/leap/baseapp/network.py +++ /dev/null @@ -1,63 +0,0 @@ -from __future__ import print_function - -import logging - -logger = logging.getLogger(name=__name__) - -from PyQt4 import QtCore - -from leap.baseapp.dialogs import ErrorDialog -from leap.base.network import NetworkCheckerThread - -from leap.util.misc import null_check - - -class NetworkCheckerAppMixin(object): - """ - initialize an instance of the Network Checker, - which gathers error and passes them on. - """ - ERR_NETERR = False - - def __init__(self, *args, **kwargs): - provider = kwargs.pop('provider', None) - self.network_checker = None - if provider: - self.init_network_checker(provider) - - def init_network_checker(self, provider): - null_check(provider, "provider_domain") - if not self.network_checker: - self.network_checker = NetworkCheckerThread( - error_cb=self.networkError.emit, - debug=self.debugmode, - provider=provider) - self.network_checker.start() - - @QtCore.pyqtSlot(object) - def runNetworkChecks(self): - logger.debug('running checks (from NetworkChecker Mixin slot)') - self.network_checker.run_checks() - - @QtCore.pyqtSlot(object) - def onNetworkError(self, exc): - """ - slot that receives a network exceptions - and raises a user error message - """ - # FIXME this should not HANDLE anything after - # the network check thread has been stopped. - - logger.debug('handling network exception') - if not self.ERR_NETERR: - self.ERR_NETERR = True - - logger.error(exc.message) - dialog = ErrorDialog(parent=self) - if exc.critical: - dialog.criticalMessage(exc.usermessage, "network error") - else: - dialog.warningMessage(exc.usermessage, "network error") - - self.start_or_stopVPN() - self.network_checker.stop() diff --git a/src/leap/baseapp/permcheck.py b/src/leap/baseapp/permcheck.py deleted file mode 100644 index 6b74cb6e..00000000 --- a/src/leap/baseapp/permcheck.py +++ /dev/null @@ -1,17 +0,0 @@ -import commands -import os - -from leap.util.fileutil import which - - -def is_pkexec_in_system(): - pkexec_path = which('pkexec') - if not pkexec_path: - return False - return os.access(pkexec_path, os.X_OK) - - -def is_auth_agent_running(): - return bool( - commands.getoutput( - 'ps aux | grep polkit-[g]nome-authentication-agent-1')) diff --git a/src/leap/baseapp/systray.py b/src/leap/baseapp/systray.py deleted file mode 100644 index 77eb3fe9..00000000 --- a/src/leap/baseapp/systray.py +++ /dev/null @@ -1,268 +0,0 @@ -import logging -import sys - -import sip -sip.setapi('QString', 2) -sip.setapi('QVariant', 2) - -from PyQt4 import QtCore -from PyQt4 import QtGui - -from leap import __branding as BRANDING -from leap import __version__ as VERSION - -from leap.gui import mainwindow_rc - -logger = logging.getLogger(__name__) - - -class StatusAwareTrayIconMixin(object): - """ - a mix of several functions needed - to create a systray and make it - get updated from conductor status - polling. - """ - states = { - "disconnected": 0, - "connecting": 1, - "connected": 2} - - iconpath = { - "disconnected": ':/images/conn_error.png', - "connecting": ':/images/conn_connecting.png', - "connected": ':/images/conn_connected.png'} - - Icons = { - 'disconnected': lambda self: QtGui.QIcon( - self.iconpath['disconnected']), - 'connecting': lambda self: QtGui.QIcon( - self.iconpath['connecting']), - 'connected': lambda self: QtGui.QIcon( - self.iconpath['connected']) - } - - def __init__(self, *args, **kwargs): - self.createIconGroupBox() - self.createActions() - self.createTrayIcon() - - # not sure if this really belongs here, but... - self.timer = QtCore.QTimer() - - def show_systray_icon(self): - #logger.debug('showing tray icon................') - self.trayIcon.show() - - def createIconGroupBox(self): - """ - dummy icongroupbox - (to be removed from here -- reference only) - """ - con_widgets = { - 'disconnected': QtGui.QLabel(), - 'connecting': QtGui.QLabel(), - 'connected': QtGui.QLabel(), - } - con_widgets['disconnected'].setPixmap( - QtGui.QPixmap( - self.iconpath['disconnected'])) - con_widgets['connecting'].setPixmap( - QtGui.QPixmap( - self.iconpath['connecting'])) - con_widgets['connected'].setPixmap( - QtGui.QPixmap( - self.iconpath['connected'])), - self.ConnectionWidgets = con_widgets - - self.statusIconBox = QtGui.QGroupBox( - self.tr("EIP Connection Status")) - statusIconLayout = QtGui.QHBoxLayout() - statusIconLayout.addWidget(self.ConnectionWidgets['disconnected']) - statusIconLayout.addWidget(self.ConnectionWidgets['connecting']) - statusIconLayout.addWidget(self.ConnectionWidgets['connected']) - statusIconLayout.itemAt(1).widget().hide() - statusIconLayout.itemAt(2).widget().hide() - - self.leapConnStatus = QtGui.QLabel( - self.tr("<b>disconnected</b>")) - statusIconLayout.addWidget(self.leapConnStatus) - - self.statusIconBox.setLayout(statusIconLayout) - - def createTrayIcon(self): - """ - creates the tray icon - """ - self.trayIconMenu = QtGui.QMenu(self) - - self.trayIconMenu.addAction(self.connAct) - self.trayIconMenu.addSeparator() - self.trayIconMenu.addAction(self.detailsAct) - self.trayIconMenu.addSeparator() - self.trayIconMenu.addAction(self.aboutAct) - # we should get this hidden inside the "about" dialog - # (as a little button maybe) - #self.trayIconMenu.addAction(self.aboutQtAct) - self.trayIconMenu.addSeparator() - self.trayIconMenu.addAction(self.quitAction) - - self.trayIcon = QtGui.QSystemTrayIcon(self) - self.setIcon('disconnected') - self.trayIcon.setContextMenu(self.trayIconMenu) - - #self.trayIconMenu.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - #self.trayIconMenu.customContextMenuRequested.connect( - #self.on_context_menu) - - #def bad(self): - #logger.error('this should not be called') - - def createActions(self): - """ - creates actions to be binded to tray icon - """ - # XXX change action name on (dis)connect - self.connAct = QtGui.QAction( - self.tr("Encryption ON turn &off"), - self, - triggered=lambda: self.start_or_stopVPN()) - - self.detailsAct = QtGui.QAction( - self.tr("&Details..."), - self, - triggered=self.detailsWin) - self.aboutAct = QtGui.QAction( - self.tr("&About"), self, - triggered=self.about) - self.aboutQtAct = QtGui.QAction( - self.tr("About Q&t"), self, - triggered=QtGui.qApp.aboutQt) - self.quitAction = QtGui.QAction( - self.tr("&Quit"), self, - triggered=self.cleanupAndQuit) - - def toggleEIPAct(self): - # this is too simple by now. - # XXX get STATUS CONSTANTS INSTEAD - - icon_status = self.conductor.get_icon_name() - if icon_status == "connected": - self.connAct.setEnabled(True) - self.connAct.setText( - self.tr('Encryption ON turn o&ff')) - return - if icon_status == "disconnected": - self.connAct.setEnabled(True) - self.connAct.setText( - self.tr('Encryption OFF turn &on')) - return - if icon_status == "connecting": - self.connAct.setDisabled(True) - self.connAct.setText(self.tr('connecting...')) - return - - def detailsWin(self): - visible = self.isVisible() - if visible: - self.hide() - else: - self.show() - if sys.platform == "darwin": - self.raise_() - - def about(self): - # move to widget - flavor = BRANDING.get('short_name', None) - content = self.tr( - ("LEAP client<br>" - "(version <b>%s</b>)<br>" % VERSION)) - if flavor: - content = content + ('<br>Flavor: <i>%s</i><br>' % flavor) - content = content + ( - "<br><a href='https://leap.se/'>" - "https://leap.se</a>") - QtGui.QMessageBox.about(self, self.tr("About"), content) - - def setConnWidget(self, icon_name): - oldlayout = self.statusIconBox.layout() - - for i in range(3): - oldlayout.itemAt(i).widget().hide() - new = self.states[icon_name] - oldlayout.itemAt(new).widget().show() - - def setIcon(self, name): - icon_fun = self.Icons.get(name) - if icon_fun and callable(icon_fun): - icon = icon_fun(self) - self.trayIcon.setIcon(icon) - - def getIcon(self, icon_name): - return self.states.get(icon_name, None) - - def setIconToolTip(self): - """ - get readable status and place it on systray tooltip - """ - status = self.conductor.status.get_readable_status() - self.trayIcon.setToolTip(status) - - def iconActivated(self, reason): - """ - handles left click, left double click - showing the trayicon menu - """ - if reason in (QtGui.QSystemTrayIcon.Trigger, - QtGui.QSystemTrayIcon.DoubleClick): - context_menu = self.trayIcon.contextMenu() - # for some reason, context_menu.show() - # is failing in a way beyond my understanding. - # (not working the first time it's clicked). - # this works however. - # XXX in osx it shows some glitches. - context_menu.exec_(self.trayIcon.geometry().center()) - - @QtCore.pyqtSlot() - def onTimerTick(self): - self.statusUpdate() - - @QtCore.pyqtSlot(object) - def onOpenVPNStatusChange(self, status): - """ - updates icon, according to the openvpn status change. - """ - icon_name = self.conductor.get_icon_name() - if not icon_name: - return - - # XXX refactor. Use QStateMachine - - if icon_name in ("disconnected", "connected"): - self.eipStatusChange.emit(icon_name) - - if icon_name in ("connecting"): - # let's see how it matches - leap_status_name = self.conductor.get_leap_status() - self.eipStatusChange.emit(leap_status_name) - - if icon_name == "connected": - # When we change to "connected', we launch - # the network checker. - self.initNetworkChecker.emit() - - self.setIcon(icon_name) - # change connection pixmap widget - self.setConnWidget(icon_name) - - @QtCore.pyqtSlot(str) - def onEIPConnStatusChange(self, newstatus): - """ - slot for EIP status changes - not to be confused with onOpenVPNStatusChange. - this only updates the non-debug LEAP Status line - next to the connection icon. - """ - # XXX move bold to style sheet - self.leapConnStatus.setText( - "<b>%s</b>" % newstatus) |