Fix some issues with search and mod creation (#77)

This commit is contained in:
Aeledfyr 2020-10-16 12:04:38 -05:00 committed by GitHub
parent 77d35b61a9
commit 7983e82b60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 34 deletions

View File

@ -203,7 +203,12 @@ async fn mod_create_inner(
while let Some(chunk) = field.next().await {
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;
}
@ -211,9 +216,6 @@ async fn mod_create_inner(
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) =
super::version_creation::get_name_ext(&content_disposition)?;
@ -374,18 +376,35 @@ async fn mod_create_inner(
file_name: upload_data.file_name.clone(),
});
let mut author_username = None;
let mut author_id = None;
let team = models::team_item::TeamBuilder {
members: create_data
.team_members
.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(),
name: member.name,
role: member.role,
}
})
.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 status = ModStatus::Processing;
@ -440,8 +459,8 @@ async fn mod_create_inner(
versions: versions_list,
page_url: format!("https://modrinth.com/mod/{}", mod_id),
icon_url: mod_builder.icon_url.clone().unwrap(),
author: user.username,
author_url: format!("https://modrinth.com/user/{}", user.id),
author: author_username,
author_url: format!("https://modrinth.com/user/{}", author_id),
// TODO: latest version info
latest_version: String::new(),
downloads: 0,

View File

@ -186,12 +186,15 @@ pub async fn index_curseforge(
.date_modified
.parse::<chrono::DateTime<chrono::Utc>>()?;
let mut author = String::new();
let mut author_url = String::new();
let author;
let author_url;
if curseforge_mod.authors.len() > 0 {
author = (&curseforge_mod.authors[0].name).to_string();
author_url = (&curseforge_mod.authors[0].url).to_string();
if let Some(user) = curseforge_mod.authors.get(0) {
author = user.name.clone();
author_url = user.url.clone();
} else {
author = String::from("unknown");
author_url = curseforge_mod.website_url.clone();
}
docs_to_add.push(UploadSearchMod {

View File

@ -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 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
"
).fetch(&pool);
while let Some(result) = results.next().await {
if let Ok(result) = result {
while let Some(result) = mods.next().await {
if let Ok(mod_data) = result {
let versions: Vec<String> = sqlx::query!(
"
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
WHERE versions.mod_id = $1
",
result.id
mod_data.id
)
.fetch_many(&pool)
.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
WHERE versions.mod_id = $1
",
result.id
mod_data.id
)
.fetch_many(&pool)
.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
WHERE mc.joining_mod_id = $1
",
result.id
mod_data.id
)
.fetch_many(&pool)
.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
",
crate::models::teams::OWNER_ROLE,
result.team_id,
mod_data.team_id,
)
.fetch_one(&pool)
.await?;
let mut icon_url = "".to_string();
if let Some(url) = result.icon_url {
if let Some(url) = mod_data.icon_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 {
mod_id: format!("local-{}", crate::models::ids::ModId(result.id as u64)),
title: result.title,
description: result.description,
mod_id: format!("local-{}", mod_id),
title: mod_data.title,
description: mod_data.description,
categories,
versions,
downloads: result.downloads,
page_url: format!("https://modrinth.com/mod/{}", result.id),
downloads: mod_data.downloads,
page_url: format!("https://modrinth.com/mod/{}", mod_id),
icon_url,
author: user.username,
author_url: format!("https://modrinth.com/user/{}", user.id),
date_created: result.published,
created_timestamp: result.published.timestamp(),
date_modified: result.updated,
modified_timestamp: result.updated.timestamp(),
author_url: format!("https://modrinth.com/user/{}", author_id),
date_created: mod_data.published,
created_timestamp: mod_data.published.timestamp(),
date_modified: mod_data.updated,
modified_timestamp: mod_data.updated.timestamp(),
latest_version: "".to_string(), // TODO: Info about latest version
host: Cow::Borrowed("modrinth"),
empty: Cow::Borrowed("{}{}{}"),

View File

@ -23,6 +23,8 @@ pub enum SearchError {
IntParsingError(#[from] std::num::ParseIntError),
#[error("Environment Error")]
EnvError(#[from] dotenv::Error),
#[error("Invalid index to sort by: {0}")]
InvalidIndex(String),
}
impl actix_web::ResponseError for SearchError {
@ -32,6 +34,7 @@ impl actix_web::ResponseError for SearchError {
SearchError::IndexDBError(..) => StatusCode::INTERNAL_SERVER_ERROR,
SearchError::SerDeError(..) => 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::SerDeError(..) => "invalid_input",
SearchError::IntParsingError(..) => "invalid_input",
SearchError::InvalidIndex(..) => "invalid_input",
},
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);
}
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
.get_index(format!("{}_mods", index).as_ref())
.get_index(index)
.await?
.search::<ResultSearchMod>(&query)
.await?;