#![allow(warnings)]
extern crate ipfs_api;
extern crate chrono;
extern crate mime;
extern crate futures;
extern crate serde;
extern crate serde_json;
extern crate uuid;
extern crate clap;
extern crate toml;
extern crate config;
extern crate hyper;
extern crate env_logger;
extern crate itertools;
#[macro_use] extern crate failure;
#[macro_use] extern crate is_match;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate log;
#[macro_use] extern crate tokio;
#[macro_use] extern crate add_getters_setters;
mod cli_ui;
mod configuration;
mod repository;
mod state;
mod typeext;
mod types;
mod version;
use std::collections::BTreeMap;
use std::str::FromStr;
use std::ops::Deref;
use std::sync::Arc;
use chrono::NaiveDateTime;
use futures::future::Future;
use futures::future::FutureExt;
use futures::future::TryFutureExt;
use serde_json::to_string_pretty as serde_json_to_string_pretty;
use serde_json::from_str as serde_json_from_str;
use failure::Fallible as Result;
use crate::configuration::Configuration;
use crate::repository::Repository;
use crate::types::block::Block;
use crate::types::content::Content;
use crate::types::content::Payload;
use crate::types::util::IPFSHash;
use crate::types::util::IPNSHash;
use crate::types::util::MimeType;
use crate::types::util::Timestamp;
use crate::types::util::Version;
use std::process::exit;
#[tokio::main]
async fn main() -> Result<()> {
let _ = env_logger::init();
debug!("Logger initialized");
let boot = || -> (Configuration, Repository) {
debug!("Loading configuration");
let mut config = config::Config::default();
config
.merge(config::File::with_name("distrox"))
.map_err(|e| {
error!("Error loading config file: {:?}", e);
exit(1);
})
.unwrap(); // safe!
let config = config.try_into::<configuration::Configuration>()
.map_err(|e| {
error!("Error parsing config file: {:?}", e);
exit(1);
})
.unwrap(); // safe!
debug!("Config loaded");
debug!("Loading repository...");
let repo = Repository::new(config.api_url(), config.api_port())
.map_err(|e| {
error!("Error opening repository: {:?}", e);
exit(1);
})
.unwrap(); // safe
debug!("Repository loaded successfully!");
(config, repo)
};
match cli_ui::build_ui()
.get_matches()
.subcommand()
{
("gui", _mtch) => {
Err(format_err!("Not yet supported"))
}
("is-block", Some(mtch)) => {
debug!("Calling: is-block");
let (_config, repo) = boot();
let hash = IPFSHash::from(mtch.value_of("HASH").unwrap()); // safe by clap
debug!("Working with hash: {}", hash);
repo.get_block(hash)
.await
.map_err(|e| {
let ignore_err = is_match!(e.downcast_ref(), Some(&ipfs_api::response::Error::Api(..)));
if !ignore_err {
error!("Error running: {:?}", e);
print_error_details(e);
}
exit(1)
})
.map(|_| ())
}
("is-content", Some(mtch)) => {
debug!("Calling: is-content");
let (_config, repo) = boot();
let hash = IPFSHash::from(mtch.value_of("HASH").unwrap()); // safe by clap
debug!("Working with hash: {}", hash);
repo.get_content(hash)
.await
.map_err(|e| {
let ignore_err = is_match!(e.downcast_ref(), Some(&ipfs_api::response::Error::Api(..)));
if !ignore_err {
error!("Error running: {:?}", e);
print_error_details(e);
}
exit(1)
})
.map(|_| ())
}
("is-post", Some(mtch)) => {
debug!("Calling: is-post");
let (_config, repo) = boot();
let hash = IPFSHash::from(mtch.value_of("HASH").unwrap()); // safe by clap
debug!("Working with hash: {}", hash);
let (tx, rx) = ::std::sync::mpsc::channel();
repo.get_content(hash)
.await
.map_err(|e| {
let ignore_err = is_match!(e.downcast_ref(), Some(&ipfs_api::response::Error::Api(..)));
if !ignore_err {
error!("Error running: {:?}", e);
print_error_details(e);
}
exit(1)
})
.map(move |content|<