diff --git a/src/client/mod.rs b/src/client/mod.rs new file mode 100644 index 0000000..11e0266 --- /dev/null +++ b/src/client/mod.rs @@ -0,0 +1,5 @@ + + +pub mod raw_term; +pub mod recorder; +mod terminal; diff --git a/src/raw_term.rs b/src/client/raw_term.rs similarity index 100% rename from src/raw_term.rs rename to src/client/raw_term.rs diff --git a/src/client/recorder.rs b/src/client/recorder.rs new file mode 100644 index 0000000..7e2ca9c --- /dev/null +++ b/src/client/recorder.rs @@ -0,0 +1,73 @@ +//! Setting up a recorder + +use std::fs::File; +use std::io::Write; + +use std::path::PathBuf; +use std::process::Command; + +use std::thread; + +use anyhow::Result; + +use crate::asciicast::Header; + +use super::terminal::Terminal; + +#[derive(Debug, Parser)] +pub struct RecordOpts { + #[clap(long = "output", default_value = "output.cast")] + output_file: PathBuf, +} + +pub fn record(opts: RecordOpts) -> Result<()> { + let mut file = File::create(&opts.output_file)?; + + let mut command = Command::new("zsh"); + command.env("TERM", "xterm-256color"); + + // Write header + // TODO: Clean this up + let header = { + let command_str = format!("{:?}", command); + let env = command + .get_envs() + .into_iter() + .filter_map(|(a, b)| b.map(|b| (a, b))) + .map(|(a, b)| { + ( + a.to_string_lossy().to_string(), + b.to_string_lossy().to_string(), + ) + }) + .collect(); + Header { + version: 2, + width: 30, + height: 30, + + timestamp: None, + duration: None, + idle_time_limit: None, + command: Some(command_str), + title: None, + env: Some(env), + theme: None, + } + }; + + serde_json::to_writer(&file, &header)?; + file.write(b"\n")?; + + let (pty, rx) = Terminal::setup(command)?; + thread::spawn(move || { + for event in rx.into_iter() { + serde_json::to_writer(&file, &event); + file.write(b"\n"); + } + }); + + pty.wait_until_complete()?; + + Ok(()) +} diff --git a/src/recorder.rs b/src/client/terminal.rs similarity index 98% rename from src/recorder.rs rename to src/client/terminal.rs index 6974cf5..98d36df 100644 --- a/src/recorder.rs +++ b/src/client/terminal.rs @@ -1,5 +1,3 @@ -//! Setting up a recorder - use std::env; use std::ffi::CString; use std::io::stdin; @@ -12,18 +10,15 @@ use anyhow::{Context, Result}; use libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; use nix::fcntl::{open, OFlag}; use nix::pty::openpty; - -use nix::sys::{ - select::{select, FdSet}, - stat::Mode, -}; +use nix::sys::select::{select, FdSet}; +use nix::sys::stat::Mode; use nix::unistd::{ close, dup, dup2, execvpe, fork, fsync, read, setsid, ttyname, write, ForkResult, }; use crate::asciicast::{Event, EventKind}; -use crate::raw_term::RawTerm; +use crate::client::raw_term::RawTerm; pub struct Terminal { event_tx: Sender, diff --git a/src/lib.rs b/src/lib.rs index 1f1e247..c0a9508 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,13 +1,11 @@ #[macro_use] extern crate anyhow; #[macro_use] +extern crate clap; +#[macro_use] extern crate serde_derive; #[macro_use] extern crate tracing; pub mod asciicast; -mod raw_term; -pub mod recorder; -// pub mod recorder; -// pub mod term; -// pub mod writer; +pub mod client; diff --git a/src/main.rs b/src/main.rs index 750d48d..6965ad6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,9 @@ #[macro_use] extern crate tracing; -use std::process::Command; -use std::thread; -use std::{fs::File, io::Write}; - use anyhow::Result; use clap::{ArgAction, Parser}; -use liveterm::{asciicast::Header, recorder::Terminal}; +use liveterm::client::recorder::{record, RecordOpts}; use tracing::Level; #[derive(Parser)] @@ -23,59 +19,11 @@ struct Opt { enum Subcommand { /// Record terminal session. #[structopt(name = "rec")] - Record, -} + Record(RecordOpts), -fn record() -> Result<()> { - let mut file = File::create("output.cast")?; - - let mut command = Command::new("zsh"); - command.env("TERM", "xterm-256color"); - - // Write header - // TODO: Clean this up - let header = { - let command_str = format!("{:?}", command); - let env = command - .get_envs() - .into_iter() - .filter_map(|(a, b)| b.map(|b| (a, b))) - .map(|(a, b)| { - ( - a.to_string_lossy().to_string(), - b.to_string_lossy().to_string(), - ) - }) - .collect(); - Header { - version: 2, - width: 30, - height: 30, - - timestamp: None, - duration: None, - idle_time_limit: None, - command: Some(command_str), - title: None, - env: Some(env), - theme: None, - } - }; - - serde_json::to_writer(&file, &header)?; - file.write(b"\n")?; - - let (pty, rx) = Terminal::setup(command)?; - thread::spawn(move || { - for event in rx.into_iter() { - serde_json::to_writer(&file, &event); - file.write(b"\n"); - } - }); - - pty.wait_until_complete()?; - - Ok(()) + /// Run the server. + #[structopt(name = "server")] + Server, } fn main() -> Result<()> { @@ -83,9 +31,11 @@ fn main() -> Result<()> { setup_logging(&opt)?; match opt.subcommand { - Subcommand::Record => { - record()?; + Subcommand::Record(opts) => { + record(opts)?; } + + Subcommand::Server => {} } Ok(()) }