Compare commits
3
Commits
20241002-4
...
20241002-7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58d3c5cc2e | ||
|
|
520fb02fb6 | ||
|
|
2cb12a3d59 |
No files matched your search
@@ -124,13 +124,24 @@ pub fn image_size(f: &NamedTempFile) -> Option<(usize, usize)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Determine size of image with buffer
|
/// Determine size of image with buffer
|
||||||
pub fn image_size_vec(v: &[u8]) -> Option<(usize, usize)> {
|
pub fn image_size_vec(v: &[u8], mime: &str) -> Option<(usize, usize)> {
|
||||||
if let Ok(size) = imagesize::blob_size(v)
|
match mime {
|
||||||
.inspect_err(|err| tracing::error!("Failed to generate image size! {err:?}"))
|
"image/svg+xml" => {
|
||||||
{
|
let tree =
|
||||||
Some((size.width, size.height))
|
report_internal_error!(usvg::Tree::from_data(v, &Default::default())).ok()?;
|
||||||
} else {
|
|
||||||
None
|
let size = tree.size();
|
||||||
|
Some((size.width() as usize, size.height() as usize))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if let Ok(size) = imagesize::blob_size(v)
|
||||||
|
.inspect_err(|err| tracing::error!("Failed to generate image size! {err:?}"))
|
||||||
|
{
|
||||||
|
Some((size.width, size.height))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ impl IntoResponse for Error {
|
|||||||
ErrorType::FileTooLarge { .. } => StatusCode::UNPROCESSABLE_ENTITY,
|
ErrorType::FileTooLarge { .. } => StatusCode::UNPROCESSABLE_ENTITY,
|
||||||
ErrorType::FileTypeNotAllowed => StatusCode::BAD_REQUEST,
|
ErrorType::FileTypeNotAllowed => StatusCode::BAD_REQUEST,
|
||||||
ErrorType::ImageProcessingFailed => StatusCode::INTERNAL_SERVER_ERROR,
|
ErrorType::ImageProcessingFailed => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
ErrorType::NoEmbedData => StatusCode::BAD_REQUEST,
|
||||||
};
|
};
|
||||||
|
|
||||||
(status, Json(&self)).into_response()
|
(status, Json(&self)).into_response()
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ pub enum ErrorType {
|
|||||||
},
|
},
|
||||||
FileTypeNotAllowed,
|
FileTypeNotAllowed,
|
||||||
ImageProcessingFailed,
|
ImageProcessingFailed,
|
||||||
|
NoEmbedData,
|
||||||
|
|
||||||
// ? Legacy errors
|
// ? Legacy errors
|
||||||
VosoUnavailable,
|
VosoUnavailable,
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ impl<'r> Responder<'r, 'static> for Error {
|
|||||||
ErrorType::FileTooLarge { .. } => Status::UnprocessableEntity,
|
ErrorType::FileTooLarge { .. } => Status::UnprocessableEntity,
|
||||||
ErrorType::FileTypeNotAllowed => Status::BadRequest,
|
ErrorType::FileTypeNotAllowed => Status::BadRequest,
|
||||||
ErrorType::ImageProcessingFailed => Status::InternalServerError,
|
ErrorType::ImageProcessingFailed => Status::InternalServerError,
|
||||||
|
ErrorType::NoEmbedData => Status::BadRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Serialize the error data structure into JSON.
|
// Serialize the error data structure into JSON.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use axum::{extract::Query, response::IntoResponse, routing::get, Json, Router};
|
use axum::{extract::Query, response::IntoResponse, routing::get, Json, Router};
|
||||||
use reqwest::header;
|
use reqwest::header;
|
||||||
use revolt_result::Result;
|
use revolt_models::v0::Embed;
|
||||||
|
use revolt_result::{create_error, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use utoipa::ToSchema;
|
use utoipa::ToSchema;
|
||||||
|
|
||||||
@@ -87,5 +88,9 @@ async fn embed(
|
|||||||
Query(UrlQuery { url }): Query<UrlQuery>,
|
Query(UrlQuery { url }): Query<UrlQuery>,
|
||||||
// TypedHeader(Authorization(_bearer)): TypedHeader<Authorization<Bearer>>,
|
// TypedHeader(Authorization(_bearer)): TypedHeader<Authorization<Bearer>>,
|
||||||
) -> Result<impl IntoResponse> {
|
) -> Result<impl IntoResponse> {
|
||||||
Request::generate_embed(url).await.map(Json)
|
match Request::generate_embed(url).await {
|
||||||
|
Ok(Embed::None) => Err(create_error!(NoEmbedData)),
|
||||||
|
result => result,
|
||||||
|
}
|
||||||
|
.map(Json)
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ impl Request {
|
|||||||
let Request { response, mime } = Request::new(url).await?;
|
let Request { response, mime } = Request::new(url).await?;
|
||||||
|
|
||||||
if matches!(mime.type_(), mime::IMAGE | mime::VIDEO) {
|
if matches!(mime.type_(), mime::IMAGE | mime::VIDEO) {
|
||||||
let bytes = report_internal_error!(response.bytes().await)?;
|
let bytes = report_internal_error!(response.bytes().await);
|
||||||
|
|
||||||
let result = match bytes {
|
let result = match bytes {
|
||||||
Ok(bytes) => {
|
Ok(bytes) => {
|
||||||
@@ -122,20 +122,21 @@ impl Request {
|
|||||||
_ => Ok(None),
|
_ => Ok(None),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let response = if let Some(Request { response, .. }) = request {
|
let request = if let Some(request) = request {
|
||||||
response
|
request
|
||||||
} else {
|
} else {
|
||||||
let Request { response, mime } = Request::new(url).await?;
|
let request = Request::new(url).await?;
|
||||||
if matches!(mime.type_(), mime::IMAGE) {
|
if matches!(request.mime.type_(), mime::IMAGE) {
|
||||||
response
|
request
|
||||||
} else {
|
} else {
|
||||||
return Err(create_error!(FileTypeNotAllowed));
|
return Err(create_error!(FileTypeNotAllowed));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some((width, height)) =
|
if let Some((width, height)) = image_size_vec(
|
||||||
image_size_vec(&report_internal_error!(response.bytes().await)?)
|
&report_internal_error!(request.response.bytes().await)?,
|
||||||
{
|
request.mime.as_ref(),
|
||||||
|
) {
|
||||||
Ok(Some(Image {
|
Ok(Some(Image {
|
||||||
url: url.to_owned(),
|
url: url.to_owned(),
|
||||||
width,
|
width,
|
||||||
|
|||||||
@@ -156,8 +156,13 @@ pub async fn create_website_embed(original_url: &str, document: &str) -> Option<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove image if video exists
|
||||||
|
if metadata.video.is_some() {
|
||||||
|
metadata.image.take();
|
||||||
|
}
|
||||||
|
|
||||||
// fetch image size if missing
|
// fetch image size if missing
|
||||||
if metadata.special.is_none() && metadata.image.is_none() {
|
if metadata.special.is_none() {
|
||||||
if let Some(Image {
|
if let Some(Image {
|
||||||
width, height, url, ..
|
width, height, url, ..
|
||||||
}) = &metadata.image
|
}) = &metadata.image
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ docker build -t ghcr.io/revoltchat/base:latest -f Dockerfile.useCurrentArch .
|
|||||||
docker build -t ghcr.io/revoltchat/server:$TAG - < crates/delta/Dockerfile
|
docker build -t ghcr.io/revoltchat/server:$TAG - < crates/delta/Dockerfile
|
||||||
docker build -t ghcr.io/revoltchat/bonfire:$TAG - < crates/bonfire/Dockerfile
|
docker build -t ghcr.io/revoltchat/bonfire:$TAG - < crates/bonfire/Dockerfile
|
||||||
docker build -t ghcr.io/revoltchat/autumn:$TAG - < crates/services/autumn/Dockerfile
|
docker build -t ghcr.io/revoltchat/autumn:$TAG - < crates/services/autumn/Dockerfile
|
||||||
|
docker build -t ghcr.io/revoltchat/january:$TAG - < crates/services/january/Dockerfile
|
||||||
|
|
||||||
if [ "$DEBUG" = "true" ]; then
|
if [ "$DEBUG" = "true" ]; then
|
||||||
git restore Cargo.toml
|
git restore Cargo.toml
|
||||||
@@ -32,3 +33,4 @@ fi
|
|||||||
docker push ghcr.io/revoltchat/server:$TAG
|
docker push ghcr.io/revoltchat/server:$TAG
|
||||||
docker push ghcr.io/revoltchat/bonfire:$TAG
|
docker push ghcr.io/revoltchat/bonfire:$TAG
|
||||||
docker push ghcr.io/revoltchat/autumn:$TAG
|
docker push ghcr.io/revoltchat/autumn:$TAG
|
||||||
|
docker push ghcr.io/revoltchat/january:$TAG
|
||||||
Reference in new issue
Block a user