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.
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<bool>,
exec: E,
redis: &RedisPool,
) -> Result<Vec<MinecraftGameVersion>, 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

View File

@@ -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

View File

@@ -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<String> = 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<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_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] =

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 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!(

View File

@@ -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<CommonProject> = test::read_body_json(projects).await;
assert_eq!(projects.len(), expected_count);
}
},