Ejemplo n.º 1
0
def main(argv, env=None):
    if env is None:
        env = os.environ

    # Some default values for our options are taken from the environment.
    # This allows the player to spawn copies of itself without having to
    # pass command-line options, which can be awkward or impossible depending
    # on the terminal program in use.
    argv = list(argv)
    if len(argv) == 1 and "PIAS_OPT_COMMAND" in env:
        argv.append(env["PIAS_OPT_COMMAND"])

    default_datafile = env.get("PIAS_OPT_DATAFILE")

    parser = argparse.ArgumentParser()
    parser.add_argument("--join", action="store_true",
                        help="join an existing record/replay session",
                        default=env.get("PIAS_OPT_JOIN", False))
    subparsers = parser.add_subparsers(dest="subcommand", title="subcommands")

    # The "record" command.
    parser_record = subparsers.add_parser("record")
    parser_record.add_argument("datafile",
                               nargs="?" if default_datafile else 1,
                               default=[default_datafile])
    parser_record.add_argument("--shell",
                               help="the shell to execute",
                               default=util.get_default_shell())
    datafile_opts = parser_record.add_mutually_exclusive_group()
    datafile_opts.add_argument("--append", action="store_true",
                               help="append to an existing session file",
                               default=False)
    datafile_opts.add_argument("-f", "--overwrite", action="store_true",
                               help="overwrite an existing session file",
                               default=False)

    # The "play" command.
    parser_play = subparsers.add_parser("play")
    parser_play.add_argument("datafile",
                             nargs="?" if default_datafile else 1,
                             default=[default_datafile])
    parser_play.add_argument("--terminal",
                             help="the terminal program to execute",
                             default=util.get_default_terminal())
    parser_play.add_argument("--auto-type", type=int, nargs="?", const=100,
                             help="automatically type at this speed in ms",
                             default=False)
    parser_play.add_argument("--auto-waypoint", type=int, nargs="?", const=600,
                             help="auto type newlines at this speed in ms",
                             default=False)

    # The "replay" alias for the "play" command.
    # Python2.7 argparse doesn't seem to have proper support for aliases.
    subparsers.add_parser("replay", parents=(parser_play,),
                          conflict_handler="resolve")

    # Parse the arguments and do some addition sanity-checking.

    args = parser.parse_args(argv[1:])

    args.datafile = args.datafile[0]
    sock_path = args.datafile + ".pias-session.sock"

    def err(msg, *args):
        if args:
            msg = msg % args
        print>>sys.stderr, msg

    if os.path.exists(sock_path) and not args.join:
        err("Error: a recording session is already in progress.")
        err("You can:")
        err(" * use --join to join the session as a new terminal.")
        err(" * remove the file %r to clean up a dead session.", sock_path)
        return 1

    if not os.path.exists(sock_path) and args.join:
        err("Error: no recording session is currently in progress.")
        err("Execute without --join to begin a new session.")
        return 1

    if args.subcommand == "record" and os.path.exists(args.datafile):
        if not args.join and not args.append and not args.overwrite:
            err("Error: the recording data file already exists.")
            err("You can:")
            err(" * use --append to add data to an existing recording.")
            err(" * use --overwrite to overwrite an existing recording.")
            err(" * manually remove the file %r.", args.datafile)
            return 1

    if args.subcommand == "record" and not os.path.exists(args.datafile):
        if not args.join and args.append:
            err("Error: the recording data file does not exist.")
            err("Execute without --append to begin a new recording.")
            return 1

    # Now we can dispatch to the appropriate command.

    recorder = player = eventlog = None

    try:
        if args.subcommand == "record":
            if not args.join:
                eventlog = EventLog(args.datafile, "a" if args.append else "w")
                recorder = Recorder(sock_path, eventlog, args.shell)
                recorder.start()
            join_recorder(sock_path)

        elif args.subcommand in ("play", "replay"):
            if not args.join:
                eventlog = EventLog(args.datafile, "r")
                player = Player(sock_path, eventlog, args.terminal,
                                args.auto_type, args.auto_waypoint)
                player.start()
            join_player(sock_path)

        else:
            raise RuntimeError("Unknown command %r" % (args.subcommand,))

    finally:
        if eventlog is not None:
            eventlog.close()
        if recorder is not None:
            recorder.wait()
        if player is not None:
            player.wait()
        if os.path.exists(sock_path) and not args.join:
            os.unlink(sock_path)
Ejemplo n.º 2
0
def main(argv, env=None):
    if env is None:
        env = os.environ

    argv = list(argv)
    if len(argv) == 1 and "PIAS_OPT_COMMAND" in env:
        argv.append(env["PIAS_OPT_COMMAND"])

    default_datafile = env.get("PIAS_OPT_DATAFILE")

    parser = argparse.ArgumentParser()
    parser.add_argument("--join", action="store_true",
                        help="join an existing record/replay session",
                        default=env.get("PIAS_OPT_JOIN", False))
    subparsers = parser.add_subparsers(dest="subcommand", title="subcommands")

    # The "record" command.
    parser_record = subparsers.add_parser("record")
    parser_record.add_argument("datafile",
                               nargs="?" if default_datafile else 1,
                               default=[default_datafile])
    parser_record.add_argument("--shell",
                               help="the shell to execute",
                               default=util.get_default_shell())

    # The "replay" command.
    parser_replay = subparsers.add_parser("replay")
    parser_replay.add_argument("datafile",
                               nargs="?" if default_datafile else 1,
                               default=[default_datafile])
    parser_replay.add_argument("--terminal",
                               help="the terminal program to execute",
                               default=util.get_default_terminal())

    args = parser.parse_args(argv[1:])

    args.datafile = args.datafile[0]
    sock_path = args.datafile + ".sock"
    if os.path.exists(sock_path) and not args.join:
        raise RuntimeError("session already in progress")

    recorder = player = eventlog = None

    try:
        if args.subcommand == "record":
            if not args.join:
                eventlog = EventLog(args.datafile, "w")
                recorder = Recorder(sock_path, eventlog, args.shell)
                recorder.start()
            join_recorder(sock_path)

        elif args.subcommand == "replay":
            if not args.join:
                eventlog = EventLog(args.datafile, "r")
                player = Player(sock_path, eventlog, args.terminal)
                player.start()
            join_player(sock_path)

    finally:
        if eventlog is not None:
            eventlog.close()
        if recorder is not None:
            recorder.wait()
        if player is not None:
            player.wait()
        if os.path.exists(sock_path) and not args.join:
            os.unlink(sock_path)
