Example #1
0
def test_functions():
    assert formatDuration(1) == '1 second'
    assert formatDuration(4) == '4 seconds'
    assert formatDuration(154, precise=False) == '3 min'
    assert formatDuration(154, precise=True) == '2 min, 34 sec'
    assert formatDuration(7199) == '2 h, 0 min'
    assert formatDuration(3700) == '1 h, 2 min'
    assert formatDuration(24 * 3600 + 7240, precise=False) == '1 day, 2 h'
    assert formatDuration(48 * 3600 - 1) == '2 days, 0 h'

    assert bitDescription(0x5, (0, 'a'), (1, 'b', 'c'),
                          (2, 'd', 'e')) == 'a, c, d'

    assert parseConnectionString('[email protected]:pass@host:1301', 1302) == \
        {'user': '******', 'password': '******', 'host': 'host',
         'port': 1301}
    assert parseConnectionString('user:@host', 1302) == \
        {'user': '******', 'password': '', 'host': 'host', 'port': 1302}
    assert parseConnectionString('user@host:1301', 1302) == \
        {'user': '******', 'password': None, 'host': 'host', 'port': 1301}
    assert parseConnectionString('user@ho-st:1301', 1302) == \
        {'user': '******', 'password': None, 'host': 'ho-st', 'port': 1301}
    assert parseConnectionString('', 1302) is None
    assert parseConnectionString('host?', 1302) is None

    # pylint: disable=range-builtin-not-iterating
    assert [tuple(x) for x in chunks(range(10), 3)] == \
        [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9,)]
Example #2
0
def adminclient(daemon):
    """Create a nicos admin client session and log in"""
    adminclient = TestClient()
    parsed = parseConnectionString('admin:admin@' + daemon_addr, 0)
    adminclient.connect(ConnectionData(**parsed))
    assert ('connected', None, None) in adminclient._signals

    # wait until initial setup is done
    adminclient.wait_idle()

    yield adminclient

    if adminclient.isconnected:
        adminclient._disconnecting = True
        adminclient.disconnect()
Example #3
0
def main(argv):
    server = user = via = command = ''
    password = None

    # to automatically close an SSH tunnel, we execute something on the remote
    # server that takes long enough for the client to connect to the daemon;
    # SSH then keeps the session open until the tunnel is unused, i.e. the
    # client has disconnected -- normally, "sleep" should be available as a
    # dummy remote command, but e.g. on erebos.frm2.tum.de it isn't, so we
    # allow configuring this (but only in the config file, not on the cmdline)
    viacommand = 'sleep 10'

    # a connection "profile" can be given by invoking this executable
    # under a different name (via symlink) ...
    configsection = 'connect'
    if not argv[0].endswith('nicos-client'):
        configsection = path.basename(argv[0])

    config = configparser.RawConfigParser()
    config.read([path.expanduser('~/.nicos-client')])

    # check for "command to run" switch
    if '-c' in argv:
        n = argv.index('-c')
        if len(argv) >= n:
            command = argv[n + 1]
        del argv[n:n + 2]

    # ... or by "profile" on the command line (other arguments are
    # interpreted as a connection data string)
    if argv[1:]:
        if config.has_section(argv[1]):
            configsection = argv[1]
        else:
            cd = parseConnectionString(argv[1], DEFAULT_PORT)
            server = '%s:%s' % (cd['host'], cd['port'])
            user = cd['user']
            password = cd['password']
        if argv[3:] and argv[2] == 'via':
            via = argv[3]

    # check for profile name as a config section (given by argv0 or on the
    # command line); if not present, fall back to default
    if not config.has_section(configsection):
        configsection = 'connect'

    # take all connection parameters from the config file if not defined
    # on the command line
    if not server and config.has_option(configsection, 'server'):
        server = config.get(configsection, 'server')
    if not user and config.has_option(configsection, 'user'):
        user = config.get(configsection, 'user')
    if not password and config.has_option(configsection, 'passwd'):
        password = config.get(configsection, 'passwd')
    if not via and config.has_option(configsection, 'via'):
        via = config.get(configsection, 'via')
    if config.has_option(configsection, 'viacommand'):
        viacommand = config.get(configsection, 'viacommand')

    # split server in host:port components
    try:
        host, port = server.split(':', 1)
        port = int(port)
    except ValueError:
        host = server
        port = DEFAULT_PORT

    # if SSH tunneling is requested, stop here and re-exec after tunnel is
    # set up and running
    if via:
        # use a random (hopefully free) high numbered port on our side
        nport = random.randint(10000, 20000)
        os.execvp('sh', [
            'sh', '-c',
            'ssh -f -L "%s:%s:%s" "%s" %s && %s "%s%s@localhost:%s"' %
            (nport, host, port, via, viacommand, argv[0], user,
             (':%s' % password if password is not None else ''), nport)
        ])

    # don't interrupt event thread's system calls
    signal.siginterrupt(signal.SIGINT, False)

    conndata = ConnectionData(host, port, user, password)
    client = NicosCmdClient(conndata)
    if command:
        return client.main_with_command(command)
    else:
        return client.main()
Example #4
0
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_()