mirror of
https://github.com/YGGverse/titanit.git
synced 2026-03-31 09:05:45 +00:00
dump meta on file commit
This commit is contained in:
parent
7bf68725db
commit
a1ccc27cb8
2 changed files with 56 additions and 7 deletions
34
src/main.rs
34
src/main.rs
|
|
@ -97,7 +97,7 @@ fn gemini(
|
||||||
match storage::Item::from_url(gemini.url.as_str(), &argument.directory) {
|
match storage::Item::from_url(gemini.url.as_str(), &argument.directory) {
|
||||||
Ok(item) => send(
|
Ok(item) => send(
|
||||||
&response::success::Default {
|
&response::success::Default {
|
||||||
mime: "text/gemini".to_string(),
|
mime: item.mime,
|
||||||
//data: item.file.read(vec![1000]),
|
//data: item.file.read(vec![1000]),
|
||||||
}
|
}
|
||||||
.into_bytes(),
|
.into_bytes(),
|
||||||
|
|
@ -128,8 +128,29 @@ fn titan(
|
||||||
stream: &mut TlsStream<TcpStream>,
|
stream: &mut TlsStream<TcpStream>,
|
||||||
) {
|
) {
|
||||||
use titanite::*;
|
use titanite::*;
|
||||||
|
// require content type for application,
|
||||||
|
// even MIME value is optional by Titan specification
|
||||||
|
let mime = match titan.mime {
|
||||||
|
Some(mime) => mime,
|
||||||
|
None => {
|
||||||
|
const MESSAGE: &str = "Content type is required";
|
||||||
|
return send(
|
||||||
|
&response::failure::permanent::BadRequest {
|
||||||
|
message: Some(MESSAGE.to_string()),
|
||||||
|
}
|
||||||
|
.into_bytes(),
|
||||||
|
stream,
|
||||||
|
|result| match result {
|
||||||
|
Ok(()) => println!("[{}] [warning] [{peer}] {MESSAGE}", now()),
|
||||||
|
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// validate total bytes
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
match storage::Item::create(&argument.directory) {
|
// create new destination file
|
||||||
|
match storage::Item::create(&argument.directory, mime) {
|
||||||
Ok(mut tmp) => loop {
|
Ok(mut tmp) => loop {
|
||||||
let mut input = vec![0; argument.chunk];
|
let mut input = vec![0; argument.chunk];
|
||||||
match stream.read(&mut input) {
|
match stream.read(&mut input) {
|
||||||
|
|
@ -205,10 +226,13 @@ fn titan(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// just to make sure
|
||||||
|
if titan.size > total {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
|
|
||||||
// all data received
|
// all data received
|
||||||
if titan.size >= total {
|
if titan.size == total {
|
||||||
// @TODO detect/validate/cache mime based on data received
|
|
||||||
// success
|
|
||||||
return match tmp.commit() {
|
return match tmp.commit() {
|
||||||
Ok(pmt) => send(
|
Ok(pmt) => send(
|
||||||
&response::redirect::Permanent {
|
&response::redirect::Permanent {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use anyhow::{anyhow, bail, Error, Result};
|
use anyhow::{anyhow, bail, Error, Result};
|
||||||
use std::{
|
use std::{
|
||||||
fs::{create_dir_all, remove_file, rename, File},
|
fs::{create_dir_all, remove_file, rename, File},
|
||||||
|
io::{Read, Write},
|
||||||
path::{PathBuf, MAIN_SEPARATOR},
|
path::{PathBuf, MAIN_SEPARATOR},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
thread,
|
thread,
|
||||||
|
|
@ -8,10 +9,12 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
const TMP_SUFFIX: &str = ".tmp";
|
const TMP_SUFFIX: &str = ".tmp";
|
||||||
|
const META_SUFFIX: &str = ".meta";
|
||||||
|
|
||||||
pub struct Item {
|
pub struct Item {
|
||||||
pub file: File,
|
pub file: File,
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
|
pub mime: String,
|
||||||
// pub id: u64,
|
// pub id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,12 +45,13 @@ impl Item {
|
||||||
))?;
|
))?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
file: File::open(&path)?,
|
file: File::open(&path)?,
|
||||||
|
mime: read_meta(path.to_str().unwrap())?,
|
||||||
path,
|
path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new `Self` with unique pathname in the root `directory`
|
/// Create new `Self` with unique pathname in the root `directory`
|
||||||
pub fn create(directory: &str) -> Result<Self> {
|
pub fn create(directory: &str, mime: String) -> Result<Self> {
|
||||||
loop {
|
loop {
|
||||||
// generate file id from current unix time
|
// generate file id from current unix time
|
||||||
let id = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
|
let id = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
|
||||||
|
|
@ -77,6 +81,7 @@ impl Item {
|
||||||
return Ok(Self {
|
return Ok(Self {
|
||||||
file,
|
file,
|
||||||
path,
|
path,
|
||||||
|
mime,
|
||||||
// id
|
// id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +107,10 @@ impl Item {
|
||||||
Ok(path) => path,
|
Ok(path) => path,
|
||||||
Err(e) => return Err((self, anyhow!(e))),
|
Err(e) => return Err((self, anyhow!(e))),
|
||||||
};
|
};
|
||||||
Ok(self)
|
match self.write_meta() {
|
||||||
|
Ok(()) => Ok(self),
|
||||||
|
Err(e) => Err((self, anyhow!(e))),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(e) => Err((self, anyhow!(e))),
|
Err(e) => Err((self, anyhow!(e))),
|
||||||
},
|
},
|
||||||
|
|
@ -127,4 +135,21 @@ impl Item {
|
||||||
.replace(directory, "")
|
.replace(directory, "")
|
||||||
.replace("/", "")
|
.replace("/", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// System
|
||||||
|
|
||||||
|
fn write_meta(&self) -> Result<()> {
|
||||||
|
Ok(File::create_new(meta_path(self.path.to_str().unwrap()))?
|
||||||
|
.write_all(self.mime.as_bytes())?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn meta_path(path: &str) -> String {
|
||||||
|
format!("{}{META_SUFFIX}", path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_meta(path: &str) -> Result<String> {
|
||||||
|
let mut buffer = String::new();
|
||||||
|
File::open(meta_path(path))?.read_to_string(&mut buffer)?;
|
||||||
|
Ok(buffer)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue