Support other project types in maven (#284)

This commit is contained in:
BasiqueEvangelist 2022-02-06 08:19:02 +03:00 committed by GitHub
parent f3234a6b5e
commit 6a89646e66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,3 +1,4 @@
use crate::database::models::project_item::QueryProject;
use crate::database::models::version_item::{QueryFile, QueryVersion}; use crate::database::models::version_item::{QueryFile, QueryVersion};
use crate::models::projects::ProjectId; use crate::models::projects::ProjectId;
use crate::routes::ApiError; use crate::routes::ApiError;
@ -111,6 +112,33 @@ pub async fn maven_metadata(
.body(yaserde::ser::to_string(&respdata).map_err(ApiError::XmlError)?)) .body(yaserde::ser::to_string(&respdata).map_err(ApiError::XmlError)?))
} }
fn find_file<'a>(
project_id: &str,
project: &QueryProject,
version: &'a QueryVersion,
file: &str,
) -> Option<&'a QueryFile> {
if let Some(selected_file) = version.files.iter().find(|x| x.filename == file) {
return Some(selected_file);
}
let fileext = match project.project_type.as_str() {
"mod" => "jar",
"modpack" => "mrpack",
_ => return None,
};
if file == format!("{}-{}.{}", &project_id, &version.version_number, fileext) {
version
.files
.iter()
.find(|x| x.primary)
.or_else(|| version.files.iter().last())
} else {
None
}
}
#[get("maven/modrinth/{id}/{versionnum}/{file}")] #[get("maven/modrinth/{id}/{versionnum}/{file}")]
pub async fn version_file( pub async fn version_file(
req: HttpRequest, req: HttpRequest,
@ -120,7 +148,7 @@ pub async fn version_file(
let project_data = let project_data =
database::models::Project::get_full_from_slug_or_project_id(&project_id, &**pool).await?; database::models::Project::get_full_from_slug_or_project_id(&project_id, &**pool).await?;
let data = if let Some(data) = project_data { let project = if let Some(data) = project_data {
data data
} else { } else {
return Ok(HttpResponse::NotFound().body("")); return Ok(HttpResponse::NotFound().body(""));
@ -128,13 +156,13 @@ pub async fn version_file(
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok(); let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
if !is_authorized(&data, &user_option, &pool).await? { if !is_authorized(&project, &user_option, &pool).await? {
return Ok(HttpResponse::NotFound().body("")); return Ok(HttpResponse::NotFound().body(""));
} }
let vid = if let Some(vid) = sqlx::query!( let vid = if let Some(vid) = sqlx::query!(
"SELECT id FROM versions WHERE mod_id = $1 AND version_number = $2", "SELECT id FROM versions WHERE mod_id = $1 AND version_number = $2",
data.inner.id as database::models::ids::ProjectId, project.inner.id as database::models::ids::ProjectId,
vnum vnum
) )
.fetch_optional(&**pool) .fetch_optional(&**pool)
@ -164,26 +192,16 @@ pub async fn version_file(
group_id: "maven.modrinth".to_string(), group_id: "maven.modrinth".to_string(),
artifact_id: project_id, artifact_id: project_id,
version: version.version_number, version: version.version_number,
name: data.inner.title, name: project.inner.title,
description: data.inner.description, description: project.inner.description,
}; };
return Ok(HttpResponse::Ok() return Ok(HttpResponse::Ok()
.content_type("text/xml") .content_type("text/xml")
.body(yaserde::ser::to_string(&respdata).map_err(ApiError::XmlError)?)); .body(yaserde::ser::to_string(&respdata).map_err(ApiError::XmlError)?));
} else if let Some(selected_file) = version.files.iter().find(|x| x.filename == file) { } else if let Some(selected_file) = find_file(&project_id, &project, &version, &file) {
return Ok(HttpResponse::TemporaryRedirect() return Ok(HttpResponse::TemporaryRedirect()
.header("Location", &*selected_file.url) .header("location", &*selected_file.url)
.body("")); .body(""));
} else if file == format!("{}-{}.jar", &project_id, &version.version_number) {
if let Some(selected_file) = version.files.iter().find(|x| x.primary) {
return Ok(HttpResponse::TemporaryRedirect()
.header("Location", &*selected_file.url)
.body(""));
} else if let Some(selected_file) = version.files.iter().last() {
return Ok(HttpResponse::TemporaryRedirect()
.header("Location", &*selected_file.url)
.body(""));
}
} }
Ok(HttpResponse::NotFound().body("")) Ok(HttpResponse::NotFound().body(""))
@ -198,7 +216,7 @@ pub async fn version_file_sha1(
let project_data = let project_data =
database::models::Project::get_full_from_slug_or_project_id(&project_id, &**pool).await?; database::models::Project::get_full_from_slug_or_project_id(&project_id, &**pool).await?;
let data = if let Some(data) = project_data { let project = if let Some(data) = project_data {
data data
} else { } else {
return Ok(HttpResponse::NotFound().body("")); return Ok(HttpResponse::NotFound().body(""));
@ -206,13 +224,13 @@ pub async fn version_file_sha1(
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok(); let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
if !is_authorized(&data, &user_option, &pool).await? { if !is_authorized(&project, &user_option, &pool).await? {
return Ok(HttpResponse::NotFound().body("")); return Ok(HttpResponse::NotFound().body(""));
} }
let vid = if let Some(vid) = sqlx::query!( let vid = if let Some(vid) = sqlx::query!(
"SELECT id FROM versions WHERE mod_id = $1 AND version_number = $2", "SELECT id FROM versions WHERE mod_id = $1 AND version_number = $2",
data.inner.id as database::models::ids::ProjectId, project.inner.id as database::models::ids::ProjectId,
vnum vnum
) )
.fetch_optional(&**pool) .fetch_optional(&**pool)
@ -232,32 +250,11 @@ pub async fn version_file_sha1(
return Ok(HttpResponse::NotFound().body("")); return Ok(HttpResponse::NotFound().body(""));
}; };
let selected_file = Ok(find_file(&project_id, &project, &version, &file)
if let Some(selected_file) = version.files.iter().find(|x| x.filename == file) { .and_then(|file| file.hashes.get("sha1"))
selected_file .and_then(|hash_bytes| std::str::from_utf8(hash_bytes).ok())
} else if file == format!("{}-{}.jar", &project_id, &version.version_number) { .map(|hash_str| HttpResponse::Ok().body(hash_str.to_string()))
if let Some(selected_file) = version.files.iter().last() { .unwrap_or_else(|| HttpResponse::NotFound().body("")))
selected_file
} else {
return Ok(HttpResponse::NotFound().body(""));
}
} else {
return Ok(HttpResponse::NotFound().body(""));
};
let hash_bytes = if let Some(val) = selected_file.hashes.get("sha1") {
val
} else {
return Ok(HttpResponse::NotFound().body(""));
};
let hash_text = if let Some(text) = std::str::from_utf8(hash_bytes).ok() {
text.to_string()
} else {
return Ok(HttpResponse::NotFound().body(""));
};
return Ok(HttpResponse::Ok().body(hash_text));
} }
#[get("maven/modrinth/{id}/{versionnum}/{file}.sha512")] #[get("maven/modrinth/{id}/{versionnum}/{file}.sha512")]
@ -269,7 +266,7 @@ pub async fn version_file_sha512(
let project_data = let project_data =
database::models::Project::get_full_from_slug_or_project_id(&project_id, &**pool).await?; database::models::Project::get_full_from_slug_or_project_id(&project_id, &**pool).await?;
let data = if let Some(data) = project_data { let project = if let Some(data) = project_data {
data data
} else { } else {
return Ok(HttpResponse::NotFound().body("")); return Ok(HttpResponse::NotFound().body(""));
@ -277,13 +274,13 @@ pub async fn version_file_sha512(
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok(); let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
if !is_authorized(&data, &user_option, &pool).await? { if !is_authorized(&project, &user_option, &pool).await? {
return Ok(HttpResponse::NotFound().body("")); return Ok(HttpResponse::NotFound().body(""));
} }
let vid = if let Some(vid) = sqlx::query!( let vid = if let Some(vid) = sqlx::query!(
"SELECT id FROM versions WHERE mod_id = $1 AND version_number = $2", "SELECT id FROM versions WHERE mod_id = $1 AND version_number = $2",
data.inner.id as database::models::ids::ProjectId, project.inner.id as database::models::ids::ProjectId,
vnum vnum
) )
.fetch_optional(&**pool) .fetch_optional(&**pool)
@ -303,30 +300,9 @@ pub async fn version_file_sha512(
return Ok(HttpResponse::NotFound().body("")); return Ok(HttpResponse::NotFound().body(""));
}; };
let selected_file = Ok(find_file(&project_id, &project, &version, &file)
if let Some(selected_file) = version.files.iter().find(|x| x.filename == file) { .and_then(|file| file.hashes.get("sha512"))
selected_file .and_then(|hash_bytes| std::str::from_utf8(hash_bytes).ok())
} else if file == format!("{}-{}.jar", &project_id, &version.version_number) { .map(|hash_str| HttpResponse::Ok().body(hash_str.to_string()))
if let Some(selected_file) = version.files.iter().last() { .unwrap_or_else(|| HttpResponse::NotFound().body("")))
selected_file
} else {
return Ok(HttpResponse::NotFound().body(""));
}
} else {
return Ok(HttpResponse::NotFound().body(""));
};
let hash_bytes = if let Some(val) = selected_file.hashes.get("sha512") {
val
} else {
return Ok(HttpResponse::NotFound().body(""));
};
let hash_text = if let Some(text) = std::str::from_utf8(hash_bytes).ok() {
text.to_string()
} else {
return Ok(HttpResponse::NotFound().body(""));
};
return Ok(HttpResponse::Ok().body(hash_text));
} }