diff options
Diffstat (limited to 'src/birka-web.rs')
| -rw-r--r-- | src/birka-web.rs | 119 |
1 files changed, 73 insertions, 46 deletions
diff --git a/src/birka-web.rs b/src/birka-web.rs index c145625..359b153 100644 --- a/src/birka-web.rs +++ b/src/birka-web.rs @@ -103,8 +103,12 @@ fn thumb_filename(id: i64, filename: &str) -> String { } #[get("/posts?<tags>&<last>")] -fn get_posts(conn: SiteState, tags: String, last: Option<i64>) -> Json<Vec<ImageResult>> { - let tb = &conn.inner().lock().unwrap().tb; +fn get_posts(conn: SiteState, tags: String, last: Option<i64>) -> Result<Json<Vec<ImageResult>>> { + let tb = &conn + .inner() + .lock() + .map_err(|_| anyhow!("Could not lock database."))? + .tb; // Ensure that an empty vector is passed to `tb.query` if no tags were // specified. @@ -114,11 +118,9 @@ fn get_posts(conn: SiteState, tags: String, last: Option<i64>) -> Json<Vec<Image vec![] }; - let results = tb - .query(Query::new(&tags[..], last, Some(RESULTS_PER_QUERY))) - .unwrap(); + let results = tb.query(Query::new(&tags[..], last, Some(RESULTS_PER_QUERY)))?; - Json( + Ok(Json( results .iter() .map(|image| ImageResult { @@ -129,21 +131,25 @@ fn get_posts(conn: SiteState, tags: String, last: Option<i64>) -> Json<Vec<Image tags: tb.tags_for_image(image.id).unwrap(), }) .collect(), - ) + )) } #[get("/posts/<id>")] -fn get_post(conn: SiteState, id: i64) -> Json<ImageResult> { - let tb = &conn.inner().lock().unwrap().tb; - let image = tb.image_by_id(id).unwrap(); +fn get_post(conn: SiteState, id: i64) -> Result<Json<ImageResult>> { + let tb = &conn + .inner() + .lock() + .map_err(|_| anyhow!("Could not lock database."))? + .tb; + let image = tb.image_by_id(id)?; - Json(ImageResult { + Ok(Json(ImageResult { id: image.id, filename: image_store_filename(image.id, &image.filename), thumb_filename: thumb_filename(image.id, &image.filename), orig_filename: image.filename.clone(), - tags: tb.tags_for_image(image.id).unwrap(), - }) + tags: tb.tags_for_image(image.id)?, + })) } #[derive(FromForm)] @@ -152,40 +158,50 @@ struct UpdateTags { } #[post("/posts/<id>", data = "<form>")] -fn update_post(conn: SiteState, id: i64, form: Form<UpdateTags>) -> Json<String> { - let tb = &conn.inner().lock().unwrap().tb; +fn update_post(conn: SiteState, id: i64, form: Form<UpdateTags>) -> Result<Json<String>> { + let tb = &conn + .inner() + .lock() + .map_err(|_| anyhow!("Could not lock database."))? + .tb; for tag in form.tags.split(",") { - tb.add_tag(tag).unwrap(); - tb.tag_image(id, tag).unwrap(); + tb.add_tag(tag)?; + tb.tag_image(id, tag)?; } - Json(String::from("Updated!")) + Ok(Json(String::from("Updated!"))) } #[post("/posts", data = "<data>")] -fn put_post(conn: SiteState, content_type: &ContentType, data: Data) -> Json<String> { - let conn = conn.inner().lock().unwrap(); +fn put_post(conn: SiteState, content_type: &ContentType, data: Data) -> Result<Json<String>> { + let conn = conn + .inner() + .lock() + .map_err(|_| anyhow!("Could not lock database."))?; let options = MultipartFormDataOptions::with_multipart_form_data_fields(vec![ MultipartFormDataField::text("tags"), MultipartFormDataField::raw("image") .size_limit(32 * 1024 * 1024) - .content_type_by_string(Some(multipart::mime::IMAGE_STAR)) - .unwrap(), + .content_type_by_string(Some(multipart::mime::IMAGE_STAR))?, ]); - let mut data = MultipartFormData::parse(content_type, data, options).unwrap(); - let raw = data.raw.remove("image").unwrap().remove(0); + let mut data = MultipartFormData::parse(content_type, data, options)?; + let raw = if let Some(mut data) = data.raw.remove("image") { + data.remove(0) + } else { + bail!("No `image` field.") + }; let filename = raw .file_name .unwrap_or(thread_rng().sample_iter(&Alphanumeric).take(30).collect()); let path = Path::new(&conn.image_dir).join(&filename); - let mut f = File::create(&path).unwrap(); - f.write_all(&raw.raw).unwrap(); + let mut f = File::create(&path)?; + f.write_all(&raw.raw)?; - let hash = database::hash_file(&path).unwrap(); - let id = conn.tb.import_image(&path, &hash).unwrap(); + let hash = database::hash_file(&path)?; + let id = conn.tb.import_image(&path, &hash)?; add_to_store( &Image { id, @@ -196,17 +212,21 @@ fn put_post(conn: SiteState, content_type: &ContentType, data: Data) -> Json<Str &conn.image_dir, ); - let tags = data.texts.remove("tags").unwrap().remove(0).text; - for tag in tags.split(",") { - conn.tb.add_tag(tag).unwrap(); - conn.tb.tag_image(id, tag).unwrap(); + if let Some(mut vec) = data.texts.remove("tags") { + if vec.len() == 1 { + let tags = vec.remove(0).text; + for tag in tags.split(',') { + conn.tb.add_tag(tag)?; + conn.tb.tag_image(id, tag)?; + } + } } - Json("Uploaded!".into()) + Ok(Json("Uploaded!".into())) } #[get("/")] -fn index(conn: SiteState) -> Template { +fn index(conn: SiteState) -> Result<Template> { display_posts(conn, String::from(""), None) } @@ -216,7 +236,7 @@ fn upload() -> Template { } #[get("/posts?<tags>&<last>")] -fn display_posts(conn: SiteState, tags: String, last: Option<i64>) -> Template { +fn display_posts(conn: SiteState, tags: String, last: Option<i64>) -> Result<Template> { #[derive(Serialize)] struct TagResult { name: String, @@ -236,9 +256,12 @@ fn display_posts(conn: SiteState, tags: String, last: Option<i64>) -> Template { // calling out to `get_posts` to perform the query. Otherwise, we // deadlock because the mutex is locked for the entirety of // `display_posts`. - let tb = &conn.inner().lock().unwrap().tb; - tb.top_tags(20) - .unwrap() + let tb = &conn + .inner() + .lock() + .map_err(|_| anyhow!("Could not lock database."))? + .tb; + tb.top_tags(20)? .iter() .map(|tup| TagResult { name: tup.1.clone(), @@ -246,7 +269,7 @@ fn display_posts(conn: SiteState, tags: String, last: Option<i64>) -> Template { }) .collect() }; - let images = get_posts(conn, tags, last).into_inner(); + let images = get_posts(conn, tags, last)?.into_inner(); let context = Context { tags: tag_results, next_page: if images.len() as i64 == RESULTS_PER_QUERY { @@ -257,11 +280,11 @@ fn display_posts(conn: SiteState, tags: String, last: Option<i64>) -> Template { }, images, }; - Template::render("index", context) + Ok(Template::render("index", context)) } #[get("/posts/<id>")] -fn display_post(conn: SiteState, id: i64) -> Template { +fn display_post(conn: SiteState, id: i64) -> Result<Template> { #[derive(Serialize)] struct Context { id: i64, @@ -270,18 +293,22 @@ fn display_post(conn: SiteState, id: i64) -> Template { orig_filename: String, } - let tb = &conn.inner().lock().unwrap().tb; - let image = tb.image_by_id(id).unwrap(); + let tb = &conn + .inner() + .lock() + .map_err(|_| anyhow!("Could not lock database."))? + .tb; + let image = tb.image_by_id(id)?; - Template::render( + Ok(Template::render( "image", Context { id, - tags: tb.tags_for_image(image.id).unwrap(), + tags: tb.tags_for_image(image.id)?, filename: image_store_filename(image.id, &image.filename), orig_filename: image.filename, }, - ) + )) } /// Create a thumbnail for `image` in the store at `image_dir`. |