Initial commit

This commit is contained in:
2022-11-02 15:46:41 +01:00
commit 1d32fb0365
9 changed files with 1343 additions and 0 deletions

93
src/main.rs Normal file
View File

@@ -0,0 +1,93 @@
use std::{env, fs};
use chrono::Utc;
use kv::{Config, Store, Json};
use paste::Paste;
use rand::{Rng, distributions::Alphanumeric};
use rouille::{Response, router, try_or_400, post_input};
mod paste;
// Generate random key function
fn new_key() -> String {
rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(5)
.map(char::from)
.collect()
}
fn main() {
// Get settings
let port: u16 = env::var("PORT").unwrap_or(String::from("8080")).parse().expect("Failed to parse PORT variable");
let data_dir: String = env::var("DATA_DIR").unwrap_or(String::from("./data"));
let config = Config::new(data_dir);
let store = Store::new(config).expect("Failed to initialize database store");
let about = fs::read_to_string("./about.html").expect("about.html not found!!");
// Get pastes bucket (default)
let pastes = store.bucket::<String, Json<Paste>>(Some("pastes"))
.expect("Failed to open default bucket");
// Start server
println!("Started PASTABBLE server on port {}", port);
rouille::start_server(format!("0.0.0.0:{}", port), move |req| {
router!(req,
(GET) (/) => {
Response::html(&about)
},
(GET) (/{id: String}) => {
// Get note from database, if exists
match pastes.get(&id).expect("Failed to access DB") {
Some(paste) => {
Response::text(paste.0.content)
},
None => {
Response::text(format!("Note with ID '{}' not found", &id))
.with_status_code(404)
}
}
},
(POST) (/{id: String}) => {
// Use provided key or generate new one
let key = if !id.is_empty() && !pastes.contains(&id).unwrap() {
id
} else {
loop {
let new_key = new_key();
if !pastes.contains(&new_key).expect("Could not access store") {
break new_key;
}
}
};
// Try read body from form data, and if not present from request body
let body = match post_input!(&req, {
content: String
}) {
Ok(f) => {
f.content
},
Err(_) => {
try_or_400!(rouille::input::plain_text_body(&req))
}
};
// Create and save new note
let paste = Json(Paste {
content: body,
expires: None,
language: None,
created: Utc::now()
});
pastes.set(&key, &paste).expect("Failed to save note");
// Return key
Response::text(key)
},
_ => Response::empty_404()
)
});
}

13
src/paste.rs Normal file
View File

@@ -0,0 +1,13 @@
use chrono::{DateTime, Utc};
use serde::{Serialize, Deserialize};
use chrono::serde::ts_seconds_option;
#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct Paste {
pub content: String,
pub language: Option<String>,
#[serde(with = "ts_seconds_option")]
pub expires: Option<DateTime<Utc>>,
pub created: DateTime<Utc>
}