Skip to content

Commit

Permalink
fix(index): fix index page (#56)
Browse files Browse the repository at this point in the history
* feat(contest): support list contest

* chore: bump version

* feat(contest): support for contest

* chore: fix code lint

* feat(rank): support rank
  • Loading branch information
fu050409 authored Dec 6, 2024
1 parent 8753b73 commit 0d059f6
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changes/contest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"algohub-server": patch:feat
---

Support create and list all contests.
5 changes: 5 additions & 0 deletions .changes/create-contest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"algohub-server": patch:feat
---

Support `ContestProblem` model to display submits and acceptations.
5 changes: 5 additions & 0 deletions .changes/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"algohub-server": patch:fix
---

Fixed index pages cannot be displayed correctly.
5 changes: 5 additions & 0 deletions .changes/rank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"algohub-server": patch:feat
---

Support enpoints for getting rank list.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@

# Node.js
/node_modules

# Assets
/dist
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/models/contest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,12 @@ pub struct ContestProblem {
pub submitted_count: u32,
pub accepted_count: u32,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ContestRank {
name: String,
problem_id: String,
accepted: bool,
wrongs: u32,
}
21 changes: 20 additions & 1 deletion src/routes/contest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use surrealdb::{engine::remote::ws::Client, sql::Thing, Surreal};

use crate::{
models::{
contest::{AddProblems, ContestProblem, CreateContest, UserContest},
contest::{AddProblems, ContestProblem, ContestRank, CreateContest, UserContest},
error::Error,
response::{Empty, Response},
Credentials, OwnedId,
Expand Down Expand Up @@ -119,6 +119,25 @@ pub async fn get(
}))
}

#[post("/rank/<id>", data = "<auth>")]
pub async fn rank(
db: &State<Surreal<Client>>,
id: &str,
auth: Json<Credentials<'_>>,
) -> Result<Vec<ContestRank>> {
if !session::verify(db, auth.id, auth.token).await {
return Err(Error::Unauthorized(Json("Invalid credentials".into())));
}

let rank = contest::rank(db, id).await?;

Ok(Json(Response {
success: true,
message: "Contest rank retrieved successfully".into(),
data: Some(rank),
}))
}

pub fn routes() -> Vec<rocket::Route> {
use rocket::routes;
routes![create, get, add_problems, list_problems, list_all]
Expand Down
9 changes: 7 additions & 2 deletions src/routes/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ use rocket::fs::NamedFile;
use surrealdb::engine::remote::ws::Client;
use surrealdb::{engine::remote::ws::Ws, opt::auth::Root, Surreal};

#[get("/")]
async fn index() -> Result<NamedFile, std::io::Error> {
NamedFile::open("dist/index.html").await
}

#[get("/<file..>", rank = 1)]
async fn index(file: PathBuf) -> Option<NamedFile> {
async fn files(file: PathBuf) -> Option<NamedFile> {
NamedFile::open(Path::new("dist/").join(file)).await.ok()
}

Expand All @@ -39,7 +44,7 @@ pub async fn init_db(db_addr: &str) -> Result<Surreal<Client>> {
pub async fn rocket(db: Surreal<Client>) -> rocket::Rocket<rocket::Build> {
rocket::build()
.attach(CORS)
.mount("/", routes![index])
.mount("/", routes![index, files])
.mount("/account", account::routes())
.mount("/asset", asset::routes())
.mount("/problem", problem::routes())
Expand Down
34 changes: 33 additions & 1 deletion src/utils/contest.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anyhow::Result;
use surrealdb::{engine::remote::ws::Client, sql::Thing, Surreal};

use crate::models::contest::{Contest, ContestData, ContestProblem};
use crate::models::contest::{Contest, ContestData, ContestProblem, ContestRank};

pub async fn create(
db: &Surreal<Client>,
Expand Down Expand Up @@ -106,3 +106,35 @@ pub async fn remove_problem(
.await?
.take(0)?)
}

const RANK_QUERY: &str = r#"
SELECT VALUE array::map((SELECT VALUE id FROM type::thing("contest", $id).problems), |$problem| {
LET $submissions = SELECT judge_result.status.type AS status, created_at
FROM submission WHERE problem.id == $problem AND $parent.id == creator ORDER BY created_at ASC;
LET $first_accepted = array::find_index($submissions, |$submission| {
RETURN $submission.status == "accepted"
});
RETURN IF $first_accepted {
RETURN {
name: $problem.title,
problem_id: record::id($problem),
accepted: true,
wrongs: count($submissions) - $first_accepted - 1,
}
} ELSE {
RETURN {
name: $problem.title,
problem_id: record::id($problem),
accepted: false,
wrongs: count($submissions),
}
}
}) FROM array::distinct(SELECT VALUE creator FROM submission)
"#;
pub async fn rank(db: &Surreal<Client>, id: &str) -> Result<Vec<ContestRank>> {
Ok(db
.query(RANK_QUERY)
.bind(("id", id.to_string()))
.await?
.take(0)?)
}

0 comments on commit 0d059f6

Please sign in to comment.