diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/Cargo.toml | 49 | ||||
-rw-r--r-- | cli/src/cli.rs | 59 | ||||
-rw-r--r-- | cli/src/commands/mod.rs | 2 | ||||
-rw-r--r-- | cli/src/commands/profile.rs | 67 | ||||
-rw-r--r-- | cli/src/main.rs | 27 |
5 files changed, 204 insertions, 0 deletions
diff --git a/cli/Cargo.toml b/cli/Cargo.toml new file mode 100644 index 0000000..e558c19 --- /dev/null +++ b/cli/Cargo.toml @@ -0,0 +1,49 @@ +[package] +name = "distrox-cli" +version = "0.1.0" +authors = ["Matthias Beyer <mail@beyermatthias.de>"] + +description = "Distributed network build on IPFS, CLI frontend" + +keywords = ["social", "network", "ipfs", "distributed"] +readme = "README.md" +license = "GPL-2.0" + +documentation = "https://docs.rs/distrox" +repository = "https://github.com/matthiasbeyer/distrox" +homepage = "http://github.com/matthiasbeyer/distrox" + +edition = "2018" + +[dependencies] +anyhow = "1" +async-trait = "0.1" +chrono = { version = "0.4", features = ["serde"] } +cid = "0.5" +clap = "3.0.0-beta.5" +daglib = { git = "https://git.sr.ht/~matthiasbeyer/daglib", branch = "master" } +env_logger = "0.8" +futures = "0.3" +log = "0.4" +tokio = { version = "1", features = ["full", "rt", "macros"] } +mime = "0.3" +rand_core = { version = "0.6", features = ["getrandom"] } +rand_os = "0.2" +ed25519-dalek = "*" +http = "0.2" +serde = "1" +serde_json = "1" +getset = "0.1" +xdg = "2.4" +tracing = "0.1" +ctrlc = "3.2" + +[dependencies.ipfs] +git = "https://github.com/rs-ipfs/rust-ipfs/" +rev = "ad3ab49b4d9236363969b0f74f14aabc7c906b3b" + +[dependencies.distrox-lib] +path = "../lib" + +[dev-dependencies] +multibase = "0.8" diff --git a/cli/src/cli.rs b/cli/src/cli.rs new file mode 100644 index 0000000..3f74128 --- /dev/null +++ b/cli/src/cli.rs @@ -0,0 +1,59 @@ +use clap::crate_authors; +use clap::crate_version; +use clap::App; +use clap::Arg; + +pub fn app<'a>() -> App<'a> { + App::new("distrox") + .author(crate_authors!()) + .version(crate_version!()) + .about("Distributed social network") + + .subcommand(App::new("profile") + .author(crate_authors!()) + .version(crate_version!()) + .about("Profile actions") + + .subcommand(App::new("create") + .author(crate_authors!()) + .version(crate_version!()) + .about("Create profile") + + .arg(Arg::new("name") + .long("name") + .required(true) + .takes_value(true) + .value_name("NAME") + .about("Name of the profile") + ) + ) + + .subcommand(App::new("serve") + .author(crate_authors!()) + .version(crate_version!()) + .about("Just serve the profile") + + .arg(Arg::new("name") + .long("name") + .required(true) + .takes_value(true) + .value_name("NAME") + .about("Name of the profile") + ) + + .arg(Arg::new("connect") + .long("connect") + .required(false) + .takes_value(true) + .value_name("MULTIADDR") + .about("Connect to MULTIADDR as well") + ) + ) + ) + + .subcommand(App::new("gui") + .author(crate_authors!()) + .version(crate_version!()) + .about("Start the distrox gui") + ) +} diff --git a/cli/src/commands/mod.rs b/cli/src/commands/mod.rs new file mode 100644 index 0000000..5569bcb --- /dev/null +++ b/cli/src/commands/mod.rs @@ -0,0 +1,2 @@ +mod profile; +pub use profile::profile; diff --git a/cli/src/commands/profile.rs b/cli/src/commands/profile.rs new file mode 100644 index 0000000..0eb8b75 --- /dev/null +++ b/cli/src/commands/profile.rs @@ -0,0 +1,67 @@ +use std::sync::atomic::AtomicBool; +use std::sync::atomic::Ordering; +use std::sync::Arc; + +use anyhow::Context; +use anyhow::Result; +use clap::ArgMatches; + +use distrox_lib::config::Config; +use distrox_lib::profile::Profile; + +pub async fn profile(matches: &ArgMatches) -> Result<()> { + match matches.subcommand() { + Some(("create", m)) => profile_create(m).await, + Some(("serve", m)) => profile_serve(m).await, + _ => unimplemented!(), + } +} + +async fn profile_create(matches: &ArgMatches) -> Result<()> { + let name = matches.value_of("name").map(String::from).unwrap(); // required + let state_dir = Profile::state_dir_path(&name)?; + log::info!("Creating '{}' in {}", name, state_dir.display()); + + let profile = Profile::create(&state_dir, &name, Config::default()).await?; + log::info!("Saving..."); + profile.save().await?; + + log::info!("Shutting down..."); + profile.exit().await +} + +async fn profile_serve(matches: &ArgMatches) -> Result<()> { + use ipfs::MultiaddrWithPeerId; + + let name = matches.value_of("name").map(String::from).unwrap(); // required + let connect_peer = matches.value_of("connect").map(|s| { + s.parse::<MultiaddrWithPeerId>() + .map_err(anyhow::Error::from) + }).transpose()?; + + let state_dir = Profile::state_dir_path(&name)?; + + log::info!("Loading '{}' from {}", name, state_dir.display()); + let profile = Profile::load(Config::default(), &name).await?; + log::info!("Profile loaded"); + log::info!("Profile HEAD = {:?}", profile.head()); + + if let Some(connect_to) = connect_peer { + log::info!("Connecting to {:?}", connect_to); + profile.connect(connect_to).await?; + } + + let running = Arc::new(AtomicBool::new(true)); + let r = running.clone(); + + ctrlc::set_handler(move || { + r.store(false, Ordering::SeqCst); + }).context("Error setting Ctrl-C handler")?; + + log::info!("Serving..."); + while running.load(Ordering::SeqCst) { + tokio::time::sleep(std::time::Duration::from_millis(500)).await // sleep not so busy + } + log::info!("Shutting down..."); + profile.exit().await +} diff --git a/cli/src/main.rs b/cli/src/main.rs new file mode 100644 index 0000000..fea466c --- /dev/null +++ b/cli/src/main.rs @@ -0,0 +1,27 @@ +use anyhow::Result; + +mod cli; +mod commands; + +fn main() -> Result<()> { + let _ = env_logger::try_init()?; + let matches = crate::cli::app().get_matches(); + + match matches.subcommand() { + Some(("profile", matches)) => crate::commands::profile(matches).await, + Some(("gui", _)) => { + unimplemented!() + }, + Some((other, _)) => { + log::error!("No subcommand {} implemented", other); + Ok(()) + }, + + _ => { + log::error!("Don't know what to do"); + Ok(()) + }, + } +} + + |