コード例 #1
0
ファイル: utils.py プロジェクト: umithardal/nicos
 def createRootLogger(self, prefix='nicos', console=True, logfile=True):
     self.log = NicosLogger('nicos')
     self.log.parent = None
     self.log.setLevel(DEBUG)
     self.testhandler = TestLogHandler()
     self.log.addHandler(self.testhandler)
     self._master_handler = None
コード例 #2
0
ファイル: cacheinspector.py プロジェクト: umithardal/nicos
 def createRootLogger(self, prefix='nicos', console=True, logfile=True):
     self.log = NicosLogger('nicos')
     self.log.setLevel(INFO)
     self.log.parent = None
     self.log.addHandler(ColoredConsoleHandler())
     self._qthandler = StatusBarHandler()
     self.log.addHandler(self._qthandler)
コード例 #3
0
ファイル: auxwindows.py プロジェクト: ess-dmsc/nicos
    def __init__(self, parent, wintype, config):
        from nicos.clients.gui.panels.utils import createWindowItem
        QMainWindow.__init__(self, parent)
        loadUi(self, 'auxwindow.ui')
        self.mainwindow = parent
        self.client = parent.client
        self.log = NicosLogger('AuxiliaryWindow')
        self.log.parent = self.mainwindow.log

        self.type = wintype
        self.panels = []
        self.splitters = []

        self.sgroup = SettingGroup(config.name)
        with self.sgroup as settings:
            loadUserStyle(self, settings)

        self.setWindowTitle(config.name)
        widget = createWindowItem(config.contents, self, self, self, self.log)
        if widget:
            self.centralLayout.addWidget(widget)
        self.centralLayout.setContentsMargins(6, 6, 6, 6)

        with self.sgroup as settings:
            loadBasicWindowSettings(self, settings)

        if len(self.splitstate) == len(self.splitters):
            for sp, st in zip(self.splitters, self.splitstate):
                sp.restoreState(st)

        setups = config[1].get('setups', '')
        self.setSetups(setups)
        self.client.register(self, 'session/mastersetup')

        SetupDepWindowMixin.__init__(self, self.client)
コード例 #4
0
    def __init__(self, parent, client, **configs):
        QDialog.__init__(self, parent)
        DlgUtils.__init__(self, self.toolName)
        loadUi(self, 'tools/downtime.ui')
        self.sendBtn = self.buttonBox.addButton('&Send',
                                                QDialogButtonBox.AcceptRole)
        self.sendBtn.setIcon(QIcon(':/mail'))
        self.sendBtn.setDisabled(True)

        self.parentwindow = parent
        self.client = client
        if hasattr(parent, 'mainwindow'):
            self.mainwindow = parent.mainwindow
            self.log = NicosLogger(self.toolName)
            self.log.parent = self.mainwindow.log
        else:
            self.log = configs.get('log', None)
        self.sgroup = SettingGroup(self.toolName)

        self._sender = configs.get('sender', '*****@*****.**')
        self._receiver = configs.get('receiver', '*****@*****.**')
        self._mailserver = configs.get('mailserver', '') or \
            self._getDeviceComponent('experiment', 'mailserver', 'smtp.frm2.tum.de')
        self._instrument = configs.get('instrument', '') or \
            self._getDeviceComponent('instrument', 'instrument', 'DEMO')
        t = self.mailheaderText.text().replace('{{instrument}}',
                                               self._instrument)
        self.mailheaderText.setText(t)

        self.startDown.setDateTime(QDateTime.currentDateTime().addSecs(-3600))
        self.endDown.setDateTime(QDateTime.currentDateTime())
        self.errorText.setVisible(False)
        with self.sgroup as settings:
            self.loadSettings(settings)
        self.reasons.clearEditText()
コード例 #5
0
ファイル: client.py プロジェクト: ess-dmsc/nicos
 def __init__(self, parent, parent_logger):
     QObject.__init__(self, parent)
     logger = NicosLogger('client')
     logger.parent = parent_logger
     NicosClient.__init__(self, logger.warning)
     self._reg_keys = {}
     self._event_mask = ['livedata']
     self.cache.connect(self.on_cache_event)
     self.connected.connect(self.on_connected_event)
