use mysql_async::Pool;
use hyper::{Response, Body, StatusCode};
use hyper::body::to_bytes;
use serde_json::json;
use std::collections::HashMap;
use crate::http::set_json_body;
use crate::perms;
use crate::qs_param;
use db::messages::Message;
pub async fn get_by_time(pool: &Pool, response: &mut Response
, params: HashMap) {
/*
* Has a ton of required parameters just be warned
* @channel: channel id we're looking at
* @start-time: how long ago do we start searching
* @end-time: how long ago do we stop searching
* {
* "channel_id": 1,
* "start_time": unix_now - 24 hours
* "end_time": unix_now - 23 hours
* }
*
*/
let channel_id = qs_param!(params, "channel_id", u64);
let start_time = qs_param!(params, "start_time", i64);
let end_time = qs_param!(params, "end_time", i64);
let limit = qs_param!(params, "limit", u64);
// TODO: flatten me mommy
if let (Some(channel), Some(start), Some(end)) = (channel_id, start_time, end_time) {
match Message::get_time_range(pool, channel, start, end, limit).await {
Ok(db_response) => {
match db_response {
// this absolute lack of data streaming is prolly gonna suck like
// a whore in hell week for performance but lets pretend servers don't get massive
db::Response::Set(messages) => {
set_json_body(response, json!({"messages": messages}));
},
db::Response::RestrictedInput(_/*error message to log*/) => {
*response.status_mut() = StatusCode::BAD_REQUEST;
}
_ => {
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
}
};
},
Err(e) => {
eprintln!("{}", e);
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
}
};
} else {
*response.status_mut() = StatusCode::BAD_REQUEST;
}
}
pub async fn send_message(pool: &Pool, response: &mut Response, body: Body, params: HashMap) {
/*
* Message content is sent in the message body
* @channel_id: channel id that we're going to send a message to
* TODO: more features here because send_message is a large handler
*/
use db::Response::*;
use db::member::Member;
use crate::db::common::FromDB;
// NOTE: auth module guarantees this will be there in the correct form
let uid = qs_param!(params, "id", u64).unwrap();
let permissions = match Member::get(pool, uid).await {
Row(user) => user.permissions,
_ => 0
};
if perms::has_perm(permissions, perms::SEND_MESSAGES) == false {
*response.status_mut() = StatusCode::BAD_REQUEST;
return;
}
let channel_id = qs_param!(params, "channel_id", u64);
// Black magic
let body_bytes: &[u8] = &to_bytes(body).await.unwrap(); // yolo
let content = String::from_utf8_lossy(body_bytes);
// 400 on empty bodies or missing channel id's
if content.len() == 0 || channel_id.is_none() {
*response.status_mut() = StatusCode::BAD_REQUEST;
} else {
match db::messages::Message::send(pool, &content, channel_id.unwrap(), uid).await {
Ok(Empty) => {}, // nothing to do hyper defaults to 200
Ok(RestrictedInput(_msg)) => *response.status_mut() = StatusCode::BAD_REQUEST,
Ok(Other(msg)) => {
eprintln!("{}", msg);
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
},
_ => *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR
}
}
}
pub async fn from_id(pool: &Pool, response: &mut Response, params: HashMap) {
/*
* @start-id: u64
* @limit: optional
* @channel: u64
* {
* "channel_id": 1,
* "start": 123,
* "limit": 100
* }
*/
let channel = qs_param!(params, "channel_id", u64);
let start_id = qs_param!(params, "start", u64);
let limit = qs_param!(params, "limit", u64);
if let (Some(channel), Some(start_id)) = (channel, start_id) {
match Message::get_from_id(pool, channel, start_id, limit).await {
Ok(db_response) => {
match db_response {
db::Response::Set(messages) => {
// NOTE this check is here because the db's check doesn't
// correctly with async and caching and magic idfk its here
// it works its correct and the cost is the same as putting
// it in the db layer so whatever
if messages.len() == 0 {
*response.status_mut() = StatusCode::NOT_FOUND;
}
else {
set_json_body(response, json!({"messages": messages}));
}
},
_ => *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR
};
},
Err(err) => {
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
eprintln!("{}", err);
}
};
}
else {
*response.status_mut() = StatusCode::BAD_REQUEST;
}
}