summaryrefslogtreecommitdiffstats
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/Cargo.toml49
-rw-r--r--cli/src/cli.rs59
-rw-r--r--cli/src/commands/mod.rs2
-rw-r--r--cli/src/commands/profile.rs67
-rw-r--r--cli/src/main.rs27
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(())
+ },
+ }
+}
+
+