Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: optimize server codes #34

Merged
merged 2 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changes/optimize.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"algohub-server": patch:feat
---

Optimize data structures and code for better performance.

Also, make the codes more readable and easier to maintain.
5 changes: 4 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ jobs:
--user root --pass root
- name: Rust Cache
uses: Swatinem/rust-cache@v2
- run: cargo test --verbose --all-features
- name: Test
run: cargo test --verbose --all-features
- name: Lint
run: cargo fmt --all -- --check && cargo clippy --all-features -- -D warnings
8 changes: 8 additions & 0 deletions src/models/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,11 @@ pub struct Session {
pub account_id: Thing,
pub token: String,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(crate = "rocket::serde")]
pub struct MergeProfile<'r> {
pub id: &'r str,
pub token: &'r str,
pub profile: Profile,
}
15 changes: 14 additions & 1 deletion src/models/asset.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use std::path::PathBuf;

use rocket::fs::TempFile;
use rocket::{
fs::{NamedFile, TempFile},
response::Responder,
};
use serde::{Deserialize, Serialize};
use surrealdb::sql::Thing;

Expand All @@ -25,3 +28,13 @@ pub struct CreateAsset<'a> {
pub struct UserContent {
pub id: String,
}

pub struct AssetFile(pub(crate) NamedFile);

impl<'r, 'o: 'r> Responder<'r, 'o> for AssetFile {
fn respond_to(self, req: &rocket::Request) -> rocket::response::Result<'o> {
rocket::Response::build_from(self.0.respond_to(req)?)
.raw_header("Cache-control", "max-age=86400") // 24h (24*60*60)
.ok()
}
}
18 changes: 16 additions & 2 deletions src/models/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,21 @@ pub struct Category {

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct CreateCategory {
pub name: String,
pub struct CategoryData<'c> {
pub name: &'c str,
pub owner: UserRecordId,
}

#[derive(Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct CreateCategory<'r> {
pub id: &'r str,
pub token: &'r str,

pub data: CategoryData<'r>,
}

#[derive(Serialize, Deserialize)]
pub struct ListCategories {
pub owner: UserRecordId,
}
17 changes: 13 additions & 4 deletions src/models/organization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ pub struct Organization {

pub description: Option<String>,

pub owner: Vec<Thing>,
pub member: Vec<Thing>,
pub owners: Vec<Thing>,
pub members: Vec<Thing>,

pub creator: String,

Expand All @@ -20,8 +20,17 @@ pub struct Organization {

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct CreateOrganization {
pub name: String,
pub struct OrganizationData<'c> {
pub name: &'c str,
pub display_name: Option<String>,
pub description: Option<String>,
}

#[derive(Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct CreateOrganization<'r> {
pub id: &'r str,
pub token: &'r str,

pub org: OrganizationData<'r>,
}
6 changes: 6 additions & 0 deletions src/models/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ pub struct OwnedCredentials {
pub token: String,
}

#[derive(Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct OwnedId {
pub id: String,
}

#[derive(Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct Token<'r> {
Expand Down
24 changes: 6 additions & 18 deletions src/routes/account.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use std::path::Path;

use rocket::{get, post, serde::json::Json, tokio::fs::remove_dir_all, State};
use serde::{Deserialize, Serialize};
use surrealdb::{engine::remote::ws::Client, Surreal};

use crate::{
models::{
account::{Login, Profile, Register},
account::{Login, MergeProfile, Profile, Register},
error::{Error, ErrorResponse},
response::{Empty, Response},
OwnedCredentials, Record, Token,
Expand Down Expand Up @@ -50,14 +49,6 @@ pub async fn register(
}
}

#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(crate = "rocket::serde")]
pub struct MergeProfile<'r> {
pub id: &'r str,
pub token: &'r str,
pub profile: Profile,
}

#[post("/profile", data = "<profile>")]
pub async fn profile(
db: &State<Surreal<Client>>,
Expand Down Expand Up @@ -122,22 +113,19 @@ pub async fn delete(db: &State<Surreal<Client>>, id: &str, auth: Json<Token<'_>>
.into())
}

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

