diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2018-10-07 10:45:21 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2018-10-21 14:54:29 +0200 |
commit | faab79aa4e8d1adcaf62e2bfe5ce8b1c27815608 (patch) | |
tree | 9d04e11fc2dc84cd895bd057ae31dde061f8af6b | |
parent | 38e634d1022441ea7daded63c082473479c3d7f5 (diff) |
[WIP] Add high-level CLI definition
-rw-r--r-- | src/cli_ui.rs | 27 | ||||
-rw-r--r-- | src/main.rs | 36 | ||||
-rw-r--r-- | src/repository/mod.rs | 44 |
3 files changed, 93 insertions, 14 deletions
diff --git a/src/cli_ui.rs b/src/cli_ui.rs index aff5530..ecbe66d 100644 --- a/src/cli_ui.rs +++ b/src/cli_ui.rs @@ -376,6 +376,33 @@ pub fn build_ui<'a>() -> App<'a, 'a> { .help("") ) ) + + // High-level commands + + .subcommand(SubCommand::with_name("create-profile") + .about("Create a new profile") + .version("0.1.0") + .arg(Arg::with_name("name") + .index(1) + .required(true) + .takes_value(true) + .multiple(false) + .help("The name of the profile. Also the name of the IPFS Key used for this profile.") + ) + ) + + .subcommand(SubCommand::with_name("post") + .about("Write a new post") + .version("0.1.0") + .arg(Arg::with_name("editor") + .long("editor") + .required(false) + .takes_value(true) + .multiple(false) + .help("Set the editor") + ) + ) + } diff --git a/src/main.rs b/src/main.rs index 522e489..23d4715 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,7 @@ mod version; use std::collections::BTreeMap; use std::str::FromStr; +use std::ops::Deref; use chrono::NaiveDateTime; use futures::future::Future; @@ -743,6 +744,41 @@ fn main() { }; } + ("create-profile", Some(mtch)) => { + debug!("Calling: create-profile"); + let (config, repo) = boot(); + + let name = mtch.value_of("name").map(String::from).unwrap(); // safe by clap + let keyname = format!("distrox-{}", name); + let timestamp = Timestamp::from(::chrono::offset::Local::now().naive_local()); + let payload = Payload::Profile { + names: vec![name], + picture: None, + more: BTreeMap::new(), + }; + let profile = Content::new(vec![], Some(timestamp), payload); + + hyper::rt::run({ + // use ipfs defaults for lifetime and ttl + repo.new_profile(keyname, profile, None, None) + .map_err(|e| { + error!("Error running: {:?}", e); + print_error_details(e); + exit(1) + }) + .map(|(profile_name, profile_key)| { + println!("{}, {}", profile_name.deref(), profile_key.deref()); + }) + }); + }, + + //("post", Some(mtch)) => { + // debug!("Calling: post"); + // let (config, repo) = boot(); + + // unimplemented!() + //}, + (other, _mtch) => { error!("Unknown command: {}", other); exit(1) diff --git a/src/repository/mod.rs b/src/repository/mod.rs index 631b4a8..3c5729e 100644 --- a/src/repository/mod.rs +++ b/src/repository/mod.rs @@ -263,33 +263,41 @@ impl Repository { self.resolve_content_profile(state) .and_then(|_| { - client.name_publish(&name, false, lifetime.as_ref(), ttl.as_ref(), Some(&key)) + client.name_publish(&name, + false, + lifetime.as_ref().map(String::deref), + ttl.as_ref().map(String::deref), + Some(&key)) .map_err(From::from) .map(|_| ()) }) } - pub fn new_profile<'a, N>(&'a self, - keyname: N, - profile: &Content, - lifetime: Option<&str>, - ttl: Option<&str>) + pub fn new_profile<'a>(&'a self, + keyname: String, + profile: Content, + lifetime: Option<String>, + ttl: Option<String>) -> impl Future<Item = (ProfileName, ProfileKey), Error = Error> - where N: AsRef<str> { use ipfs_api::KeyType; if !is_match!(profile.payload(), Payload::Profile { .. }) { - return ::futures::future::err(err_msg(format!("Not a Profile: {:?}", profile))) + let out = ::futures::future::err(err_msg(format!("Not a Profile: {:?}", profile))); + return ::futures::future::Either::B(out) } let client = self.client.clone(); - client - .key_gen(keyname.as_ref(), KeyType::Rsa, 4096) + + let result = client + .key_gen(&keyname, KeyType::Rsa, 4096) + .map_err(Error::from) .map(|kp| (kp.name, kp.id)) .and_then(|(key_name, key_id)| { // put the content into IPFS - self.put_content(profile) + let prof = profile; + self.put_content(&prof) .map(|content_hash| (content_hash, key_name, key_id)) + .map_err(Error::from) }) .and_then(|(content_hash, key_name, key_id)| { // put the content into a new block let block = Block::new(protocol_version(), @@ -298,15 +306,23 @@ impl Repository { self.put_block(&block) .map(|block_hash| (block_hash, key_name, key_id)) + .map_err(Error::from) }) .and_then(|(block_hash, key_name, key_id)| { let path = format!("/ipfs/{}", block_hash); client - .name_publish(&path, false, lifetime, ttl, Some(&key_name)) + .name_publish(&path, + false, + lifetime.as_ref().map(String::deref), + ttl.as_ref().map(String::deref), + Some(&key_name)) .map(|_publish_response| { - (key_name, key_id) + (ProfileName(key_name), ProfileKey(key_id)) }) - }) + .map_err(Error::from) + }); + + ::futures::future::Either::A(result) } } |