コード例 #6
0
ファイル: auxwindows.py プロジェクト: ess-dmsc/nicos
    def __init__(self, item, window, menuwindow, parent):
        from nicos.clients.gui.panels.utils import createWindowItem
        QMainWindow.__init__(self, parent)
        self.user_color = window.user_color
        self.mainwindow = window.mainwindow
        self.log = NicosLogger('AuxiliarySubWindow')
        self.log.parent = self.mainwindow.log

        self.panels = []

        # we have to nest one step to get consistent layout spacing
        # around the central widget
        central = QWidget(self)
        layout = QVBoxLayout()
        # only keep margin at the top (below the tabs)
        layout.setContentsMargins(0, 6, 0, 0)
        if len(item) == 1:
            (subitem, setupSpec) = item + (None, )
        else:
            (subitem, setupSpec) = item
        it = createWindowItem(subitem, window, menuwindow, self, self.log)
        if it:
            if isinstance(it, (
                    Panel,
                    QSplitter,
            )):
                if isinstance(it, Panel):
                    it.hideTitle()
                # if tab has its own setups overwrite panels setups
                if setupSpec:
                    it.setSetups(setupSpec)
                it.setWidgetVisible.connect(parent.setWidgetVisibleSlot)
            layout.addWidget(it)
            central.setLayout(layout)
            self.setCentralWidget(central)
コード例 #7
0
 def __init__(self, item, window, menuwindow, topwindow, parent=None):
     from nicos.clients.gui.panels.utils import createWindowItem
     QSplitter.__init__(self, parent)
     window.splitters.append(self)
     self.log = NicosLogger('Splitter')
     self.log.parent = topwindow.log
     SetupDepPanelMixin.__init__(self, window.client, item.options)
     for subitem in item.children:
         sub = createWindowItem(subitem, window, menuwindow, topwindow,
                                self.log)
         if sub:
             self.addWidget(sub)
コード例 #8
0
 def __init__(self, item, window, menuwindow, topwindow, parent=None):
     from nicos.clients.gui.panels.utils import createWindowItem
     QWidget.__init__(self, parent)
     self.log = NicosLogger(self.logger_name)
     self.log.parent = topwindow.log
     layout = self.layout_type(parent)
     SetupDepPanelMixin.__init__(self, window.client, item.options)
     for subitem in item.children:
         sub = createWindowItem(subitem, window, menuwindow, topwindow,
                                self.log)
         if sub:
             layout.addWidget(sub)
     self.setLayout(layout)
コード例 #9
0
 def __init__(self, parent, client, options):
     QWidget.__init__(self, parent)
     self.log = NicosLogger(self.panelName)
     self.log.parent = parent.mainwindow.log
     SetupDepPanelMixin.__init__(self, client, options)
     DlgUtils.__init__(self, self.panelName)
     self.parentwindow = parent
     self.client = client
     self.mainwindow = parent.mainwindow
     self.actions = set()
     self.sgroup = SettingGroup(self.panelName)
     with self.sgroup as settings:
         self.loadSettings(settings)
     self.setProperty('type', 'Panel')
     self.setProperty('panel', self.__class__.__name__)
コード例 #10
0
ファイル: cacheinspector.py プロジェクト: umithardal/nicos
class CISession(SingleDeviceSession):
    """Session for the cache inspector: makes log messages appear in the
    status bar of the main window.
    """

    _qthandler = None

    def createRootLogger(self, prefix='nicos', console=True, logfile=True):
        self.log = NicosLogger('nicos')
        self.log.setLevel(INFO)
        self.log.parent = None
        self.log.addHandler(ColoredConsoleHandler())
        self._qthandler = StatusBarHandler()
        self.log.addHandler(self._qthandler)
コード例 #11
0
 def __init__(self, parent, client, panelcfg, title, **options):
     from nicos.clients.gui.panels.utils import createWindowItem
     QDialog.__init__(self, parent)
     self.panels = []
     self.mainwindow = parent.mainwindow
     self.log = NicosLogger('PanelDialog')
     self.log.parent = self.mainwindow.log
     self.client = client
     self.user_color = self.palette().color(QPalette.Base)
     self.user_font = self.font()
     if isinstance(panelcfg, type) and issubclass(panelcfg, Panel):
         panelcfg = panel('%s.%s' % (panelcfg.__module__,
                                     panelcfg.__name__), **options)
     elif isinstance(panelcfg, str):
         panelcfg = panel(panelcfg, **options)
     hbox = QHBoxLayout()
     hbox.setContentsMargins(0, 0, 0, 0)
     pnl = createWindowItem(panelcfg, self, self, self.mainwindow, self.log)
     if pnl:
         hbox.addWidget(pnl)
     self.setLayout(hbox)
     self.setWindowTitle(title)
     SetupDepWindowMixin.__init__(self, self.client)
     self.setProperty('type', 'PanelDialog')
