smtp-mail 0.1.3.0 → 0.1.4.0
raw patch · 3 files changed
+50/−28 lines, 3 filesdep +filepathdep ~mime-mailPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: filepath
Dependency ranges changed: mime-mail
API changes (from Hackage documentation)
- Network.Mail.SMTP.Auth: login :: UserName -> Password -> (ByteString, ByteString)
+ Network.Mail.SMTP: filePart :: Text -> FilePath -> IO Part
+ Network.Mail.SMTP: htmlPart :: Text -> Part
+ Network.Mail.SMTP: login :: SMTPConnection -> UserName -> Password -> IO (ReplyCode, ByteString)
+ Network.Mail.SMTP: plainTextPart :: Text -> Part
+ Network.Mail.SMTP.Auth: encodeLogin :: UserName -> Password -> (ByteString, ByteString)
- Network.Mail.SMTP: simpleMail :: Address -> [Address] -> [Address] -> [Address] -> Text -> Text -> Maybe Text -> Mail
+ Network.Mail.SMTP: simpleMail :: Address -> [Address] -> [Address] -> [Address] -> Text -> [Part] -> Mail
Files
- Network/Mail/SMTP.hs +41/−20
- Network/Mail/SMTP/Auth.hs +7/−7
- smtp-mail.cabal +2/−1
Network/Mail/SMTP.hs view
@@ -4,6 +4,9 @@ sendMail , sendMailWithLogin , simpleMail+ , plainTextPart+ , htmlPart+ , filePart -- * Types , Command(..) , Response(..)@@ -25,12 +28,14 @@ , connectSMTP -- * Operation to a Connection , sendCommand+ , login , closeSMTP , renderAndSend ) where import System.IO+import System.FilePath (takeFileName) import Control.Monad (unless) import Data.Monoid@@ -111,15 +116,17 @@ -- | Repeatedly attempt to send a 'Command' to the SMTP server tryCommand :: Int -> SMTPConnection -> Command -> ReplyCode -> IO ByteString-tryCommand tries st cmd expectedReply | tries <= 0 = do- closeSMTP st- fail $ "cannot execute command " ++ show cmd ++- ", expected reply code " ++ show expectedReply tryCommand tries st cmd expectedReply = do- (code, msg) <- sendCommand st cmd- if code == expectedReply then- return msg else- tryCommand (tries - 1) st cmd expectedReply+ (code, msg) <- sendCommand st cmd+ if code == expectedReply + then return msg+ else if tries > 1+ then tryCommand (tries - 1) st cmd expectedReply+ else do+ closeSMTP st+ fail $ "Unexpected reply to: " ++ show cmd ++ + ", Expected reply code: " ++ show expectedReply +++ ", Got this instead: " ++ show code ++ " " ++ show msg -- | Create an 'SMTPConnection' from an already connected Handle connectStream :: Handle -> IO SMTPConnection@@ -164,7 +171,7 @@ unless (code == 235) $ fail "authentication failed." return (code, msg) where command = "AUTH LOGIN"- (userB64, passB64) = login username password+ (userB64, passB64) = encodeLogin username password sendCommand (SMTPC conn _) (AUTH at username password) = do bsPutCrLf conn command (code, msg) <- parseResponse conn@@ -234,6 +241,10 @@ renderAndSend con mail closeSMTP con +-- | A convenience function that sends 'AUTH' 'LOGIN' to the server+login :: SMTPConnection -> UserName -> Password -> IO (ReplyCode, ByteString)+login con user pass = sendCommand con (AUTH LOGIN user pass)+ -- | A simple interface for generating a 'Mail' with a plantext body and -- an optional HTML body. simpleMail :: Address -- ^ from@@ -241,24 +252,34 @@ -> [Address] -- ^ CC -> [Address] -- ^ BCC -> T.Text -- ^ subject- -> TL.Text -- ^ plain body- -> Maybe TL.Text -- ^ optional HTML body+ -> [Part] -- ^ list of parts (list your preferred part last) -> Mail-simpleMail from to cc bcc subject plainBody htmlBody =+simpleMail from to cc bcc subject parts = Mail { mailFrom = from , mailTo = to , mailCc = cc , mailBcc = bcc , mailHeaders = [ ("Subject", subject) ]- , mailParts = [ parts plainBody htmlBody ]+ , mailParts = [parts] }- where - plainPart plain' = Part "text/plain; charset=utf-8" - QuotedPrintableText Nothing [] $ TL.encodeUtf8 plain'- htmlPart html' = Part "text/html; charset=utf-8" - QuotedPrintableText Nothing [] $ TL.encodeUtf8 html'- parts plain' Nothing = [ plainPart plain' ]- parts plain' (Just html') = [ plainPart plain', htmlPart html' ]++-- | Construct a plain text 'Part'+plainTextPart :: TL.Text -> Part+plainTextPart = Part "text/plain; charset=utf-8" + QuotedPrintableText Nothing [] . TL.encodeUtf8++-- | Construct an html 'Part'+htmlPart :: TL.Text -> Part+htmlPart = Part "text/html; charset=utf-8" + QuotedPrintableText Nothing [] . TL.encodeUtf8++-- | Construct a file attachment 'Part'+filePart :: T.Text -- ^ content type+ -> FilePath -- ^ path to file + -> IO Part+filePart ct fp = do+ content <- B.readFile fp+ return $ Part ct Base64 (Just $ T.pack (takeFileName fp)) [] content lazyToStrict :: B.ByteString -> S.ByteString lazyToStrict = S.concat . B.toChunks
Network/Mail/SMTP/Auth.hs view
@@ -2,7 +2,7 @@ UserName, Password, AuthType(..),- login,+ encodeLogin, auth, ) where @@ -48,11 +48,11 @@ ikey = B.pack $ B.zipWith xor key' ipad okey = B.pack $ B.zipWith xor key' opad -plain :: UserName -> Password -> ByteString-plain user pass = b64Encode $ intercalate "\0" [user, user, pass]+encodePlain :: UserName -> Password -> ByteString+encodePlain user pass = b64Encode $ intercalate "\0" [user, user, pass] -login :: UserName -> Password -> (ByteString, ByteString)-login user pass = (b64Encode user, b64Encode pass)+encodeLogin :: UserName -> Password -> (ByteString, ByteString)+encodeLogin user pass = (b64Encode user, b64Encode pass) cramMD5 :: String -> UserName -> Password -> ByteString cramMD5 challenge user pass =@@ -63,6 +63,6 @@ pass' = toAscii pass auth :: AuthType -> String -> UserName -> Password -> ByteString-auth PLAIN _ u p = plain u p-auth LOGIN _ u p = let (u', p') = login u p in B8.unwords [u', p']+auth PLAIN _ u p = encodePlain u p+auth LOGIN _ u p = let (u', p') = encodeLogin u p in B8.unwords [u', p'] auth CRAM_MD5 c u p = cramMD5 c u p
smtp-mail.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: smtp-mail-version: 0.1.3.0+version: 0.1.4.0 synopsis: Simple email sending via SMTP -- description: homepage: http://github.com/jhickner/smtp-mail@@ -25,6 +25,7 @@ build-depends: base >= 4.5 && < 5, network,+ filepath, mime-mail, bytestring, text,