diff options
| author | Ken Swenson <[email protected]> | 2017-05-28 15:56:47 -0400 |
|---|---|---|
| committer | Zeyla Hellyer <[email protected]> | 2017-05-28 12:56:47 -0700 |
| commit | 46b79ddb45d03bfbe0eb10a9d5e1c53c9a15f55b (patch) | |
| tree | addb6c38cb0b5f81122841474deed95897e62d57 /src/http | |
| parent | impl From<char> for ReactionType (diff) | |
| download | serenity-46b79ddb45d03bfbe0eb10a9d5e1c53c9a15f55b.tar.xz serenity-46b79ddb45d03bfbe0eb10a9d5e1c53c9a15f55b.zip | |
Implement multiple attachments
Diffstat (limited to 'src/http')
| -rw-r--r-- | src/http/mod.rs | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/http/mod.rs b/src/http/mod.rs index eb4235d..95d07ab 100644 --- a/src/http/mod.rs +++ b/src/http/mod.rs @@ -45,7 +45,9 @@ use serde_json; use std::collections::BTreeMap; use std::default::Default; use std::fmt::Write as FmtWrite; +use std::fs::File; use std::io::{ErrorKind as IoErrorKind, Read}; +use std::path::PathBuf; use std::sync::{Arc, Mutex}; use ::constants; use ::internal::prelude::*; @@ -1378,6 +1380,7 @@ pub fn remove_group_recipient(group_id: u64, user_id: u64) -> Result<()> { /// if the file is too large to send. /// /// [`HttpError::InvalidRequest`]: enum.HttpError.html#variant.InvalidRequest +#[deprecated(since="0.2.0", note="Please use `send_files` instead.")] pub fn send_file<R: Read>(channel_id: u64, mut file: R, filename: &str, map: JsonMap) -> Result<Message> { let uri = format!(api!("/channels/{}/messages"), channel_id); @@ -1415,6 +1418,63 @@ pub fn send_file<R: Read>(channel_id: u64, mut file: R, filename: &str, map: Jso serde_json::from_reader::<HyperResponse, Message>(response).map_err(From::from) } +/// Sends file(s) to a channel. +/// +/// # Errors +/// +/// Returns an +/// [`HttpError::InvalidRequest(PayloadTooLarge)`][`HttpError::InvalidRequest`] +/// if the file is too large to send. +/// +/// [`HttpError::InvalidRequest`]: enum.HttpError.html#variant.InvalidRequest +pub fn send_files<T: Into<AttachmentType>>(channel_id: u64, files: Vec<T>, map: JsonMap) + -> Result<Message> { + let uri = format!(api!("/channels/{}/messages"), channel_id); + let url = match Url::parse(&uri) { + Ok(url) => url, + Err(_) => return Err(Error::Url(uri)), + }; + + let mut request = Request::new(Method::Post, url)?; + request.headers_mut() + .set(header::Authorization(TOKEN.lock().unwrap().clone())); + request.headers_mut() + .set(header::UserAgent(constants::USER_AGENT.to_owned())); + + let mut request = Multipart::from_request(request)?; + let mut file_num = String::from("0".to_owned()); + + for file in files { + match file.into() { + AttachmentType::File((mut f, filename)) => { + request.write_stream(&file_num, &mut f, Some(&filename), None)?; + }, + AttachmentType::Path(p) => { + request.write_file(&file_num, &p)?; + }, + } + + unsafe { + let vec = file_num.as_mut_vec(); + vec[0] += 1; + } + } + + for (k, v) in map { + match v { + Value::Bool(false) => request.write_text(&k, "false")?, + Value::Bool(true) => request.write_text(&k, "true")?, + Value::Number(inner) => request.write_text(&k, inner.to_string())?, + Value::String(inner) => request.write_text(&k, inner)?, + _ => continue, + }; + } + + let response = request.send()?; + + serde_json::from_reader::<HyperResponse, Message>(response).map_err(From::from) +} + /// Sends a message to a channel. pub fn send_message(channel_id: u64, map: &Value) -> Result<Message> { let body = map.to_string(); @@ -1544,6 +1604,32 @@ fn verify(expected_status_code: u16, mut response: HyperResponse) -> Result<()> Err(Error::Http(HttpError::InvalidRequest(response.status))) } +/// Enum that allows a user to pass a `Path` or a `File` type to `send_files` +pub enum AttachmentType { + /// Indicates that the `AttachmentType` is a `File` + File((File, String)), + /// Indicates that the `AttachmentType` is a `Path` + Path(PathBuf), +} + +impl From<String> for AttachmentType { + fn from(s: String) -> AttachmentType { + AttachmentType::Path(PathBuf::from(&s)) + } +} + +impl<'a> From<&'a str> for AttachmentType { + fn from(s: &'a str) -> AttachmentType { + AttachmentType::Path(PathBuf::from(s)) + } +} + +impl<'a> From<(File, &'a str)> for AttachmentType { + fn from(f: (File, &str)) -> AttachmentType { + AttachmentType::File((f.0, f.1.to_owned())) + } +} + /// Representation of the method of a query to send for the [`get_guilds`] /// function. /// |