use clap::{CommandFactory, Parser, Subcommand};
use zoom_cli::config::Config;
use zoom_cli::output::{OutputConfig, exit_codes};
use zoom_cli::{api, commands};
#[derive(Parser)]
#[command(
name = "zoom",
version,
about = "CLI for the Zoom API",
arg_required_else_help = true
)]
struct Cli {
#[arg(long, env = "ZOOM_PROFILE", global = true)]
profile: Option<String>,
#[arg(long, global = true)]
json: bool,
#[arg(long, global = true)]
quiet: bool,
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand)]
enum Command {
#[command(subcommand, arg_required_else_help = true)]
Meetings(MeetingsCommand),
#[command(subcommand, arg_required_else_help = true)]
Recordings(RecordingsCommand),
#[command(subcommand, arg_required_else_help = true)]
Users(UsersCommand),
#[command(subcommand, arg_required_else_help = true)]
Reports(ReportsCommand),
Init {
#[arg(long)]
profile: Option<String>,
},
Schema {
resource: String,
},
Completions {
shell: clap_complete::Shell,
},
}
#[derive(Subcommand)]
enum MeetingsCommand {
List {
#[arg(long, default_value = "me")]
user: String,
#[arg(long)]
r#type: Option<String>,
},
Get { id: u64 },
Create {
#[arg(long)]
topic: String,
#[arg(long)]
duration: Option<u32>,
#[arg(long)]
start: Option<String>,
#[arg(long)]
password: Option<String>,
},
Update {
id: u64,
#[arg(long)]
topic: Option<String>,
#[arg(long)]
duration: Option<u32>,
#[arg(long)]
start: Option<String>,
},
Delete { id: u64 },
End { id: u64 },
Participants {
meeting_id: String,
},
}
#[derive(Subcommand)]
enum RecordingsCommand {
List {
#[arg(long, default_value = "me")]
user: String,
#[arg(long)]
from: Option<String>,
#[arg(long)]
to: Option<String>,
},
Get {
meeting_id: String,
},
Download {
meeting_id: String,
#[arg(long, default_value = ".")]
out: String,
},
Start {
meeting_id: u64,
},
Stop {
meeting_id: u64,
},
Pause {
meeting_id: u64,
},
Resume {
meeting_id: u64,
},
}
#[derive(Subcommand)]
enum UsersCommand {
List {
#[arg(long)]
status: Option<String>,
},
Get { id_or_email: String },
Me,
}
#[derive(Subcommand)]
enum ReportsCommand {
Meetings {
#[arg(long, default_value = "me")]
user: String,
#[arg(long)]
from: String,
#[arg(long)]
to: Option<String>,
},
}
#[tokio::main]
async fn main() {
let cli = Cli::parse();
let out = OutputConfig::new(cli.json, cli.quiet);
match &cli.command {
Command::Init { profile } => {
if let Err(e) = commands::init::init(profile.clone()).await {
eprintln!("{e}");
std::process::exit(exit_codes::for_error(&e));
}
return;
}
Command::Schema { resource } => {
commands::schema(resource, &out);
return;
}
Command::Completions { shell } => {
clap_complete::generate(*shell, &mut Cli::command(), "zoom", &mut std::io::stdout());
return;
}
_ => {}
}
let cfg = match Config::load(cli.profile) {
Ok(c) => c,
Err(e) => {
eprintln!("{e}");
std::process::exit(exit_codes::CONFIG_ERROR);
}
};
let mut client = api::ZoomClient::new(cfg.account_id, cfg.client_id, cfg.client_secret);
let result = match cli.command {
Command::Meetings(cmd) => match cmd {
MeetingsCommand::List { user, r#type } => {
commands::meetings::list(&mut client, &out, &user, r#type.as_deref()).await
}
MeetingsCommand::Get { id } => commands::meetings::get(&mut client, &out, id).await,
MeetingsCommand::Create {
topic,
duration,
start,
password,
} => {
commands::meetings::create(&mut client, &out, topic, duration, start, password)
.await
}
MeetingsCommand::Update {
id,
topic,
duration,
start,
} => commands::meetings::update(&mut client, &out, id, topic, duration, start).await,
MeetingsCommand::Delete { id } => {
commands::meetings::delete(&mut client, &out, id).await
}
MeetingsCommand::End { id } => commands::meetings::end(&mut client, &out, id).await,
MeetingsCommand::Participants { meeting_id } => {
commands::meetings::participants(&mut client, &out, &meeting_id).await
}
},
Command::Recordings(cmd) => match cmd {
RecordingsCommand::List { user, from, to } => {
commands::recordings::list(&mut client, &out, &user, from.as_deref(), to.as_deref())
.await
}
RecordingsCommand::Get { meeting_id } => {
commands::recordings::get(&mut client, &out, &meeting_id).await
}
RecordingsCommand::Download {
meeting_id,
out: out_dir,
} => commands::recordings::download(&mut client, &out, &meeting_id, &out_dir).await,
RecordingsCommand::Start { meeting_id } => {
commands::recordings::control(&mut client, &out, meeting_id, "start").await
}
RecordingsCommand::Stop { meeting_id } => {
commands::recordings::control(&mut client, &out, meeting_id, "stop").await
}
RecordingsCommand::Pause { meeting_id } => {
commands::recordings::control(&mut client, &out, meeting_id, "pause").await
}
RecordingsCommand::Resume { meeting_id } => {
commands::recordings::control(&mut client, &out, meeting_id, "resume").await
}
},
Command::Users(cmd) => match cmd {
UsersCommand::List { status } => {
commands::users::list(&mut client, &out, status.as_deref()).await
}
UsersCommand::Get { id_or_email } => {
commands::users::get(&mut client, &out, &id_or_email).await
}
UsersCommand::Me => commands::users::me(&mut client, &out).await,
},
Command::Reports(cmd) => match cmd {
ReportsCommand::Meetings { user, from, to } => {
commands::reports::meetings(&mut client, &out, &user, &from, to.as_deref()).await
}
},
Command::Init { .. } | Command::Schema { .. } | Command::Completions { .. } => {
unreachable!()
}
};
if let Err(e) = result {
eprintln!("{e}");
std::process::exit(exit_codes::for_error(&e));
}
}