diff options
Diffstat (limited to 'backend/src/routes')
-rw-r--r-- | backend/src/routes/bots.rs | 96 | ||||
-rw-r--r-- | backend/src/routes/mod.rs | 1 | ||||
-rw-r--r-- | backend/src/routes/users.rs | 2 |
3 files changed, 98 insertions, 1 deletions
diff --git a/backend/src/routes/bots.rs b/backend/src/routes/bots.rs new file mode 100644 index 0000000..413c145 --- /dev/null +++ b/backend/src/routes/bots.rs @@ -0,0 +1,96 @@ +use rand::Rng; +use rocket::data::ToByteUnit; +use rocket::fs::TempFile; +use rocket::Data; +use rocket::{response::status, serde::json::Json}; +use serde::{Deserialize, Serialize}; +use std::io::Cursor; +use std::path::Path; + +use crate::DbConn; + +use crate::db::bots::{self, CodeBundle}; +use crate::db::users::User; +use bots::Bot; + +#[derive(Serialize, Deserialize, Debug)] +pub struct BotParams { + name: String, +} + +// TODO: handle errors +#[post("/bots", data = "<params>")] +pub async fn create_bot( + db_conn: DbConn, + user: User, + params: Json<BotParams>, +) -> status::Created<Json<Bot>> { + db_conn + .run(move |conn| { + let bot_params = bots::NewBot { + owner_id: user.id, + name: ¶ms.name, + }; + let bot = bots::create_bot(&bot_params, conn).unwrap(); + let bot_url = uri!(get_bot(bot.id)).to_string(); + status::Created::new(bot_url).body(Json(bot)) + }) + .await +} + +// TODO: handle errors +#[get("/bots/<bot_id>")] +pub async fn get_bot(db_conn: DbConn, bot_id: i32) -> Json<Bot> { + db_conn + .run(move |conn| { + let bot = bots::find_bot(bot_id, conn).unwrap(); + Json(bot) + }) + .await +} + +// TODO: proper error handling +#[post("/bots/<bot_id>/upload", data = "<data>")] +pub async fn upload_bot_code( + db_conn: DbConn, + user: User, + bot_id: i32, + data: Data<'_>, +) -> status::Created<Json<CodeBundle>> { + // TODO: put in config somewhere + let data_path = "./data/bots"; + + let bot = db_conn + .run(move |conn| bots::find_bot(bot_id, conn)) + .await + .expect("Bot not found"); + + assert_eq!(user.id, bot.owner_id); + + // generate a random filename + let token: [u8; 16] = rand::thread_rng().gen(); + let name = base64::encode(&token); + + let path = Path::new(data_path).join(name); + let capped_buf = data.open(10usize.megabytes()).into_bytes().await.unwrap(); + assert!(capped_buf.is_complete()); + let buf = capped_buf.into_inner(); + + zip::ZipArchive::new(Cursor::new(buf)) + .unwrap() + .extract(&path) + .unwrap(); + + let code_bundle = db_conn + .run(move |conn| { + let bundle = bots::NewCodeBundle { + bot_id: bot.id, + path: path.to_str().unwrap(), + }; + bots::create_code_bundle(&bundle, conn).expect("Failed to create code bundle") + }) + .await; + + // TODO: proper location + status::Created::new("").body(Json(code_bundle)) +} diff --git a/backend/src/routes/mod.rs b/backend/src/routes/mod.rs index 913bd46..718d7ef 100644 --- a/backend/src/routes/mod.rs +++ b/backend/src/routes/mod.rs @@ -1 +1,2 @@ +pub mod bots; pub mod users; diff --git a/backend/src/routes/users.rs b/backend/src/routes/users.rs index 72a857f..45a94b9 100644 --- a/backend/src/routes/users.rs +++ b/backend/src/routes/users.rs @@ -55,7 +55,7 @@ pub struct UserData { impl From<User> for UserData { fn from(user: User) -> Self { UserData { - user_id: user.user_id, + user_id: user.id, username: user.username, } } |