use crate::addressing::Address; use crate::database::Entry; use crate::hash::{decode, encode}; use actix::prelude::*; use actix_files::NamedFile; use actix_web::error::{ErrorBadRequest, ErrorInternalServerError}; use actix_web::{error, get, post, web, Error, HttpResponse}; use anyhow::Result; use log::debug; use serde::Deserialize; use std::collections::HashMap; use std::path::PathBuf; #[derive(Clone)] pub struct State { pub directory: PathBuf, pub db: Addr, pub hasher: Addr, } #[get("/raw/{hash}")] pub async fn get_raw(state: web::Data, hash: web::Path) -> Result { let address = Address::decode(&decode(hash.into_inner()).map_err(ErrorInternalServerError)?) .map_err(ErrorInternalServerError)?; if let Address::Hash(hash) = address { let response = state .db .send(crate::database::RetrieveByHash { hash }) .await?; debug!("{:?}", response); match response { Ok(result) => match result { Some(path) => Ok(NamedFile::open(path)?), None => Err(error::ErrorNotFound("NOT FOUND")), }, Err(e) => Err(error::ErrorInternalServerError(e)), } } else { Err(ErrorBadRequest("Address does not refer to a file.")) } } #[get("/get/{address_str}")] pub async fn get_object( state: web::Data, address_str: web::Path, ) -> Result { let response: Result> = state .db .send(crate::database::RetrieveObject { target: Address::decode( &decode(address_str.into_inner()).map_err(ErrorInternalServerError)?, ) .map_err(ErrorInternalServerError)?, }) .await?; debug!("{:?}", response); let mut result: HashMap = HashMap::new(); for entry in response.map_err(error::ErrorInternalServerError)? { result.insert(encode(&entry.identity.0), entry.as_json()); } Ok(HttpResponse::Ok().json(result)) } #[derive(Deserialize)] pub struct LookupRequest { query: String, } #[get("/api/lookup")] pub async fn get_lookup( state: web::Data, web::Query(info): web::Query, ) -> Result { let response = state .db .send(crate::database::LookupByFilename { query: info.query }) .await?; Ok(HttpResponse::Ok().json(response.map_err(error::ErrorInternalServerError)?)) } #[post("/api/refresh")] pub async fn api_refresh(state: web::Data) -> Result { actix::spawn(crate::filesystem::reimport_directory( state.directory.clone(), state.db.clone(), state.hasher.clone(), )); Ok(HttpResponse::Ok().finish()) }