slight refactoring
This commit is contained in:
parent
9866e178d8
commit
98e96c2157
6 changed files with 93 additions and 72 deletions
5
src/client/mod.rs
Normal file
5
src/client/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
|
||||||
|
pub mod raw_term;
|
||||||
|
pub mod recorder;
|
||||||
|
mod terminal;
|
73
src/client/recorder.rs
Normal file
73
src/client/recorder.rs
Normal file
|
@ -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(())
|
||||||
|
}
|
|
@ -1,5 +1,3 @@
|
||||||
//! Setting up a recorder
|
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::io::stdin;
|
use std::io::stdin;
|
||||||
|
@ -12,18 +10,15 @@ use anyhow::{Context, Result};
|
||||||
use libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
|
use libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
|
||||||
use nix::fcntl::{open, OFlag};
|
use nix::fcntl::{open, OFlag};
|
||||||
use nix::pty::openpty;
|
use nix::pty::openpty;
|
||||||
|
use nix::sys::select::{select, FdSet};
|
||||||
use nix::sys::{
|
use nix::sys::stat::Mode;
|
||||||
select::{select, FdSet},
|
|
||||||
stat::Mode,
|
|
||||||
};
|
|
||||||
use nix::unistd::{
|
use nix::unistd::{
|
||||||
close, dup, dup2, execvpe, fork, fsync, read, setsid, ttyname, write,
|
close, dup, dup2, execvpe, fork, fsync, read, setsid, ttyname, write,
|
||||||
ForkResult,
|
ForkResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::asciicast::{Event, EventKind};
|
use crate::asciicast::{Event, EventKind};
|
||||||
use crate::raw_term::RawTerm;
|
use crate::client::raw_term::RawTerm;
|
||||||
|
|
||||||
pub struct Terminal {
|
pub struct Terminal {
|
||||||
event_tx: Sender<Event>,
|
event_tx: Sender<Event>,
|
|
@ -1,13 +1,11 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate anyhow;
|
extern crate anyhow;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
extern crate clap;
|
||||||
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate tracing;
|
extern crate tracing;
|
||||||
|
|
||||||
pub mod asciicast;
|
pub mod asciicast;
|
||||||
mod raw_term;
|
pub mod client;
|
||||||
pub mod recorder;
|
|
||||||
// pub mod recorder;
|
|
||||||
// pub mod term;
|
|
||||||
// pub mod writer;
|
|
||||||
|
|
68
src/main.rs
68
src/main.rs
|
@ -1,13 +1,9 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate tracing;
|
extern crate tracing;
|
||||||
|
|
||||||
use std::process::Command;
|
|
||||||
use std::thread;
|
|
||||||
use std::{fs::File, io::Write};
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::{ArgAction, Parser};
|
use clap::{ArgAction, Parser};
|
||||||
use liveterm::{asciicast::Header, recorder::Terminal};
|
use liveterm::client::recorder::{record, RecordOpts};
|
||||||
use tracing::Level;
|
use tracing::Level;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
|
@ -23,59 +19,11 @@ struct Opt {
|
||||||
enum Subcommand {
|
enum Subcommand {
|
||||||
/// Record terminal session.
|
/// Record terminal session.
|
||||||
#[structopt(name = "rec")]
|
#[structopt(name = "rec")]
|
||||||
Record,
|
Record(RecordOpts),
|
||||||
}
|
|
||||||
|
|
||||||
fn record() -> Result<()> {
|
/// Run the server.
|
||||||
let mut file = File::create("output.cast")?;
|
#[structopt(name = "server")]
|
||||||
|
Server,
|
||||||
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(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
|
@ -83,9 +31,11 @@ fn main() -> Result<()> {
|
||||||
setup_logging(&opt)?;
|
setup_logging(&opt)?;
|
||||||
|
|
||||||
match opt.subcommand {
|
match opt.subcommand {
|
||||||
Subcommand::Record => {
|
Subcommand::Record(opts) => {
|
||||||
record()?;
|
record(opts)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Subcommand::Server => {}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue