Skip to content

Commit

Permalink
build successful
Browse files Browse the repository at this point in the history
  • Loading branch information
jaybutera committed Aug 23, 2023
1 parent 0158cb1 commit 5a69711
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 19 deletions.
91 changes: 78 additions & 13 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@ mod utils;
use actix_session::Session;
use actix_web::{web, App, HttpServer, HttpResponse, Result, HttpRequest, post, get};
use actix_cors::Cors;

use types::{AnyError, VerificationPayload, ServerState, Index, TopicData, MediaUid};
use types::{
AnyError,
VerificationPayload,
ServerState,
Args,
TopicData,
MediaUid};
use ed25519_dalek::{SigningKey, Signature, Verifier, VerifyingKey};
use anyhow::anyhow;
use std::str::FromStr;
use http_types::mime::{self, Mime};
use std::path::PathBuf;
use acidjson::AcidJson;
use rand_core;
use smol::stream::StreamExt;
use structopt::StructOpt;

use crate::utils::{
save_file,
Expand All @@ -33,6 +40,33 @@ fn normalize_topic(topic: &str) -> String {
.trim().to_string()
}

/// Start the thumbnail generator process which generates for all files passed on the channel
async fn thumbnail_generator(args: &Args) -> smol::channel::Sender<PathBuf> {
// Concurrently maintain a queue of thumbnails to generate,
// at most N at a time
let thumbnail_queue = async_channel::unbounded::<PathBuf>();
let thumbnail_queue_sender = thumbnail_queue.0.clone();
let mut thumbnail_queue_receiver = thumbnail_queue.1.clone();

let mut thumbnail_path = args.root_dir.clone();
thumbnail_path.push("thumbnails");

smol::spawn(async move {
while let Some(path) = thumbnail_queue_receiver.next().await {
let max_thumbnail_size = 500;
let res = save_thumbnail(
path.clone(), thumbnail_path.clone(),
max_thumbnail_size)
.await;
if let Err(e) = res {
log::error!("Error saving thumbnail: {}", e);
}
}
}).detach();

thumbnail_queue_sender
}

/*
async fn main_async() -> Result<()> {
let args = types::Args::from_args();
Expand Down Expand Up @@ -140,11 +174,13 @@ async fn generate_challenge(
#[post("/authenticate")]
async fn authenticate(
session: Session,
data: web::Data<ServerState>,
//data: web::Data<ServerState>,
payload: web::Json<VerificationPayload>,
) -> Result<HttpResponse> {
let pubkey: [u8; 32] = payload.public_key[..].try_into()?;
let public_key = VerifyingKey::from_bytes(&pubkey)?;
let pubkey: [u8; 32] = payload.public_key[..].try_into()
.map_err(|_| AnyError::from(anyhow!("Invalid public key length!")))?;
let public_key = VerifyingKey::from_bytes(&pubkey)
.map_err(|_| AnyError::from(anyhow!("Invalid public key!")))?;

//let sid = req.session().id();
//info!("Session ID: {}", sid);
Expand All @@ -163,7 +199,7 @@ async fn authenticate(
session.insert("verified", true)?;
Ok(HttpResponse::Ok().finish())
} else {
Err(anyhow!("Signature is invalid!").into())
Err(AnyError::from(anyhow!("Signature is invalid!")).into())
}
}

Expand Down Expand Up @@ -458,18 +494,47 @@ fn from_extension(extension: impl AsRef<str>) -> Option<Mime> {

#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
env_logger::init_from_env(env_logger::Env::new().default_filter_or("debug"));

let args = Args::from_args();
let port = args.port;
//log::start();

// If migrate is true, run migrate function instead of starting server
if args.migrate {
//generate_thumbnails(&args.root_dir).await?;
//update_media_names(&args.root_dir).await?;
return Ok(());
}

let thumbnail_sender = thumbnail_generator(&args).await;
let state = ServerState {
args: args.clone(),
thumbnail_sender,
};

use actix_web::web::Data;
HttpServer::new(move || {
App::new()
.wrap(
Cors::permissive()
)
.app_data(Data::new(state.clone()))
//.wrap(middleware::Compress::default())
.wrap(Cors::permissive())
.service(get_index)
.service(upload_image)
.service(get_image_list)
.service(get_tag_list)
.service(add_tag_to_topic)
.service(rm_tag_from_topic)
.service(get_image_thumbnail)
.service(get_image_full)
.service(generate_keys)
.service(generate_challenge)
.service(authenticate)
.wrap(actix_web::middleware::Logger::default())
// TODO use a better session key and secure it
.wrap(actix_session::CookieSession::signed(&[0; 32]).secure(false))
.service(generate_challenge)
.service(authenticate)
})
.bind("localhost:2342")?
.bind(format!("localhost:{}", port))?
.run()
.await
}
8 changes: 3 additions & 5 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use structopt::StructOpt;
use serde::{Serialize, Deserialize};
use std::collections::HashSet;
use log::info;
use std::fmt::Display;

#[derive(Serialize, Deserialize, PartialEq, Eq)]
pub struct HashVal([u8; 32]);
Expand Down Expand Up @@ -34,10 +33,9 @@ impl::std::fmt::Display for AnyError {
}

/*
impl std::fmt::Display for HashVal {
// This trait requires `fmt` with this exact signature.
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?}", self.0)
impl AnyError {
pub fn anyhow(s: &str) -> Self {
AnyError::from(anyhow::anyhow!(s))
}
}
*/
Expand Down
12 changes: 11 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,11 @@ pub async fn save_file(
thumbnail_sender: smol::channel::Sender<PathBuf>,
) -> anyhow::Result<String> {
let mut hasher = Hasher::new();
// First give it a random temp name
let file = File::create(rand_string()).await?;
let mut buf_writer = BufWriter::new(file);

// TODO limit chunk size
let mut buf_writer = BufWriter::new(file);
while let Some(chunk) = payload.next().await {
let chunk = chunk?;
hasher.update(&chunk);
Expand All @@ -383,5 +385,13 @@ pub async fn save_file(

let uid = hex::encode(hash_output);

// Rename file
let image_fname = format!("{}.{}", uid, ext);
let image_path = root_dir.join(&image_fname);
smol::fs::rename(&image_fname, &image_path).await?;

// Save thumbnail
thumbnail_sender.send(image_path.clone()).await?;

Ok(uid)
}

0 comments on commit 5a69711

Please sign in to comment.