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),
#[command(subcommand, arg_required_else_help = true)]
Webinars(WebinarsCommand),
#[command(subcommand, arg_required_else_help = true)]
Config(ConfigCommand),
Init {
#[arg(long)]
profile: Option<String>,
},
Schema {
resource: String,
},
Completions {
shell: clap_complete::Shell,
},
}
#[derive(Subcommand)]
enum ConfigCommand {
Show,
Delete {
profile: String,
#[arg(long)]
force: bool,
},
}
#[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,
},
Invite { id: u64 },
}
#[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,
},
Delete {
meeting_id: String,
#[arg(long)]
permanent: bool,
},
Start {
meeting_id: u64,
},
Stop {
meeting_id: u64,
},
Pause {
meeting_id: u64,
},
Resume {
meeting_id: u64,
},
Transcript {
meeting_id: String,
#[arg(long, default_value = ".")]
out: String,
},
}
#[derive(Subcommand)]
enum UsersCommand {
List {
#[arg(long)]
status: Option<String>,
},
Get { id_or_email: String },
Me,
Create {
#[arg(long)]
email: String,
#[arg(long)]
first_name: Option<String>,
#[arg(long)]
last_name: Option<String>,
#[arg(long, default_value = "1")]
r#type: u8,
},
Deactivate { id_or_email: String },
Activate { id_or_email: String },
}
#[derive(Subcommand)]
enum WebinarsCommand {
List {
#[arg(long, default_value = "me")]
user: String,
},
Get { id: u64 },
}
#[derive(Subcommand)]
enum ReportsCommand {
Meetings {
#[arg(long, default_value = "me")]
user: String,
#[arg(long)]
from: String,
#[arg(long)]
to: Option<String>,
},
Participants {
meeting_id: String,
},
}
#[tokio::main]
async fn main() {
let cli = Cli::parse();
let out = OutputConfig::new(cli.json, cli.quiet);
match &cli.command {
Command::Config(ConfigCommand::Show) => {
commands::config::show(cli.profile.as_deref(), &out);
return;
}
Command::Config(ConfigCommand::Delete { profile, force }) => {
if let Err(e) = commands::config::delete(profile, *force, &out) {
eprintln!("{e}");
std::process::exit(exit_codes::for_error(&e));
}
return;
}
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
}
MeetingsCommand::Invite { id } => {
commands::meetings::invite(&mut client, &out, 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
}
RecordingsCommand::Delete {
meeting_id,
permanent,
} => commands::recordings::delete(&mut client, &out, &meeting_id, !permanent).await,
RecordingsCommand::Transcript {
meeting_id,
out: out_dir,
} => commands::recordings::transcript(&mut client, &out, &meeting_id, &out_dir).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,
UsersCommand::Create {
email,
first_name,
last_name,
r#type,
} => {
commands::users::create(&mut client, &out, email, first_name, last_name, r#type)
.await
}
UsersCommand::Deactivate { id_or_email } => {
commands::users::deactivate(&mut client, &out, &id_or_email).await
}
UsersCommand::Activate { id_or_email } => {
commands::users::activate(&mut client, &out, &id_or_email).await
}
},
Command::Reports(cmd) => match cmd {
ReportsCommand::Meetings { user, from, to } => {
commands::reports::meetings(&mut client, &out, &user, &from, to.as_deref()).await
}
ReportsCommand::Participants { meeting_id } => {
commands::reports::participants(&mut client, &out, &meeting_id).await
}
},
Command::Webinars(cmd) => match cmd {
WebinarsCommand::List { user } => {
commands::webinars::list(&mut client, &out, &user).await
}
WebinarsCommand::Get { id } => commands::webinars::get(&mut client, &out, id).await,
},
Command::Config(ConfigCommand::Show | ConfigCommand::Delete { .. })
| Command::Init { .. }
| Command::Schema { .. }
| Command::Completions { .. } => {
unreachable!()
}
};
if let Err(e) = result {
eprintln!("{e}");
std::process::exit(exit_codes::for_error(&e));
}
}