From f7d1baf3ec7778200bb96b32de4ac05e19fc97d2 Mon Sep 17 00:00:00 2001 From: asonix Date: Wed, 9 Dec 2020 23:09:39 -0600 Subject: [PATCH] Rename to Collections, use pict-rs's 'resize' instead of 'thumbnail' --- Cargo.lock | 2 +- Cargo.toml | 2 +- docker/dev/docker-compose.yml | 2 +- src/connection.rs | 2 +- src/lib.rs | 138 +++++++++--------- src/main.rs | 2 + src/middleware.rs | 4 +- src/store.rs | 76 +++++----- ...gation.rs.html => edit_collection.rs.html} | 30 ++-- templates/index.rs.html | 8 +- templates/layout.rs.html | 2 +- templates/not_found.rs.html | 2 +- ...gation.rs.html => view_collection.rs.html} | 12 +- 13 files changed, 142 insertions(+), 140 deletions(-) rename templates/{edit_aggregation.rs.html => edit_collection.rs.html} (72%) rename templates/{view_aggregation.rs.html => view_collection.rs.html} (66%) diff --git a/Cargo.lock b/Cargo.lock index 5621b6e..577792a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1334,7 +1334,7 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pict-rs-aggregator" -version = "0.1.1" +version = "0.1.2" dependencies = [ "actix-web", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index 3592d76..b46c6b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pict-rs-aggregator" -version = "0.1.1" +version = "0.1.2" authors = ["asonix "] edition = "2018" build = "src/build.rs" diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml index 4330617..81e8f12 100644 --- a/docker/dev/docker-compose.yml +++ b/docker/dev/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.3' services: pictrs: - image: asonix/pictrs:v0.2.6-r0 + image: asonix/pictrs:v0.3.0-alpha.0-r0 user: root restart: always volumes: diff --git a/src/connection.rs b/src/connection.rs index 4269072..c63537d 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -88,7 +88,7 @@ impl Connection { fn thumbnail_url(&self, size: u16, file: &str, extension: Extension) -> String { let mut url = self.upstream.clone(); url.set_path(&format!("/image/process.{}", extension)); - url.set_query(Some(&format!("src={}&thumbnail={}", file, size))); + url.set_query(Some(&format!("src={}&resize={}", file, size))); url.to_string() } diff --git a/src/lib.rs b/src/lib.rs index a64c6a9..26337dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -77,41 +77,41 @@ impl State { } } - fn create_aggregation_path(&self) -> String { + fn create_collection_path(&self) -> String { self.scoped("") } - fn edit_aggregation_path(&self, id: Uuid, token: &ValidToken) -> String { + fn edit_collection_path(&self, id: Uuid, token: &ValidToken) -> String { self.scoped(&format!("{}?token={}", id, token.token)) } - fn update_aggregation_path(&self, id: Uuid, token: &ValidToken) -> String { + fn update_collection_path(&self, id: Uuid, token: &ValidToken) -> String { self.scoped(&format!("{}?token={}", id, token.token)) } - fn delete_aggregation_path(&self, id: Uuid, token: &ValidToken) -> String { + fn delete_collection_path(&self, id: Uuid, token: &ValidToken) -> String { self.scoped(&format!("{}/delete?token={}", id, token.token)) } - fn public_aggregation_path(&self, id: Uuid) -> String { + fn public_collection_path(&self, id: Uuid) -> String { self.scoped(&format!("{}", id)) } - fn create_entry_path(&self, aggregation_id: Uuid, token: &ValidToken) -> String { - self.scoped(&format!("{}/entry?token={}", aggregation_id, token.token)) + fn create_entry_path(&self, collection_id: Uuid, token: &ValidToken) -> String { + self.scoped(&format!("{}/entry?token={}", collection_id, token.token)) } - fn update_entry_path(&self, aggregation_id: Uuid, id: Uuid, token: &ValidToken) -> String { + fn update_entry_path(&self, collection_id: Uuid, id: Uuid, token: &ValidToken) -> String { self.scoped(&format!( "{}/entry/{}?token={}", - aggregation_id, id, token.token + collection_id, id, token.token )) } - fn delete_entry_path(&self, aggregation_id: Uuid, id: Uuid, token: &ValidToken) -> String { + fn delete_entry_path(&self, collection_id: Uuid, id: Uuid, token: &ValidToken) -> String { self.scoped(&format!( "{}/entry/{}/delete?token={}", - aggregation_id, id, token.token + collection_id, id, token.token )) } @@ -162,17 +162,17 @@ pub fn service(client: Client, state: State) -> Scope { .service( web::resource("") .route(web::get().to(index)) - .route(web::post().to(create_aggregation)), + .route(web::post().to(create_collection)), ) .service( - web::scope("/{aggregation}") + web::scope("/{collection}") .wrap(middleware::Verify) .service( web::resource("") - .route(web::get().to(aggregation)) - .route(web::post().to(update_aggregation)), + .route(web::get().to(collection)) + .route(web::post().to(update_collection)), ) - .service(web::resource("/delete").route(web::get().to(delete_aggregation))) + .service(web::resource("/delete").route(web::get().to(delete_collection))) .service( web::scope("/entry") .service(web::resource("").route(web::post().to(upload))) @@ -189,19 +189,19 @@ pub fn service(client: Client, state: State) -> Scope { fn to_edit_page(id: Uuid, token: &ValidToken, state: &State) -> HttpResponse { HttpResponse::SeeOther() - .header(LOCATION, state.edit_aggregation_path(id, token)) + .header(LOCATION, state.edit_collection_path(id, token)) .finish() } fn to_404(state: &State) -> HttpResponse { HttpResponse::MovedPermanently() - .header(LOCATION, state.create_aggregation_path()) + .header(LOCATION, state.create_collection_path()) .finish() } fn to_home(state: &State) -> HttpResponse { HttpResponse::SeeOther() - .header(LOCATION, state.create_aggregation_path()) + .header(LOCATION, state.create_collection_path()) .finish() } @@ -266,7 +266,7 @@ impl ResponseError for Error { } #[derive(serde::Deserialize, serde::Serialize)] -pub struct Aggregation { +pub struct Collection { title: String, description: String, } @@ -306,17 +306,17 @@ impl TokenStorage { } #[derive(serde::Deserialize)] -struct AggregationPath { - aggregation: Uuid, +struct CollectionPath { + collection: Uuid, } -impl AggregationPath { +impl CollectionPath { fn key(&self) -> String { - format!("{}", self.aggregation) + format!("{}", self.collection) } fn entry_range(&self) -> std::ops::Range> { - let base = format!("{}/entry/", self.aggregation).as_bytes().to_vec(); + let base = format!("{}/entry/", self.collection).as_bytes().to_vec(); let mut start = base.clone(); let mut end = base; @@ -327,26 +327,26 @@ impl AggregationPath { } fn token_key(&self) -> String { - format!("{}/token", self.aggregation) + format!("{}/token", self.collection) } } #[derive(serde::Deserialize)] struct EntryPath { - aggregation: Uuid, + collection: Uuid, entry: Uuid, } impl EntryPath { fn key(&self) -> String { - format!("{}/entry/{}", self.aggregation, self.entry) + format!("{}/entry/{}", self.collection, self.entry) } } async fn upload( req: HttpRequest, pl: web::Payload, - path: web::Path, + path: web::Path, token: ValidToken, conn: web::Data, state: web::Data, @@ -370,7 +370,7 @@ async fn upload( }; let entry_path = EntryPath { - aggregation: path.aggregation, + collection: path.collection, entry: Uuid::new_v4(), }; @@ -381,7 +381,7 @@ async fn upload( .exec(&state.store) .await?; - Ok(to_edit_page(path.aggregation, &token, &state)) + Ok(to_edit_page(path.collection, &token, &state)) } #[derive(serde::Deserialize)] @@ -428,30 +428,30 @@ async fn index(state: web::Data) -> Result { .body(cursor.into_inner())) } -async fn aggregation( - path: web::Path, +async fn collection( + path: web::Path, token: Option, state: web::Data, ) -> Result { match token { - Some(token) => edit_aggregation(path, token, state).await, - None => view_aggregation(path, state).await, + Some(token) => edit_collection(path, token, state).await, + None => view_collection(path, state).await, } } -async fn view_aggregation( - path: web::Path, +async fn view_collection( + path: web::Path, state: web::Data, ) -> Result { - let aggregation = state.store.aggregation(&path).await?; + let collection = state.store.collection(&path).await?; let entries = state.store.entries(path.entry_range()).await?; let mut cursor = Cursor::new(vec![]); - self::templates::view_aggregation( + self::templates::view_collection( &mut cursor, - path.aggregation, - &aggregation, + path.collection, + &collection, &entries, &state, )?; @@ -461,20 +461,20 @@ async fn view_aggregation( .body(cursor.into_inner())) } -async fn edit_aggregation( - path: web::Path, +async fn edit_collection( + path: web::Path, token: ValidToken, state: web::Data, ) -> Result { - let aggregation = state.store.aggregation(&path).await?; + let collection = state.store.collection(&path).await?; let entries = state.store.entries(path.entry_range()).await?; let mut cursor = Cursor::new(vec![]); - self::templates::edit_aggregation( + self::templates::edit_collection( &mut cursor, - &aggregation, - path.aggregation, + &collection, + path.collection, &entries, &token, &state, @@ -485,47 +485,47 @@ async fn edit_aggregation( .body(cursor.into_inner())) } -async fn create_aggregation( - aggregation: web::Form, +async fn create_collection( + collection: web::Form, state: web::Data, ) -> Result { - let aggregation_id = Uuid::new_v4(); - let aggregation_path = AggregationPath { - aggregation: aggregation_id, + let collection_id = Uuid::new_v4(); + let collection_path = CollectionPath { + collection: collection_id, }; let token = Token { token: Uuid::new_v4(), }; - store::CreateAggregation { - aggregation_path: &aggregation_path, - aggregation: &aggregation, + store::CreateCollection { + collection_path: &collection_path, + collection: &collection, token: &token, } .exec(&state.store) .await?; Ok(to_edit_page( - aggregation_path.aggregation, + collection_path.collection, &ValidToken { token: token.token }, &state, )) } -async fn update_aggregation( - path: web::Path, - form: web::Form, +async fn update_collection( + path: web::Path, + form: web::Form, token: ValidToken, state: web::Data, ) -> Result { - store::UpdateAggregation { - aggregation_path: &path, - aggregation: &form, + store::UpdateCollection { + collection_path: &path, + collection: &form, } .exec(&state.store) .await?; - Ok(to_edit_page(path.aggregation, &token, &state)) + Ok(to_edit_page(path.collection, &token, &state)) } async fn update_entry( @@ -541,7 +541,7 @@ async fn update_entry( .exec(&state.store) .await?; - Ok(to_edit_page(entry_path.aggregation, &token, &state)) + Ok(to_edit_page(entry_path.collection, &token, &state)) } async fn delete_entry( @@ -560,11 +560,11 @@ async fn delete_entry( .exec(&state.store) .await?; - Ok(to_edit_page(entry_path.aggregation, &token, &state)) + Ok(to_edit_page(entry_path.collection, &token, &state)) } -async fn delete_aggregation( - path: web::Path, +async fn delete_collection( + path: web::Path, _token: ValidToken, conn: web::Data, state: web::Data, @@ -578,8 +578,8 @@ async fn delete_aggregation( futures::future::try_join_all(future_vec).await?; - store::DeleteAggregation { - aggregation_path: &path, + store::DeleteCollection { + collection_path: &path, } .exec(&state.store) .await?; diff --git a/src/main.rs b/src/main.rs index 505df96..8e9db39 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use actix_web::{ middleware::{Compress, Logger}, App, HttpServer, }; +use std::time::Duration; use structopt::StructOpt; #[actix_web::main] @@ -20,6 +21,7 @@ async fn main() -> Result<(), anyhow::Error> { HttpServer::new(move || { let client = Client::builder() + .timeout(Duration::from_secs(30)) .header("User-Agent", "pict_rs_aggregator-v0.1.0") .finish(); diff --git a/src/middleware.rs b/src/middleware.rs index d8b6c46..a254568 100644 --- a/src/middleware.rs +++ b/src/middleware.rs @@ -100,7 +100,7 @@ where let state_fut = web::Data::::extract(&req); let token_fut = Option::>::extract(&req); - let path_fut = web::Path::::extract(&req); + let path_fut = web::Path::::extract(&req); let req = ServiceRequest::from_parts(req, pl) .map_err(|_| VerifyError) @@ -136,7 +136,7 @@ where } async fn verify( - path: &crate::AggregationPath, + path: &crate::CollectionPath, token: crate::Token, state: &crate::State, ) -> Result<(), VerifyError> { diff --git a/src/store.rs b/src/store.rs index 36ac6ef..1e93873 100644 --- a/src/store.rs +++ b/src/store.rs @@ -1,4 +1,4 @@ -use crate::{Aggregation, AggregationPath, Entry, EntryPath, Token}; +use crate::{Collection, CollectionPath, Entry, EntryPath, Token}; use actix_web::web; use sled::{Db, Tree}; use std::ops::Range; @@ -9,19 +9,19 @@ pub(crate) struct Store { tree: Tree, } -pub(crate) struct CreateAggregation<'a> { - pub(crate) aggregation_path: &'a AggregationPath, - pub(crate) aggregation: &'a Aggregation, +pub(crate) struct CreateCollection<'a> { + pub(crate) collection_path: &'a CollectionPath, + pub(crate) collection: &'a Collection, pub(crate) token: &'a Token, } -pub(crate) struct UpdateAggregation<'a> { - pub(crate) aggregation_path: &'a AggregationPath, - pub(crate) aggregation: &'a Aggregation, +pub(crate) struct UpdateCollection<'a> { + pub(crate) collection_path: &'a CollectionPath, + pub(crate) collection: &'a Collection, } -pub(crate) struct DeleteAggregation<'a> { - pub(crate) aggregation_path: &'a AggregationPath, +pub(crate) struct DeleteCollection<'a> { + pub(crate) collection_path: &'a CollectionPath, } pub(crate) struct CreateEntry<'a> { @@ -38,21 +38,21 @@ pub(crate) struct DeleteEntry<'a> { pub(crate) entry_path: &'a EntryPath, } -impl<'a> CreateAggregation<'a> { +impl<'a> CreateCollection<'a> { pub(crate) async fn exec(self, store: &Store) -> Result<(), Error> { - store.create_aggregation(self).await + store.create_collection(self).await } } -impl<'a> UpdateAggregation<'a> { +impl<'a> UpdateCollection<'a> { pub(crate) async fn exec(self, store: &Store) -> Result<(), Error> { - store.update_aggregation(self).await + store.update_collection(self).await } } -impl<'a> DeleteAggregation<'a> { +impl<'a> DeleteCollection<'a> { pub(crate) async fn exec(self, store: &Store) -> Result<(), Error> { - store.delete_aggregation(self).await + store.delete_collection(self).await } } @@ -77,15 +77,15 @@ impl<'a> DeleteEntry<'a> { impl Store { pub(crate) fn new(db: &Db) -> Result { Ok(Store { - tree: db.open_tree("aggregations")?, + tree: db.open_tree("collections")?, }) } - async fn create_aggregation(&self, config: CreateAggregation<'_>) -> Result<(), Error> { - let aggregation_key = config.aggregation_path.key(); - let aggregation_value = serde_json::to_string(&config.aggregation)?; + async fn create_collection(&self, config: CreateCollection<'_>) -> Result<(), Error> { + let collection_key = config.collection_path.key(); + let collection_value = serde_json::to_string(&config.collection)?; - let token_key = config.aggregation_path.token_key(); + let token_key = config.collection_path.token_key(); let token2 = config.token.clone(); let token_value = serde_json::to_string(&web::block(move || token2.hash()).await?)?; @@ -93,7 +93,7 @@ impl Store { web::block(move || { tree.transaction(move |tree| { - tree.insert(aggregation_key.as_bytes(), aggregation_value.as_bytes())?; + tree.insert(collection_key.as_bytes(), collection_value.as_bytes())?; tree.insert(token_key.as_bytes(), token_value.as_bytes())?; Ok(()) }) @@ -103,22 +103,22 @@ impl Store { Ok(()) } - async fn update_aggregation(&self, config: UpdateAggregation<'_>) -> Result<(), Error> { - let aggregation_key = config.aggregation_path.key(); - let aggregation_value = serde_json::to_string(&config.aggregation)?; + async fn update_collection(&self, config: UpdateCollection<'_>) -> Result<(), Error> { + let collection_key = config.collection_path.key(); + let collection_value = serde_json::to_string(&config.collection)?; let tree = self.tree.clone(); - web::block(move || tree.insert(aggregation_key.as_bytes(), aggregation_value.as_bytes())) + web::block(move || tree.insert(collection_key.as_bytes(), collection_value.as_bytes())) .await?; Ok(()) } - async fn delete_aggregation(&self, config: DeleteAggregation<'_>) -> Result<(), Error> { - let entry_range = config.aggregation_path.entry_range(); - let token_key = config.aggregation_path.token_key(); - let aggregation_key = config.aggregation_path.key(); + async fn delete_collection(&self, config: DeleteCollection<'_>) -> Result<(), Error> { + let entry_range = config.collection_path.entry_range(); + let token_key = config.collection_path.token_key(); + let collection_key = config.collection_path.key(); let tree = self.tree.clone(); @@ -133,7 +133,7 @@ impl Store { tree.remove(key)?; } tree.remove(token_key.as_bytes())?; - tree.remove(aggregation_key.as_bytes())?; + tree.remove(collection_key.as_bytes())?; Ok(()) })?; @@ -175,19 +175,19 @@ impl Store { Ok(()) } - pub(crate) async fn aggregation( + pub(crate) async fn collection( &self, - path: &AggregationPath, - ) -> Result { - let aggregation_key = path.key(); + path: &CollectionPath, + ) -> Result { + let collection_key = path.key(); let tree = self.tree.clone(); - let opt = web::block(move || tree.get(aggregation_key.as_bytes())).await?; + let opt = web::block(move || tree.get(collection_key.as_bytes())).await?; match opt { Some(a) => { - let aggregation = serde_json::from_slice(&a)?; - Ok(aggregation) + let collection = serde_json::from_slice(&a)?; + Ok(collection) } None => Err(Error::NotFound), } @@ -232,7 +232,7 @@ impl Store { Ok(v) } - pub(crate) async fn token(&self, path: &AggregationPath) -> Result { + pub(crate) async fn token(&self, path: &CollectionPath) -> Result { let token_key = path.token_key(); let tree = self.tree.clone(); diff --git a/templates/edit_aggregation.rs.html b/templates/edit_collection.rs.html similarity index 72% rename from templates/edit_aggregation.rs.html rename to templates/edit_collection.rs.html index 76df146..fcac71f 100644 --- a/templates/edit_aggregation.rs.html +++ b/templates/edit_collection.rs.html @@ -1,10 +1,10 @@ -@use crate::{ui::ButtonKind, Aggregation, Entry, State, ValidToken}; +@use crate::{ui::ButtonKind, Collection, Entry, State, ValidToken}; @use super::{button, button_link, image_preview, file_input, layout, text_area, text_input, statics::file_upload_js}; @use uuid::Uuid; -@(aggregation: &Aggregation, aggregation_id: Uuid, entries: &[(Uuid, Entry)], token: &ValidToken, state: &State) +@(collection: &Collection, collection_id: Uuid, entries: &[(Uuid, Entry)], token: &ValidToken, state: &State) -@:layout(state, "Edit Aggregation", None, { +@:layout(state, "Edit Collection", None, {