mirror of
https://github.com/Dangoware/confetti-box.git
synced 2025-04-19 23:32:58 -05:00
Fixed clippy suggestions, ran cargo fmt
This commit is contained in:
parent
071b3c206c
commit
3892975fc2
6 changed files with 79 additions and 49 deletions
|
@ -1,5 +1,10 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::{hash_map::Values, HashMap, HashSet}, ffi::OsStr, fs::{self, File}, io, path::{Path, PathBuf}, sync::{Arc, RwLock}
|
collections::{hash_map::Values, HashMap, HashSet},
|
||||||
|
ffi::OsStr,
|
||||||
|
fs::{self, File},
|
||||||
|
io,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
use bincode::{config::Configuration, decode_from_std_read, encode_into_std_write, Decode, Encode};
|
use bincode::{config::Configuration, decode_from_std_read, encode_into_std_write, Decode, Encode};
|
||||||
|
@ -63,16 +68,13 @@ impl Mochibase {
|
||||||
/// Save the database to its file
|
/// Save the database to its file
|
||||||
pub fn save(&self) -> Result<(), io::Error> {
|
pub fn save(&self) -> Result<(), io::Error> {
|
||||||
// Create a file and write the LZ4 compressed stream into it
|
// Create a file and write the LZ4 compressed stream into it
|
||||||
let file = File::create(&self.path.with_extension("bkp"))?;
|
let file = File::create(self.path.with_extension("bkp"))?;
|
||||||
let mut lz4_file = lz4_flex::frame::FrameEncoder::new(file);
|
let mut lz4_file = lz4_flex::frame::FrameEncoder::new(file);
|
||||||
encode_into_std_write(self, &mut lz4_file, BINCODE_CFG)
|
encode_into_std_write(self, &mut lz4_file, BINCODE_CFG)
|
||||||
.map_err(|e| io::Error::other(format!("failed to save database: {e}")))?;
|
.map_err(|e| io::Error::other(format!("failed to save database: {e}")))?;
|
||||||
lz4_file.try_finish()?;
|
lz4_file.try_finish()?;
|
||||||
|
|
||||||
fs::rename(
|
fs::rename(self.path.with_extension("bkp"), &self.path).unwrap();
|
||||||
self.path.with_extension("bkp"),
|
|
||||||
&self.path
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -283,14 +285,12 @@ pub async fn clean_loop(
|
||||||
|
|
||||||
/// A unique identifier for an entry in the database, 8 characters long,
|
/// A unique identifier for an entry in the database, 8 characters long,
|
||||||
/// consists of ASCII alphanumeric characters (`a-z`, `A-Z`, and `0-9`).
|
/// consists of ASCII alphanumeric characters (`a-z`, `A-Z`, and `0-9`).
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
#[derive(Debug, PartialEq, Eq, Clone, Hash, Decode, Encode, Deserialize, Serialize)]
|
||||||
#[derive(Decode, Encode)]
|
|
||||||
#[derive(Deserialize, Serialize)]
|
|
||||||
pub struct Mmid(String);
|
pub struct Mmid(String);
|
||||||
|
|
||||||
impl Mmid {
|
impl Mmid {
|
||||||
/// Create a new random MMID
|
/// Create a new random MMID
|
||||||
pub fn new() -> Self {
|
pub fn new_random() -> Self {
|
||||||
let string = Alphanumeric.sample_string(&mut rand::thread_rng(), 8);
|
let string = Alphanumeric.sample_string(&mut rand::thread_rng(), 8);
|
||||||
|
|
||||||
Self(string)
|
Self(string)
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
use std::{str::FromStr, sync::{Arc, RwLock}};
|
use std::{
|
||||||
|
str::FromStr,
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
};
|
||||||
|
|
||||||
use rocket::{
|
use rocket::{
|
||||||
get,
|
get,
|
||||||
|
@ -11,7 +14,7 @@ use rocket::{
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
database::{Mochibase, Mmid, MochiFile},
|
database::{Mmid, MochiFile, Mochibase},
|
||||||
settings::Settings,
|
settings::Settings,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,10 +37,7 @@ pub fn server_info(settings: &State<Settings>) -> Json<ServerInfo> {
|
||||||
|
|
||||||
/// Get information about a file
|
/// Get information about a file
|
||||||
#[get("/info/<mmid>")]
|
#[get("/info/<mmid>")]
|
||||||
pub async fn file_info(
|
pub async fn file_info(db: &State<Arc<RwLock<Mochibase>>>, mmid: &str) -> Option<Json<MochiFile>> {
|
||||||
db: &State<Arc<RwLock<Mochibase>>>,
|
|
||||||
mmid: &str,
|
|
||||||
) -> Option<Json<MochiFile>> {
|
|
||||||
let mmid: Mmid = mmid.try_into().ok()?;
|
let mmid: Mmid = mmid.try_into().ok()?;
|
||||||
let entry = db.read().unwrap().get(&mmid).cloned()?;
|
let entry = db.read().unwrap().get(&mmid).cloned()?;
|
||||||
|
|
||||||
|
|
55
src/lib.rs
55
src/lib.rs
|
@ -1,23 +1,28 @@
|
||||||
pub mod database;
|
pub mod database;
|
||||||
pub mod endpoints;
|
pub mod endpoints;
|
||||||
|
pub mod pages;
|
||||||
|
pub mod resources;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
pub mod strings;
|
pub mod strings;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod pages;
|
|
||||||
pub mod resources;
|
|
||||||
|
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
|
||||||
use crate::database::{Mmid, MochiFile, Mochibase};
|
use crate::database::{Mmid, MochiFile, Mochibase};
|
||||||
use maud::{html, Markup, PreEscaped};
|
|
||||||
use crate::pages::{footer, head};
|
use crate::pages::{footer, head};
|
||||||
use rocket::{
|
|
||||||
data::ToByteUnit, form::Form, fs::TempFile, get, post, serde::{json::Json, Serialize}, FromForm, State
|
|
||||||
};
|
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
use crate::strings::{parse_time_string, to_pretty_time};
|
use crate::strings::{parse_time_string, to_pretty_time};
|
||||||
use crate::utils::hash_file;
|
use crate::utils::hash_file;
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use maud::{html, Markup, PreEscaped};
|
||||||
|
use rocket::{
|
||||||
|
data::ToByteUnit,
|
||||||
|
form::Form,
|
||||||
|
fs::TempFile,
|
||||||
|
get, post,
|
||||||
|
serde::{json::Json, Serialize},
|
||||||
|
FromForm, State,
|
||||||
|
};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
|
@ -97,19 +102,19 @@ pub async fn handle_upload(
|
||||||
};
|
};
|
||||||
|
|
||||||
let raw_name = file_data
|
let raw_name = file_data
|
||||||
.file
|
.file
|
||||||
.raw_name()
|
.raw_name()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.dangerous_unsafe_unsanitized_raw()
|
.dangerous_unsafe_unsanitized_raw()
|
||||||
.as_str()
|
.as_str()
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
// Get temp path for the file
|
// Get temp path for the file
|
||||||
let temp_filename = settings.temp_dir.join(Uuid::new_v4().to_string());
|
let temp_filename = settings.temp_dir.join(Uuid::new_v4().to_string());
|
||||||
file_data.file.persist_to(&temp_filename).await?;
|
file_data.file.persist_to(&temp_filename).await?;
|
||||||
|
|
||||||
// Get hash and random identifier and expiry
|
// Get hash and random identifier and expiry
|
||||||
let file_mmid = Mmid::new();
|
let file_mmid = Mmid::new_random();
|
||||||
let file_hash = hash_file(&temp_filename).await?;
|
let file_hash = hash_file(&temp_filename).await?;
|
||||||
let expiry = current + expire_time;
|
let expiry = current + expire_time;
|
||||||
|
|
||||||
|
@ -118,11 +123,11 @@ pub async fn handle_upload(
|
||||||
|
|
||||||
let constructed_file = MochiFile::new(
|
let constructed_file = MochiFile::new(
|
||||||
file_mmid.clone(),
|
file_mmid.clone(),
|
||||||
raw_name,
|
raw_name,
|
||||||
file_type.media_type().to_string(),
|
file_type.media_type().to_string(),
|
||||||
file_hash,
|
file_hash,
|
||||||
current,
|
current,
|
||||||
expiry
|
expiry,
|
||||||
);
|
);
|
||||||
|
|
||||||
// If the hash does not exist in the database,
|
// If the hash does not exist in the database,
|
||||||
|
@ -133,15 +138,17 @@ pub async fn handle_upload(
|
||||||
std::fs::remove_file(temp_filename)?;
|
std::fs::remove_file(temp_filename)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
db.write().unwrap().insert(&file_mmid, constructed_file.clone());
|
db.write()
|
||||||
|
.unwrap()
|
||||||
|
.insert(&file_mmid, constructed_file.clone());
|
||||||
|
|
||||||
Ok(Json(ClientResponse {
|
Ok(Json(ClientResponse {
|
||||||
status: true,
|
status: true,
|
||||||
name: constructed_file.name().clone(),
|
name: constructed_file.name().clone(),
|
||||||
mmid: Some(constructed_file.mmid().clone()),
|
mmid: Some(constructed_file.mmid().clone()),
|
||||||
hash: constructed_file.hash().to_string(),
|
hash: constructed_file.hash().to_string(),
|
||||||
expires: Some(constructed_file.expiry()),
|
expires: Some(constructed_file.expiry()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
src/main.rs
21
src/main.rs
|
@ -1,7 +1,14 @@
|
||||||
use std::{fs, sync::{Arc, RwLock}};
|
use std::{
|
||||||
|
fs,
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
};
|
||||||
|
|
||||||
use chrono::TimeDelta;
|
use chrono::TimeDelta;
|
||||||
use confetti_box::{database::{clean_loop, Mochibase}, endpoints, pages, resources, settings::Settings};
|
use confetti_box::{
|
||||||
|
database::{clean_loop, Mochibase},
|
||||||
|
endpoints, pages, resources,
|
||||||
|
settings::Settings,
|
||||||
|
};
|
||||||
use log::info;
|
use log::info;
|
||||||
use rocket::{data::ToByteUnit as _, routes, tokio};
|
use rocket::{data::ToByteUnit as _, routes, tokio};
|
||||||
|
|
||||||
|
@ -29,7 +36,9 @@ async fn main() {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let database = Arc::new(RwLock::new(Mochibase::open_or_new(&config.database_path).expect("Failed to open or create database")));
|
let database = Arc::new(RwLock::new(
|
||||||
|
Mochibase::open_or_new(&config.database_path).expect("Failed to open or create database"),
|
||||||
|
));
|
||||||
let local_db = database.clone();
|
let local_db = database.clone();
|
||||||
|
|
||||||
// Start monitoring thread, cleaning the database every 2 minutes
|
// Start monitoring thread, cleaning the database every 2 minutes
|
||||||
|
@ -81,6 +90,10 @@ async fn main() {
|
||||||
info!("Stopping database cleaning thread completed successfully.");
|
info!("Stopping database cleaning thread completed successfully.");
|
||||||
|
|
||||||
info!("Saving database on shutdown...");
|
info!("Saving database on shutdown...");
|
||||||
local_db.write().unwrap().save().expect("Failed to save database");
|
local_db
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.save()
|
||||||
|
.expect("Failed to save database");
|
||||||
info!("Saving database completed successfully.");
|
info!("Saving database completed successfully.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use maud::{html, Markup, DOCTYPE};
|
use maud::{html, Markup, DOCTYPE};
|
||||||
use rocket::{get, http::ContentType, response::content::{RawCss, RawJavaScript}, State};
|
use rocket::{get, State};
|
||||||
|
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,21 @@
|
||||||
use rocket::{get, http::ContentType, response::content::{RawCss, RawJavaScript}};
|
use rocket::{
|
||||||
|
get,
|
||||||
|
http::ContentType,
|
||||||
|
response::content::{RawCss, RawJavaScript},
|
||||||
|
};
|
||||||
|
|
||||||
#[get("/resources/fonts/<font>")]
|
#[get("/resources/fonts/<font>")]
|
||||||
pub fn font_static(font: &str) -> Option<(ContentType, &'static [u8])> {
|
pub fn font_static(font: &str) -> Option<(ContentType, &'static [u8])> {
|
||||||
match font {
|
match font {
|
||||||
"Roboto.woff2" => Some((ContentType::WOFF2, include_bytes!("../web/fonts/roboto.woff2"))),
|
"Roboto.woff2" => Some((
|
||||||
"FiraCode.woff2" => Some((ContentType::WOFF2, include_bytes!("../web/fonts/fira-code.woff2"))),
|
ContentType::WOFF2,
|
||||||
_ => None
|
include_bytes!("../web/fonts/roboto.woff2"),
|
||||||
|
)),
|
||||||
|
"FiraCode.woff2" => Some((
|
||||||
|
ContentType::WOFF2,
|
||||||
|
include_bytes!("../web/fonts/fira-code.woff2"),
|
||||||
|
)),
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue