diff options
| author | Austin Hellyer <[email protected]> | 2016-11-07 08:47:12 -0800 |
|---|---|---|
| committer | Austin Hellyer <[email protected]> | 2016-11-07 08:47:12 -0800 |
| commit | 4db16290ba02aad362f16b0b41d46abab39c737c (patch) | |
| tree | a86d8b79fff5c294d16ffb25a435e32bec3d9658 /src/model | |
| parent | Remove Context::get_application{s,_info} (diff) | |
| download | serenity-4db16290ba02aad362f16b0b41d46abab39c737c.tar.xz serenity-4db16290ba02aad362f16b0b41d46abab39c737c.zip | |
Add Attachment::download{,to_directory}
Adds two methods to the Attachment model:
- download: uses Hyper to download the attachment and return it as a vec
of bytes;
- download_to_directory: equivilant to `download`, except it will also
save the bytes to a file named equivilant to the filename in a given
directory.
Check the documentation for Attachment for more information and
examples:
<https://docs.austinhellyer.me/serenity.rs/latest/serenity/model/struct.Attachment.html>
Diffstat (limited to 'src/model')
| -rw-r--r-- | src/model/channel.rs | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/model/channel.rs b/src/model/channel.rs index 84bc61f..014442a 100644 --- a/src/model/channel.rs +++ b/src/model/channel.rs @@ -1,7 +1,11 @@ +use hyper::Client as HyperClient; use serde_json::builder::ObjectBuilder; use std::borrow::Cow; use std::fmt::{self, Write}; +use std::fs::File; +use std::io::{Read, Write as IoWrite}; use std::mem; +use std::path::{Path, PathBuf}; use super::utils::{ decode_id, into_map, @@ -27,6 +31,146 @@ impl Attachment { None } } + + /// Downloads the attachment, returning back a vector of bytes. + /// + /// # Examples + /// + /// Download all of the attachments associated with a [`Message`]: + /// + /// ```rust,no_run + /// use serenity::Client; + /// use std::env; + /// use std::fs::File; + /// use std::io::Write; + /// use std::path::Path; + /// + /// let token = env::var("DISCORD_TOKEN").expect("token in environment"); + /// let mut client = Client::login_bot(&token); + /// + /// client.on_message(|context, message| { + /// for attachment in message.attachments { + /// let content = match attachment.download() { + /// Ok(content) => content, + /// Err(why) => { + /// println!("Error downloading attachment: {:?}", why); + /// let _ = context.say("Error downloading attachment"); + /// + /// return; + /// }, + /// }; + /// + /// let mut file = match File::create(&attachment.filename) { + /// Ok(file) => file, + /// Err(why) => { + /// println!("Error creating file: {:?}", why); + /// let _ = context.say("Error creating file"); + /// + /// return; + /// }, + /// }; + /// + /// if let Err(why) = file.write(&content) { + /// println!("Error writing to file: {:?}", why); + /// + /// return; + /// } + /// + /// let _ = context.say(&format!("Saved {:?}", attachment.filename)); + /// } + /// }); + /// + /// client.on_ready(|_context, ready| { + /// println!("{} is connected!", ready.user.name); + /// }); + /// + /// let _ = client.start(); + /// ``` + /// + /// # Errors + /// + /// Returns an [`Error::Io`] when there is a problem reading the contents + /// of the HTTP response. + /// + /// Returns an [`Error::Hyper`] when there is a problem retrieving the + /// attachment. + /// + /// [`Error::Hyper`]: ../enum.Error.html#variant.Hyper + /// [`Error::Io`]: ../enum.Error.html#variant.Io + /// [`Message`]: struct.Message.html + pub fn download(&self) -> Result<Vec<u8>> { + let hyper = HyperClient::new(); + let mut response = try!(hyper.get(&self.url).send()); + + let mut bytes = vec![]; + try!(response.read_to_end(&mut bytes)); + + Ok(bytes) + } + + /// Downloads the attachment, saving it to the provided directory path. + /// Returns a path to the saved file. + /// + /// # Examples + /// + /// Download all of the attachments associated with a [`Message`] to a + /// given folder: + /// + /// ```rust,no_run + /// use serenity::Client; + /// use std::env; + /// use std::fs; + /// + /// // Make sure that the directory to store images in exists. + /// fs::create_dir_all("./attachment_downloads") + /// .expect("err making directory"); + /// + /// let token = env::var("DISCORD_TOKEN").expect("token in environment"); + /// let mut client = Client::login_bot(&token); + /// + /// client.on_message(|context, message| { + /// for attachment in message.attachments { + /// let dir = "./attachment_downloads"; + /// + /// let _ = match attachment.download_to_directory(dir) { + /// Ok(_saved_filepath) => { + /// context.say(&format!("Saved {:?}", attachment.filename)) + /// }, + /// Err(why) => { + /// println!("Error saving attachment: {:?}", why); + /// context.say("Error saving attachment") + /// }, + /// }; + /// } + /// }); + /// + /// client.on_ready(|_context, ready| { + /// println!("{} is connected!", ready.user.name); + /// }); + /// + /// let _ = client.start(); + /// ``` + /// + /// # Errors + /// + /// Returns an [`Error::Io`] when there is a problem reading the contents of + /// the HTTP response, creating the file, or writing to the file. + /// + /// Returns an [`Error::Hyper`] when there is a problem retrieving the + /// attachment. + /// + /// [`Error::Hyper`]: ../enum.Error.html#variant.Hyper + /// [`Error::Io`]: ../enum.Error.html#variant.Io + /// [`Message`]: struct.Message.html + pub fn download_to_directory<P: AsRef<Path>>(&self, path: P) -> Result<PathBuf> { + let bytes = try!(self.download()); + + let filepath: PathBuf = path.as_ref().join(&self.filename); + let mut file = try!(File::create(&filepath)); + try!(file.write(&bytes)); + + Ok(filepath) + } } impl Channel { |