diff --git a/src/database/models/legacy_loader_fields.rs b/src/database/models/legacy_loader_fields.rs index d322768e..0804fe36 100644 --- a/src/database/models/legacy_loader_fields.rs +++ b/src/database/models/legacy_loader_fields.rs @@ -5,6 +5,7 @@ // These fields only apply to minecraft-java, and are hardcoded to the minecraft-java game. use chrono::{DateTime, Utc}; +use itertools::Itertools; use serde::{Deserialize, Serialize}; use serde_json::json; @@ -34,6 +35,8 @@ impl MinecraftGameVersion { } pub async fn list<'a, E>( + version_type_option: Option<&str>, + major_option: Option, exec: E, redis: &RedisPool, ) -> Result, DatabaseError> @@ -47,10 +50,25 @@ impl MinecraftGameVersion { })?; let game_version_enum_values = LoaderFieldEnumValue::list(game_version_enum.id, exec, redis).await?; - Ok(game_version_enum_values + + let game_versions = game_version_enum_values .into_iter() .map(MinecraftGameVersion::from_enum_value) - .collect()) + .filter(|x| { + let mut bool = true; + + if let Some(version_type) = version_type_option { + bool &= &*x.type_ == version_type; + } + if let Some(major) = major_option { + bool &= x.major == major; + } + + bool + }) + .collect_vec(); + + Ok(game_versions) } // TODO: remove this diff --git a/src/routes/v3/versions.rs b/src/routes/v3/versions.rs index b96ad2dd..ad34f3e9 100644 --- a/src/routes/v3/versions.rs +++ b/src/routes/v3/versions.rs @@ -777,36 +777,44 @@ pub async fn version_list( // Attempt to populate versions with "auto featured" versions if response.is_empty() && !versions.is_empty() && filters.featured.unwrap_or(false) { - // TODO: Re-implement this - // let (loaders, game_versions) = futures::future::try_join( - // database::models::loader_fields::Loader::list(&**pool, &redis), - // database::models::loader_fields::GameVersion::list_filter( - // None, - // Some(true), - // &**pool, - // &redis, - // ), - // ) - // .await?; + // TODO: This is a bandaid fix for detecting auto-featured versions. + // In the future, not all versions will have 'game_versions' fields, so this will need to be changed. + let (loaders, game_versions) = futures::future::try_join( + database::models::loader_fields::Loader::list(&**pool, &redis), + database::models::legacy_loader_fields::MinecraftGameVersion::list( + None, + Some(true), + &**pool, + &redis, + ), + ) + .await?; - // let mut joined_filters = Vec::new(); - // for game_version in &game_versions { - // for loader in &loaders { - // joined_filters.push((game_version, loader)) - // } - // } + let mut joined_filters = Vec::new(); + for game_version in &game_versions { + for loader in &loaders { + joined_filters.push((game_version, loader)) + } + } - // joined_filters.into_iter().for_each(|filter| { - // versions - // .iter() - // .find(|version| { - // // version.game_versions.contains(&filter.0.version) - // // && - // version.loaders.contains(&filter.1.loader) - // }) - // .map(|version| response.push(version.clone())) - // .unwrap_or(()); - // }); + joined_filters.into_iter().for_each(|filter| { + versions + .iter() + .find(|version| { + // TODO: This is the bandaid fix for detecting auto-featured versions. + let game_versions = version + .version_fields + .iter() + .find(|vf| vf.field_name == "game_versions") + .map(|vf| vf.value.clone()) + .map(|v| v.as_strings()) + .unwrap_or_default(); + game_versions.contains(&filter.0.version) + && version.loaders.contains(&filter.1.loader) + }) + .map(|version| response.push(version.clone())) + .unwrap_or(()); + }); if response.is_empty() { versions diff --git a/src/search/indexing/mod.rs b/src/search/indexing/mod.rs index 63166908..c12a7d1c 100644 --- a/src/search/indexing/mod.rs +++ b/src/search/indexing/mod.rs @@ -293,26 +293,27 @@ async fn update_and_add_to_index( client: &Client, index: &Index, projects: &[UploadSearchProject], - additional_fields: &[String], + _additional_fields: &[String], ) -> Result<(), IndexingError> { - let mut new_filterable_attributes: Vec = index.get_filterable_attributes().await?; - let mut new_displayed_attributes = index.get_displayed_attributes().await?; + // TODO: Uncomment this- hardcoding loader_fields is a band-aid fix, and will be fixed soon + // let mut new_filterable_attributes: Vec = index.get_filterable_attributes().await?; + // let mut new_displayed_attributes = index.get_displayed_attributes().await?; - new_filterable_attributes.extend(additional_fields.iter().map(|s| s.to_string())); - new_displayed_attributes.extend(additional_fields.iter().map(|s| s.to_string())); - info!("add attributes."); - let filterable_task = index - .set_filterable_attributes(new_filterable_attributes) - .await?; - let displayable_task = index - .set_displayed_attributes(new_displayed_attributes) - .await?; - filterable_task - .wait_for_completion(client, None, Some(TIMEOUT)) - .await?; - displayable_task - .wait_for_completion(client, None, Some(TIMEOUT)) - .await?; + // new_filterable_attributes.extend(additional_fields.iter().map(|s: &String| s.to_string())); + // new_displayed_attributes.extend(additional_fields.iter().map(|s| s.to_string())); + // info!("add attributes."); + // let filterable_task = index + // .set_filterable_attributes(new_filterable_attributes) + // .await?; + // let displayable_task = index + // .set_displayed_attributes(new_displayed_attributes) + // .await?; + // filterable_task + // .wait_for_completion(client, None, Some(TIMEOUT)) + // .await?; + // displayable_task + // .wait_for_completion(client, None, Some(TIMEOUT)) + // .await?; info!("Adding to index."); @@ -374,7 +375,13 @@ const DEFAULT_DISPLAYED_ATTRIBUTES: &[&str] = &[ "featured_gallery", "color", // Note: loader fields are not here, but are added on as they are needed (so they can be dynamically added depending on which exist). - + // TODO: remove these- as they should be automatically populated. This is a band-aid fix. + "server_only", + "client_only", + "game_versions", + "singleplayer", + "client_and_server", + "mrpack_loaders", // Non-searchable fields for filling out the Project model. "license_url", "monetization_status", @@ -409,6 +416,14 @@ const DEFAULT_ATTRIBUTES_FOR_FACETING: &[&str] = &[ "project_id", "open_source", "color", + // Note: loader fields are not here, but are added on as they are needed (so they can be dynamically added depending on which exist). + // TODO: remove these- as they should be automatically populated. This is a band-aid fix. + "server_only", + "client_only", + "game_versions", + "singleplayer", + "client_and_server", + "mrpack_loaders", ]; const DEFAULT_SORTABLE_ATTRIBUTES: &[&str] = diff --git a/src/util/webhook.rs b/src/util/webhook.rs index 380b95e6..747739c5 100644 --- a/src/util/webhook.rs +++ b/src/util/webhook.rs @@ -81,7 +81,7 @@ pub async fn send_discord_webhook( // TODO: This should be updated to use the generic loader fields w/ discord from the project game // TODO: This should use the project_item get route - let all_game_versions = MinecraftGameVersion::list(pool, redis).await?; + let all_game_versions = MinecraftGameVersion::list(None, None, pool, redis).await?; let row = sqlx::query!( diff --git a/tests/project.rs b/tests/project.rs index e69b1f3e..9ab5a382 100644 --- a/tests/project.rs +++ b/tests/project.rs @@ -17,7 +17,7 @@ use labrinth::models::teams::ProjectPermissions; use labrinth::util::actix::{MultipartSegment, MultipartSegmentData}; use serde_json::json; -use crate::common::api_common::models::CommonItemType; +use crate::common::api_common::models::{CommonItemType, CommonProject}; use crate::common::api_common::request_data::ProjectCreationRequestData; use crate::common::api_common::{ApiProject, ApiTeams, ApiVersion}; use crate::common::dummy_data::{ @@ -1372,8 +1372,9 @@ async fn projects_various_visibility() { for (pat, expected_count) in visible_pat_pairs { let projects = env .api - .get_user_projects_deserialized_common(USER_USER_ID, pat) + .get_projects(&[&alpha_project_id, &beta_project_id], pat) .await; + let projects: Vec = test::read_body_json(projects).await; assert_eq!(projects.len(), expected_count); } },