This commit is contained in:
parent
be1451ce45
commit
33da605c03
13 changed files with 534 additions and 9 deletions
|
|
@ -11,7 +11,9 @@ use uuid::Uuid;
|
|||
use crate::{
|
||||
AppState,
|
||||
auth::{self, ApiError, AuthUser},
|
||||
chat, db, voice,
|
||||
chat, db,
|
||||
models::{Guild, SoundboardSound},
|
||||
voice,
|
||||
};
|
||||
|
||||
pub fn routes() -> Router<AppState> {
|
||||
|
|
@ -37,6 +39,10 @@ pub fn routes() -> Router<AppState> {
|
|||
)
|
||||
.route("/guilds/{guild_id}/invites", post(create_invite))
|
||||
.route("/invites/{code}/join", post(join_invite))
|
||||
.route(
|
||||
"/guilds/{guild_id}/sounds",
|
||||
get(list_sounds).post(upload_sound),
|
||||
)
|
||||
.route("/channels", post(create_channel))
|
||||
.route(
|
||||
"/channels/{channel_id}/messages",
|
||||
|
|
@ -399,11 +405,8 @@ async fn join_invite(
|
|||
State(state): State<AppState>,
|
||||
user: AuthUser,
|
||||
Path(code): Path<String>,
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let guild = db::join_invite(&state.db, &code.to_uppercase(), user.id)
|
||||
.await
|
||||
.map_err(|e| ApiError::bad_request(&format!("failed to join invite: {e}")))?;
|
||||
|
||||
) -> Result<Json<Guild>, ApiError> {
|
||||
let guild = db::join_invite(&state.db, &code, user.id).await?;
|
||||
Ok(Json(guild))
|
||||
}
|
||||
|
||||
|
|
@ -675,6 +678,87 @@ async fn chat_ws(
|
|||
Ok(ws.on_upgrade(move |socket| chat::handle_socket(state, socket, user.id)))
|
||||
}
|
||||
|
||||
async fn list_sounds(
|
||||
State(state): State<AppState>,
|
||||
user: AuthUser,
|
||||
Path(guild_id): Path<Uuid>,
|
||||
) -> Result<Json<Vec<SoundboardSound>>, ApiError> {
|
||||
ensure_guild_member(&state, guild_id, user.id).await?;
|
||||
let sounds = db::list_sounds(&state.db, guild_id).await?;
|
||||
Ok(Json(sounds))
|
||||
}
|
||||
|
||||
async fn upload_sound(
|
||||
State(state): State<AppState>,
|
||||
user: AuthUser,
|
||||
Path(guild_id): Path<Uuid>,
|
||||
mut multipart: axum::extract::Multipart,
|
||||
) -> Result<Json<SoundboardSound>, ApiError> {
|
||||
ensure_guild_member(&state, guild_id, user.id).await?;
|
||||
|
||||
let mut name = None;
|
||||
let mut icon = None;
|
||||
let mut file_data = None;
|
||||
let mut file_name = None;
|
||||
|
||||
while let Some(field) = multipart
|
||||
.next_field()
|
||||
.await
|
||||
.map_err(|e| ApiError::bad_request(&e.to_string()))?
|
||||
{
|
||||
let field_name = field.name().unwrap_or_default().to_string();
|
||||
if field_name == "name" {
|
||||
name = Some(
|
||||
field
|
||||
.text()
|
||||
.await
|
||||
.map_err(|e| ApiError::bad_request(&e.to_string()))?,
|
||||
);
|
||||
} else if field_name == "icon" {
|
||||
icon = Some(
|
||||
field
|
||||
.text()
|
||||
.await
|
||||
.map_err(|e| ApiError::bad_request(&e.to_string()))?,
|
||||
);
|
||||
} else if field_name == "file" {
|
||||
file_name = Some(field.file_name().unwrap_or("sound.mp3").to_string());
|
||||
file_data = Some(
|
||||
field
|
||||
.bytes()
|
||||
.await
|
||||
.map_err(|e| ApiError::bad_request(&e.to_string()))?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let (name, icon, file_data, file_name) = match (name, icon, file_data, file_name) {
|
||||
(Some(n), Some(i), Some(d), Some(f)) => (n, i, d, f),
|
||||
_ => return Err(ApiError::bad_request("missing fields")),
|
||||
};
|
||||
|
||||
let extension = std::path::Path::new(&file_name)
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.unwrap_or("mp3");
|
||||
|
||||
let safe_file_name = format!("{}.{}", Uuid::new_v4(), extension);
|
||||
let upload_dir = std::path::Path::new("static/uploads/soundboard");
|
||||
tokio::fs::create_dir_all(upload_dir)
|
||||
.await
|
||||
.map_err(|e| ApiError::internal(&e.to_string()))?;
|
||||
|
||||
let file_path = upload_dir.join(&safe_file_name);
|
||||
tokio::fs::write(&file_path, file_data)
|
||||
.await
|
||||
.map_err(|e| ApiError::internal(&e.to_string()))?;
|
||||
|
||||
let web_path = format!("/static/uploads/soundboard/{}", safe_file_name);
|
||||
|
||||
let sound = db::create_sound(&state.db, guild_id, user.id, &name, &icon, &web_path).await?;
|
||||
Ok(Json(sound))
|
||||
}
|
||||
|
||||
async fn ensure_guild_member(
|
||||
state: &AppState,
|
||||
guild_id: Uuid,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue