feat(email): Improve attachment methods
This commit is contained in:
@@ -3,7 +3,7 @@ rust:
|
||||
- stable
|
||||
- beta
|
||||
- nightly
|
||||
- 1.20.0
|
||||
- 1.26.0
|
||||
matrix:
|
||||
allow_failures:
|
||||
- rust: nightly
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
//! It can be useful for testing purposes, or if you want to keep track of sent messages.
|
||||
//!
|
||||
|
||||
use Envelope;
|
||||
use SendableEmail;
|
||||
use Transport;
|
||||
use file::error::FileResult;
|
||||
use serde_json;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::path::{Path, PathBuf};
|
||||
use Envelope;
|
||||
use SendableEmail;
|
||||
use Transport;
|
||||
|
||||
pub mod error;
|
||||
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
//!
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/lettre/0.9.0")]
|
||||
#![deny(missing_copy_implementations, trivial_casts, trivial_numeric_casts, unsafe_code,
|
||||
unstable_features, unused_import_braces, unused_qualifications)]
|
||||
#![deny(
|
||||
missing_copy_implementations, trivial_casts, trivial_numeric_casts, unsafe_code,
|
||||
unstable_features, unused_import_braces, unused_qualifications
|
||||
)]
|
||||
#[cfg(feature = "smtp-transport")]
|
||||
extern crate base64;
|
||||
#[cfg(feature = "smtp-transport")]
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
//! The sendmail transport sends the email using the local sendmail command.
|
||||
//!
|
||||
|
||||
use sendmail::error::SendmailResult;
|
||||
use std::io::prelude::*;
|
||||
use std::io::Read;
|
||||
use std::process::{Command, Stdio};
|
||||
use SendableEmail;
|
||||
use Transport;
|
||||
use sendmail::error::SendmailResult;
|
||||
use std::io::Read;
|
||||
use std::io::prelude::*;
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
pub mod error;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
//! SMTP commands
|
||||
|
||||
use EmailAddress;
|
||||
use base64;
|
||||
use smtp::authentication::{Credentials, Mechanism};
|
||||
use smtp::error::Error;
|
||||
@@ -8,6 +7,7 @@ use smtp::extension::ClientId;
|
||||
use smtp::extension::{MailParameter, RcptParameter};
|
||||
use smtp::response::Response;
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use EmailAddress;
|
||||
|
||||
/// EHLO command
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
use native_tls::TlsConnector;
|
||||
use smtp::authentication::{Credentials, Mechanism, DEFAULT_ENCRYPTED_MECHANISMS,
|
||||
DEFAULT_UNENCRYPTED_MECHANISMS};
|
||||
use smtp::client::InnerClient;
|
||||
use smtp::client::net::ClientTlsParameters;
|
||||
use smtp::client::net::DEFAULT_TLS_PROTOCOLS;
|
||||
use smtp::client::InnerClient;
|
||||
use smtp::commands::*;
|
||||
use smtp::error::{Error, SmtpResult};
|
||||
use smtp::extension::{ClientId, Extension, MailBodyParameter, MailParameter, ServerInfo};
|
||||
|
||||
@@ -5,7 +5,7 @@ use nom::simple_errors::Err as NomError;
|
||||
use nom::{crlf, ErrorKind as NomErrorKind, IResult as NomResult};
|
||||
use std::fmt::{Display, Formatter, Result};
|
||||
use std::result;
|
||||
use std::str::{FromStr, from_utf8};
|
||||
use std::str::{from_utf8, FromStr};
|
||||
|
||||
/// First digit indicates severity
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||
|
||||
@@ -7,8 +7,8 @@ mod test {
|
||||
use lettre::file::FileTransport;
|
||||
use lettre::{EmailAddress, Envelope, SendableEmail, Transport};
|
||||
use std::env::temp_dir;
|
||||
use std::fs::File;
|
||||
use std::fs::remove_file;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -14,7 +14,7 @@ fn main() {
|
||||
.from("user@example.com")
|
||||
.subject("Hi, Hello world")
|
||||
.text("Hello world.")
|
||||
.attachment(Path::new("Cargo.toml"), None, &mime::TEXT_PLAIN).unwrap()
|
||||
.attachment_from_file(Path::new("Cargo.toml"), None, &mime::TEXT_PLAIN).unwrap()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
//!
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/lettre_email/0.9.0")]
|
||||
#![deny(missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts,
|
||||
trivial_numeric_casts, unsafe_code, unstable_features, unused_import_braces,
|
||||
unused_qualifications)]
|
||||
#![deny(
|
||||
missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts,
|
||||
trivial_numeric_casts, unsafe_code, unstable_features, unused_import_braces,
|
||||
unused_qualifications
|
||||
)]
|
||||
|
||||
extern crate base64;
|
||||
extern crate email as email_format;
|
||||
@@ -19,8 +21,7 @@ pub use email_format::{Address, Header, Mailbox, MimeMessage, MimeMultipartType}
|
||||
use error::Error;
|
||||
use lettre::{EmailAddress, Envelope, Error as EmailError, SendableEmail};
|
||||
use mime::Mime;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use time::{now, Tm};
|
||||
@@ -218,72 +219,36 @@ impl EmailBuilder {
|
||||
}
|
||||
|
||||
/// Adds an attachment to the email from a file
|
||||
pub fn attachment(
|
||||
///
|
||||
/// If not specified, the filename will be extracted from the file path.
|
||||
pub fn attachment_from_file(
|
||||
self,
|
||||
path: &Path,
|
||||
filename: Option<&str>,
|
||||
content_type: &Mime,
|
||||
) -> Result<EmailBuilder, Error> {
|
||||
let file = File::open(path);
|
||||
let body = match file {
|
||||
Ok(mut f) => {
|
||||
let mut data = Vec::new();
|
||||
let read = f.read_to_end(&mut data);
|
||||
match read {
|
||||
Ok(_) => data,
|
||||
Err(e) => {
|
||||
return Err(From::from(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(From::from(e));
|
||||
}
|
||||
};
|
||||
|
||||
let actual_filename = match filename {
|
||||
Some(name) => name,
|
||||
None => match path.file_name() {
|
||||
Some(name) => match name.to_str() {
|
||||
Some(name) => name,
|
||||
None => return Err(Error::CannotParseFilename),
|
||||
},
|
||||
None => return Err(Error::CannotParseFilename),
|
||||
},
|
||||
};
|
||||
|
||||
let encoded_body = base64::encode(&body);
|
||||
let content = PartBuilder::new()
|
||||
.body(encoded_body)
|
||||
.header((
|
||||
"Content-Disposition",
|
||||
format!("attachment; filename=\"{}\"", actual_filename),
|
||||
))
|
||||
.header(("Content-Type", content_type.to_string()))
|
||||
.header(("Content-Transfer-Encoding", "base64"))
|
||||
.build();
|
||||
|
||||
Ok(self.message_type(MimeMultipartType::Mixed).child(content))
|
||||
self.attachment(
|
||||
fs::read(path)?.as_slice(),
|
||||
filename.unwrap_or(path.file_name()
|
||||
.and_then(|x| x.to_str())
|
||||
.ok_or(Error::CannotParseFilename)?),
|
||||
content_type,
|
||||
)
|
||||
}
|
||||
|
||||
/// Adds an attachment to the email from a vector of bytes.
|
||||
/// This is usefull when your attachment is actually not a file, but a sequence of bytes.
|
||||
pub fn attach_from_vec(
|
||||
pub fn attachment(
|
||||
self,
|
||||
bytes_vec: &Vec<u8>,
|
||||
body: &[u8],
|
||||
filename: &str,
|
||||
content_type: &Mime,
|
||||
) -> Result<EmailBuilder, Error> {
|
||||
let body = bytes_vec;
|
||||
|
||||
let actual_filename = filename;
|
||||
|
||||
) -> Result<EmailBuilder, Error> {
|
||||
let encoded_body = base64::encode(&body);
|
||||
let content = PartBuilder::new()
|
||||
.body(encoded_body)
|
||||
.header((
|
||||
"Content-Disposition",
|
||||
format!("attachment; filename=\"{}\"", actual_filename),
|
||||
format!("attachment; filename=\"{}\"", filename),
|
||||
))
|
||||
.header(("Content-Type", content_type.to_string()))
|
||||
.header(("Content-Transfer-Encoding", "base64"))
|
||||
|
||||
Reference in New Issue
Block a user