diff options
-rw-r--r-- | src/main.rs | 3 | ||||
-rw-r--r-- | src/repository/client.rs | 75 | ||||
-rw-r--r-- | src/repository/mod.rs | 34 |
3 files changed, 110 insertions, 2 deletions
diff --git a/src/main.rs b/src/main.rs index 4620b0a..f472d31 100644 --- a/src/main.rs +++ b/src/main.rs @@ -786,6 +786,9 @@ fn main() { //("post", Some(mtch)) => { // debug!("Calling: post"); // let (config, repo) = boot(); + // let key = repo.get_key_id_from_key_name(publish_key.clone()); + // let profile_hash = IPNSHash::from(key.deref().clone()); + // let lastest = repo.resolve_latest_block(profile_hash); // unimplemented!() //}, diff --git a/src/repository/client.rs b/src/repository/client.rs index 18d94e7..00bc273 100644 --- a/src/repository/client.rs +++ b/src/repository/client.rs @@ -10,11 +10,14 @@ use futures::future::Future; use futures::stream::Stream; use serde_json::from_str as serde_json_from_str; use serde_json::to_string as serde_json_to_str; +use chrono::NaiveDateTime; use types::block::Block; use types::content::Content; use types::content::Payload; use types::util::IPFSHash; +use types::util::IPNSHash; +use types::util::Timestamp; use repository::{ProfileName, ProfileKey}; use version::protocol_version; @@ -44,6 +47,34 @@ pub fn resolve_block(client: Arc<IpfsClient>, hash: &IPFSHash) }) } +pub fn get_key_id_from_key_name(client: Arc<IpfsClient>, name: ProfileName) + -> impl Future<Item = ProfileKey, Error = Error> +{ + client.key_list() + .map_err(Error::from) + .and_then(|list| { + list.keys + .into_iter() + .filter(|pair| pair.name == *name.deref()) + .next() + .map(|pair| ProfileKey(pair.id)) + .ok_or_else(|| err_msg("No Key")) + }) +} + +pub fn resolve_latest_block(client: Arc<IpfsClient>, hash: &IPNSHash) + -> impl Future<Item = Block, Error = Error> +{ + client + .clone() + .name_resolve(Some(hash), false, false) + .map_err(Error::from) + .and_then(|resp| { + let hash = IPFSHash::from(resp.path); + resolve_block(client, &hash) + }) +} + pub fn resolve_content(client: Arc<IpfsClient>, hash: &IPFSHash) -> impl Future<Item = Content, Error = Error> { @@ -212,3 +243,47 @@ pub fn new_profile(client: Arc<IpfsClient>, .map_err(Error::from) }) } + +pub fn new_text_post(client: Arc<IpfsClient>, + publish_key_id: ProfileKey, + latest_block: IPFSHash, + text: String, + time: Option<NaiveDateTime>) + -> impl Future<Item = (), Error = Error> +{ + resolve_block(client.clone(), &latest_block) // get devices from latest block + .and_then(|block| { + resolve_content(client.clone(), block.content()) + }) + .and_then(move |content| { + put_plain(client.clone(), text.into_bytes()) + .and_then(move |content_hash| { + let post = Payload::Post { + content_format: ::mime::TEXT_PLAIN.into(), + content: content_hash, + reply_to: None, + + comments_will_be_propagated: None, + comments_propagated_until: None, + }; + + let devices = content.devices(); + let ts = time.map(Timestamp::from); + let content_obj = Content::new(devices.to_vec(), ts, post); + + put_content(client.clone(), &content_obj) + }) + }) + .and_then(move |content_obj_hash| { + let block = Block::new(protocol_version(), vec![latest_block], content_obj_hash); + put_block(client.clone(), &block) + }) + .and_then(move |block_hash| { + announce_profile(client.clone(), + publish_key_id, + &block_hash, + None, // IPFS default + None) // IPFS default + }) +} + diff --git a/src/repository/mod.rs b/src/repository/mod.rs index 99dc858..f4a6684 100644 --- a/src/repository/mod.rs +++ b/src/repository/mod.rs @@ -16,11 +16,13 @@ use futures::stream::Stream; use serde_json::from_str as serde_json_from_str; use serde_json::to_string as serde_json_to_str; use serde::Serialize; +use chrono::NaiveDateTime; use types::block::Block; use types::content::Content; use types::content::Payload; use types::util::IPFSHash; +use types::util::IPNSHash; use version::protocol_version; // use repository::iter::BlockIter; @@ -32,7 +34,7 @@ pub struct Repository { client: Arc<IpfsClient>, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ProfileName(String); impl Deref for ProfileName { @@ -44,7 +46,7 @@ impl Deref for ProfileName { } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ProfileKey(String); impl Deref for ProfileKey { @@ -88,6 +90,13 @@ impl Repository { ::repository::client::resolve_block(self.client.clone(), hash) } + pub fn resolve_latest_block(&self, hash: &IPNSHash) + -> impl Future<Item = Block, Error = Error> + { + debug!("Resolving latest block: {}", hash); + ::repository::client::resolve_latest_block(self.client.clone(), hash) + } + /// Gets a types::Content from a hash or fails pub fn resolve_content(&self, hash: &IPFSHash) -> impl Future<Item = Content, Error = Error> @@ -232,4 +241,25 @@ impl Repository { ::futures::future::Either::A(result) } + pub fn new_text_post<'a>(&'a self, + publish_key_id: ProfileKey, + latest_block: IPFSHash, + text: String, + time: Option<NaiveDateTime>) + -> impl Future<Item = (), Error = Error> + { + debug!("New text post under {:?}, after block {:?}", publish_key_id, latest_block); + ::repository::client::new_text_post(self.client.clone(), + publish_key_id, + latest_block, + text, + time) + } + + pub fn get_key_id_from_key_name<'a>(&'a self, name: ProfileName) + -> impl Future<Item = ProfileKey, Error = Error> + { + ::repository::client::get_key_id_from_key_name(self.client.clone(), name) + } + } |