コード例 #12
0
ファイル: auxwindows.py プロジェクト: ess-dmsc/nicos
class AuxiliaryWindow(SetupDepWindowMixin, QMainWindow):

    setupSpec = ''

    closed = pyqtSignal('QMainWindow')

    def __init__(self, parent, wintype, config):
        from nicos.clients.gui.panels.utils import createWindowItem
        QMainWindow.__init__(self, parent)
        loadUi(self, 'auxwindow.ui')
        self.mainwindow = parent
        self.client = parent.client
        self.log = NicosLogger('AuxiliaryWindow')
        self.log.parent = self.mainwindow.log

        self.type = wintype
        self.panels = []
        self.splitters = []

        self.sgroup = SettingGroup(config.name)
        with self.sgroup as settings:
            loadUserStyle(self, settings)

        self.setWindowTitle(config.name)
        widget = createWindowItem(config.contents, self, self, self, self.log)
        if widget:
            self.centralLayout.addWidget(widget)
        self.centralLayout.setContentsMargins(6, 6, 6, 6)

        with self.sgroup as settings:
            loadBasicWindowSettings(self, settings)

        if len(self.splitstate) == len(self.splitters):
            for sp, st in zip(self.splitters, self.splitstate):
                sp.restoreState(st)

        setups = config[1].get('setups', '')
        self.setSetups(setups)
        self.client.register(self, 'session/mastersetup')

        SetupDepWindowMixin.__init__(self, self.client)

    def addPanel(self, panel, always=True):
        if always or panel not in self.panels:
            self.panels.append(panel)

    def on_keyChange(self, key, value, time, expired):
        if key == 'session/mastersetup' and self.setupSpec:
            if not checkSetupSpec(self.setupSpec, value, log=self.log):
                self.close()

    def setSetups(self, setupSpec):
        self.setupSpec = setupSpec
        self.log.debug('setups are: %r', self.setupSpec)

    def getPanel(self, panelName):
        for panelobj in self.panels:
            if panelobj.panelName == panelName:
                return panelobj

    def saveWindowLayout(self):
        with self.sgroup as settings:
            settings.setValue('geometry', self.saveGeometry())
            settings.setValue('windowstate', self.saveState())
            settings.setValue('splitstate',
                              [sp.saveState() for sp in self.splitters])
            settings.setValue('font', self.user_font)
            settings.setValue('color', self.user_color)

    def closeEvent(self, event):
        for pnl in self.panels:
            if not pnl.requestClose():
                event.ignore()
                return
        if self.mainwindow.autosavelayout:
            self.saveWindowLayout()
        for pnl in self.panels:
            with pnl.sgroup as settings:
                pnl.saveSettings(settings)
        event.accept()
        self.closed.emit(self)
        del self.panels[:]  # this is necessary to get the Qt objects destroyed

    @pyqtSlot()
    def on_actionFont_triggered(self):
        font, ok = QFontDialog.getFont(self.user_font, self)
        if not ok:
            return
        for pnl in self.panels:
            pnl.setCustomStyle(font, self.user_color)
        self.user_font = font

    @pyqtSlot()
    def on_actionColor_triggered(self):
        color = QColorDialog.getColor(self.user_color, self)
        if not color.isValid():
            return
        for pnl in self.panels:
            pnl.setCustomStyle(self.user_font, color)
        self.user_color = color
