From 3795dedd26fc239e143ca2a29b7e16d433f964ba Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 10 Jun 2014 17:05:06 -0300 Subject: Separate app.py and frontend_app.py logics. This prepares the scenario to run the frontend and the backend in different processes. --- src/leap/bitmask/app.py | 106 ++++++--------------------------------- src/leap/bitmask/frontend_app.py | 103 +++++++++++++++++++++++++++++++++++++ src/leap/bitmask/gui/__init__.py | 1 + 3 files changed, 119 insertions(+), 91 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/app.py b/src/leap/bitmask/app.py index d0906b7c..f1d87d18 100644 --- a/src/leap/bitmask/app.py +++ b/src/leap/bitmask/app.py @@ -39,17 +39,13 @@ # M:::::::::::~NMMM7???7MMMM:::::::::::::::::::::::NMMMI??I7MMMM:::::::::::::M # M::::::::::::::7MMMMMMM+:::::::::::::::::::::::::::?MMMMMMMZ:::::::::::::::M # (thanks to: http://www.glassgiant.com/ascii/) -import signal -import sys +import multiprocessing import os - -from functools import partial - -from PySide import QtCore, QtGui +import sys from leap.bitmask import __version__ as VERSION from leap.bitmask.config import flags -from leap.bitmask.gui.mainwindow import MainWindow +from leap.bitmask.frontend_app import run_frontend from leap.bitmask.logs.utils import create_logger from leap.bitmask.platform_init.locks import we_are_the_one_and_only from leap.bitmask.services.mail import plumber @@ -59,9 +55,6 @@ from leap.bitmask.util.requirement_checker import check_requirements from leap.common.events import server as event_server from leap.mail import __version__ as MAIL_VERSION -from twisted.internet import reactor -from twisted.internet.task import LoopingCall - import codecs codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None) @@ -84,36 +77,7 @@ def kill_the_children(): # XXX This is currently broken, but we need to fix it to avoid # orphaned processes in case of a crash. -#atexit.register(kill_the_children) - - -def sigint_handler(*args, **kwargs): - """ - Signal handler for SIGINT - """ - logger = kwargs.get('logger', None) - parentpid = kwargs.get('parentpid', None) - pid = os.getpid() - if parentpid == pid: - if logger: - logger.debug("SIGINT catched. shutting down...") - mainwindow = args[0] - mainwindow.quit() - - -def sigterm_handler(*args, **kwargs): - """ - Signal handler for SIGTERM. - This handler is actually passed to twisted reactor - """ - logger = kwargs.get('logger', None) - parentpid = kwargs.get('parentpid', None) - pid = os.getpid() - if parentpid == pid: - if logger: - logger.debug("SIGTERM catched. shutting down...") - mainwindow = args[0] - mainwindow.quit() +# atexit.register(kill_the_children) def do_display_version(opts): @@ -141,7 +105,7 @@ def do_mail_plumbing(opts): # XXX catch when import is used w/o acct -def main(): +def start_app(): """ Starts the main event loop and launches the main window. """ @@ -149,8 +113,12 @@ def main(): opts = leap_argparse.get_options() do_display_version(opts) - bypass_checks = opts.danger - start_hidden = opts.start_hidden + options = { + 'bypass_checks': opts.danger, + 'start_hidden': opts.start_hidden, + 'debug': opts.debug, + 'log_file': opts.log_file, + } flags.STANDALONE = opts.standalone flags.OFFLINE = opts.offline @@ -202,53 +170,9 @@ def main(): logger.info('Starting app') - # We force the style if on KDE so that it doesn't load all the kde - # libs, which causes a compatibility issue in some systems. - # For more info, see issue #3194 - if flags.STANDALONE and os.environ.get("KDE_SESSION_UID") is not None: - sys.argv.append("-style") - sys.argv.append("Cleanlooks") - - app = QtGui.QApplication(sys.argv) - - # To test: - # $ LANG=es ./app.py - locale = QtCore.QLocale.system().name() - qtTranslator = QtCore.QTranslator() - if qtTranslator.load("qt_%s" % locale, ":/translations"): - app.installTranslator(qtTranslator) - appTranslator = QtCore.QTranslator() - if appTranslator.load("%s.qm" % locale[:2], ":/translations"): - app.installTranslator(appTranslator) - - # Needed for initializing qsettings it will write - # .config/leap/leap.conf top level app settings in a platform - # independent way - app.setOrganizationName("leap") - app.setApplicationName("leap") - app.setOrganizationDomain("leap.se") - - window = MainWindow(bypass_checks=bypass_checks, - start_hidden=start_hidden) - - mainpid = os.getpid() - sigint_window = partial(sigint_handler, window, - logger=logger, parentpid=mainpid) - signal.signal(signal.SIGINT, sigint_window) - - # callable used in addSystemEventTrigger to handle SIGTERM - sigterm_window = partial(sigterm_handler, window, - logger=logger, parentpid=mainpid) - # SIGTERM can't be handled the same way SIGINT is, since it's - # caught by twisted. See _handleSignals method in - # twisted/internet/base.py#L1150. So, addSystemEventTrigger - # reactor's method is used. - reactor.addSystemEventTrigger('before', 'shutdown', sigterm_window) - - l = LoopingCall(QtCore.QCoreApplication.processEvents, 0, 10) - l.start(0.01) - - reactor.run() + frontend = multiprocessing.Process(target=run_frontend, args=(options, )) + frontend.start() + if __name__ == "__main__": - main() + start_app() diff --git a/src/leap/bitmask/frontend_app.py b/src/leap/bitmask/frontend_app.py index e69de29b..ed67a77a 100644 --- a/src/leap/bitmask/frontend_app.py +++ b/src/leap/bitmask/frontend_app.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +# frontend_app.py +# Copyright (C) 2013, 2014 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +import signal +import sys +import os + +from functools import partial + +from PySide import QtCore, QtGui + +from leap.bitmask.config import flags +from leap.bitmask.gui import locale_rc # noqa - silence pylint +from leap.bitmask.gui.mainwindow import MainWindow +# from leap.bitmask.logs.utils import create_logger + +import logging +logger = logging.getLogger(__name__) + + +def sigint_handler(*args, **kwargs): + """ + Signal handler for SIGINT + """ + logger = kwargs.get('logger', None) + if logger: + logger.debug("SIGINT catched. shutting down...") + mainwindow = args[0] + mainwindow.quit() + + +def sigterm_handler(*args, **kwargs): + """ + Signal handler for SIGTERM. + This handler is actually passed to twisted reactor + """ + logger = kwargs.get('logger', None) + if logger: + logger.debug("SIGTERM catched. shutting down...") + mainwindow = args[0] + mainwindow.quit() + + +def run_frontend(options): + """ + Run the GUI for the application. + + :param options: a dict of options parsed from the command line. + :type options: dict + """ + bypass_checks = options["bypass_checks"] + start_hidden = options["start_hidden"] + + # We force the style if on KDE so that it doesn't load all the kde + # libs, which causes a compatibility issue in some systems. + # For more info, see issue #3194 + if flags.STANDALONE and os.environ.get("KDE_SESSION_UID") is not None: + sys.argv.append("-style") + sys.argv.append("Cleanlooks") + + qApp = QtGui.QApplication(sys.argv) + + # To test: + # $ LANG=es ./app.py + locale = QtCore.QLocale.system().name() + qtTranslator = QtCore.QTranslator() + if qtTranslator.load("qt_%s" % locale, ":/translations"): + qApp.installTranslator(qtTranslator) + appTranslator = QtCore.QTranslator() + if appTranslator.load("%s.qm" % locale[:2], ":/translations"): + qApp.installTranslator(appTranslator) + + # Needed for initializing qsettings it will write + # .config/leap/leap.conf top level app settings in a platform + # independent way + qApp.setOrganizationName("leap") + qApp.setApplicationName("leap") + qApp.setOrganizationDomain("leap.se") + + window = MainWindow(bypass_checks=bypass_checks, + start_hidden=start_hidden) + + sigint_window = partial(sigint_handler, window, logger=logger) + signal.signal(signal.SIGINT, sigint_window) + + sys.exit(qApp.exec_()) + + +if __name__ == '__main__': + run_frontend() diff --git a/src/leap/bitmask/gui/__init__.py b/src/leap/bitmask/gui/__init__.py index 94bf1fd5..bba02061 100644 --- a/src/leap/bitmask/gui/__init__.py +++ b/src/leap/bitmask/gui/__init__.py @@ -19,5 +19,6 @@ init file for leap.gui """ # This was added for coverage and testing, but when doing the osx # bundle with py2app it fails because of this, so commenting for now +# Also creates conflicts with the new frontend/backend separation. # app = __import__("app", globals(), locals(), [], 2) # __all__ = [app] -- cgit v1.2.3