// SPDX-FileCopyrightText: 2022 Matteo Settenvini // SPDX-License-Identifier: AGPL-3.0-or-later mod api_client; mod commands; mod config; mod constants; mod event; mod recipe; use { crate::api_client::ApiClient, crate::config::Config, anyhow::Result, clap::{arg, command, ArgMatches, Command}, std::path::PathBuf, }; #[tokio::main(flavor = "multi_thread")] async fn main() -> Result<()> { let args = setup_args(); parse_args(&args).await } fn setup_args() -> ArgMatches { let server_arg = arg!(-s --server "NextCloud server to connect to").required(false); command!() .propagate_version(true) .subcommand_required(true) .arg_required_else_help(true) .subcommand( Command::new("init") .about("Authenticate against the provided NextCloud server") .arg(arg!( "NextCloud server to connect to")), ) .subcommand( Command::new("import") .about("Import the given URLs into NextCloud's cookbook") .arg(server_arg.clone()) .arg(arg!( ... "One or more URLs each pointing to page with a recipe to import in NextCloud")), ) .subcommand( Command::new("schedule") .about("") .arg(server_arg.clone()) .arg(arg!(-d --days "") .value_parser(clap::builder::RangedU64ValueParser::::new().range(1..)) .required(false) .default_value("7")) ) .subcommand( Command::new("schedule-csv") .about("TEMPORARY WIP FUNCTION USED FOR INTERNAL TESTING") .arg(server_arg.clone()) .arg(arg!( "")) .arg(arg!( "").value_parser(clap::value_parser!(PathBuf))) ) .get_matches() } async fn parse_args(args: &ArgMatches) -> Result<()> { let mut configuration = Config::new(); match args.subcommand() { Some(("init", sub_matches)) => { let server = sub_matches .get_one::("server") .expect("Mandatory parameter "); commands::init::with(&mut configuration, server).await } Some(("import", sub_matches)) => { let api_client = get_api_client(&sub_matches, &configuration)?; let urls = sub_matches .get_many::("url") .expect("At least one url is required") .map(|s| s.as_str()); commands::import::with(&api_client, urls).await } Some(("schedule", sub_matches)) => { let api_client = get_api_client(&sub_matches, &configuration)?; commands::schedule::with(&api_client).await } Some(("schedule-csv", sub_matches)) => { let api_client = get_api_client(&sub_matches, &configuration)?; let csv_file = sub_matches .get_one::("csv_file") .expect(" is a mandatory parameter, it cannot be missing"); let calendar_name = sub_matches .get_one::("calendar_name") .expect(" is a mandatory parameter, it cannot be missing"); commands::schedule_csv::with(&api_client, calendar_name.as_str(), &csv_file).await } _ => unreachable!("Exhausted list of subcommands and subcommand_required prevents `None`"), } } fn get_api_client(sub_matches: &ArgMatches, configuration: &Config) -> Result { let server_name = sub_matches .get_one::("server") .unwrap_or_else(|| { let servers = &configuration.credentials.servers; match servers.len() { 0 => panic!("No NextCloud server set up yet, use '{} init' first", env!("CARGO_BIN_NAME")), 1 => servers.iter().next().unwrap().0, _ => panic!("More than one NextCloud server set up, use the '--server' option to specify which one to use. Known servers: {:#?}", servers.keys().collect::>()), } }); ApiClient::new(&server_name, &configuration) }