Track and sort by release date of game_versions tags (#95)

This commit is contained in:
Aeledfyr
2020-10-31 23:06:47 -05:00
committed by GitHub
parent a4ba6d1444
commit da79386cc3
5 changed files with 108 additions and 55 deletions

View File

@@ -272,6 +272,7 @@ impl<'a> LoaderBuilder<'a> {
pub struct GameVersionBuilder<'a> {
pub version: Option<&'a str>,
pub version_type: Option<&'a str>,
pub date: Option<&'a chrono::DateTime<chrono::Utc>>,
}
impl GameVersion {
@@ -330,6 +331,7 @@ impl GameVersion {
let result = sqlx::query!(
"
SELECT version FROM game_versions
ORDER BY created DESC
"
)
.fetch_many(exec)
@@ -348,6 +350,7 @@ impl GameVersion {
"
SELECT version FROM game_versions
WHERE type = $1
ORDER BY created DESC
",
version_type
)
@@ -417,20 +420,32 @@ impl<'a> GameVersionBuilder<'a> {
}
}
pub fn created(self, created: &'a chrono::DateTime<chrono::Utc>) -> GameVersionBuilder<'a> {
Self {
date: Some(created),
..self
}
}
pub async fn insert<'b, E>(self, exec: E) -> Result<GameVersionId, DatabaseError>
where
E: sqlx::Executor<'b, Database = sqlx::Postgres>,
{
// This looks like a mess, but it *should* work
// This allows game versions to be partially updated without
// replacing the unspecified fields with defaults.
let result = sqlx::query!(
"
INSERT INTO game_versions (version, type)
VALUES ($1, $2)
INSERT INTO game_versions (version, type, created)
VALUES ($1, COALESCE($2, 'other'), COALESCE($3, timezone('utc', now())))
ON CONFLICT (version) DO UPDATE
SET type = excluded.type
SET type = COALESCE($2, game_versions.type),
created = COALESCE($3, game_versions.created)
RETURNING id
",
self.version,
self.version_type,
self.date.map(chrono::DateTime::naive_utc),
)
.fetch_one(exec)
.await?;

View File

@@ -170,6 +170,7 @@ pub async fn game_version_list(
pub struct GameVersionData {
#[serde(rename = "type")]
type_: String,
date: Option<chrono::DateTime<chrono::Utc>>,
}
#[put("game_version/{name}")]
@@ -194,11 +195,15 @@ pub async fn game_version_create(
// The version type currently isn't limited, but it should be one of:
// "release", "snapshot", "alpha", "beta", "other"
let _id = GameVersion::builder()
let mut builder = GameVersion::builder()
.version(&name)?
.version_type(&version_data.type_)?
.insert(&**pool)
.await?;
.version_type(&version_data.type_)?;
if let Some(date) = &version_data.date {
builder = builder.created(date);
}
let _id = builder.insert(&**pool).await?;
Ok(HttpResponse::Ok().body(""))
}

View File

@@ -82,6 +82,8 @@ struct VersionFormat<'a> {
id: String,
#[serde(rename = "type")]
type_: std::borrow::Cow<'a, str>,
#[serde(rename = "releaseTime")]
release_time: chrono::DateTime<chrono::Utc>,
}
async fn update_versions(pool: &sqlx::Pool<sqlx::Postgres>) -> Result<(), VersionIndexingError> {
@@ -92,15 +94,41 @@ async fn update_versions(pool: &sqlx::Pool<sqlx::Postgres>) -> Result<(), Versio
let mut skipped_versions_count = 0u32;
// A list of version names that contains spaces.
// Generated using the command
// ```sh
// curl https://launchermeta.mojang.com/mc/game/version_manifest.json \
// | jq '[.versions[].id | select(contains(" "))]'
// ```
const HALL_OF_SHAME: [(&str, &str); 12] = [
("1.14.2 Pre-Release 4", "1.14.2-pre4"),
("1.14.2 Pre-Release 3", "1.14.2-pre3"),
("1.14.2 Pre-Release 2", "1.14.2-pre2"),
("1.14.2 Pre-Release 1", "1.14.2-pre1"),
("1.14.1 Pre-Release 2", "1.14.1-pre2"),
("1.14.1 Pre-Release 1", "1.14.1-pre1"),
("1.14 Pre-Release 5", "1.14-pre5"),
("1.14 Pre-Release 4", "1.14-pre4"),
("1.14 Pre-Release 3", "1.14-pre3"),
("1.14 Pre-Release 2", "1.14-pre2"),
("1.14 Pre-Release 1", "1.14-pre1"),
("3D Shareware v1.34", "3D-Shareware-v1.34"),
];
for version in input.versions.into_iter() {
let name = version.id;
let mut name = version.id;
if !name
.chars()
.all(|c| c.is_ascii_alphanumeric() || "-_.".contains(c))
{
// We'll deal with these manually
skipped_versions_count += 1;
continue;
if let Some((_, alternate)) = HALL_OF_SHAME.iter().find(|(version, _)| name == *version)
{
name = String::from(*alternate);
} else {
// We'll deal with these manually
skipped_versions_count += 1;
continue;
}
}
let type_ = match &*version.type_ {
@@ -114,6 +142,7 @@ async fn update_versions(pool: &sqlx::Pool<sqlx::Postgres>) -> Result<(), Versio
crate::database::models::categories::GameVersion::builder()
.version(&name)?
.version_type(type_)?
.created(&version.release_time)
.insert(pool)
.await?;
}