Source code for mesycontrol.app_context

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# mesycontrol - Remote control for mesytec devices.
# Copyright (C) 2015-2016 mesytec GmbH & Co. KG <info@mesytec.com>
#
# 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 2
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

__author__ = 'Florian Lüke'
__email__  = 'f.lueke@mesytec.com'

from qt import QtCore
from qt import QtGui
import contextlib
import os

import app_model as am
import basic_model as bm
import config_model as cm
import config_xml
import device_registry
import future
import model_util
import util

[docs]class Context(QtCore.QObject): def __init__(self, main_file, auto_load_device_modules=True, parent=None): super(Context, self).__init__(parent) self.log = util.make_logging_source_adapter(__name__, self) self.main_file = main_file self.device_registry = device_registry.DeviceRegistry(auto_load_device_modules) hw_registry = bm.MRCRegistry() # Root of the hardware model tree setup = cm.Setup() # Root of the config model tree self.app_registry = am.MRCRegistry(hw_registry, setup) # Root of the app model tree self.director = am.Director(self.app_registry, self.device_registry) self._shutdown_callbacks = list()
[docs] def init_device_registry(self): self.device_registry.load_system_modules()
[docs] def shutdown(self): observer = future.FutureObserver() def do_disconnect(): futures = [mrc.disconnect() for mrc in self.app_registry.hw.get_mrcs()] observer.set_future(future.all_done(*futures)) util.wait_for_signal(signal=observer.done, emitting_callable=do_disconnect, timeout_ms=5000) for cb in self._shutdown_callbacks: try: cb() except Exception: self.log.exception("shutdown callback %s raised", cb)
[docs] def add_shutdown_callback(self, cb): self._shutdown_callbacks.append(cb)
[docs] def make_qsettings(self): return QtCore.QSettings("mesytec", "mesycontrol")
[docs] def open_setup(self, filename): setup = config_xml.read_setup(filename) for mrc in setup: for device in mrc: model_util.set_default_device_extensions(device, self.device_registry) setup.modified = False if not len(setup): raise RuntimeError("No MRC configurations found in %s" % filename) self.setup = setup self.set_setup_directory_hint(filename) return setup
[docs] def reset_setup(self): self.log.debug("reset_setup") self.app_registry.setup = cm.Setup()
[docs] def get_setup_directory_hint(self): s = self.make_qsettings() v = s.value('Files/last_setup_file', QtCore.QString()).toString() v = os.path.dirname(str(v)) if not len(v): v = QtGui.QDesktopServices.storageLocation( QtGui.QDesktopServices.DocumentsLocation) return v
[docs] def set_setup_directory_hint(self, filename): s = self.make_qsettings() s.setValue('Files/last_setup_file', filename)
[docs] def get_config_directory_hint(self): s = self.make_qsettings() v = s.value('Files/last_config_file', QtCore.QString()).toString() v = os.path.dirname(str(v)) if not len(v): v = QtGui.QDesktopServices.storageLocation( QtGui.QDesktopServices.DocumentsLocation) return v
[docs] def set_config_directory_hint(self, filename): s = self.make_qsettings() s.setValue('Files/last_config_file', filename)
setup = property( fget=lambda self: self.app_registry.get_config(), fset=lambda self, setup: self.app_registry.set_config(setup), doc="The contexts current setup object.")
[docs]@contextlib.contextmanager def make(*args, **kwargs): """Creates and yields a Context object. Makes sure shutdown() is called on the context after use. Usage: with app_context.make(...) as context: do_things_with(context) """ context = Context(*args, **kwargs) try: yield context finally: context.shutdown()
[docs]@contextlib.contextmanager def use(context): """Same as make() but takes a Context instance instead of creating one.""" try: yield context finally: context.shutdown()