more games information, games route (#756)

* more games information, games route

* adds banner url
This commit is contained in:
Wyatt Verchere
2023-11-14 10:01:31 -08:00
committed by GitHub
parent 375f992a0c
commit f4880d0519
19 changed files with 206 additions and 45 deletions

View File

@@ -214,6 +214,9 @@ pub struct StatusId(pub i32);
pub struct SideTypeId(pub i32);
#[derive(Copy, Clone, Debug, Type, Serialize, Deserialize)]
#[sqlx(transparent)]
pub struct GameId(pub i32);
#[derive(Copy, Clone, Debug, Type, Serialize, Deserialize)]
#[sqlx(transparent)]
pub struct DonationPlatformId(pub i32);
#[derive(Copy, Clone, Debug, Type, PartialEq, Eq, Hash, Serialize, Deserialize)]

View File

@@ -9,35 +9,71 @@ use futures::TryStreamExt;
use itertools::Itertools;
use serde::{Deserialize, Serialize};
const GAMES_LIST_NAMESPACE: &str = "games";
const LOADER_ID: &str = "loader_id";
const LOADERS_LIST_NAMESPACE: &str = "loaders";
const LOADER_FIELDS_NAMESPACE: &str = "loader_fields";
const LOADER_FIELD_ENUMS_ID_NAMESPACE: &str = "loader_field_enums";
const LOADER_FIELD_ENUM_VALUES_NAMESPACE: &str = "loader_field_enum_values";
#[derive(Clone, Serialize, Deserialize, Debug, Copy)]
pub enum Game {
MinecraftJava,
// MinecraftBedrock
// Future games
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Game {
pub id: GameId,
pub slug: String,
pub name: String,
pub icon_url: Option<String>,
pub banner_url: Option<String>,
}
impl Game {
pub fn name(&self) -> &'static str {
match self {
Game::MinecraftJava => "minecraft-java",
// Game::MinecraftBedrock => "minecraft-bedrock"
// Future games
}
pub async fn get_slug<'a, E>(
slug: &str,
exec: E,
redis: &RedisPool,
) -> Result<Option<Game>, DatabaseError>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
{
Ok(Self::list(exec, redis)
.await?
.into_iter()
.find(|x| x.slug == slug))
}
pub fn from_name(name: &str) -> Option<Game> {
match name {
"minecraft-java" => Some(Game::MinecraftJava),
// "minecraft-bedrock" => Some(Game::MinecraftBedrock)
// Future games
_ => None,
pub async fn list<'a, E>(exec: E, redis: &RedisPool) -> Result<Vec<Game>, DatabaseError>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
{
let cached_games: Option<Vec<Game>> = redis
.get_deserialized_from_json(GAMES_LIST_NAMESPACE, "games")
.await?;
if let Some(cached_games) = cached_games {
return Ok(cached_games);
}
let result = sqlx::query!(
"
SELECT id, slug, name, icon_url, banner_url FROM games
",
)
.fetch_many(exec)
.try_filter_map(|e| async {
Ok(e.right().map(|x| Game {
id: GameId(x.id),
slug: x.slug,
name: x.name,
icon_url: x.icon_url,
banner_url: x.banner_url,
}))
})
.try_collect::<Vec<Game>>()
.await?;
redis
.set_serialized_to_json(GAMES_LIST_NAMESPACE, "games", &result, None)
.await?;
Ok(result)
}
}
@@ -47,7 +83,7 @@ pub struct Loader {
pub loader: String,
pub icon: String,
pub supported_project_types: Vec<String>,
pub supported_games: Vec<Game>,
pub supported_games: Vec<String>, // slugs
}
impl Loader {
@@ -99,7 +135,7 @@ impl Loader {
"
SELECT l.id id, l.loader loader, l.icon icon,
ARRAY_AGG(DISTINCT pt.name) filter (where pt.name is not null) project_types,
ARRAY_AGG(DISTINCT g.name) filter (where g.name is not null) games
ARRAY_AGG(DISTINCT g.slug) filter (where g.slug is not null) games
FROM loaders l
LEFT OUTER JOIN loaders_project_types lpt ON joining_loader_id = l.id
LEFT OUTER JOIN project_types pt ON lpt.joining_project_type_id = pt.id
@@ -123,9 +159,6 @@ impl Loader {
supported_games: x
.games
.unwrap_or_default()
.iter()
.filter_map(|x| Game::from_name(x))
.collect(),
}))
})
.try_collect::<Vec<_>>()

View File

@@ -571,7 +571,7 @@ impl Project {
t.id thread_id, m.monetization_status monetization_status,
ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null) loaders,
ARRAY_AGG(DISTINCT pt.name) filter (where pt.name is not null) project_types,
ARRAY_AGG(DISTINCT g.name) filter (where g.name is not null) games,
ARRAY_AGG(DISTINCT g.slug) filter (where g.slug is not null) games,
ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,
ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,
JSONB_AGG(DISTINCT jsonb_build_object('id', v.id, 'date_published', v.date_published)) filter (where v.id is not null) versions,

View File

@@ -524,7 +524,7 @@ impl Version {
v.version_type version_type, v.featured featured, v.status status, v.requested_status requested_status, v.ordering ordering,
ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null) loaders,
ARRAY_AGG(DISTINCT pt.name) filter (where pt.name is not null) project_types,
ARRAY_AGG(DISTINCT g.name) filter (where g.name is not null) games,
ARRAY_AGG(DISTINCT g.slug) filter (where g.slug is not null) games,
JSONB_AGG(DISTINCT jsonb_build_object('id', f.id, 'url', f.url, 'filename', f.filename, 'primary', f.is_primary, 'size', f.size, 'file_type', f.file_type)) filter (where f.id is not null) files,
JSONB_AGG(DISTINCT jsonb_build_object('algorithm', h.algorithm, 'hash', encode(h.hash, 'escape'), 'file_id', h.file_id)) filter (where h.hash is not null) hashes,
JSONB_AGG(DISTINCT jsonb_build_object('project_id', d.mod_dependency_id, 'version_id', d.dependency_id, 'dependency_type', d.dependency_type,'file_name', dependency_file_name)) filter (where d.dependency_type is not null) dependencies,