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 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)
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 __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 __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)
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)
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)
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)
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__)
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)
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')
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
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))
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)
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_()