Featured filtering patch (#825)

This commit is contained in:
Wyatt Verchere
2024-01-06 19:31:34 -08:00
committed by GitHub
parent 527521328f
commit 541022cdc3
5 changed files with 94 additions and 52 deletions

View File

@@ -5,6 +5,7 @@
// These fields only apply to minecraft-java, and are hardcoded to the minecraft-java game. // These fields only apply to minecraft-java, and are hardcoded to the minecraft-java game.
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use itertools::Itertools;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::json; use serde_json::json;
@@ -34,6 +35,8 @@ impl MinecraftGameVersion {
} }
pub async fn list<'a, E>( pub async fn list<'a, E>(
version_type_option: Option<&str>,
major_option: Option<bool>,
exec: E, exec: E,
redis: &RedisPool, redis: &RedisPool,
) -> Result<Vec<MinecraftGameVersion>, DatabaseError> ) -> Result<Vec<MinecraftGameVersion>, DatabaseError>
@@ -47,10 +50,25 @@ impl MinecraftGameVersion {
})?; })?;
let game_version_enum_values = let game_version_enum_values =
LoaderFieldEnumValue::list(game_version_enum.id, exec, redis).await?; LoaderFieldEnumValue::list(game_version_enum.id, exec, redis).await?;
Ok(game_version_enum_values
let game_versions = game_version_enum_values
.into_iter() .into_iter()
.map(MinecraftGameVersion::from_enum_value) .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 // TODO: remove this

View File

@@ -777,36 +777,44 @@ pub async fn version_list(
// Attempt to populate versions with "auto featured" versions // Attempt to populate versions with "auto featured" versions
if response.is_empty() && !versions.is_empty() && filters.featured.unwrap_or(false) { if response.is_empty() && !versions.is_empty() && filters.featured.unwrap_or(false) {
// TODO: Re-implement this // TODO: This is a bandaid fix for detecting auto-featured versions.
// let (loaders, game_versions) = futures::future::try_join( // In the future, not all versions will have 'game_versions' fields, so this will need to be changed.
// database::models::loader_fields::Loader::list(&**pool, &redis), let (loaders, game_versions) = futures::future::try_join(
// database::models::loader_fields::GameVersion::list_filter( database::models::loader_fields::Loader::list(&**pool, &redis),
// None, database::models::legacy_loader_fields::MinecraftGameVersion::list(
// Some(true), None,
// &**pool, Some(true),
// &redis, &**pool,
// ), &redis,
// ) ),
// .await?; )
.await?;
// let mut joined_filters = Vec::new(); let mut joined_filters = Vec::new();
// for game_version in &game_versions { for game_version in &game_versions {
// for loader in &loaders { for loader in &loaders {
// joined_filters.push((game_version, loader)) joined_filters.push((game_version, loader))
// } }
// } }
// joined_filters.into_iter().for_each(|filter| { joined_filters.into_iter().for_each(|filter| {
// versions versions
// .iter() .iter()
// .find(|version| { .find(|version| {
// // version.game_versions.contains(&filter.0.version) // TODO: This is the bandaid fix for detecting auto-featured versions.
// // && let game_versions = version
// version.loaders.contains(&filter.1.loader) .version_fields
// }) .iter()
// .map(|version| response.push(version.clone())) .find(|vf| vf.field_name == "game_versions")
// .unwrap_or(()); .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() { if response.is_empty() {
versions versions

View File

@@ -293,26 +293,27 @@ async fn update_and_add_to_index(
client: &Client, client: &Client,
index: &Index, index: &Index,
projects: &[UploadSearchProject], projects: &[UploadSearchProject],
additional_fields: &[String], _additional_fields: &[String],
) -> Result<(), IndexingError> { ) -> Result<(), IndexingError> {
let mut new_filterable_attributes: Vec<String> = index.get_filterable_attributes().await?; // TODO: Uncomment this- hardcoding loader_fields is a band-aid fix, and will be fixed soon
let mut new_displayed_attributes = index.get_displayed_attributes().await?; // let mut new_filterable_attributes: Vec<String> = 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_filterable_attributes.extend(additional_fields.iter().map(|s: &String| s.to_string()));
new_displayed_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."); // info!("add attributes.");
let filterable_task = index // let filterable_task = index
.set_filterable_attributes(new_filterable_attributes) // .set_filterable_attributes(new_filterable_attributes)
.await?; // .await?;
let displayable_task = index // let displayable_task = index
.set_displayed_attributes(new_displayed_attributes) // .set_displayed_attributes(new_displayed_attributes)
.await?; // .await?;
filterable_task // filterable_task
.wait_for_completion(client, None, Some(TIMEOUT)) // .wait_for_completion(client, None, Some(TIMEOUT))
.await?; // .await?;
displayable_task // displayable_task
.wait_for_completion(client, None, Some(TIMEOUT)) // .wait_for_completion(client, None, Some(TIMEOUT))
.await?; // .await?;
info!("Adding to index."); info!("Adding to index.");
@@ -374,7 +375,13 @@ const DEFAULT_DISPLAYED_ATTRIBUTES: &[&str] = &[
"featured_gallery", "featured_gallery",
"color", "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). // 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. // Non-searchable fields for filling out the Project model.
"license_url", "license_url",
"monetization_status", "monetization_status",
@@ -409,6 +416,14 @@ const DEFAULT_ATTRIBUTES_FOR_FACETING: &[&str] = &[
"project_id", "project_id",
"open_source", "open_source",
"color", "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] = const DEFAULT_SORTABLE_ATTRIBUTES: &[&str] =

View File

@@ -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 be updated to use the generic loader fields w/ discord from the project game
// TODO: This should use the project_item get route // 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 = let row =
sqlx::query!( sqlx::query!(

View File

@@ -17,7 +17,7 @@ use labrinth::models::teams::ProjectPermissions;
use labrinth::util::actix::{MultipartSegment, MultipartSegmentData}; use labrinth::util::actix::{MultipartSegment, MultipartSegmentData};
use serde_json::json; 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::request_data::ProjectCreationRequestData;
use crate::common::api_common::{ApiProject, ApiTeams, ApiVersion}; use crate::common::api_common::{ApiProject, ApiTeams, ApiVersion};
use crate::common::dummy_data::{ use crate::common::dummy_data::{
@@ -1372,8 +1372,9 @@ async fn projects_various_visibility() {
for (pat, expected_count) in visible_pat_pairs { for (pat, expected_count) in visible_pat_pairs {
let projects = env let projects = env
.api .api
.get_user_projects_deserialized_common(USER_USER_ID, pat) .get_projects(&[&alpha_project_id, &beta_project_id], pat)
.await; .await;
let projects: Vec<CommonProject> = test::read_body_json(projects).await;
assert_eq!(projects.len(), expected_count); assert_eq!(projects.len(), expected_count);
} }
}, },