Skip to content

Commit

Permalink
Merge branch 'refector/submission' of https://github.com/swpu-acm/onl…
Browse files Browse the repository at this point in the history
…ine-judge into refector/submission
  • Loading branch information
K0nnyaku committed Nov 30, 2024
2 parents f994ab5 + c50b0af commit 7d53913
Show file tree
Hide file tree
Showing 18 changed files with 294 additions and 43 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## \[0.1.5]

### Refactors

- [`0797749`](https://github.com/swpu-acm/online-judge/commit/079774945731e11abed54382cbfb0cc54f6863f8) ([#20](https://github.com/swpu-acm/online-judge/pull/20) by [@fu050409](https://github.com/swpu-acm/online-judge/../../fu050409)) Allow get account by its surrealdb id (`Thing`).

## \[0.1.4]

### Refactors
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "algohub-server"
version = "0.1.4"
version = "0.1.5"
edition = "2021"
description = "Extremely fast async online judge backend based on Rust"
readme = "README.md"
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ extern crate rocket;
pub mod models;
pub mod utils {
pub mod account;
pub mod contest;
pub mod organization;
pub mod problem;
pub mod session;
Expand All @@ -12,10 +13,11 @@ pub mod utils {

pub mod routes {
pub mod account;
pub mod contest;
pub mod index;
pub mod problem;
pub mod organization;
pub mod submission;
pub mod problem;
}

pub mod cors;
Expand Down
11 changes: 11 additions & 0 deletions src/models/asset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use std::path::PathBuf;

use serde::{Deserialize, Serialize};
use surrealdb::sql::Thing;

#[derive(Serialize, Deserialize)]
pub struct Asset {
pub id: Option<Thing>,
pub name: String,
pub path: PathBuf,
}
73 changes: 73 additions & 0 deletions src/models/contest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use serde::{Deserialize, Serialize};
use surrealdb::sql::Thing;

use super::{OwnedCredentials, UserRecordId};

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Visibility {
Public,
Internal,
Private,
}

#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub enum Mode {
#[default]
ICPC,
OI,
}

#[derive(Serialize, Deserialize)]
pub struct Contest {
pub id: Option<Thing>,

pub name: String,
pub mode: Mode,
pub visibility: Visibility,
pub description: String,
pub announcement: Option<String>,

pub start_time: chrono::NaiveDateTime,
pub end_time: chrono::NaiveDateTime,
pub problems: Vec<Thing>,

pub owner: Thing,
pub creator: Thing,
pub updaters: Vec<Thing>,
pub participants: Vec<Thing>,

pub created_at: chrono::NaiveDateTime,
pub updated_at: chrono::NaiveDateTime,
}

#[derive(Serialize, Deserialize)]
pub struct ContestData {
pub name: String,
pub mode: Mode,
pub visibility: Visibility,
pub description: String,
pub start_time: chrono::NaiveDateTime,
pub end_time: chrono::NaiveDateTime,
pub owner: UserRecordId,
}

#[derive(Serialize, Deserialize)]
pub struct CreateContest {
pub auth: OwnedCredentials,
pub data: ContestData,
}

#[derive(Serialize, Deserialize)]
pub struct AddProblems<'a> {
pub auth: OwnedCredentials,
pub contest_id: &'a str,
pub problem_ids: Vec<&'a str>,
}

#[derive(Serialize, Deserialize)]
pub struct RemoveProblem {
pub auth: OwnedCredentials,
pub contest_id: Thing,
pub problem_id: Thing,
}
2 changes: 2 additions & 0 deletions src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
pub mod account;
pub mod asset;
pub mod contest;
pub mod error;
pub mod organization;
pub mod problem;
Expand Down
14 changes: 1 addition & 13 deletions src/models/problem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@ pub struct Sample {
pub output: String,
}

#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub enum Mode {
#[default]
ICPC,
OI,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Problem {
pub id: Option<Thing>,
Expand All @@ -38,7 +31,6 @@ pub struct Problem {
pub categories: Vec<String>,
pub tags: Vec<String>,

pub mode: Mode,
pub private: bool,

pub created_at: chrono::NaiveDateTime,
Expand All @@ -59,11 +51,9 @@ impl From<CreateProblem<'_>> for Problem {
memory_limit: val.memory_limit,
test_cases: val.test_cases,
creator: ("account", val.id).into(),
// owner: val.owner,
owner: ("account", val.id).into(),
owner: val.owner.into(),
categories: val.categories,
tags: val.tags,
mode: val.mode,
private: val.private,
created_at: chrono::Local::now().naive_local(),
updated_at: chrono::Local::now().naive_local(),
Expand Down Expand Up @@ -91,7 +81,6 @@ pub struct ProblemDetail {
pub categories: Vec<String>,
pub tags: Vec<String>,

pub mode: Mode,
pub private: bool,

pub created_at: chrono::NaiveDateTime,
Expand All @@ -115,7 +104,6 @@ impl From<Problem> for ProblemDetail {
owner: value.owner.into(),
categories: value.categories,
tags: value.tags,
mode: value.mode,
private: value.private,
created_at: value.created_at,
updated_at: value.updated_at,
Expand Down
10 changes: 5 additions & 5 deletions src/models/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ pub struct Record {

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserRecordId {
tb: String,
id: String,
pub tb: String,
pub id: String,
}

impl From<Thing> for UserRecordId {
Expand All @@ -21,9 +21,9 @@ impl From<Thing> for UserRecordId {
}
}

impl Into<Thing> for UserRecordId {
fn into(self) -> Thing {
Thing::from((self.tb, self.id))
impl From<UserRecordId> for Thing {
fn from(value: UserRecordId) -> Self {
Thing::from((value.tb, value.id))
}
}

Expand Down
1 change: 0 additions & 1 deletion src/models/submission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,4 @@ pub struct UserSubmission<'r> {
pub lang: Language,
pub problem_id: &'r str,
pub code: String,
pub private: bool,
}
2 changes: 1 addition & 1 deletion src/routes/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ pub async fn profile(db: &State<Surreal<Client>>, profile: Json<MergeProfile<'_>

#[get("/profile/<id>")]
pub async fn get_profile(db: &State<Surreal<Client>>, id: &str) -> Result<Profile> {
let profile = account::get_by_id::<Profile>(db, id)
let profile = account::get_by_identity::<Profile>(db, id)
.await
.map_err(|e| Error::ServerError(Json(e.to_string().into())))?
.ok_or(Error::NotFound(Json("Account not found".into())))?;
Expand Down
77 changes: 77 additions & 0 deletions src/routes/contest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use rocket::{serde::json::Json, State};
use serde::{Deserialize, Serialize};
use surrealdb::{engine::remote::ws::Client, sql::Thing, Surreal};

use crate::{
models::{
contest::{AddProblems, CreateContest},
error::Error,
response::{Empty, Response},
},
utils::{contest, session},
Result,
};

#[derive(Serialize, Deserialize)]
pub struct CreateResponse {
pub id: String,
}

#[post("/create", data = "<contest>")]
pub async fn create(
db: &State<Surreal<Client>>,
contest: Json<CreateContest>,
) -> Result<CreateResponse> {
if !session::verify(db, &contest.auth.id, &contest.auth.token).await {
return Err(Error::Unauthorized(Json("Invalid session".into())));
}

let contest = contest.into_inner();
let contest = contest::create(db, &contest.auth.id, contest.data)
.await
.map_err(|e| Error::ServerError(Json(e.into())))?
.ok_or(Error::ServerError(Json("Failed to create contest".into())))?;

Ok(Json(Response {
success: true,
message: "Contest created successfully".into(),
data: Some(CreateResponse {
id: contest.id.unwrap().id.to_string(),
}),
}))
}

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

let problem = data.into_inner();
contest::add_problems(
db,
problem.contest_id,
&problem
.problem_ids
.iter()
.map(|&p| Thing::from(("problem", p)))
.collect::<Vec<Thing>>(),
)
.await
.map_err(|e| Error::ServerError(Json(e.into())))?
.ok_or(Error::NotFound(Json("Contest not found".into())))?;

Ok(Json(Response {
success: true,
message: "Problems added successfully".into(),
data: None,
}))
}

pub fn routes() -> Vec<rocket::Route> {
use rocket::routes;
routes![create, add_problem]
}
7 changes: 4 additions & 3 deletions src/routes/index.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::path::{Path, PathBuf};

use super::contest;
use super::organization;
use super::problem;
use crate::{cors::CORS, routes::account};
use anyhow::Result;
use rocket::fs::NamedFile;
use surrealdb::{engine::remote::ws::Ws, opt::auth::Root, Surreal};
use super::problem;
use super::organization;
#[get("/")]
async fn index() -> Result<NamedFile, std::io::Error> {
NamedFile::open("dist/index.html").await
Expand Down Expand Up @@ -37,6 +38,6 @@ pub async fn rocket() -> rocket::Rocket<rocket::Build> {
.mount("/account", account::routes())
.mount("/problem", problem::routes())
.mount("/org", organization::routes())
.mount("/contest", contest::routes())
.manage(db)

}
2 changes: 1 addition & 1 deletion src/routes/organization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,5 @@ pub async fn delete(

pub fn routes() -> Vec<rocket::Route> {
use rocket::routes;
routes![create]
routes![create, delete]
}
28 changes: 22 additions & 6 deletions src/routes/problem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ use surrealdb::{engine::remote::ws::Client, Surreal};

use crate::{
models::{
account::Account,
error::Error,
problem::{Mode, Problem, ProblemDetail, Sample},
problem::{Problem, ProblemDetail, Sample},
response::Response,
OwnedCredentials,
OwnedCredentials, UserRecordId,
},
utils::{problem, session},
utils::{account, problem, session},
Result,
};

Expand All @@ -29,14 +30,14 @@ pub struct CreateProblem<'r> {
#[serde(skip_serializing_if = "Option::is_none")]
pub hint: Option<String>,

pub owner: UserRecordId,
pub time_limit: u64,
pub memory_limit: u64,
pub test_cases: Vec<Sample>,

pub categories: Vec<String>,
pub tags: Vec<String>,

pub mode: Mode,
pub private: bool,
}

Expand Down Expand Up @@ -120,7 +121,7 @@ pub async fn get(
#[derive(Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct ListProblem {
pub id: Option<String>,
pub identity: Option<String>,
pub auth: Option<OwnedCredentials>,
pub limit: Option<u32>,
}
Expand All @@ -141,7 +142,22 @@ pub async fn list(

let data = data.into_inner();

let problems = problem::list_for_account::<Problem>(db, data.id, authed_id, data.limit)
let account_id = if let Some(identity) = data.identity.clone() {
Some(
account::get_by_identity::<Account>(db, &identity)
.await
.map_err(|e| Error::ServerError(Json(e.to_string().into())))?
.ok_or(Error::Unauthorized(Json("Invalid identity".into())))?
.id
.unwrap()
.id
.to_string(),
)
} else {
None
};

let problems = problem::list_for_account::<Problem>(db, account_id, authed_id, data.limit)
.await
.map_err(|e| Error::ServerError(Json(e.to_string().into())))?;

Expand Down
Loading

0 comments on commit 7d53913

Please sign in to comment.