/* This file is part of DarkFi (https://dark.fi) * * Copyright (C) 2020-2023 Dyne.org foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ use serde_json::json; use simplelog::{ColorChoice, TermLogger, TerminalMode}; use structopt::StructOpt; use url::Url; use darkfi::{ rpc::{client::RpcClient, jsonrpc::JsonRequest}, util::cli::{get_log_config, get_log_level}, Result, }; #[derive(Clone, Debug, StructOpt)] #[structopt(name = "darkwikiupdate")] struct Args { #[structopt(subcommand)] sub_command: ArgsSubCommand, #[structopt(short, parse(from_occurrences))] /// Increase verbosity (-vvv supported) verbose: u8, #[structopt(short, long, default_value = "tcp://127.0.0.1:24330")] /// darkfid JSON-RPC endpoint endpoint: Url, } #[derive(Debug, Clone, PartialEq, StructOpt)] enum ArgsSubCommand { /// Publish local patches and merging received patches Update { #[structopt(long, short)] /// Run without applying the changes dry_run: bool, /// Names of files to update (Note: Will update all the documents if left empty) values: Vec, }, /// Show the history of patches Log { /// Names of files to log (Note: Will show all the log if left empty) values: Vec, }, /// Undo the local changes Restore { #[structopt(long, short)] /// Run without applying the changes dry_run: bool, /// Names of files to restore (Note: Will restore all the documents if left empty) values: Vec, }, } fn print_patches(value: &Vec) { for res in value { let res = res.as_array().unwrap(); let res: Vec<&str> = res.iter().map(|r| r.as_str().unwrap()).collect(); let (title, workspace, changes) = (res[0], res[1], res[2]); println!("WORKSPACE: {} FILE: {}", workspace, title); println!("{}", changes); println!("----------------------------------"); } } #[async_std::main] async fn main() -> Result<()> { let args = Args::from_args(); let log_level = get_log_level(args.verbose.into()); let log_config = get_log_config(); TermLogger::init(log_level, log_config, TerminalMode::Mixed, ColorChoice::Auto)?; let rpc_client = RpcClient::new(args.endpoint).await?; match args.sub_command { ArgsSubCommand::Update { dry_run, values } => { let req = JsonRequest::new("update", json!([dry_run, values])); let result = rpc_client.request(req).await?; let result = result.as_array().unwrap(); let local_patches = result[0].as_array().unwrap(); let sync_patches = result[1].as_array().unwrap(); let merge_patches = result[2].as_array().unwrap(); if !local_patches.is_empty() { println!(); println!("PUBLISH LOCAL PATCHES:"); println!(); print_patches(local_patches); } if !sync_patches.is_empty() { println!(); println!("RECEIVED PATCHES:"); println!(); print_patches(sync_patches); } if !merge_patches.is_empty() { println!(); println!("MERGE:"); println!(); print_patches(merge_patches); } } ArgsSubCommand::Restore { dry_run, values } => { let req = JsonRequest::new("restore", json!([dry_run, values])); let result = rpc_client.request(req).await?; let result = result.as_array().unwrap(); let patches = result[0].as_array().unwrap(); if !patches.is_empty() { println!(); println!("AFTER RESTORE:"); println!(); print_patches(patches); } } _ => unimplemented!(), } rpc_client.close().await }