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)
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)
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)