#[post("/login", data = "<login>")]
pub async fn login(db: &State<Surreal<Client>>, login: Json<Login<'_>>) -> Result<LoginResponse> {
pub async fn login(
db: &State<Surreal<Client>>,
login: Json<Login<'_>>,
) -> Result<OwnedCredentials> {
let session = session::authenticate(db, login.identity, login.password)
.await
.map_err(|e| Error::ServerError(Json(e.to_string().into())))?
.ok_or(Error::Unauthorized(Json("Invalid credentials".into())))?;
Ok(Response {
success: true,
message: "Login successful".into(),
data: Some(LoginResponse {
data: Some(OwnedCredentials {
id: session.account_id.id.to_string(),
token: session.token.clone(),
}),
Expand Down
15 changes: 2 additions & 13 deletions src/routes/asset.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use rocket::{
form::Form,
fs::NamedFile,
response::Responder,
serde::json::Json,
tokio::fs::{create_dir_all, File},
State,
Expand All @@ -10,7 +9,7 @@ use surrealdb::{engine::remote::ws::Client, Surreal};

use crate::{
models::{
asset::{CreateAsset, UserContent},
asset::{AssetFile, CreateAsset, UserContent},
error::Error,
response::{Empty, Response},
Credentials,
Expand Down Expand Up @@ -82,16 +81,6 @@ pub async fn upload(
}))
}

pub struct AssetFile(NamedFile);

impl<'r, 'o: 'r> Responder<'r, 'o> for AssetFile {
fn respond_to(self, req: &rocket::Request) -> rocket::response::Result<'o> {
rocket::Response::build_from(self.0.respond_to(req)?)
.raw_header("Cache-control", "max-age=86400") // 24h (24*60*60)
.ok()
}
}

#[get("/<id>")]
pub async fn get(db: &State<Surreal<Client>>, id: &str) -> Option<AssetFile> {
let asset = asset::get_by_id(db, id).await.ok()??;
Expand All @@ -113,7 +102,7 @@ pub async fn delete(

let asset = asset::get_by_id(db, id)
.await
.map_err(|e| Error::from(e))?
.map_err(Error::from)?
.ok_or(Error::NotFound(Json("Asset not found".into())))?;

rocket::tokio::fs::remove_file(&asset.path)
Expand Down
32 changes: 6 additions & 26 deletions src/routes/category.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,21 @@
use crate::{
models::{
category::{Category, CreateCategory},
category::{Category, CreateCategory, ListCategories},
error::Error,
response::{Empty, Response},
UserRecordId,
OwnedId,
},
utils::{category, session},
Result,
};
use rocket::{post, serde::json::Json, State};
use serde::{Deserialize, Serialize};
use surrealdb::{engine::remote::ws::Client, Surreal};

#[derive(Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct CategoryData<'r> {
pub id: &'r str,
pub token: &'r str,

pub data: CreateCategory,
}

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

#[post("/create", data = "<category>")]
pub async fn create(
db: &State<Surreal<Client>>,
category: Json<CategoryData<'_>>,
) -> Result<CreateCatResponse> {
category: Json<CreateCategory<'_>>,
) -> Result<OwnedId> {
if !session::verify(db, category.id, category.token).await {
return Err(Error::Unauthorized(Json(
"Failed to grant permission".into(),
Expand All @@ -45,7 +30,7 @@ pub async fn create(
Ok(Json(Response {
success: true,
message: "Category created successfully".into(),
data: Some(CreateCatResponse {
data: Some(OwnedId {
id: data.id.unwrap().id.to_string(),
}),
}))
Expand All @@ -55,7 +40,7 @@ pub async fn create(
pub async fn delete(
db: &State<Surreal<Client>>,
id: &str,
category: Json<CategoryData<'_>>,
category: Json<CreateCategory<'_>>,
) -> Result<Empty> {
if !session::verify(db, category.id, category.token).await {
return Err(Error::Unauthorized(Json(
Expand All @@ -75,11 +60,6 @@ pub async fn delete(
.into())
}

#[derive(Serialize, Deserialize)]
pub struct ListCategories {
pub owner: UserRecordId,
}

#[post("/list", data = "<data>")]
pub async fn list(
db: &State<Surreal<Client>>,
Expand Down
14 changes: 3 additions & 11 deletions src/routes/contest.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
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},
OwnedId,
},
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> {
pub async fn create(db: &State<Surreal<Client>>, contest: Json<CreateContest>) -> Result<OwnedId> {
if !session::verify(db, &contest.auth.id, &contest.auth.token).await {
return Err(Error::Unauthorized(Json("Invalid session".into())));
}
Expand All @@ -35,7 +27,7 @@ pub async fn create(
Ok(Json(Response {
success: true,
message: "Contest created successfully".into(),
data: Some(CreateResponse {
data: Some(OwnedId {
id: contest.id.unwrap().id.to_string(),
}),
}))
Expand Down
4 changes: 2 additions & 2 deletions src/routes/index.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use std::path::{Path, PathBuf};

use super::asset;
use super::category;
use super::contest;
use super::organization;
use super::problem;
use super::submission;
use super::category;
use crate::{cors::CORS, routes::account};
use anyhow::Result;
use rocket::fs::NamedFile;
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
Expand Down Expand Up @@ -43,7 +44,6 @@ pub async fn rocket() -> rocket::Rocket<rocket::Build> {
.mount("/problem", problem::routes())
.mount("/org", organization::routes())
.mount("/category", category::routes())

.mount("/contest", contest::routes())
.mount("/code", submission::routes())
.manage(db)
Expand Down
Loading