コード例 #13
0
class DownTimeTool(DlgUtils, QDialog):
    toolName = 'DownTimeTool'

    def __init__(self, parent, client, **configs):
        QDialog.__init__(self, parent)
        DlgUtils.__init__(self, self.toolName)
        loadUi(self, 'tools/downtime.ui')
        self.sendBtn = self.buttonBox.addButton('&Send',
                                                QDialogButtonBox.AcceptRole)
        self.sendBtn.setIcon(QIcon(':/mail'))
        self.sendBtn.setDisabled(True)

        self.parentwindow = parent
        self.client = client
        if hasattr(parent, 'mainwindow'):
            self.mainwindow = parent.mainwindow
            self.log = NicosLogger(self.toolName)
            self.log.parent = self.mainwindow.log
        else:
            self.log = configs.get('log', None)
        self.sgroup = SettingGroup(self.toolName)

        self._sender = configs.get('sender', '*****@*****.**')
        self._receiver = configs.get('receiver', '*****@*****.**')
        self._mailserver = configs.get('mailserver', '') or \
            self._getDeviceComponent('experiment', 'mailserver', 'smtp.frm2.tum.de')
        self._instrument = configs.get('instrument', '') or \
            self._getDeviceComponent('instrument', 'instrument', 'DEMO')
        t = self.mailheaderText.text().replace('{{instrument}}',
                                               self._instrument)
        self.mailheaderText.setText(t)

        self.startDown.setDateTime(QDateTime.currentDateTime().addSecs(-3600))
        self.endDown.setDateTime(QDateTime.currentDateTime())
        self.errorText.setVisible(False)
        with self.sgroup as settings:
            self.loadSettings(settings)
        self.reasons.clearEditText()

    def loadSettings(self, settings):
        try:
            reasons = settings.value('reasons')
        except TypeError:
            reasons = []
        if reasons:
            self.reasons.addItems(reasons)

    def closeEvent(self, event):
        self.deleteLater()
        self.accept()

    def on_buttonBox_accepted(self):
        self._saveSettings()
        self._sendMail()
        self.accept()

    def on_buttonBox_rejected(self):
        self.reject()
        self.close()

    def on_reasons_editTextChanged(self, text):
        self._enableSend()

    def on_startDown_dateTimeChanged(self, date):
        self._enableSend()

    def on_endDown_dateTimeChanged(self, date):
        self._enableSend()

    def _enableSend(self):
        timeCorrect = self.startDown.dateTime() < self.endDown.dateTime()
        self.sendBtn.setDisabled(not timeCorrect or
                                 not self.reasons.currentText().strip())
        self.errorText.setVisible(not timeCorrect)

    def _getDeviceComponent(self, devname, param, default=''):
        try:
            val = self.client.eval('session.%s.%s' % (devname, param), default)
        except (AttributeError, NameError):
            val = default
        return val

    def _getMailAdresses(self, val):
        ret = []
        for i in val.split(','):
            t = i.strip().partition('<')[-1].rpartition('>')[0]
            ret += [t] if t else [i.strip()]
        return ret

    def _saveSettings(self):
        items = [self.reasons.currentText()] + \
                [self.reasons.itemText(i).strip() for i in
                 range(self.reasons.count())]
        with self.sgroup as settings:
            settings.setValue('reasons', list(collections.Counter(items)))

    def _sendMail(self):
        responsibles = self._getMailAdresses(
            self._getDeviceComponent('instrument', 'responsible'))
        sender = self._sender or self._getDeviceComponent('experiment',
                                                          'mailsender',
                                                          responsibles[0])
        receivers = self._getMailAdresses(self._receiver)
        if responsibles and responsibles[0]:
            receivers += responsibles
        topic = self.mailheaderText.text()
        body = 'The instrument %s had a downtime from %s to %s due to:\n\n%s' %\
               (self._instrument, self.startDown.text(), self.endDown.text(),
                self.reasons.currentText())
        err = sendMail(self._mailserver, receivers, sender, topic, body)
        if err:
            if self.log:
                self.log.error(' - '.join(err))
            self.showError('\n'.join(err))
コード例 #14
0
ファイル: utils.py プロジェクト: umithardal/nicos
class TestSession(Session):
    autocreate_devices = False
    cache_class = TestCacheClient

    def __init__(self, appname, daemonized=False):
        old_setup_info = getattr(self, '_setup_info', {})
        Session.__init__(self, appname, daemonized)
        self._setup_info = old_setup_info
        self._setup_paths = (path.join(module_root, 'test', 'setups'), )
        self._user_level = system_user.level

    def readSetupInfo(self):
        # since we know the setups don't change, only read them once
        if not self._setup_info:
            return Session.readSetupInfo(self)
        return self._setup_info

    def createRootLogger(self, prefix='nicos', console=True, logfile=True):
        self.log = NicosLogger('nicos')
        self.log.parent = None
        self.log.setLevel(DEBUG)
        self.testhandler = TestLogHandler()
        self.log.addHandler(self.testhandler)
        self._master_handler = None

    def runsource(self, source, filename='<input>', symbol='single'):
        code = self.commandHandler(source,
                                   lambda src: compile(src, filename, symbol))
        if code is None:
            return
        exec_(code, self.namespace)

    def delay(self, _secs):
        # TODO: this sleep shouldn't be necessary
        sleep(0.0001)

    def _string_to_level(self, level):
        if isinstance(level, string_types):
            for k, v in ACCESS_LEVELS.items():
                if v == level:
                    return k
            raise ValueError('invalid access level name: %r' % level)
        return level

    @contextlib.contextmanager
    def withUserLevel(self, level):
        old_level = self._user_level
        self._user_level = self._string_to_level(level)
        yield
        self._user_level = old_level

    def checkAccess(self, required):
        if 'level' in required:
            rlevel = self._string_to_level(required['level'])
            if rlevel > self._user_level:
                raise AccessError('%s access is not sufficient, %s access '
                                  'is required' %
                                  (ACCESS_LEVELS.get(self._user_level,
                                                     str(self._user_level)),
                                   ACCESS_LEVELS.get(rlevel, str(rlevel))))
        return Session.checkAccess(self, required)
