Collections (#688)

* initial draft; unfinished

* images, fixes

* fixes

* println

* revisions

* fixes

* alternate context setup version

* rev

* partial revs

* rev

* clippy ,fmt

* fmt/clippy/prepare

* fixes

* revs
This commit is contained in:
Wyatt Verchere
2023-09-13 22:22:32 -07:00
committed by GitHub
parent 35cd277fcf
commit 9bd2cb3c7e
30 changed files with 2579 additions and 24 deletions

View File

@@ -1,9 +1,11 @@
use super::version_creation::InitialVersionData;
use crate::auth::{get_user_from_headers, AuthenticationError};
use crate::database::models;
use crate::database::models::thread_item::ThreadBuilder;
use crate::database::models::{self, image_item};
use crate::file_hosting::{FileHost, FileHostingError};
use crate::models::error::ApiError;
use crate::models::ids::ImageId;
use crate::models::images::{Image, ImageContext};
use crate::models::pats::Scopes;
use crate::models::projects::{
DonationLink, License, MonetizationStatus, ProjectId, ProjectStatus, SideType, VersionId,
@@ -233,6 +235,11 @@ struct ProjectCreateData {
#[serde(default = "default_requested_status")]
/// The status of the mod to be set once it is approved
pub requested_status: ProjectStatus,
// Associations to uploaded images in body/description
#[validate(length(max = 10))]
#[serde(default)]
pub uploaded_images: Vec<ImageId>,
}
#[derive(Serialize, Deserialize, Validate, Clone)]
@@ -466,7 +473,6 @@ async fn project_create_inner(
.await?,
);
}
project_create_data = create_data;
}
@@ -512,7 +518,7 @@ async fn project_create_inner(
icon_data = Some(
process_icon_upload(
uploaded_files,
project_id,
project_id.0,
file_extension,
file_host,
field,
@@ -779,6 +785,41 @@ async fn project_create_inner(
let id = project_builder_actual.insert(&mut *transaction).await?;
for image_id in project_create_data.uploaded_images {
if let Some(db_image) =
image_item::Image::get(image_id.into(), &mut *transaction, redis).await?
{
let image: Image = db_image.into();
if !matches!(image.context, ImageContext::Project { .. })
|| image.context.inner_id().is_some()
{
return Err(CreateError::InvalidInput(format!(
"Image {} is not unused and in the 'project' context",
image_id
)));
}
sqlx::query!(
"
UPDATE uploaded_images
SET mod_id = $1
WHERE id = $2
",
id as models::ids::ProjectId,
image_id.0 as i64
)
.execute(&mut *transaction)
.await?;
image_item::Image::clear_cache(image.id.into(), redis).await?;
} else {
return Err(CreateError::InvalidInput(format!(
"Image {} does not exist",
image_id
)));
}
}
let thread_id = ThreadBuilder {
type_: ThreadType::Project,
members: vec![],
@@ -935,7 +976,7 @@ async fn create_initial_version(
async fn process_icon_upload(
uploaded_files: &mut Vec<UploadedFile>,
project_id: ProjectId,
id: u64,
file_extension: &str,
file_host: &dyn FileHost,
mut field: Field,
@@ -950,7 +991,7 @@ async fn process_icon_upload(
let upload_data = file_host
.upload_file(
content_type,
&format!("data/{project_id}/{hash}.{file_extension}"),
&format!("data/{id}/{hash}.{file_extension}"),
data.freeze(),
)
.await?;