diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2021-01-01 11:54:43 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2021-01-01 11:54:43 +0100 |
commit | 8ef5f5a8ad82c2f3b57795b16ce7b4458ad576f0 (patch) | |
tree | d081f4dc84f606a62b5ab1ce9d8e6a57927e7a19 | |
parent | 2f95226ff8c1996699591960c5127c41b0fc5f6f (diff) |
Remove stuff
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r-- | Cargo.toml | 27 | ||||
-rw-r--r-- | README.md | 22 | ||||
-rw-r--r-- | assets/index.html | 11 | ||||
-rw-r--r-- | assets/index_post.html | 0 | ||||
-rw-r--r-- | assets/index_pre.html | 3 | ||||
-rw-r--r-- | assets/style.css | 25 | ||||
-rw-r--r-- | distrox.toml | 37 | ||||
-rw-r--r-- | shell.nix | 13 | ||||
-rw-r--r-- | src/cli.rs | 43 | ||||
-rw-r--r-- | src/configuration.rs | 107 | ||||
-rw-r--r-- | src/gui.rs | 31 | ||||
-rw-r--r-- | src/main.rs | 115 | ||||
-rw-r--r-- | src/middleware.rs | 108 | ||||
-rw-r--r-- | src/model.rs | 146 | ||||
-rw-r--r-- | src/server.rs | 78 | ||||
-rw-r--r-- | src/types/block.rs | 85 | ||||
-rw-r--r-- | src/types/content.rs | 104 | ||||
-rw-r--r-- | src/types/mod.rs | 5 | ||||
-rw-r--r-- | src/types/payload.rs | 279 | ||||
-rw-r--r-- | src/types/util.rs | 172 | ||||
-rw-r--r-- | src/version.rs | 4 |
21 files changed, 3 insertions, 1412 deletions
@@ -16,30 +16,3 @@ homepage = "http://github.com/matthiasbeyer/distrox" edition = "2018" [dependencies] -is-match = "0.1" -anyhow = "1" -futures = "0.3" -ipfs-api = { version = "0.7", features = ["actix"], default-features = false } -serde = "1" -serde_derive = "1" -serde_json = "1" -mime = "0.3" -chrono = { version = "0.4", features = ["serde"] } -uuid = { version = "0.7", features = ["serde", "v4"] } -clap = "2" -log = "0.4" -env_logger = "0.7" -config = "0.9" -toml = "0.4" -hyper = "0.12" -itertools = "0.7" -tokio = { version = "0.2", features = ["full"] } -add_getters_setters = "1.1" -xdg = "2" -structopt = "0.3" -web-view = "0.6" -handlebars = "3" -actix-rt = "1" -actix-web = "2" -failure = "0.1" -pidlock = { git = "https://github.com/matthiasbeyer/pidlock", branch = "my-master" } @@ -2,27 +2,9 @@ A distributed social network build on IPFS. -## TODO - -1. Implement protocol -1. Implement working prototype with CLI frontend -1. Implement GUI frontend with azul or Qt. -1. Publish POC on IPFS forums, Rust forums, reddit, hackernews, etc and ask for - comments and contributors. - - -## POC/MVP should contain - -1. Publishing content (text or media data) -1. Following profiles - 1. requires investigation how to do right, because that information should - be stored locally, but also should be synced to other devices of the - profile. -1. Merging other devices - 1. Merging strategies must be defined and investigated - ## License -GPL-2.0 only. +Server: AGPL-2.0 only. + diff --git a/assets/index.html b/assets/index.html deleted file mode 100644 index eb9e2e0..0000000 --- a/assets/index.html +++ /dev/null @@ -1,11 +0,0 @@ - </style> - </head> - <body> - <div id="sidebar_left"> - </div> - <div id="content"> - </div> - <div id="sidebar_right"> - </div> - </body> -</html> diff --git a/assets/index_post.html b/assets/index_post.html deleted file mode 100644 index e69de29..0000000 --- a/assets/index_post.html +++ /dev/null diff --git a/assets/index_pre.html b/assets/index_pre.html deleted file mode 100644 index da6f618..0000000 --- a/assets/index_pre.html +++ /dev/null @@ -1,3 +0,0 @@ -<html> - <head> - <style> diff --git a/assets/style.css b/assets/style.css deleted file mode 100644 index 120b1bd..0000000 --- a/assets/style.css +++ /dev/null @@ -1,25 +0,0 @@ -body { - background-color: black; -} - -#sidebar_left { - background-color: grey; - height: 100%; - position: fixed; - top: 0; - left: 0; - width: 10%; - min-width: 15em; - float: left; -} - -#sidebar_right { - background-color: grey; - height: 100%; - position: fixed; - top: 0; - right: 0; - width: 10%; - min-width: 15em; - float: right; -} diff --git a/distrox.toml b/distrox.toml index f150886..39e9461 100644 --- a/distrox.toml +++ b/distrox.toml @@ -7,40 +7,3 @@ ipfs-api-port = 5001 # The Port for the app itself app-port = 5002 -# Whether to automatically "ipfs pin" chain objects -autoserve-chains = true - -# Whether to automatically "ipfs pin" foreign posts if their content is text -autoserve-text-posts = true - -# Whether to serve content/chains from blocked profiles -serve-blocked = false - -# Whether to automatically "ipfs pin" followed profiles -autoserve-followed = true - -# Default amount of bytes which are loaded for each post -max-autoload-per-post = 1024 - -# List of Mimetypes which should not be served -autoserve-blacklist = [] - -# List of Mimetypes which can be served -autoserve-whitelist = [] - -# Name under which to provide the local device. E.G. -# Some("/ipfs/QmVrLsEDn27sScp3k23sgZNefVTjSAL3wpgW1iWPi4MgoY") -# -# If none, one will be generated and set -# device_name = "" - -# Key to sign stuff that comes from this device. -# -# Create by using `ipfs key gen <name>` -#device_key = "" - -# Devices for the profile -# E.G: -# ["/ipfs/QmVrLsEDn27sScp3k23sgZNefVTjSAL3wpgW1iWPi4MgoY"] -devices = [] - @@ -18,21 +18,10 @@ let dbus libtool ]; - - gtk = with pkgs; [ - glib - pango - gdk-pixbuf - atk - gtk3 - - libsoup - webkitgtk - ]; in pkgs.mkShell rec { - buildInputs = env ++ dependencies ++ gtk; + buildInputs = env ++ dependencies; LIBCLANG_PATH = "${pkgs.llvmPackages.libclang}/lib"; } diff --git a/src/cli.rs b/src/cli.rs deleted file mode 100644 index c91b653..0000000 --- a/src/cli.rs +++ /dev/null @@ -1,43 +0,0 @@ -use std::path::PathBuf; - -use structopt::StructOpt; -use anyhow::Error; - -#[derive(Debug, StructOpt)] -#[structopt(name = "distrox", about = "Distrox - The distributed social network")] -pub struct CLI { - #[structopt(short, long)] - debug: bool, - - #[structopt(short, long)] - trace: bool, - - #[structopt(short, long)] - port: Option<u16>, - - #[structopt(parse(from_os_str))] - configfile: Option<PathBuf>, - - #[structopt(subcommand)] - cmd: Option<Command> -} - -impl CLI { - pub fn cmd(&self) -> Option<&Command> { - self.cmd.as_ref() - } - - pub fn port(&self) -> Option<u16> { - self.port.as_ref().map(|p| *p) - } -} - -#[derive(Debug, PartialEq, StructOpt)] -#[structopt(about = "Start the server part (running in foreground")] -pub enum Command { - Server, -} - -pub fn cli() -> Result<CLI, Error> { - Ok(CLI::from_args()) -} diff --git a/src/configuration.rs b/src/configuration.rs deleted file mode 100644 index 5b39090..0000000 --- a/src/configuration.rs +++ /dev/null @@ -1,107 +0,0 @@ -use crate::types::util::MimeType; - -// use chrono::Duration; - -/// Configuration read from a configuration file -#[derive(Serialize, Deserialize, Debug, AddGetter)] -pub struct Configuration { - #[serde(rename = "ipfs-api-url")] - #[get] - /// The URL of the API - api_url: String, - - #[serde(rename = "ipfs-api-port")] - #[get] - /// The Port of the API - api_port: u16, - - #[serde(rename = "app-port")] - #[get] - /// The Port of the App itself - app_port: u16, - - #[serde(rename = "autoserve-chains")] - #[get] - /// Whether to automatically "ipfs pin" chain objects - autoserve_chains: bool, - - #[serde(rename = "autoserve-text-posts")] - #[get] - /// Whether to automatically "ipfs pin" foreign posts if their content is text - autoserve_text_posts: bool, - - #[serde(rename = "serve-blocked")] - #[get] - /// Whether to serve content/chains from blocked profiles - serve_blocked: bool, - - #[serde(rename = "autoserve-followed")] - #[get] - /// Whether to automatically "ipfs pin" followed profiles - autoserve_followed: bool, - - #[serde(rename = "max-autoload-per-post")] - #[get] - /// Default amount of bytes which are loaded for each post - max_autoload_per_post: usize, - - #[serde(rename = "autoserve-blacklist")] - #[get] - /// List of Mimetypes which should not be served - autoserve_blacklist: Vec<MimeType>, - - #[serde(rename = "autoserve-whitelist")] - #[get] - /// List of Mimetypes which can be served - autoserve_whitelist: Vec<MimeType>, - - // #[serde(rename = "merge-timeout")] - // #[get] - // /// Timeout before merge should be attempted - // merge_timeout: Duration, - // - - /// Name under which to provide the local device. E.G. - /// Some("/ipfs/QmVrLsEDn27sScp3k23sgZNefVTjSAL3wpgW1iWPi4MgoY") - /// - /// If none, one will be generated and set - #[serde(rename = "device_name")] - #[get] - device_name: Option<String>, - - /// Key to sign stuff that comes from this device. - /// - /// Create by using `ipfs key gen <name>` - #[serde(rename = "device_key")] - #[get] - device_key: Option<String>, - - /// Devices for the profile - /// E.G: - /// ["/ipfs/QmVrLsEDn27sScp3k23sgZNefVTjSAL3wpgW1iWPi4MgoY"] - #[serde(rename = "devices")] - #[get] - devices: Vec<String>, -} - -impl Default for Configuration { - fn default() -> Self { - Configuration { - api_url : String::from("127.0.0.1"), - api_port : 5001, - app_port : 5002, - autoserve_chains : true, - autoserve_text_posts : true, - serve_blocked : false, - autoserve_followed : true, - max_autoload_per_post : 1024 * 1024, - autoserve_blacklist : Vec::new(), - autoserve_whitelist : Vec::new(), - // merge_timeout : Duration::minutes(15), - device_name : None, - device_key : None, - devices : Vec::new(), - } - } -} - diff --git a/src/gui.rs b/src/gui.rs deleted file mode 100644 index 1d5281e..0000000 --- a/src/gui.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::fmt::Debug; - -use anyhow::Error; -use anyhow::Result; -use web_view::WVResult; -use web_view::WebView; - -use crate::cli::*; -use crate::types::util::*; - -pub fn run_gui(adr: String) -> Result<()> { - let webview_content = web_view::Content::Url(format!("http://{}", adr)); - - web_view::builder() - .title("My Project") - .content(webview_content) - .resizable(true) - .debug(true) - .user_data(()) - .invoke_handler(invoke_handler) - .build() - .map_err(Error::from)? - .run() - .map_err(Error::from) -} - -fn invoke_handler<T: Debug>(webview: &mut WebView<T>, s: &str) -> WVResult { - debug!("invoke-handler: {:?}, {:?}", webview, s); - Ok(()) -} - diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 80e6ec9..0000000 --- a/src/main.rs +++ /dev/null @@ -1,115 +0,0 @@ -#![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; -extern crate xdg; -extern crate handlebars; -extern crate web_view; -extern crate actix_rt; -extern crate actix_web; -extern crate failure; -extern crate pidlock; - -#[macro_use] extern crate anyhow; -#[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; -#[macro_use] extern crate structopt; - -mod cli; -mod configuration; -mod gui; -mod model; -mod middleware; -mod server; -mod types; -mod version; - -use std::collections::BTreeMap; -use std::str::FromStr; -use std::ops::Deref; -use std::sync::Arc; -use std::path::PathBuf; - -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 anyhow::Result; -use anyhow::Error; -use env_logger::Env; - -use crate::cli::*; -use crate::configuration::Configuration; -use crate::model::Model; -use crate::middleware::Middleware; -use crate::types::block::Block; -use crate::types::content::Content; -use crate::types::payload::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; - -#[actix_rt::main] -async fn main() -> Result<()> { - let cli = cli()?; - let _ = env_logger::from_env(Env::default().default_filter_or("info")).init(); - debug!("Logger initialized"); - - let config_file_name = PathBuf::from("distrox.toml"); - let config: Configuration = { - let configfile = xdg::BaseDirectories::with_prefix("distrox")? - .find_config_file(&config_file_name) - .ok_or_else(|| anyhow!("No configuration found"))?; - - let configstr = ::std::fs::read_to_string(&configfile)?; - ::toml::from_str(&configstr)? - }; - - let port = cli.port().unwrap_or_else(|| *config.get_app_port()); - let adr = format!("127.0.0.1:{}", port); - - let mut server_lock = crate::server::mk_lock(); - let server_running = crate::server::is_running(&server_lock); - let start_server = crate::server::do_start(&cli); - - match (server_running, start_server) { - (true, false) => crate::gui::run_gui(adr), - (false, false) => { - // fork() - info!("Spawning server thread..."); - let path = std::env::current_exe()?; - let mut child = std::process::Command::new(path).arg("server").spawn()?; - let r = crate::gui::run_gui(adr); - child.kill()?; - r - }, - - (false, true) => crate::server::run_server(config, server_lock, adr).await, - - (true, true) => { - info!("Server is already running. Doing nothing."); - return Ok(()) - }, - } -} - diff --git a/src/middleware.rs b/src/middleware.rs deleted file mode 100644 index 61fe716..0000000 --- a/src/middleware.rs +++ /dev/null @@ -1,108 +0,0 @@ -use std::collections::BTreeMap; - -use anyhow::Error; -use futures::Stream; -use futures::stream; - -use crate::types::util::IPFSHash; -use crate::types::util::MimeType; -use crate::types::util::IPNSHash; -use crate::types::block::Block; -use crate::model::Model; -use crate::types::content::Content; -use crate::types::payload::Payload; -use crate::types::util::Timestamp; -use crate::version::protocol_version; - -/// The "Middleware" type implements the actual application logic -#[derive(Debug, Clone)] -pub struct Middleware { - repo: Model, - device_name: IPNSHash, - publishing_key: String -} - -impl Middleware { - - pub fn load(device_name: IPNSHash, publishing_key: String, host: &str, port: u16) -> Result<Self, Error> { - Model::new(host, port).map(|repo| Middleware { repo, device_name, publishing_key }) - } - - pub async fn new_profile(repo: Model, publishing_key: &str, names: Vec<String>) -> Result<Self, Error> { - let payload = Payload::Profile { - names, - picture: None, - more: BTreeMap::new(), - }; - let timestamp = Timestamp::now(); - let content = Content::new(vec![], Some(timestamp), payload); - - let content_hash = repo.put_content(content).await?; - let head = repo.put_block(Block::new(protocol_version(), vec![], content_hash)).await?; - let device_name = repo.publish(&publishing_key, &head).await?; - - Ok(Middleware { repo, device_name, publishing_key: publishing_key.to_string() }) - } - - pub async fn new_post(&self, - content: Vec<u8>, - mime: MimeType, - reply_to: Option<IPFSHash>, - comments_will_be_propagated: Option<bool>, - comments_propagated_until: Option<Timestamp>) - -> Result<(), Error> - { - let content_hash = self.repo.put_raw_bytes(content).await?; - - let payload = Payload::Post { - content_format: mime, - content: content_hash, - reply_to, - comments_will_be_propagated, - comments_propagated_until, - }; - let timestamp = Timestamp::now(); - let content = Content::new(vec![], Some(timestamp), payload); - - let content_hash = self.repo.put_content(content).await?; - - let head = self.repo.put_block(Block::new(protocol_version(), vec![], content_hash)).await?; - let device_name = self.repo.publish(&self.publishing_key, &head).await?; - - Ok(()) - } - - pub fn blocks(&self, head: IPFSHash) -> impl Stream<Item = Result<Block, Error>> { - stream::unfold((self.repo.clone(), vec![head]), move |(repo, mut state)| { - async { - if let Some(hash) = state.pop() { - match repo - .get_block(hash) - .await - .map(move |block| { - block.parents().iter().for_each(|parent| { - state.push(parent.clone()) - }); - - (block, state) - }) - .map(Some) - .transpose() - { - Some(Ok((item, state))) => Some((Ok(item), (repo, state))), - Some(Err(e)) => Some((Err(e), (repo, vec![]))), - None => None, - } - } else { - None - } - } - }) - } - - pub async fn blocks_of(&self, ipns: IPNSHash) -> Result<impl Stream<Item = Result<Block, Error>>, Error> { - self.repo.resolve(ipns).await.map(|ipfs| self.blocks(ipfs)) - } - -} - diff --git a/src/model.rs b/src/model.rs deleted file mode 100644 index 85fcf22..0000000 --- a/src/model.rs +++ /dev/null @@ -1,146 +0,0 @@ -//! The "model" module implements the Database-layer of the application - -use std::io::Cursor; -use std::ops::Deref; -use std::result::Result as RResult; -use std::sync::Arc; - -use anyhow::Error; -use chrono::NaiveDateTime; -use failure::Fail; -use futures::future::Future; -use futures::future::FutureExt; -use futures::stream::Stream; -use futures::stream::StreamExt; -use futures::stream::TryStreamExt; -use ipfs_api::IpfsClient; -use ipfs_api::TryFromUri; -use serde::Serialize; -use serde::de::DeserializeOwned; -use serde_json::from_str as serde_json_from_str; -use serde_json::to_string as serde_json_to_str; - -use crate::types::block::Block; -use crate::types::content::Content; -use crate::types::payload::Payload; -use crate::types::util::IPFSHash; -use crate::types::util::IPNSHash; - -#[derive(Clone)] -pub struct Model(IpfsClient); - -impl std::fmt::Debug for Model{ - fn fmt(&self, f: &mut std::fmt::Formatter) -> RResult<(), std::fmt::Error> { - write!(f, "Model") - } -} - -impl Model { - pub fn new(host: &str, port: u16) -> Result<Model, Error> { - debug!("Creating new Model object: {}:{}", host, port); - IpfsClient::from_str(&format!("{}:{}", host, port)) - .map(Model) - .map_err(|e| Error::from(e.compat())) - } - - - // - // - // Low-level interface to the ipfs-api - // - // - - pub(crate) async fn get_raw_bytes<H: AsRef<IPFSHash>>(&self, hash: H) -> Result<Vec<u8>, Error> { - debug!("Get: {}", hash.as_ref()); - self.0 - .cat(hash.as_ref()) - .map_ok(|b| b.to_vec()) - .try_concat() - .map(|r| r.map_err(|e| anyhow!("UNIMPLEMENTED!()"))) - .await - } - - pub(crate) async fn put_raw_bytes(&self, data: Vec<u8>) -> Result<IPFSHash, Error> { - debug!("Put: {:?}", data); - self.0 - .add(Cursor::new(data)) - .await - .map(|res| IPFSHash::from(res.hash)) - .map_err(|e| anyhow!("UNIMPLEMENTED!()")) - } - - pub(crate) async fn publish(&self, key: &str, hash: &str) -> Result<IPNSHash, Error> { - debug!("Publish: {:?} -> {:?}", key, hash); - self.0 - .name_publish(hash, false, None, None, Some(key)) - .await - .map(|res| IPNSHash::from(res.value)) - .map_err(|e| anyhow!("UNIMPLEMENTED!()")) - } - - pub(crate) async fn resolve(&self, ipns: IPNSHash) -> Result<IPFSHash, Error> { - self.0 - .name_resolve(Some(&ipns), true, false) - .await - .map(|res| IPFSHash::from(res.path)) - .map_err(|e| anyhow!("UNIMPLEMENTED!()")) - } - - // - // - // Generic typed interface - // - // - - pub(crate) async fn get_typed<H, D>(&self, hash: H) -> Result<D, Error> - where H: AsRef<IPFSHash>, - D: DeserializeOwned - { - self.get_raw_bytes(hash) - .await - .and_then(|data| { - debug!("Got data, building object: {:?}", data); - - serde_json::from_slice(&data).map_err(|e| Error::from(e.compat())) - }) - } - - pub(crate) async fn put_typed<S, Ser>(&self, data: &S) -> Result<IPFSHash, Error> - where S: AsRef<Ser>, - Ser: Serialize - { - let data = serde_json_to_str(data.as_ref())?; - self.put_raw_bytes(data.into_bytes()).await - } - - // - // - // Typed interface - // - // - - pub async fn get_block<H>(&self, hash: H) -> Result<Block, Error> - where H: AsRef<IPFSHash> - { - self.get_typed(hash).await - } - - pub async fn put_block<B>(&self, b: B) -> Result<IPFSHash, Error> - where B: AsRef<Block> - { - self.put_typed(b.as_ref()).await - } - - pub async fn get_content<H>(&self, hash: H) -> Result<Content, Error> - where H: AsRef<IPFSHash> - { - self.get_typed(hash).await - } - - pub async fn put_content<C>(&self, c: C) -> Result<IPFSHash, Error> - where C: AsRef<Content> - { - self.put_typed(c.as_ref()).await - } - -} diff --git a/src/server.rs b/src/server.rs deleted file mode 100644 index b1fa237..0000000 --- a/src/server.rs +++ /dev/null @@ -1,78 +0,0 @@ -use std::path::PathBuf; - -use anyhow::Error; -use anyhow::Result; -use pidlock::{Pidlock, PidlockState}; -use actix_web::HttpResponse; -use actix_web::Responder; -use actix_web::http::StatusCode; -use actix_web::body::Body; - -use crate::cli::*; -use crate::configuration::Configuration; -use crate::middleware::Middleware; -use crate::types::util::*; - -pub fn mk_lock() -> Pidlock { - pidlock::Pidlock::new("/tmp/distrox_server.pid") -} - -pub fn do_start(cli: &CLI) -> bool { - cli.cmd().map(|cmd| Command::Server == *cmd).unwrap_or(false) -} - -pub fn is_running(server_lock: &Pidlock) -> bool { - PathBuf::from("/tmp/distrox_server.pid").exists() -} - - -pub async fn run_server(config: Configuration, mut server_lock: Pidlock, adr: String) -> Result<()> { - let app = { - let device_name = config.get_device_name(); - let device_key = config.get_device_key(); - - if let (Some(name), Some(key)) = (device_name, device_key) { - let name = IPNSHash::from(name.clone()); - let key = key.clone(); - let api_url = config.get_api_url().clone(); - let api_port = config.get_api_port().clone(); - - Middleware::load(name, key, &api_url, api_port) - } else { - // ask user for name(s) - // boot repository - // load Middleware object - unimplemented!() - } - }?; - - info!("Starting server"); - let _ = server_lock.acquire().map_err(|_| anyhow!("Error while getting the PID lock"))?; - - info!("Got PID lock for server"); - actix_web::HttpServer::new(|| { - actix_web::App::new() - .route("*", actix_web::web::get().to(index)) - }) - .bind(adr.clone()) - .expect(&format!("Could not bind to address {}", adr)) - .run() - .await; - - info!("Server shutdown"); - info!("Releasing PID lock for server"); - server_lock.release().map_err(|_| anyhow!("Error while releasing the PID lock")) -} - -async fn index() -> impl Responder { - debug!("serve index"); - let s = format!("{pre}{style}{index}{post}", - pre = include_str!("../assets/index_pre.html"), - style = include_str!("../assets/style.css"), - index = include_str!("../assets/index.html"), - post = include_str!("../assets/index_post.html"), - ); - - HttpResponse::build(StatusCode::OK).body(Body::from_slice(s.as_bytes())) -} - diff --git a/src/types/block.rs b/src/types/block.rs deleted file mode 100644 index c70ceef..0000000 --- a/src/types/block.rs +++ /dev/null @@ -1,85 +0,0 @@ -use crate::types::util::IPFSHash; -use crate::types::util::Version; -use crate::types::content::Content; -use crate::types::payload::*; -use crate::types::content::LoadedContent; -use crate::model::Model; - -use anyhow::Error; - -#[derive(Serialize, Deserialize, Debug)] -pub struct Block { - /// The version of the API in use - #[serde(rename = "v")] - version: Version, - - /// The parents of this Profile instance - /// - /// Multiple are required for merging. - #[serde(rename = "parents")] - #[serde(default)] - parents: Vec<IPFSHash>, - - /// The content of this block, pointed to by IPFS hash. - #[serde(rename = "content")] - content: IPFSHash, -} - -impl Block { - pub fn new(version: Version, parents: Vec<IPFSHash>, content: IPFSHash) -> Self { - Block { version, parents, content } - } - - pub fn version(&self) -> &Version { - &self.version - } - - pub fn parents(&self) -> &Vec<IPFSHash> { - &self.parents - } - - pub fn content(&self) -> &IPFSHash { - &self.content - } - - pub async fn load(self, r: &Model) -> Result<LoadedBlock, Error> { - Ok({ - LoadedBlock { - version: self.version, - parents: self.parents, - content: r.get_content(&self.content) - .await? - .load(r) - .await? - } - }) - } -} - -impl AsRef<Block> for Block { - fn as_ref(&self) -> &Self { - &self - } -} - -#[derive(Debug)] -pub struct LoadedBlock { - version: Version, - parents: Vec<IPFSHash>, - content: LoadedContent, -} - -impl LoadedBlock { - pub fn version(&self) -> &Version { - &self.version - } - - pub fn parents(&self) -> &Vec<IPFSHash> { - &self.parents - } - - pub fn content(&self) -> &LoadedContent { - &self.content - } -} - diff --git a/src/types/content.rs b/src/types/content.rs deleted file mode 100644 index 8b6eb4d..0000000 --- a/src/types/content.rs +++ /dev/null @@ -1,104 +0,0 @@ -use std::collections::BTreeMap; - -use anyhow::Error; - -use crate::types::util::IPFSHash; -use crate::types::util::IPNSHash; -use crate::types::util::MimeType; -use crate::types::util::Timestamp; -use crate::types::payload::Payload; -use crate::types::payload::LoadedPayload; -use crate::model::Model; - -#[derive(Serialize, Deserialize, Debug)] -pub struct Content { - - // - // - // Metadata about the content - // -------------------------- - // - // This metadata should be added to each block version. It is a small amount of bytes, but it - // makes the aggregation much simpler. - // - // In v2 of the API, we might change this and put all this meta-information into variants of - // `Payload`, if we find that aggregation is fast enough. - // - - /// A list of IPNS hashes which are posting to this chain (so if a client has one profile - /// node, it can find the latest profile nodes from all devices a user posts from) - #[serde(rename = "devices")] - devices: Vec<IPNSHash>, - - /// Timestamp (UNIX timestamp) when this was created. Can be left out. - #[serde(rename = "timestamp")] - #[serde(default)] - timestamp: Option<Timestamp>, - - /// The payload of the content block - #[serde(rename = "payload")] - payload: Payload, - -} - -impl Content { - |