コード例 #15
0
ファイル: main.py プロジェクト: ess-dmsc/nicos
def main(argv):
    global log  # pylint: disable=global-statement

    userpath = path.join(path.expanduser('~'), '.config', 'nicos')

    # Set up logging for the GUI instance.
    initLoggers()
    log = NicosLogger('gui')
    log.parent = None
    log.setLevel(logging.INFO)
    log.addHandler(ColoredConsoleHandler())
    log.addHandler(
        NicosLogfileHandler(path.join(userpath, 'log'),
                            'gui',
                            use_subdir=False))

    # set up logging for unhandled exceptions in Qt callbacks
    def log_unhandled(*exc_info):
        traceback.print_exception(*exc_info)
        log.exception('unhandled exception in QT callback', exc_info=exc_info)

    sys.excepthook = log_unhandled

    app = QApplication(argv, organizationName='nicos', applicationName='gui')

    opts = parseargs()

    if opts.configfile is None:
        try:
            config.apply()
        except RuntimeError:
            pass
        # If "demo" is detected automatically, let the user choose their
        # instrument configuration.
        need_dialog = config.instrument is None or \
                      (config.setup_package == 'nicos_demo' and
                       config.instrument == 'demo' and
                       'INSTRUMENT' not in os.environ)
        if need_dialog:
            opts.configfile = InstrSelectDialog.select(
                'Your instrument could not be automatically detected.')
            if opts.configfile is None:
                return
        else:
            opts.configfile = path.join(config.setup_package_path,
                                        config.instrument, 'guiconfig.py')

    with open(opts.configfile, 'rb') as fp:
        configcode = fp.read()
    gui_conf = processGuiConfig(configcode)
    gui_conf.stylefile = ''

    if gui_conf.options.get('facility') in ['ess', 'sinq']:
        gui_conf.stylefile = f"{config.nicos_root}" \
                             f"/nicos/clients/flowui/guiconfig.qss"

    stylefiles = [
        path.join(userpath, 'style-%s.qss' % sys.platform),
        path.join(userpath, 'style.qss'),
        path.splitext(opts.configfile)[0] + '-%s.qss' % sys.platform,
        path.splitext(opts.configfile)[0] + '.qss',
    ]

    for stylefile in [gui_conf.stylefile] or stylefiles:
        if path.isfile(stylefile):
            try:
                with open(stylefile, 'r', encoding='utf-8') as fd:
                    app.setStyleSheet(fd.read())
                gui_conf.stylefile = stylefile
                break
            except Exception:
                log.warning('Error setting user style sheet from %s',
                            stylefile,
                            exc=1)

    mainwindow_cls = _mainwindow_cls.get(
        gui_conf.options.get('facility', 'default'))
    mainwindow = mainwindow_cls(log, gui_conf, opts.viewonly, opts.tunnel)
    log.addHandler(DebugHandler(mainwindow))

    if opts.connect:
        parsed = parseConnectionString(opts.connect, DEFAULT_PORT)
        if parsed:
            cdata = ConnectionData(**parsed)
            cdata.viewonly = opts.viewonly
            mainwindow.setConnData(cdata)
            if cdata.password is not None:
                # we have a password, connect right away
                mainwindow.client.connect(mainwindow.conndata)
            else:
                # we need to ask for password, override last preset (uses given
                # connection data) and force showing connect window
                mainwindow.lastpreset = ''
                mainwindow.autoconnect = True
    mainwindow.startup()

    return app.exec_()