You've already forked AstralRinth
forked from didirus/AstralRinth
Project Colors (#512)
* Inital tests * Finish project colors * Run fmt + clippy + prepare * Fix dp+rp fmting
This commit is contained in:
@@ -30,6 +30,7 @@ pub use self::index::index_get;
|
||||
pub use self::not_found::not_found;
|
||||
use crate::file_hosting::FileHostingError;
|
||||
use actix_web::web;
|
||||
use image::ImageError;
|
||||
|
||||
pub fn v2_config(cfg: &mut web::ServiceConfig) {
|
||||
cfg.service(
|
||||
@@ -230,6 +231,8 @@ pub enum ApiError {
|
||||
DiscordError(String),
|
||||
#[error("Error while decoding Base62: {0}")]
|
||||
Decoding(#[from] crate::models::ids::DecodingError),
|
||||
#[error("Image Parsing Error: {0}")]
|
||||
ImageError(#[from] ImageError),
|
||||
}
|
||||
|
||||
impl actix_web::ResponseError for ApiError {
|
||||
@@ -280,6 +283,9 @@ impl actix_web::ResponseError for ApiError {
|
||||
actix_web::http::StatusCode::FAILED_DEPENDENCY
|
||||
}
|
||||
ApiError::Decoding(..) => actix_web::http::StatusCode::BAD_REQUEST,
|
||||
ApiError::ImageError(..) => {
|
||||
actix_web::http::StatusCode::BAD_REQUEST
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,6 +310,7 @@ impl actix_web::ResponseError for ApiError {
|
||||
ApiError::Payments(..) => "payments_error",
|
||||
ApiError::DiscordError(..) => "discord_error",
|
||||
ApiError::Decoding(..) => "decoding_error",
|
||||
ApiError::ImageError(..) => "invalid_image",
|
||||
},
|
||||
description: &self.to_string(),
|
||||
},
|
||||
|
||||
@@ -18,6 +18,7 @@ use actix_web::web::Data;
|
||||
use actix_web::{post, HttpRequest, HttpResponse};
|
||||
use chrono::Utc;
|
||||
use futures::stream::StreamExt;
|
||||
use image::ImageError;
|
||||
use rust_decimal::Decimal;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::postgres::PgPool;
|
||||
@@ -65,6 +66,8 @@ pub enum CreateError {
|
||||
Unauthorized(#[from] AuthenticationError),
|
||||
#[error("Authentication Error: {0}")]
|
||||
CustomAuthenticationError(String),
|
||||
#[error("Image Parsing Error: {0}")]
|
||||
ImageError(#[from] ImageError),
|
||||
}
|
||||
|
||||
impl actix_web::ResponseError for CreateError {
|
||||
@@ -95,6 +98,7 @@ impl actix_web::ResponseError for CreateError {
|
||||
CreateError::SlugCollision => StatusCode::BAD_REQUEST,
|
||||
CreateError::ValidationError(..) => StatusCode::BAD_REQUEST,
|
||||
CreateError::FileValidationError(..) => StatusCode::BAD_REQUEST,
|
||||
CreateError::ImageError(..) => StatusCode::BAD_REQUEST,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,6 +124,7 @@ impl actix_web::ResponseError for CreateError {
|
||||
CreateError::SlugCollision => "invalid_input",
|
||||
CreateError::ValidationError(..) => "invalid_input",
|
||||
CreateError::FileValidationError(..) => "invalid_input",
|
||||
CreateError::ImageError(..) => "invalid_image",
|
||||
},
|
||||
description: &self.to_string(),
|
||||
})
|
||||
@@ -468,7 +473,7 @@ pub async fn project_create_inner(
|
||||
))
|
||||
})?;
|
||||
|
||||
let mut icon_url = None;
|
||||
let mut icon_data = None;
|
||||
|
||||
while let Some(item) = payload.next().await {
|
||||
let mut field: Field = item.map_err(CreateError::MultipartError)?;
|
||||
@@ -482,13 +487,13 @@ pub async fn project_create_inner(
|
||||
super::version_creation::get_name_ext(&content_disposition)?;
|
||||
|
||||
if name == "icon" {
|
||||
if icon_url.is_some() {
|
||||
if icon_data.is_some() {
|
||||
return Err(CreateError::InvalidInput(String::from(
|
||||
"Projects can only have one icon",
|
||||
)));
|
||||
}
|
||||
// Upload the icon to the cdn
|
||||
icon_url = Some(
|
||||
icon_data = Some(
|
||||
process_icon_upload(
|
||||
uploaded_files,
|
||||
project_id,
|
||||
@@ -731,7 +736,7 @@ pub async fn project_create_inner(
|
||||
title: project_create_data.title,
|
||||
description: project_create_data.description,
|
||||
body: project_create_data.body,
|
||||
icon_url,
|
||||
icon_url: icon_data.clone().map(|x| x.0),
|
||||
issues_url: project_create_data.issues_url,
|
||||
source_url: project_create_data.source_url,
|
||||
wiki_url: project_create_data.wiki_url,
|
||||
@@ -759,6 +764,7 @@ pub async fn project_create_inner(
|
||||
ordering: x.ordering,
|
||||
})
|
||||
.collect(),
|
||||
color: icon_data.and_then(|x| x.1),
|
||||
};
|
||||
|
||||
let now = Utc::now();
|
||||
@@ -803,6 +809,7 @@ pub async fn project_create_inner(
|
||||
gallery: gallery_urls,
|
||||
flame_anvil_project: None,
|
||||
flame_anvil_user: None,
|
||||
color: project_builder.color,
|
||||
};
|
||||
|
||||
let _project_id = project_builder.insert(&mut *transaction).await?;
|
||||
@@ -911,9 +918,9 @@ async fn process_icon_upload(
|
||||
project_id: ProjectId,
|
||||
file_extension: &str,
|
||||
file_host: &dyn FileHost,
|
||||
mut field: actix_multipart::Field,
|
||||
mut field: Field,
|
||||
cdn_url: &str,
|
||||
) -> Result<String, CreateError> {
|
||||
) -> Result<(String, Option<u32>), CreateError> {
|
||||
if let Some(content_type) =
|
||||
crate::util::ext::get_image_content_type(file_extension)
|
||||
{
|
||||
@@ -924,6 +931,8 @@ async fn process_icon_upload(
|
||||
)
|
||||
.await?;
|
||||
|
||||
let color = crate::util::img::get_color_from_img(&data)?;
|
||||
|
||||
let hash = sha1::Sha1::from(&data).hexdigest();
|
||||
let upload_data = file_host
|
||||
.upload_file(
|
||||
@@ -938,7 +947,7 @@ async fn process_icon_upload(
|
||||
file_name: upload_data.file_name.clone(),
|
||||
});
|
||||
|
||||
Ok(format!("{}/{}", cdn_url, upload_data.file_name))
|
||||
Ok((format!("{}/{}", cdn_url, upload_data.file_name), color))
|
||||
} else {
|
||||
Err(CreateError::InvalidIconFormat(file_extension.to_string()))
|
||||
}
|
||||
|
||||
@@ -1288,6 +1288,9 @@ pub async fn project_icon_edit(
|
||||
"Icons must be smaller than 256KiB",
|
||||
)
|
||||
.await?;
|
||||
|
||||
let color = crate::util::img::get_color_from_img(&bytes)?;
|
||||
|
||||
let hash = sha1::Sha1::from(&bytes).hexdigest();
|
||||
let project_id: ProjectId = project_item.id.into();
|
||||
let upload_data = file_host
|
||||
@@ -1303,10 +1306,11 @@ pub async fn project_icon_edit(
|
||||
sqlx::query!(
|
||||
"
|
||||
UPDATE mods
|
||||
SET icon_url = $1
|
||||
WHERE (id = $2)
|
||||
SET icon_url = $1, color = $2
|
||||
WHERE (id = $3)
|
||||
",
|
||||
format!("{}/{}", cdn_url, upload_data.file_name),
|
||||
color.map(|x| x as i32),
|
||||
project_item.id as database::models::ids::ProjectId,
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
@@ -1379,7 +1383,7 @@ pub async fn delete_project_icon(
|
||||
sqlx::query!(
|
||||
"
|
||||
UPDATE mods
|
||||
SET icon_url = NULL
|
||||
SET icon_url = NULL, color = NULL
|
||||
WHERE (id = $1)
|
||||
",
|
||||
project_item.id as database::models::ids::ProjectId,
|
||||
|
||||
Reference in New Issue
Block a user