aboutsummaryrefslogtreecommitdiff
path: root/src/http
diff options
context:
space:
mode:
authorKen Swenson <[email protected]>2017-05-28 15:56:47 -0400
committerZeyla Hellyer <[email protected]>2017-05-28 12:56:47 -0700
commit46b79ddb45d03bfbe0eb10a9d5e1c53c9a15f55b (patch)
treeaddb6c38cb0b5f81122841474deed95897e62d57 /src/http
parentimpl From<char> for ReactionType (diff)
downloadserenity-46b79ddb45d03bfbe0eb10a9d5e1c53c9a15f55b.tar.xz
serenity-46b79ddb45d03bfbe0eb10a9d5e1c53c9a15f55b.zip
Implement multiple attachments
Diffstat (limited to 'src/http')
-rw-r--r--src/http/mod.rs86
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.
///