You've already forked AstralRinth
forked from didirus/AstralRinth
Version slugs (#533)
* Version slugs * Get rid of new field, finish it up
This commit is contained in:
@@ -5832,6 +5832,29 @@
|
|||||||
},
|
},
|
||||||
"query": "\n UPDATE mods\n SET license_url = $1\n WHERE (id = $2)\n "
|
"query": "\n UPDATE mods\n SET license_url = $1\n WHERE (id = $2)\n "
|
||||||
},
|
},
|
||||||
|
"c15ec51ec0e9900e5569557a618760cb4bbb303f0f9ca1189f18557e67d18b56": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Int8"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Int8",
|
||||||
|
"Text",
|
||||||
|
"Int8",
|
||||||
|
"Text"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "\n SELECT v.id FROM versions v\n INNER JOIN mods m ON mod_id = m.id\n WHERE (m.id = $1 OR m.slug = $2) AND (v.id = $3 OR v.version_number = $4)\n ORDER BY date_published ASC\n "
|
||||||
|
},
|
||||||
"c1a3f6dcef6110d6ea884670fb82bac14b98e922bb5673c048ccce7b7300539b": {
|
"c1a3f6dcef6110d6ea884670fb82bac14b98e922bb5673c048ccce7b7300539b": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
@@ -7418,6 +7441,37 @@
|
|||||||
},
|
},
|
||||||
"query": "\n SELECT name FROM project_types pt\n INNER JOIN mods ON mods.project_type = pt.id\n WHERE mods.id = $1\n "
|
"query": "\n SELECT name FROM project_types pt\n INNER JOIN mods ON mods.project_type = pt.id\n WHERE mods.id = $1\n "
|
||||||
},
|
},
|
||||||
|
"ef9391658df31e28c53525c3338a05d9025bb31101547c4cb9d439f793bc7721": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "version_id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Int8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "date_published",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Timestamptz"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Int8",
|
||||||
|
"VarcharArray",
|
||||||
|
"VarcharArray",
|
||||||
|
"Varchar",
|
||||||
|
"Int8",
|
||||||
|
"Int8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "\n SELECT DISTINCT ON(v.date_published, v.id) version_id, v.date_published FROM versions v\n INNER JOIN game_versions_versions gvv ON gvv.joining_version_id = v.id\n INNER JOIN game_versions gv on gvv.game_version_id = gv.id AND (cardinality($2::varchar[]) = 0 OR gv.version = ANY($2::varchar[]))\n INNER JOIN loaders_versions lv ON lv.version_id = v.id\n INNER JOIN loaders l on lv.loader_id = l.id AND (cardinality($3::varchar[]) = 0 OR l.loader = ANY($3::varchar[]))\n WHERE v.mod_id = $1 AND ($4::varchar IS NULL OR v.version_type = $4)\n ORDER BY v.date_published, v.id DESC\n LIMIT $5 OFFSET $6\n "
|
||||||
|
},
|
||||||
"f0db9d8606ccc2196a9cfafe0e7090dab42bf790f25e0469b8947fac1cf043d5": {
|
"f0db9d8606ccc2196a9cfafe0e7090dab42bf790f25e0469b8947fac1cf043d5": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
@@ -7767,37 +7821,6 @@
|
|||||||
},
|
},
|
||||||
"query": "SELECT EXISTS(SELECT 1 FROM notifications WHERE id=$1)"
|
"query": "SELECT EXISTS(SELECT 1 FROM notifications WHERE id=$1)"
|
||||||
},
|
},
|
||||||
"fcc7bedf9709bf49ae152064240a6e8bfa8ff4d5a63707e8b1450d9d77fb6f14": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "version_id",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Int8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "date_published",
|
|
||||||
"ordinal": 1,
|
|
||||||
"type_info": "Timestamptz"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Left": [
|
|
||||||
"Int8",
|
|
||||||
"VarcharArray",
|
|
||||||
"VarcharArray",
|
|
||||||
"Varchar",
|
|
||||||
"Int8",
|
|
||||||
"Int8"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "\n SELECT DISTINCT ON(v.date_published, v.id) version_id, v.date_published FROM versions v\n INNER JOIN game_versions_versions gvv ON gvv.joining_version_id = v.id\n INNER JOIN game_versions gv on gvv.game_version_id = gv.id AND (cardinality($2::varchar[]) = 0 OR gv.version = ANY($2::varchar[]))\n INNER JOIN loaders_versions lv ON lv.version_id = v.id\n INNER JOIN loaders l on lv.loader_id = l.id AND (cardinality($3::varchar[]) = 0 OR l.loader = ANY($3::varchar[]))\n WHERE v.mod_id = $1 AND ($4::varchar IS NULL OR v.version_type = $4)\n ORDER BY v.date_published, v.id ASC\n LIMIT $5 OFFSET $6\n "
|
|
||||||
},
|
|
||||||
"fcd15905507769ab7f9839d64d1be3ee3f61cd555aee57dace76f8e53e91d344": {
|
"fcd15905507769ab7f9839d64d1be3ee3f61cd555aee57dace76f8e53e91d344": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use super::ids::*;
|
use super::ids::*;
|
||||||
use super::DatabaseError;
|
use super::DatabaseError;
|
||||||
|
use crate::models::ids::base62_impl::parse_base62;
|
||||||
use crate::models::projects::{FileType, VersionStatus, VersionType};
|
use crate::models::projects::{FileType, VersionStatus, VersionType};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
@@ -499,7 +500,7 @@ impl Version {
|
|||||||
INNER JOIN loaders_versions lv ON lv.version_id = v.id
|
INNER JOIN loaders_versions lv ON lv.version_id = v.id
|
||||||
INNER JOIN loaders l on lv.loader_id = l.id AND (cardinality($3::varchar[]) = 0 OR l.loader = ANY($3::varchar[]))
|
INNER JOIN loaders l on lv.loader_id = l.id AND (cardinality($3::varchar[]) = 0 OR l.loader = ANY($3::varchar[]))
|
||||||
WHERE v.mod_id = $1 AND ($4::varchar IS NULL OR v.version_type = $4)
|
WHERE v.mod_id = $1 AND ($4::varchar IS NULL OR v.version_type = $4)
|
||||||
ORDER BY v.date_published, v.id ASC
|
ORDER BY v.date_published, v.id DESC
|
||||||
LIMIT $5 OFFSET $6
|
LIMIT $5 OFFSET $6
|
||||||
",
|
",
|
||||||
project_id as ProjectId,
|
project_id as ProjectId,
|
||||||
@@ -905,6 +906,39 @@ impl Version {
|
|||||||
.try_collect::<Vec<QueryVersion>>()
|
.try_collect::<Vec<QueryVersion>>()
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_full_from_id_slug<'a, 'b, E>(
|
||||||
|
project_id_or_slug: &str,
|
||||||
|
slug: &str,
|
||||||
|
executor: E,
|
||||||
|
) -> Result<Option<QueryVersion>, sqlx::error::Error>
|
||||||
|
where
|
||||||
|
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
|
||||||
|
{
|
||||||
|
let project_id_opt =
|
||||||
|
parse_base62(project_id_or_slug).ok().map(|x| x as i64);
|
||||||
|
let id_opt = parse_base62(slug).ok().map(|x| x as i64);
|
||||||
|
let id = sqlx::query!(
|
||||||
|
"
|
||||||
|
SELECT v.id FROM versions v
|
||||||
|
INNER JOIN mods m ON mod_id = m.id
|
||||||
|
WHERE (m.id = $1 OR m.slug = $2) AND (v.id = $3 OR v.version_number = $4)
|
||||||
|
ORDER BY date_published ASC
|
||||||
|
",
|
||||||
|
project_id_opt,
|
||||||
|
project_id_or_slug,
|
||||||
|
id_opt,
|
||||||
|
slug
|
||||||
|
)
|
||||||
|
.fetch_optional(executor)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
if let Some(version_id) = id {
|
||||||
|
Version::get_full(VersionId(version_id.id), executor).await
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -277,6 +277,12 @@ async fn main() -> std::io::Result<()> {
|
|||||||
dotenvy::var("RATE_LIMIT_IGNORE_KEY").ok(),
|
dotenvy::var("RATE_LIMIT_IGNORE_KEY").ok(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.app_data(web::FormConfig::default().error_handler(|err, _req| {
|
||||||
|
routes::ApiError::Validation(err.to_string()).into()
|
||||||
|
}))
|
||||||
|
.app_data(web::PathConfig::default().error_handler(|err, _req| {
|
||||||
|
routes::ApiError::Validation(err.to_string()).into()
|
||||||
|
}))
|
||||||
.app_data(web::QueryConfig::default().error_handler(|err, _req| {
|
.app_data(web::QueryConfig::default().error_handler(|err, _req| {
|
||||||
routes::ApiError::Validation(err.to_string()).into()
|
routes::ApiError::Validation(err.to_string()).into()
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ pub fn projects_config(cfg: &mut web::ServiceConfig) {
|
|||||||
.service(
|
.service(
|
||||||
web::scope("{project_id}")
|
web::scope("{project_id}")
|
||||||
.service(versions::version_list)
|
.service(versions::version_list)
|
||||||
.service(projects::dependency_list),
|
.service(projects::dependency_list)
|
||||||
|
.service(versions::version_project_get),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ pub async fn get_update_from_hash(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if let Some(version_id) = version_ids.last() {
|
if let Some(version_id) = version_ids.first() {
|
||||||
let version_data =
|
let version_data =
|
||||||
database::models::Version::get_full(*version_id, &**pool)
|
database::models::Version::get_full(*version_id, &**pool)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -503,7 +503,7 @@ pub async fn update_files(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if let Some(latest_version) = updated_versions.last() {
|
if let Some(latest_version) = updated_versions.first() {
|
||||||
let mut version_ids = version_ids.write().await;
|
let mut version_ids = version_ids.write().await;
|
||||||
|
|
||||||
version_ids.insert(*latest_version, row.hash);
|
version_ids.insert(*latest_version, row.hash);
|
||||||
|
|||||||
@@ -144,6 +144,31 @@ pub async fn version_list(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Given a project ID/slug and a version slug
|
||||||
|
#[get("version/{slug}")]
|
||||||
|
pub async fn version_project_get(
|
||||||
|
req: HttpRequest,
|
||||||
|
info: web::Path<(String, String)>,
|
||||||
|
pool: web::Data<PgPool>,
|
||||||
|
) -> Result<HttpResponse, ApiError> {
|
||||||
|
let id = info.into_inner();
|
||||||
|
let version_data =
|
||||||
|
database::models::Version::get_full_from_id_slug(&id.0, &id.1, &**pool)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let user_option = get_user_from_headers(req.headers(), &**pool).await.ok();
|
||||||
|
|
||||||
|
if let Some(data) = version_data {
|
||||||
|
if is_authorized_version(&data.inner, &user_option, &pool).await? {
|
||||||
|
return Ok(
|
||||||
|
HttpResponse::Ok().json(models::projects::Version::from(data))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(HttpResponse::NotFound().body(""))
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct VersionIds {
|
pub struct VersionIds {
|
||||||
pub ids: String,
|
pub ids: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user