feat(email): Improve attachment methods

This commit is contained in:
Alexis Mousset
2018-05-31 00:09:57 +02:00
parent 283d45824e
commit c9c82495ce
10 changed files with 37 additions and 70 deletions

View File

@@ -3,7 +3,7 @@ rust:
- stable
- beta
- nightly
- 1.20.0
- 1.26.0
matrix:
allow_failures:
- rust: nightly

View File

@@ -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;

View File

@@ -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")]

View File

@@ -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;

View File

@@ -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)]

View File

@@ -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};

View File

@@ -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)]

View File

@@ -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]

View File

@@ -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();

View File

@@ -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"))