Fix some issues with search and mod creation (#77)
This commit is contained in:
parent
77d35b61a9
commit
7983e82b60
@ -203,7 +203,12 @@ async fn mod_create_inner(
|
|||||||
while let Some(chunk) = field.next().await {
|
while let Some(chunk) = field.next().await {
|
||||||
data.extend_from_slice(&chunk.map_err(CreateError::MultipartError)?);
|
data.extend_from_slice(&chunk.map_err(CreateError::MultipartError)?);
|
||||||
}
|
}
|
||||||
mod_create_data = Some(serde_json::from_slice(&data)?);
|
let create_data: ModCreateData = serde_json::from_slice(&data)?;
|
||||||
|
|
||||||
|
check_length("mod_name", 3, 255, &*create_data.mod_name)?;
|
||||||
|
check_length("mod_description", 3, 2048, &*create_data.mod_description)?;
|
||||||
|
|
||||||
|
mod_create_data = Some(create_data);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,9 +216,6 @@ async fn mod_create_inner(
|
|||||||
CreateError::InvalidInput(String::from("`data` field must come before file fields"))
|
CreateError::InvalidInput(String::from("`data` field must come before file fields"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
check_length("mod_name", 3, 255, &*create_data.mod_name)?;
|
|
||||||
check_length("mod_description", 3, 2048, &*create_data.mod_description)?;
|
|
||||||
|
|
||||||
let (file_name, file_extension) =
|
let (file_name, file_extension) =
|
||||||
super::version_creation::get_name_ext(&content_disposition)?;
|
super::version_creation::get_name_ext(&content_disposition)?;
|
||||||
|
|
||||||
@ -374,18 +376,35 @@ async fn mod_create_inner(
|
|||||||
file_name: upload_data.file_name.clone(),
|
file_name: upload_data.file_name.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mut author_username = None;
|
||||||
|
let mut author_id = None;
|
||||||
|
|
||||||
let team = models::team_item::TeamBuilder {
|
let team = models::team_item::TeamBuilder {
|
||||||
members: create_data
|
members: create_data
|
||||||
.team_members
|
.team_members
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|member| models::team_item::TeamMemberBuilder {
|
.map(|member| {
|
||||||
|
if member.role == crate::models::teams::OWNER_ROLE {
|
||||||
|
author_id = Some(member.user_id);
|
||||||
|
author_username = Some(member.name.clone());
|
||||||
|
}
|
||||||
|
models::team_item::TeamMemberBuilder {
|
||||||
user_id: member.user_id.into(),
|
user_id: member.user_id.into(),
|
||||||
name: member.name,
|
name: member.name,
|
||||||
role: member.role,
|
role: member.role,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let (author_username, author_id) = if let (Some(u), Some(id)) = (author_username, author_id) {
|
||||||
|
(u, id)
|
||||||
|
} else {
|
||||||
|
return Err(CreateError::InvalidInput(String::from(
|
||||||
|
"A mod must have an author",
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
let team_id = team.insert(&mut *transaction).await?;
|
let team_id = team.insert(&mut *transaction).await?;
|
||||||
|
|
||||||
let status = ModStatus::Processing;
|
let status = ModStatus::Processing;
|
||||||
@ -440,8 +459,8 @@ async fn mod_create_inner(
|
|||||||
versions: versions_list,
|
versions: versions_list,
|
||||||
page_url: format!("https://modrinth.com/mod/{}", mod_id),
|
page_url: format!("https://modrinth.com/mod/{}", mod_id),
|
||||||
icon_url: mod_builder.icon_url.clone().unwrap(),
|
icon_url: mod_builder.icon_url.clone().unwrap(),
|
||||||
author: user.username,
|
author: author_username,
|
||||||
author_url: format!("https://modrinth.com/user/{}", user.id),
|
author_url: format!("https://modrinth.com/user/{}", author_id),
|
||||||
// TODO: latest version info
|
// TODO: latest version info
|
||||||
latest_version: String::new(),
|
latest_version: String::new(),
|
||||||
downloads: 0,
|
downloads: 0,
|
||||||
|
|||||||
@ -186,12 +186,15 @@ pub async fn index_curseforge(
|
|||||||
.date_modified
|
.date_modified
|
||||||
.parse::<chrono::DateTime<chrono::Utc>>()?;
|
.parse::<chrono::DateTime<chrono::Utc>>()?;
|
||||||
|
|
||||||
let mut author = String::new();
|
let author;
|
||||||
let mut author_url = String::new();
|
let author_url;
|
||||||
|
|
||||||
if curseforge_mod.authors.len() > 0 {
|
if let Some(user) = curseforge_mod.authors.get(0) {
|
||||||
author = (&curseforge_mod.authors[0].name).to_string();
|
author = user.name.clone();
|
||||||
author_url = (&curseforge_mod.authors[0].url).to_string();
|
author_url = user.url.clone();
|
||||||
|
} else {
|
||||||
|
author = String::from("unknown");
|
||||||
|
author_url = curseforge_mod.website_url.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
docs_to_add.push(UploadSearchMod {
|
docs_to_add.push(UploadSearchMod {
|
||||||
|
|||||||
@ -12,14 +12,14 @@ pub async fn index_local(pool: PgPool) -> Result<Vec<UploadSearchMod>, IndexingE
|
|||||||
|
|
||||||
let mut docs_to_add: Vec<UploadSearchMod> = vec![];
|
let mut docs_to_add: Vec<UploadSearchMod> = vec![];
|
||||||
|
|
||||||
let mut results = sqlx::query!(
|
let mut mods = sqlx::query!(
|
||||||
"
|
"
|
||||||
SELECT m.id, m.title, m.description, m.downloads, m.icon_url, m.body_url, m.published, m.updated, m.team_id FROM mods m
|
SELECT m.id, m.title, m.description, m.downloads, m.icon_url, m.body_url, m.published, m.updated, m.team_id FROM mods m
|
||||||
"
|
"
|
||||||
).fetch(&pool);
|
).fetch(&pool);
|
||||||
|
|
||||||
while let Some(result) = results.next().await {
|
while let Some(result) = mods.next().await {
|
||||||
if let Ok(result) = result {
|
if let Ok(mod_data) = result {
|
||||||
let versions: Vec<String> = sqlx::query!(
|
let versions: Vec<String> = sqlx::query!(
|
||||||
"
|
"
|
||||||
SELECT gv.version FROM versions
|
SELECT gv.version FROM versions
|
||||||
@ -27,7 +27,7 @@ pub async fn index_local(pool: PgPool) -> Result<Vec<UploadSearchMod>, IndexingE
|
|||||||
INNER JOIN game_versions gv ON gvv.game_version_id=gv.id
|
INNER JOIN game_versions gv ON gvv.game_version_id=gv.id
|
||||||
WHERE versions.mod_id = $1
|
WHERE versions.mod_id = $1
|
||||||
",
|
",
|
||||||
result.id
|
mod_data.id
|
||||||
)
|
)
|
||||||
.fetch_many(&pool)
|
.fetch_many(&pool)
|
||||||
.try_filter_map(|e| async { Ok(e.right().map(|c| c.version)) })
|
.try_filter_map(|e| async { Ok(e.right().map(|c| c.version)) })
|
||||||
@ -41,7 +41,7 @@ pub async fn index_local(pool: PgPool) -> Result<Vec<UploadSearchMod>, IndexingE
|
|||||||
INNER JOIN loaders ON loaders.id = lv.loader_id
|
INNER JOIN loaders ON loaders.id = lv.loader_id
|
||||||
WHERE versions.mod_id = $1
|
WHERE versions.mod_id = $1
|
||||||
",
|
",
|
||||||
result.id
|
mod_data.id
|
||||||
)
|
)
|
||||||
.fetch_many(&pool)
|
.fetch_many(&pool)
|
||||||
.try_filter_map(|e| async { Ok(e.right().map(|c| c.loader)) })
|
.try_filter_map(|e| async { Ok(e.right().map(|c| c.loader)) })
|
||||||
@ -55,7 +55,7 @@ pub async fn index_local(pool: PgPool) -> Result<Vec<UploadSearchMod>, IndexingE
|
|||||||
INNER JOIN categories c ON mc.joining_category_id=c.id
|
INNER JOIN categories c ON mc.joining_category_id=c.id
|
||||||
WHERE mc.joining_mod_id = $1
|
WHERE mc.joining_mod_id = $1
|
||||||
",
|
",
|
||||||
result.id
|
mod_data.id
|
||||||
)
|
)
|
||||||
.fetch_many(&pool)
|
.fetch_many(&pool)
|
||||||
.try_filter_map(|e| async { Ok(e.right().map(|c| c.category)) })
|
.try_filter_map(|e| async { Ok(e.right().map(|c| c.category)) })
|
||||||
@ -71,32 +71,35 @@ pub async fn index_local(pool: PgPool) -> Result<Vec<UploadSearchMod>, IndexingE
|
|||||||
WHERE tm.team_id = $2
|
WHERE tm.team_id = $2
|
||||||
",
|
",
|
||||||
crate::models::teams::OWNER_ROLE,
|
crate::models::teams::OWNER_ROLE,
|
||||||
result.team_id,
|
mod_data.team_id,
|
||||||
)
|
)
|
||||||
.fetch_one(&pool)
|
.fetch_one(&pool)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let mut icon_url = "".to_string();
|
let mut icon_url = "".to_string();
|
||||||
|
|
||||||
if let Some(url) = result.icon_url {
|
if let Some(url) = mod_data.icon_url {
|
||||||
icon_url = url;
|
icon_url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mod_id = crate::models::ids::ModId(mod_data.id as u64);
|
||||||
|
let author_id = crate::models::ids::UserId(user.id as u64);
|
||||||
|
|
||||||
docs_to_add.push(UploadSearchMod {
|
docs_to_add.push(UploadSearchMod {
|
||||||
mod_id: format!("local-{}", crate::models::ids::ModId(result.id as u64)),
|
mod_id: format!("local-{}", mod_id),
|
||||||
title: result.title,
|
title: mod_data.title,
|
||||||
description: result.description,
|
description: mod_data.description,
|
||||||
categories,
|
categories,
|
||||||
versions,
|
versions,
|
||||||
downloads: result.downloads,
|
downloads: mod_data.downloads,
|
||||||
page_url: format!("https://modrinth.com/mod/{}", result.id),
|
page_url: format!("https://modrinth.com/mod/{}", mod_id),
|
||||||
icon_url,
|
icon_url,
|
||||||
author: user.username,
|
author: user.username,
|
||||||
author_url: format!("https://modrinth.com/user/{}", user.id),
|
author_url: format!("https://modrinth.com/user/{}", author_id),
|
||||||
date_created: result.published,
|
date_created: mod_data.published,
|
||||||
created_timestamp: result.published.timestamp(),
|
created_timestamp: mod_data.published.timestamp(),
|
||||||
date_modified: result.updated,
|
date_modified: mod_data.updated,
|
||||||
modified_timestamp: result.updated.timestamp(),
|
modified_timestamp: mod_data.updated.timestamp(),
|
||||||
latest_version: "".to_string(), // TODO: Info about latest version
|
latest_version: "".to_string(), // TODO: Info about latest version
|
||||||
host: Cow::Borrowed("modrinth"),
|
host: Cow::Borrowed("modrinth"),
|
||||||
empty: Cow::Borrowed("{}{}{}"),
|
empty: Cow::Borrowed("{}{}{}"),
|
||||||
|
|||||||
@ -23,6 +23,8 @@ pub enum SearchError {
|
|||||||
IntParsingError(#[from] std::num::ParseIntError),
|
IntParsingError(#[from] std::num::ParseIntError),
|
||||||
#[error("Environment Error")]
|
#[error("Environment Error")]
|
||||||
EnvError(#[from] dotenv::Error),
|
EnvError(#[from] dotenv::Error),
|
||||||
|
#[error("Invalid index to sort by: {0}")]
|
||||||
|
InvalidIndex(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl actix_web::ResponseError for SearchError {
|
impl actix_web::ResponseError for SearchError {
|
||||||
@ -32,6 +34,7 @@ impl actix_web::ResponseError for SearchError {
|
|||||||
SearchError::IndexDBError(..) => StatusCode::INTERNAL_SERVER_ERROR,
|
SearchError::IndexDBError(..) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
SearchError::SerDeError(..) => StatusCode::BAD_REQUEST,
|
SearchError::SerDeError(..) => StatusCode::BAD_REQUEST,
|
||||||
SearchError::IntParsingError(..) => StatusCode::BAD_REQUEST,
|
SearchError::IntParsingError(..) => StatusCode::BAD_REQUEST,
|
||||||
|
SearchError::InvalidIndex(..) => StatusCode::BAD_REQUEST,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +45,7 @@ impl actix_web::ResponseError for SearchError {
|
|||||||
SearchError::IndexDBError(..) => "indexdb_error",
|
SearchError::IndexDBError(..) => "indexdb_error",
|
||||||
SearchError::SerDeError(..) => "invalid_input",
|
SearchError::SerDeError(..) => "invalid_input",
|
||||||
SearchError::IntParsingError(..) => "invalid_input",
|
SearchError::IntParsingError(..) => "invalid_input",
|
||||||
|
SearchError::InvalidIndex(..) => "invalid_input",
|
||||||
},
|
},
|
||||||
description: &self.to_string(),
|
description: &self.to_string(),
|
||||||
})
|
})
|
||||||
@ -161,8 +165,16 @@ pub async fn search_for_mod(info: &SearchRequest) -> Result<SearchResults, Searc
|
|||||||
query = query.with_facet_filters(facets);
|
query = query.with_facet_filters(facets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let index = match index {
|
||||||
|
"relevance" => "relevance_mods",
|
||||||
|
"downloads" => "downloads_mods",
|
||||||
|
"updated" => "updated_mods",
|
||||||
|
"newest" => "newest_mods",
|
||||||
|
i => return Err(SearchError::InvalidIndex(i.to_string())),
|
||||||
|
};
|
||||||
|
|
||||||
let results = client
|
let results = client
|
||||||
.get_index(format!("{}_mods", index).as_ref())
|
.get_index(index)
|
||||||
.await?
|
.await?
|
||||||
.search::<ResultSearchMod>(&query)
|
.search::<ResultSearchMod>(&query)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user