diff options
author | Colin Reeder <vpzomtrrfrt@gmail.com> | 2020-10-27 20:53:31 -0600 |
---|---|---|
committer | Colin Reeder <vpzomtrrfrt@gmail.com> | 2020-10-27 20:53:31 -0600 |
commit | f04ee322507cf76af43d68a9642347634e58937d (patch) | |
tree | 323da782364ce0abf499eba09faed2b09c85634d | |
parent | eccee34766b4602fbb44daa483ea2c98fd48d34e (diff) |
Move href endpoints to /stable
-rw-r--r-- | src/main.rs | 10 | ||||
-rw-r--r-- | src/routes/api/comments.rs | 88 | ||||
-rw-r--r-- | src/routes/api/mod.rs | 89 | ||||
-rw-r--r-- | src/routes/api/posts.rs | 85 | ||||
-rw-r--r-- | src/routes/api/stable.rs | 278 | ||||
-rw-r--r-- | src/routes/api/users.rs | 87 |
6 files changed, 328 insertions, 309 deletions
diff --git a/src/main.rs b/src/main.rs index 45e304f..33bcd80 100644 --- a/src/main.rs +++ b/src/main.rs @@ -147,7 +147,7 @@ pub struct BaseContext { impl BaseContext { pub fn process_href<'a>(&self, href: &'a str, post_id: PostLocalID) -> Cow<'a, str> { if href.starts_with("local-media://") { - format!("{}/unstable/posts/{}/href", self.host_url_api, post_id).into() + format!("{}/stable/posts/{}/href", self.host_url_api, post_id).into() } else { href.into() } @@ -172,7 +172,7 @@ impl BaseContext { match href { Some(href) => Some(if href.starts_with("local-media://") { format!( - "{}/unstable/comments/{}/attachments/0/href", + "{}/stable/comments/{}/attachments/0/href", self.host_url_api, comment_id ) .into() @@ -185,11 +185,7 @@ impl BaseContext { pub fn process_avatar_href<'a>(&self, href: &'a str, user_id: UserLocalID) -> Cow<'a, str> { if href.starts_with("local-media://") { - format!( - "{}/unstable/users/{}/avatar/href", - self.host_url_api, user_id, - ) - .into() + format!("{}/stable/users/{}/avatar/href", self.host_url_api, user_id,).into() } else { href.into() } diff --git a/src/routes/api/comments.rs b/src/routes/api/comments.rs index 545771c..0c91b97 100644 --- a/src/routes/api/comments.rs +++ b/src/routes/api/comments.rs @@ -219,89 +219,6 @@ async fn route_unstable_comments_delete( } } -async fn route_unstable_comments_attachments_0_href_get( - params: (CommentLocalID,), - ctx: Arc<crate::RouteContext>, - req: hyper::Request<hyper::Body>, -) -> Result<hyper::Response<hyper::Body>, crate::Error> { - let (comment_id,) = params; - - let lang = crate::get_lang_for_req(&req); - let db = ctx.db_pool.get().await?; - - let row = db - .query_opt( - "SELECT attachment_href FROM reply WHERE id=$1", - &[&comment_id], - ) - .await?; - match row { - None => Ok(crate::simple_response( - hyper::StatusCode::NOT_FOUND, - lang.tr("no_such_comment", None).into_owned(), - )), - Some(row) => { - let href: Option<String> = row.get(0); - match href { - None => Ok(crate::simple_response( - hyper::StatusCode::NOT_FOUND, - lang.tr("no_such_attachment", None).into_owned(), - )), - Some(href) => { - if href.starts_with("local-media://") { - // local media, serve file content - - let media_id: crate::Pineapple = (&href[14..]).parse()?; - - let media_row = db - .query_opt( - "SELECT path, mime FROM media WHERE id=$1", - &[&media_id.as_int()], - ) - .await?; - match media_row { - None => Ok(crate::simple_response( - hyper::StatusCode::NOT_FOUND, - lang.tr("media_upload_missing", None).into_owned(), - )), - Some(media_row) => { - let path: &str = media_row.get(0); - let mime: &str = media_row.get(1); - - if let Some(media_location) = &ctx.media_location { - let path = media_location.join(path); - - let file = tokio::fs::File::open(path).await?; - let body = hyper::Body::wrap_stream( - tokio_util::codec::FramedRead::new( - file, - tokio_util::codec::BytesCodec::new(), - ), - ); - - Ok(crate::common_response_builder() - .header(hyper::header::CONTENT_TYPE, mime) - .body(body)?) - } else { - Ok(crate::simple_response( - hyper::StatusCode::NOT_FOUND, - lang.tr("media_upload_missing", None).into_owned(), - )) - } - } - } - } else { - Ok(crate::common_response_builder() - .status(hyper::StatusCode::FOUND) - .header(hyper::header::LOCATION, &href) - .body(href.into())?) - } - } - } - } - } -} - async fn route_unstable_comments_like( params: (CommentLocalID,), ctx: Arc<crate::RouteContext>, @@ -670,11 +587,6 @@ pub fn route_comments() -> crate::RouteNode<()> { .with_handler_async("GET", route_unstable_comments_get) .with_handler_async("DELETE", route_unstable_comments_delete) .with_child( - "attachments/0/href", - crate::RouteNode::new() - .with_handler_async("GET", route_unstable_comments_attachments_0_href_get), - ) - .with_child( "replies", crate::RouteNode::new() .with_handler_async("POST", route_unstable_comments_replies_create), diff --git a/src/routes/api/mod.rs b/src/routes/api/mod.rs index 05c9ec0..e6f41e5 100644 --- a/src/routes/api/mod.rs +++ b/src/routes/api/mod.rs @@ -11,6 +11,7 @@ mod communities; mod forgot_password; mod media; mod posts; +mod stable; mod users; lazy_static::lazy_static! { @@ -158,51 +159,55 @@ enum RespThingInfo<'a> { } pub fn route_api() -> crate::RouteNode<()> { - crate::RouteNode::new().with_child( - "unstable", - crate::RouteNode::new() - .with_child( - "actors:lookup", - crate::RouteNode::new().with_child_str( - crate::RouteNode::new().with_handler_async("GET", route_unstable_actors_lookup), - ), - ) - .with_child( - "logins", - crate::RouteNode::new() - .with_handler_async("POST", route_unstable_logins_create) - .with_child( - "~current", + crate::RouteNode::new() + .with_child( + "unstable", + crate::RouteNode::new() + .with_child( + "actors:lookup", + crate::RouteNode::new().with_child_str( crate::RouteNode::new() - .with_handler_async("GET", route_unstable_logins_current_get) - .with_handler_async("DELETE", route_unstable_logins_current_delete), + .with_handler_async("GET", route_unstable_actors_lookup), ), - ) - .with_child("media", media::route_media()) - .with_child( - "nodeinfo/2.0", - crate::RouteNode::new().with_handler_async("GET", route_unstable_nodeinfo_20_get), - ) - .with_child("communities", communities::route_communities()) - .with_child( - "instance", - crate::RouteNode::new() - .with_handler_async("GET", route_unstable_instance_get) - .with_handler_async("PATCH", route_unstable_instance_patch), - ) - .with_child( - "misc", - crate::RouteNode::new().with_child( - "render_markdown", + ) + .with_child( + "logins", crate::RouteNode::new() - .with_handler_async("POST", route_unstable_misc_render_markdown), - ), - ) - .with_child("posts", posts::route_posts()) - .with_child("comments", comments::route_comments()) - .with_child("users", users::route_users()) - .with_child("forgot_password", forgot_password::route_forgot_password()), - ) + .with_handler_async("POST", route_unstable_logins_create) + .with_child( + "~current", + crate::RouteNode::new() + .with_handler_async("GET", route_unstable_logins_current_get) + .with_handler_async("DELETE", route_unstable_logins_current_delete), + ), + ) + .with_child("media", media::route_media()) + .with_child( + "nodeinfo/2.0", + crate::RouteNode::new() + .with_handler_async("GET", route_unstable_nodeinfo_20_get), + ) + .with_child("communities", communities::route_communities()) + .with_child( + "instance", + crate::RouteNode::new() + .with_handler_async("GET", route_unstable_instance_get) + .with_handler_async("PATCH", route_unstable_instance_patch), + ) + .with_child( + "misc", + crate::RouteNode::new().with_child( + "render_markdown", + crate::RouteNode::new() + .with_handler_async("POST", route_unstable_misc_render_markdown), + ), + ) + .with_child("posts", posts::route_posts()) + .with_child("comments", comments::route_comments()) + .with_child("users", users::route_users()) + .with_child("forgot_password", forgot_password::route_forgot_password()), + ) + .with_child("stable", stable::route_stable()) } async fn insert_token( diff --git a/src/routes/api/posts.rs b/src/routes/api/posts.rs index 0be75ac..0ca17da 100644 --- a/src/routes/api/posts.rs +++ b/src/routes/api/posts.rs @@ -459,86 +459,6 @@ async fn route_unstable_posts_delete( } } -async fn route_unstable_posts_href_get( - params: (PostLocalID,), - ctx: Arc<crate::RouteContext>, - req: hyper::Request<hyper::Body>, -) -> Result<hyper::Response<hyper::Body>, crate::Error> { - let (post_id,) = params; - - let lang = crate::get_lang_for_req(&req); - let db = ctx.db_pool.get().await?; - - let row = db - .query_opt("SELECT href FROM post WHERE id=$1", &[&post_id]) - .await?; - match row { - None => Ok(crate::simple_response( - hyper::StatusCode::NOT_FOUND, - lang.tr("no_such_post", None).into_owned(), - )), - Some(row) => { - let href: Option<String> = row.get(0); - match href { - None => Ok(crate::simple_response( - hyper::StatusCode::NOT_FOUND, - lang.tr("post_not_link", None).into_owned(), - )), - Some(href) => { - if href.starts_with("local-media://") { - // local media, serve file content - - let media_id: crate::Pineapple = (&href[14..]).parse()?; - - let media_row = db - .query_opt( - "SELECT path, mime FROM media WHERE id=$1", - &[&media_id.as_int()], - ) - .await?; - match media_row { - None => Ok(crate::simple_response( - hyper::StatusCode::NOT_FOUND, - lang.tr("media_upload_missing", None).into_owned(), - )), - Some(media_row) => { - let path: &str = media_row.get(0); - let mime: &str = media_row.get(1); - - if let Some(media_location) = &ctx.media_location { - let path = media_location.join(path); - - let file = tokio::fs::File::open(path).await?; - let body = hyper::Body::wrap_stream( - tokio_util::codec::FramedRead::new( - file, - tokio_util::codec::BytesCodec::new(), - ), - ); - - Ok(crate::common_response_builder() - .header(hyper::header::CONTENT_TYPE, mime) - .body(body)?) - } else { - Ok(crate::simple_response( - hyper::StatusCode::NOT_FOUND, - lang.tr("media_upload_missing", None).into_owned(), - )) - } - } - } - } else { - Ok(crate::common_response_builder() - .status(hyper::StatusCode::FOUND) - .header(hyper::header::LOCATION, &href) - .body(href.into())?) - } - } - } - } - } -} - async fn route_unstable_posts_like( params: (PostLocalID,), ctx: Arc<crate::RouteContext>, @@ -898,11 +818,6 @@ pub fn route_posts() -> crate::RouteNode<()> { .with_handler_async("GET", route_unstable_posts_get) .with_handler_async("DELETE", route_unstable_posts_delete) .with_child( - "href", - crate::RouteNode::new() - .with_handler_async("GET", route_unstable_posts_href_get), - ) - .with_child( "replies", crate::RouteNode::new() .with_handler_async("POST", route_unstable_posts_replies_create), diff --git a/src/routes/api/stable.rs b/src/routes/api/stable.rs new file mode 100644 index 0000000..322d45e --- /dev/null +++ b/src/routes/api/stable.rs @@ -0,0 +1,278 @@ +use crate::{CommentLocalID, PostLocalID, UserLocalID}; +use std::sync::Arc; + +async fn route_stable_comments_attachments_0_href_get( + params: (CommentLocalID,), + ctx: Arc<crate::RouteContext>, + req: hyper::Request<hyper::Body>, +) -> Result<hyper::Response<hyper::Body>, crate::Error> { + let (comment_id,) = params; + + let lang = crate::get_lang_for_req(&req); + let db = ctx.db_pool.get().await?; + + let row = db + .query_opt( + "SELECT attachment_href FROM reply WHERE id=$1", + &[&comment_id], + ) + .await?; + match row { + None => Ok(crate::simple_response( + hyper::StatusCode::NOT_FOUND, + lang.tr("no_such_comment", None).into_owned(), + )), + Some(row) => { + let href: Option<String> = row.get(0); + match href { + None => Ok(crate::simple_response( + hyper::StatusCode::NOT_FOUND, + lang.tr("no_such_attachment", None).into_owned(), + )), + Some(href) => { + if href.starts_with("local-media://") { + // local media, serve file content + + let media_id: crate::Pineapple = (&href[14..]).parse()?; + + let media_row = db + .query_opt( + "SELECT path, mime FROM media WHERE id=$1", + &[&media_id.as_int()], + ) + .await?; + match media_row { + None => Ok(crate::simple_response( + hyper::StatusCode::NOT_FOUND, + lang.tr("media_upload_missing", None).into_owned(), + )), + Some(media_row) => { + let path: &str = media_row.get(0); + let mime: &str = media_row.get(1); + + if let Some(media_location) = &ctx.media_location { + let path = media_location.join(path); + + let file = tokio::fs::File::open(path).await?; + let body = hyper::Body::wrap_stream( + tokio_util::codec::FramedRead::new( + file, + tokio_util::codec::BytesCodec::new(), + ), + ); + + Ok(crate::common_response_builder() + .header(hyper::header::CONTENT_TYPE, mime) + .body(body)?) + } else { + Ok(crate::simple_response( + hyper::StatusCode::NOT_FOUND, + lang.tr("media_upload_missing", None).into_owned(), + )) + } + } + } + } else { + Ok(crate::common_response_builder() + .status(hyper::StatusCode::FOUND) + .header(hyper::header::LOCATION, &href) + .body(href.into())?) + } + } + } + } + } +} + +async fn route_stable_posts_href_get( + params: (PostLocalID,), + ctx: Arc<crate::RouteContext>, + req: hyper::Request<hyper::Body>, +) -> Result<hyper::Response<hyper::Body>, crate::Error> { + let (post_id,) = params; + + let lang = crate::get_lang_for_req(&req); + let db = ctx.db_pool.get().await?; + + let row = db + .query_opt("SELECT href FROM post WHERE id=$1", &[&post_id]) + .await?; + match row { + None => Ok(crate::simple_response( + hyper::StatusCode::NOT_FOUND, + lang.tr("no_such_post", None).into_owned(), + )), + Some(row) => { + let href: Option<String> = row.get(0); + match href { + None => Ok(crate::simple_response( + hyper::StatusCode::NOT_FOUND, + lang.tr("post_not_link", None).into_owned(), + )), + Some(href) => { + if href.starts_with("local-media://") { + // local media, serve file content + + let media_id: crate::Pineapple = (&href[14..]).parse()?; + + let media_row = db + .query_opt( + "SELECT path, mime FROM media WHERE id=$1", + &[&media_id.as_int()], + ) + .await?; + match media_row { + None => Ok(crate::simple_response( + hyper::StatusCode::NOT_FOUND, + lang.tr("media_upload_missing", None).into_owned(), + )), + Some(media_row) => { + let path: &str = media_row.get(0); + let mime: &str = media_row.get(1); + + if let Some(media_location) = &ctx.media_location { + let path = media_location.join(path); + + let file = tokio::fs::File::open(path).await?; + let body = hyper::Body::wrap_stream( + tokio_util::codec::FramedRead::new( + file, + tokio_util::codec::BytesCodec::new(), + ), + ); + + Ok(crate::common_response_builder() + .header(hyper::header::CONTENT_TYPE, mime) + .body(body)?) + } else { + Ok(crate::simple_response( + hyper::StatusCode::NOT_FOUND, + lang.tr("media_upload_missing", None).into_owned(), + )) + } + } + } + } else { + Ok(crate::common_response_builder() + .status(hyper::StatusCode::FOUND) + .header(hyper::header::LOCATION, &href) + .body(href.into())?) + } + } + } + } + } +} + +async fn route_unstable_users_avatar_href_get( + params: (UserLocalID,), + ctx: Arc<crate::RouteContext>, + req: hyper::Request<hyper::Body>, +) -> Result<hyper::Response<hyper::Body>, crate::Error> { + let (user_id,) = params; + + let lang = crate::get_lang_for_req(&req); + let db = ctx.db_pool.get().await?; + + let row = db + .query_opt("SELECT avatar FROM person WHERE id=$1", &[&user_id]) + .await?; + match row { + None => Ok(crate::simple_response( + hyper::StatusCode::NOT_FOUND, + lang.tr("no_such_user", None).into_owned(), + )), + Some(row) => { + let href: Option<String> = row.get(0); + match href { + None => Ok(crate::simple_response( + hyper::StatusCode::NOT_FOUND, + lang.tr("user_no_avatar", None).into_owned(), + )), + Some(href) => { + if href.starts_with("local-media://") { + // local media, serve file content + + let media_id: crate::Pineapple = (&href[14..]).parse()?; + + let media_row = db + .query_opt( + "SELECT path, mime FROM media WHERE id=$1", + &[&media_id.as_int()], + ) + .await?; + match media_row { + None => Ok(crate::simple_response( + hyper::StatusCode::NOT_FOUND, + lang.tr("media_upload_missing", None).into_owned(), + )), + Some(media_row) => { + let path: &str = media_row.get(0); + let mime: &str = media_row.get(1); + + if let Some(media_location) = &ctx.media_location { + let path = media_location.join(path); + + let file = tokio::fs::File::open(path).await?; + let body = hyper::Body::wrap_stream( + tokio_util::codec::FramedRead::new( + file, + tokio_util::codec::BytesCodec::new(), + ), + ); + + Ok(crate::common_response_builder() + .header(hyper::header::CONTENT_TYPE, mime) + .body(body)?) + } else { + Ok(crate::simple_response( + hyper::StatusCode::NOT_FOUND, + lang.tr("media_upload_missing", None).into_owned(), + )) + } + } + } + } else { + Ok(crate::common_response_builder() + .status(hyper::StatusCode::FOUND) + .header(hyper::header::LOCATION, &href) + .body(href.into())?) + } + } + } + } + } +} + +pub fn route_stable() -> crate::RouteNode<()> { + crate::RouteNode::new() + .with_child( + "comments", + crate::RouteNode::new().with_child_parse::<CommentLocalID, _>( + crate::RouteNode::new().with_child( + "attachments/0/href", + crate::RouteNode::new() + .with_handler_async("GET", route_stable_comments_attachments_0_href_get), + ), + ), + ) + .with_child( + "posts", + crate::RouteNode::new().with_child_parse::<PostLocalID, _>( + crate::RouteNode::new().with_child( + "href", + crate::RouteNode::new().with_handler_async("GET", route_stable_posts_href_get), + ), + ), + ) + .with_child( + "users", + crate::RouteNode::new().with_child_parse::<UserLocalID, _>( + crate::RouteNode::new().with_child( + "avatar/href", + crate::RouteNode::new() + .with_handler_async("GET", route_unstable_users_avatar_href_get), + ), + ), + ) +} diff --git a/src/routes/api/users.rs b/src/routes/api/users.rs index 3e593b3..a0c8f21 100644 --- a/src/routes/api/users.rs +++ b/src/routes/api/users.rs @@ -343,88 +343,6 @@ async fn route_unstable_users_patch( Ok(crate::empty_response()) } -async fn route_unstable_users_avatar_href_get( - params: (UserIDOrMe,), - ctx: Arc<crate::RouteContext>, - req: hyper::Request<hyper::Body>, -) -> Result<hyper::Response<hyper::Body>, crate::Error> { - let (user_id,) = params; - - let lang = crate::get_lang_for_req(&req); - let db = ctx.db_pool.get().await?; - - let user_id = user_id.try_resolve(&req, &db).await?; - - let row = db - .query_opt("SELECT avatar FROM person WHERE id=$1", &[&user_id]) - .await?; - match row { - None => Ok(crate::simple_response( - hyper::StatusCode::NOT_FOUND, - lang.tr("no_such_user", None).into_owned(), - )), - Some(row) => { - let href: Option<String> = row.get(0); - match href { - None => Ok(crate::simple_response( - hyper::StatusCode::NOT_FOUND, - lang.tr("user_no_avatar", None).into_owned(), - )), - Some(href) => { - if href.starts_with("local-media://") { - // local media, serve file content - - let media_id: crate::Pineapple = (&href[14..]).parse()?; - - let media_row = db - .query_opt( - "SELECT path, mime FROM media WHERE id=$1", - &[&media_id.as_int()], - ) - .await?; - match media_row { - None => Ok(crate::simple_response( - hyper::StatusCode::NOT_FOUND, - lang.tr("media_upload_missing", None).into_owned(), - )), - Some(media_row) => { - let path: &str = media_row.get(0); - let mime: &str = media_row.get(1); - - if let Some(media_location) = &ctx.media_location { - let path = media_location.join(path); - - let file = tokio::fs::File::open(path).await?; - let body = hyper::Body::wrap_stream( - tokio_util::codec::FramedRead::new( - file, - tokio_util::codec::BytesCodec::new(), - ), - ); - - Ok(crate::common_response_builder() - .header(hyper::header::CONTENT_TYPE, mime) - .body(body)?) - } else { - Ok(crate::simple_response( - hyper::StatusCode::NOT_FOUND, - lang.tr("media_upload_missing", None).into_owned(), - )) - } - } - } - } else { - Ok(crate::common_response_builder() - .status(hyper::StatusCode::FOUND) - .header(hyper::header::LOCATION, &href) - .body(href.into())?) - } - } - } - } - } -} - async fn route_unstable_users_following_posts_list( params: (UserIDOrMe,), ctx: Arc<crate::RouteContext>, @@ -754,11 +672,6 @@ pub fn route_users() -> crate::RouteNode<()> { .with_handler_async("GET", route_unstable_users_get) .with_handler_async("PATCH", route_unstable_users_patch) .with_child( - "avatar/href", - crate::RouteNode::new() - .with_handler_async("GET", route_unstable_users_avatar_href_get), - ) - .with_child( "following:posts", crate::RouteNode::new() .with_handler_async("GET", route_unstable_users_following_posts_list), |