Skip to content

Commit

Permalink
Merge pull request #3 from javerik/refactor_database
Browse files Browse the repository at this point in the history
javerik: Refactored db_sqlite.rs and the usage.
  • Loading branch information
kendofriendo authored Nov 30, 2023
2 parents bbf54c8 + 8365966 commit 91eb288
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 160 deletions.
4 changes: 3 additions & 1 deletion src/endpoints/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,9 @@ pub async fn create(

for (_, pasta) in pastas.iter().enumerate() {
if pasta.id == id {
insert(Some(&pastas), Some(pasta));
if let Err(e) = insert(Some(&pastas), Some(pasta)){
log::error!("Failed to insert pasta with id {} => {}", pasta.id, e);
}
}
}

Expand Down
21 changes: 17 additions & 4 deletions src/endpoints/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::util::misc::{decrypt, encrypt, remove_expired};
use crate::{AppState, Pasta, ARGS};
use actix_multipart::Multipart;
use actix_web::{get, post, web, Error, HttpResponse};
use actix_web::error::ErrorInternalServerError;
use askama::Template;
use futures::TryStreamExt;

Expand Down Expand Up @@ -168,7 +169,10 @@ pub async fn post_edit_private(
.content
.replace_range(.., res.unwrap().as_str());
// save pasta in database
update(Some(&pastas), Some(&pastas[index]));
if let Err(e) = update(Some(&pastas), Some(&pastas[index])) {
log::error!("Failed to update pastas => {}", e);
return Err(ErrorInternalServerError("Database update error"));
}
} else {
return Ok(HttpResponse::Found()
.append_header((
Expand Down Expand Up @@ -272,7 +276,10 @@ pub async fn post_submit_edit_private(
.content
.replace_range(.., &encrypt(&new_content, &password));
// save pasta in database
update(Some(&pastas), Some(&pastas[index]));
if let Err(e) = update(Some(&pastas), Some(&pastas[index])) {
log::error!("Update error for pasta with id {} => {}", &pastas[index].id, e);
return Err(ErrorInternalServerError("Database update error"));
}
} else {
return Ok(HttpResponse::Found()
.append_header((
Expand Down Expand Up @@ -339,7 +346,10 @@ pub async fn post_edit(
if res.is_ok() {
pastas[i].content.replace_range(.., &new_content);
// save pasta in database
update(Some(&pastas), Some(&pastas[i]));
if let Err(e) = update(Some(&pastas), Some(&pastas[i])) {
log::error!("Failed to update pasta with id {} => {}", &pastas[i].id, e);
return Err(ErrorInternalServerError("Database update error"))
}
} else {
return Ok(HttpResponse::Found()
.append_header((
Expand All @@ -359,7 +369,10 @@ pub async fn post_edit(
} else {
pastas[i].content.replace_range(.., &new_content);
// save pasta in database
update(Some(&pastas), Some(&pastas[i]));
if let Err(e) = update(Some(&pastas), Some(&pastas[i])) {
log::error!("Failed to update pasta with id {} => {}", &pastas[i].id, e);
return Err(ErrorInternalServerError("Database update error"))
}
}

return Ok(HttpResponse::Found()
Expand Down
75 changes: 47 additions & 28 deletions src/endpoints/pasta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use askama::Template;
use futures::TryStreamExt;
use magic_crypt::{new_magic_crypt, MagicCryptTrait};
use std::time::{SystemTime, UNIX_EPOCH};
use actix_web::error::ErrorInternalServerError;

#[derive(Template)]
#[template(path = "upload.html", escape = "none")]
Expand All @@ -24,7 +25,7 @@ fn pastaresponse(
data: web::Data<AppState>,
id: web::Path<String>,
password: String,
) -> HttpResponse {
) -> Result<HttpResponse, Error> {
// get access to the pasta collection
let mut pastas = data.pastas.lock().unwrap();

Expand All @@ -50,19 +51,22 @@ fn pastaresponse(

if found {
if pastas[index].encrypt_server && password == *"" {
return HttpResponse::Found()
return Ok(HttpResponse::Found()
.append_header((
"Location",
format!("/auth/{}", pastas[index].id_as_animals()),
))
.finish();
.finish());
}

// increment read count
pastas[index].read_count += 1;

// save the updated read count
update(Some(&pastas), Some(&pastas[index]));
if let Err(error) = update(Some(&pastas), Some(&pastas[index])) {
log::error!("Failed to update pasta with id {} => {}", &pastas[index].id, error);
return Err(ErrorInternalServerError("Database update error"))
}

let original_content = pastas[index].content.to_owned();

Expand All @@ -74,12 +78,12 @@ fn pastaresponse(
.content
.replace_range(.., res.unwrap().as_str());
} else {
return HttpResponse::Found()
return Ok(HttpResponse::Found()
.append_header((
"Location",
format!("/auth/{}/incorrect", pastas[index].id_as_animals()),
))
.finish();
.finish());
}
}

Expand Down Expand Up @@ -108,17 +112,19 @@ fn pastaresponse(

// update last read time
pastas[index].last_read = timenow;

// save the updated read count
update(Some(&pastas), Some(&pastas[index]));
if let Err(e) = update(Some(&pastas), Some(&pastas[index])) {
log::error!("Failed to update pasta with id {} => {}", &pastas[index].id, e);
return Err(ErrorInternalServerError("Database update error"))
}

return response;
return Ok(response);
}

// otherwise send pasta not found error
HttpResponse::Ok()
Ok(HttpResponse::Ok()
.content_type("text/html")
.body(ErrorTemplate { args: &ARGS }.render().unwrap())
.body(ErrorTemplate { args: &ARGS }.render().unwrap()))
}

#[post("/upload/{id}")]
Expand All @@ -136,8 +142,7 @@ pub async fn postpasta(
}
}
}

Ok(pastaresponse(data, id, password))
pastaresponse(data, id, password)
}

#[post("/p/{id}")]
Expand All @@ -155,21 +160,20 @@ pub async fn postshortpasta(
}
}
}

Ok(pastaresponse(data, id, password))
pastaresponse(data, id, password)
}

#[get("/upload/{id}")]
pub async fn getpasta(data: web::Data<AppState>, id: web::Path<String>) -> HttpResponse {
pub async fn getpasta(data: web::Data<AppState>, id: web::Path<String>) -> Result<HttpResponse, Error> {
pastaresponse(data, id, String::from(""))
}

#[get("/p/{id}")]
pub async fn getshortpasta(data: web::Data<AppState>, id: web::Path<String>) -> HttpResponse {
pub async fn getshortpasta(data: web::Data<AppState>, id: web::Path<String>) -> Result<HttpResponse, Error> {
pastaresponse(data, id, String::from(""))
}

fn urlresponse(data: web::Data<AppState>, id: web::Path<String>) -> HttpResponse {
fn urlresponse(data: web::Data<AppState>, id: web::Path<String>) -> Result<HttpResponse, Error> {
// get access to the pasta collection
let mut pastas = data.pastas.lock().unwrap();

Expand Down Expand Up @@ -199,7 +203,10 @@ fn urlresponse(data: web::Data<AppState>, id: web::Path<String>) -> HttpResponse
pastas[index].read_count += 1;

// save the updated read count
update(Some(&pastas), Some(&pastas[index]));
if let Err(e) = update(Some(&pastas), Some(&pastas[index])) {
log::error!("Failed to update pasta with id {} => {}", &pastas[index].id, e);
return Err(ErrorInternalServerError("Database update error"))
}

// send redirect if it's a url pasta
if pastas[index].pasta_type == "url" {
Expand All @@ -220,9 +227,12 @@ fn urlresponse(data: web::Data<AppState>, id: web::Path<String>) -> HttpResponse
pastas[index].last_read = timenow;

// save the updated read count
update(Some(&pastas), Some(&pastas[index]));
if let Err(e) = update(Some(&pastas), Some(&pastas[index])) {
log::error!("Failed to update pasta with id {} => {}", &pastas[index].id, e);
return Err(ErrorInternalServerError("Database update error"))
}

return response;
return Ok(response);
// send error if we're trying to open a non-url pasta as a redirect
} else {
HttpResponse::Ok()
Expand All @@ -232,18 +242,18 @@ fn urlresponse(data: web::Data<AppState>, id: web::Path<String>) -> HttpResponse
}

// otherwise send pasta not found error
HttpResponse::Ok()
Ok(HttpResponse::Ok()
.content_type("text/html")
.body(ErrorTemplate { args: &ARGS }.render().unwrap())
.body(ErrorTemplate { args: &ARGS }.render().unwrap()))
}

#[get("/url/{id}")]
pub async fn redirecturl(data: web::Data<AppState>, id: web::Path<String>) -> HttpResponse {
pub async fn redirecturl(data: web::Data<AppState>, id: web::Path<String>) -> Result<HttpResponse, Error> {
urlresponse(data, id)
}

#[get("/u/{id}")]
pub async fn shortredirecturl(data: web::Data<AppState>, id: web::Path<String>) -> HttpResponse {
pub async fn shortredirecturl(data: web::Data<AppState>, id: web::Path<String>) -> Result<HttpResponse, Error> {
urlresponse(data, id)
}

Expand Down Expand Up @@ -289,7 +299,10 @@ pub async fn getrawpasta(
pastas[index].read_count += 1;

// save the updated read count
update(Some(&pastas), Some(&pastas[index]));
if let Err(e) = update(Some(&pastas), Some(&pastas[index])) {
log::error!("Failed to update pasta with id {} => {}", &pastas[index].id, e);
return Err(ErrorInternalServerError("Database update error"))
}

// get current unix time in seconds
let timenow: i64 = match SystemTime::now().duration_since(UNIX_EPOCH) {
Expand Down Expand Up @@ -370,7 +383,10 @@ pub async fn postrawpasta(
pastas[index].read_count += 1;

// save the updated read count
update(Some(&pastas), Some(&pastas[index]));
if let Err(e) = update(Some(&pastas), Some(&pastas[index])) {
log::error!("Failed to update pasta with id {} => {}", &pastas[index].id, e);
return Err(ErrorInternalServerError("Database update error"))
}

let original_content = pastas[index].content.to_owned();

Expand Down Expand Up @@ -404,7 +420,10 @@ pub async fn postrawpasta(
pastas[index].last_read = timenow;

// save the updated read count
update(Some(&pastas), Some(&pastas[index]));
if let Err(e) = update(Some(&pastas), Some(&pastas[index])) {
log::error!("Failed to update pasta with id {} => {}", &pastas[index].id, e);
return Err(ErrorInternalServerError("Database update error"))
}

// send raw content of pasta
let response = Ok(HttpResponse::NotFound()
Expand Down
26 changes: 16 additions & 10 deletions src/endpoints/remove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ use crate::util::misc::{decrypt, remove_expired};
use crate::AppState;
use askama::Template;
use std::fs;
use actix_web::error::ErrorInternalServerError;

#[get("/remove/{id}")]
pub async fn remove(data: web::Data<AppState>, id: web::Path<String>) -> HttpResponse {
pub async fn remove(data: web::Data<AppState>, id: web::Path<String>) -> Result<HttpResponse, Error> {
let mut pastas = data.pastas.lock().unwrap();

let id = if ARGS.hash_ids {
Expand All @@ -27,12 +28,12 @@ pub async fn remove(data: web::Data<AppState>, id: web::Path<String>) -> HttpRes
if pasta.id == id {
// if it's encrypted or read-only, it needs password to be deleted
if pasta.encrypt_server || pasta.readonly {
return HttpResponse::Found()
return Ok(HttpResponse::Found()
.append_header((
"Location",
format!("/auth_remove_private/{}", pasta.id_as_animals()),
))
.finish();
.finish());
}

// remove the file itself
Expand Down Expand Up @@ -63,19 +64,22 @@ pub async fn remove(data: web::Data<AppState>, id: web::Path<String>) -> HttpRes
// remove it from in-memory pasta list
pastas.remove(i);

delete(Some(&pastas), Some(id));
if let Err(error) = delete(Some(&pastas), Some(id)) {
log::error!("Failed to delete pasta with id {} => {}", id, error);
return Err(ErrorInternalServerError("Database delete error"));
}

return HttpResponse::Found()
return Ok(HttpResponse::Found()
.append_header(("Location", format!("{}/list", ARGS.public_path_as_str())))
.finish();
.finish());
}
}

remove_expired(&mut pastas);

HttpResponse::Ok()
Ok(HttpResponse::Ok()
.content_type("text/html")
.body(ErrorTemplate { args: &ARGS }.render().unwrap())
.body(ErrorTemplate { args: &ARGS }.render().unwrap()))
}

#[post("/remove/{id}")]
Expand Down Expand Up @@ -137,8 +141,10 @@ pub async fn post_remove(

// remove it from in-memory pasta list
pastas.remove(i);

delete(Some(&pastas), Some(id));
if let Err(error) = delete(Some(&pastas), Some(id)) {
log::error!("Failed to delete pasta with id {} => {}", id, error);
return Err(ErrorInternalServerError("Database delete error"));
}

return Ok(HttpResponse::Found()
.append_header((
Expand Down
18 changes: 16 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::endpoints::{
pasta as pasta_endpoint, qr, remove, static_resources,
};
use crate::pasta::Pasta;
use crate::util::db::read_all;
use crate::util::db::{read_all};
use crate::util::telemetry::start_telemetry_thread;
use actix_web::middleware::Condition;
use actix_web::{middleware, web, App, HttpServer};
Expand All @@ -17,6 +17,7 @@ use log::LevelFilter;
use std::fs;
use std::io::Write;
use std::sync::Mutex;
use crate::util::db_sqlite::init_db;

pub mod args;
pub mod pasta;
Expand Down Expand Up @@ -56,6 +57,7 @@ pub struct AppState {

#[actix_web::main]
async fn main() -> std::io::Result<()> {

Builder::new()
.format(|buf, record| {
writeln!(
Expand All @@ -69,6 +71,11 @@ async fn main() -> std::io::Result<()> {
.filter(None, LevelFilter::Info)
.init();

if let Err(error) = init_db() {
log::error!("Failed to initialize database {}", error);
panic!("Failed to initialize database {}", error);
}

log::info!(
"MicroBin starting on http://{}:{}",
ARGS.bind.to_string(),
Expand All @@ -90,8 +97,15 @@ async fn main() -> std::io::Result<()> {
}
};

let pastas = match read_all() {
Ok(v) => v,
Err(e) => {
panic!("Could not read pastas {}", e)
}
};

let data = web::Data::new(AppState {
pastas: Mutex::new(read_all()),
pastas: Mutex::new(pastas),
});

if !ARGS.disable_telemetry {
Expand Down
Loading

0 comments on commit 91eb288

Please sign in to comment.