def curses_push(args):
    """
    """
    devices = get_device()
    if len(devices) == 0:
        print('No device is selected.')
        return

    logger.debug('%d devices selected' % len(devices))
    configlets = set()
    has_error = False

    if config.stdin:
        lines = sys.stdin.readlines()
        configlets.add(Configlet(config.STDIN_FNAME, lines))
    else:
        for arg in args:
            configlets.update(get_configlets(arg))

    # some error checking for configlets
    for configlet in configlets:
        # warn empty file
        if configlet.is_empty:
            print(configlet.name % 'WARNING: file %s is empty')
            continue
        # Configlet error checking:(1) check vendor tag and (2) unicode
        # check vendor tag
        if configlet.tags.get('vendor') is None:
            print('Configlet %s needs to have vendor tag' % configlet.name)
            has_error = True
        # check for unicode
        for line in configlet.lines:
            try:
                line.decode('ascii')
            except UnicodeDecodeError:
                print('configlets %s contains unicode at line\n-%s' %
                      (configlet.name, line))
                has_error = True

    if has_error:
        return

    if config.gen_md5:
        for configlet in configlets:
            print('%s %s' % (configlet.name, configlet.gen_md5))
        return

    work_to_do = False
    dry_run_needed = False

    for device in devices:

        device.configlets = []

        for configlet in configlets:
            if configlet.valid_for(device) and not configlet.is_empty:
                device.configlets.append(configlet)
                work_to_do = True
                if device.vendor in config.DRY_RUN_VENDORS:
                    dry_run_needed = True

    ndevice = 0
    # dict{device_name:diff}
    all_diffs = {}
    if work_to_do:
        for device in devices:
            if not device.configlets:
                continue

            ndevice += 1
            if device.vendor != 'juniper':
                if config.atomic:
                    print('atomic is only for juniper, but %s is %s'
                          % (device.name, device.vendor))
                    return

            if device.vendor not in config.DRY_RUN_VENDORS:
                if config.dry_run:
                    print('dry_run is not supported for %s (%s)'
                          % (device.name, device.vendor))
                    return

    try:
        PrintReminder().print_reminder(
                config.dry_run, ndevice, config.diff_dir)
    except Exception as ex:
        print('Cannot read reminder from configerator %s' % str(ex))

    if work_to_do:
        # create diff dir if not exist
        if config.diff_dir:
            try:
                os.makedirs(config.diff_dir)
            except:
                pass

        # force users must dry_run before real push
        if (dry_run_needed and
                not config.dry_run and
                not is_dry_run_prev(configlets) and
                not config.clowntown):
            PrintReminder.yellow(''.join([
                '\nYour previous "fbpush" is not dry_run for \n%s\n'
                % args, 'Or confilget(s) are modified? ',
                'Please dry_run and review the diff again.',
                ]))
            return

        if config.clowntown:
            PrintReminder.red(
                    'You by pass dry_run check, '
                    'I believe you have a legit reason')

        if config.stdin:
            # release previous piped program fd
            # otherwise curse lib will fail
            fd = open('/dev/tty')
            os.dup2(fd.fileno(), 0)

        if not config.username:
            config.username = getpass.getuser()
        while not config.password:
            config.password = getpass.getpass()
            if not config.password:
                print('Password cannot be empty!')

        connections = []
        try:
            stdscr = curses.initscr()
            screen = push.Screen(connections, stdscr)
            screen.fsm = FSM_PushCurses(init_state=FSM_PushCurses.ST_START)
            reactor.addReader(screen)

            start_time = int(time.time())

            # one single diff file
            if config.diff_dir and not config.multiple_diffs:
                diff_fh = open(os.path.join(
                               config.diff_dir,
                               config.FBPUSH_SINGLE_FILENAME), 'w', 0)
            for device in devices:
                if not device.configlets:
                    continue

                # multiple diff files
                if config.diff_dir and config.multiple_diffs:
                    diff_fh = open(os.path.join(
                        config.diff_dir, device.name + '.diff'), 'w', 0)

                if device.vendor == 'juniper':
                    jnx = push.JunoscriptRpc(
                        screen,
                        connections,
                        device,
                        config.username,
                        config.password,
                        start_time,
                        all_diffs,
                        diff_fh)
                    jnx.addConfiglets(device.configlets)
                    jnx.fsm = FSM_PushJnx(init_state=FSM_PushJnx.ST_START)

                    if config.diff_dir:
                        jnx.fsm.addDiffing(jnx)
                    else:  # bypass diffing
                        jnx.fsm.addCommits(jnx)

                    reactor.connectSSL(
                        # juniper is not connect thru fcr
                        # need to specify ip here
                        device.ip,
                        config.XNM_SSL_PORT,
                        jnx,
                        ssl.ClientContextFactory())
                    connections.append(jnx)

            logger.info('Launching reactor with %d connetions',
                        len(connections))
            reactor.run()
        finally:
            curses.nocbreak()
            stdscr.keypad(0)
            stdscr.standout()
            curses.echo()
            curses.endwin()

            # write md5 of all files (args) into a file,
            # to indicate user has dry_run
            if config.dry_run:
                update_dry_run_hash(configlets)

            for connection in connections:
                if not connection.diff_fh.closed:
                    connection.diff_fh.close()

            return all_diffs
    else:
        print('Nothing to do. No match between configlets and devices')
        config.parser.print_help()
dataset/ETHPy150Open facebook/fbpush/fbpush/main.py/curses_push/swapped operands of `%`