Ejemplo n.º 3
0
def main(argv, env=None):
    if env is None:
        env = os.environ

    # Some default values for our options are taken from the environment.
    # This allows the player to spawn copies of itself without having to
    # pass command-line options, which can be awkward or impossible depending
    # on the terminal program in use.
    argv = list(argv)
    if len(argv) == 1 and "PIAS_OPT_COMMAND" in env:
        argv.append(env["PIAS_OPT_COMMAND"])

    default_datafile = env.get("PIAS_OPT_DATAFILE")

    parser = argparse.ArgumentParser()
    parser.add_argument("--join",
                        action="store_true",
                        help="join an existing record/replay session",
                        default=env.get("PIAS_OPT_JOIN", False))
    parser.add_argument(
        "--shell",
        help="the shell to execute when recording or live-replaying",
        default=util.get_default_shell(fallback=None))
    subparsers = parser.add_subparsers(dest="subcommand", title="subcommands")

    # The "record" command.
    parser_record = subparsers.add_parser("record")
    parser_record.add_argument("datafile",
                               nargs="?" if default_datafile else 1,
                               default=[default_datafile])
    datafile_opts = parser_record.add_mutually_exclusive_group()
    datafile_opts.add_argument("--append",
                               action="store_true",
                               help="append to an existing session file",
                               default=False)
    datafile_opts.add_argument("-f",
                               "--overwrite",
                               action="store_true",
                               help="overwrite an existing session file",
                               default=False)

    # The "play" command.
    parser_play = subparsers.add_parser("play")
    parser_play.add_argument("datafile",
                             nargs="?" if default_datafile else 1,
                             default=[default_datafile])
    parser_play.add_argument("--terminal",
                             help="the terminal program to execute",
                             default=util.get_default_terminal(fallback=None))
    parser_play.add_argument("--auto-type",
                             type=int,
                             nargs="?",
                             const=100,
                             help="automatically type at this speed in ms",
                             default=False)
    parser_play.add_argument("--auto-waypoint",
                             type=int,
                             nargs="?",
                             const=600,
                             help="auto type newlines at this speed in ms",
                             default=False)
    parser_play.add_argument(
        "--live-replay",
        action="store_true",
        help=
        "recorded input is passed to a live session, and recorded output is ignored",
        default=False)

    # The "replay" alias for the "play" command.
    # Python2.7 argparse doesn't seem to have proper support for aliases.
    subparsers.add_parser("replay",
                          parents=(parser_play, ),
                          conflict_handler="resolve")

    # Parse the arguments and do some addition sanity-checking.
    args = parser.parse_args(argv[1:])
    if not args.subcommand:
        parser.error("too few arguments")

    args.datafile = args.datafile[0]
    sock_path = args.datafile + ".pias-session.sock"

    def err(msg, *args):
        if args:
            msg = msg % args
        sys.stderr.write(msg + '\n')

    if os.path.exists(sock_path) and not args.join:
        err("Error: a recording session is already in progress.")
        err("You can:")
        err(" * use --join to join the session as a new terminal.")
        err(" * remove the file %r to clean up a dead session.", sock_path)
        return 1

    if not os.path.exists(sock_path) and args.join:
        err("Error: no recording session is currently in progress.")
        err("Execute without --join to begin a new session.")
        return 1

    if args.subcommand == "record" and os.path.exists(args.datafile):
        if not args.join and not args.append and not args.overwrite:
            err("Error: the recording data file already exists.")
            err("You can:")
            err(" * use --append to add data to an existing recording.")
            err(" * use --overwrite to overwrite an existing recording.")
            err(" * manually remove the file %r.", args.datafile)
            return 1

    if args.subcommand == "record" and not os.path.exists(args.datafile):
        if not args.join and args.append:
            err("Error: the recording data file does not exist.")
            err("Execute without --append to begin a new recording.")
            return 1

    # Now we can dispatch to the appropriate command.

    recorder = player = eventlog = None

    try:
        if args.subcommand == "record":
            if not args.join:
                eventlog = EventLog(args.datafile, "a" if args.append else "w",
                                    args.shell)
                recorder = Recorder(sock_path, eventlog, args.shell)
                recorder.start()
            join_recorder(sock_path)

        elif args.subcommand in ("play", "replay"):
            if not args.join:
                eventlog = EventLog(args.datafile,
                                    "r",
                                    args.shell,
                                    live_replay=args.live_replay)
                shell = args.shell or eventlog.shell
                player = Player(sock_path, eventlog, args.terminal,
                                args.auto_type, args.auto_waypoint,
                                args.live_replay, args.shell)
                player.start()
            join_player(sock_path)

        else:
            raise RuntimeError("Unknown command %r" % (args.subcommand, ))

    finally:
        if eventlog is not None:
            eventlog.close()
        if recorder is not None:
            recorder.wait()
        if player is not None:
            player.wait()
        if os.path.exists(sock_path) and not args.join:
            os.unlink(sock_path)