diff --git a/README.md b/README.md index dfb9ace2..056c75a6 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ If everything is set up correctly, you should see `rocket`'s development server >> (stats_viewer) GET /demonlist/statsviewer >> (nation_stats_viewer) GET /demonlist/statsviewer/nations >> (demon_permalink) GET /demonlist/permalink/ + >> (demon_levelid) GET /demonlist/levelid/ >> (heatmap_css) GET /demonlist/statsviewer/heatmap.css >> (FileServer: pointercrate-core-pages/static) GET /static/core/ [10] >> (FileServer: pointercrate-user-pages/static) GET /static/user/ [10] diff --git a/pointercrate-demonlist-api/src/lib.rs b/pointercrate-demonlist-api/src/lib.rs index bd22c2b2..3adf265a 100644 --- a/pointercrate-demonlist-api/src/lib.rs +++ b/pointercrate-demonlist-api/src/lib.rs @@ -97,6 +97,7 @@ pub fn setup(rocket: Rocket) -> Rocket { pages::nation_stats_viewer, pages::demon_page, pages::demon_permalink, + pages::demon_levelid, pages::heatmap_css ], ) diff --git a/pointercrate-demonlist-api/src/pages.rs b/pointercrate-demonlist-api/src/pages.rs index f84922d6..243c13df 100644 --- a/pointercrate-demonlist-api/src/pages.rs +++ b/pointercrate-demonlist-api/src/pages.rs @@ -93,6 +93,15 @@ pub async fn demon_permalink(demon_id: i32, pool: &State) -> R Ok(Redirect::to(rocket::uri!("/demonlist", demon_page(position)))) } +#[rocket::get("/levelid//")] +pub async fn demon_levelid(level_id: i32, pool: &State) -> Result { + let mut connection = pool.connection().await?; + + let position = MinimalDemon::by_level_id(level_id, &mut connection).await?.position; + + Ok(Redirect::to(rocket::uri!("/demonlist", demon_page(position)))) +} + #[localized] #[rocket::get("//")] pub async fn demon_page(position: i16, pool: &State, gd: &State) -> Result { diff --git a/pointercrate-demonlist/src/demon/get.rs b/pointercrate-demonlist/src/demon/get.rs index 09858e04..e3c79934 100644 --- a/pointercrate-demonlist/src/demon/get.rs +++ b/pointercrate-demonlist/src/demon/get.rs @@ -20,6 +20,16 @@ impl MinimalDemon { }) } + pub async fn by_level_id(id: i32, connection: &mut PgConnection) -> Result { + sqlx::query_as!(MinimalDemon, r#"SELECT id, name, position FROM demons WHERE level_id = $1"#, i64::from(id)) + .fetch_one(connection) + .await + .map_err(|err| match err { + Error::RowNotFound => DemonlistError::DemonNotFoundLevelID { level_id: id }, + _ => err.into(), + }) + } + pub async fn by_name(name: &str, connection: &mut PgConnection) -> Result { let mut stream = sqlx::query!(r#"SELECT id, name, position FROM demons WHERE name = $1"#, name.to_string()).fetch(connection); diff --git a/pointercrate-demonlist/src/error.rs b/pointercrate-demonlist/src/error.rs index 5c2dec0a..d4fa4fc9 100644 --- a/pointercrate-demonlist/src/error.rs +++ b/pointercrate-demonlist/src/error.rs @@ -78,6 +78,10 @@ pub enum DemonlistError { demon_id: i32, }, + DemonNotFoundLevelID { + level_id: i32, + }, + DemonNotFoundName { demon_name: String, }, @@ -226,6 +230,7 @@ impl PointercrateError for DemonlistError { PlayerNotFound { .. } => 40401, PlayerNotFoundName { .. } => 40401, DemonNotFound { .. } => 40401, + DemonNotFoundLevelID { .. } => 40401, DemonNotFoundName { .. } => 40401, DemonNotFoundPosition { .. } => 40401, RecordNotFound { .. } => 40401, @@ -283,6 +288,7 @@ impl Display for DemonlistError { DemonlistError::PlayerNotFoundName { player_name } => trp!("error-demonlist-playernotfoundname", "player-name" = player_name), DemonlistError::DemonNotFound { demon_id } => trp!("error-demonlist-demonnotfound", "demon-id" = demon_id), + DemonlistError::DemonNotFoundLevelID { level_id } => trp!("error-demonlist-demonnotfoundlevelid", "level-id" = level_id), DemonlistError::DemonNotFoundName { demon_name } => trp!("error-demonlist-demonnotfoundname", "demon-name" = demon_name), DemonlistError::DemonNotFoundPosition { demon_position } => trp!("error-demonlist-demonnotfoundposition", "demon-position" = demon_position),