hailgun-send (empty) → 0.1.0.0
raw patch · 4 files changed
+233/−0 lines, 4 filesdep +basedep +bytestringdep +configuratorsetup-changed
Dependencies added: base, bytestring, configurator, hailgun, text
Files
- LICENSE +20/−0
- Main.hs +138/−0
- Setup.hs +2/−0
- hailgun-send.cabal +73/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2014 Robert Massaioli++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Main.hs view
@@ -0,0 +1,138 @@+module Main where++import Mail.Hailgun++import Control.Applicative ((<$>))+import qualified Data.ByteString.Char8 as BC+import Data.Configurator (load, require, Worth(..))+import qualified Data.List as DL+import qualified Data.Text as T+import System.Console.GetOpt (getOpt, OptDescr(..), ArgDescr(..), ArgOrder(..), usageInfo)+import System.Environment (getArgs)+import System.Exit (exitFailure)++-- The purpose of this module is to provide a way to send emails to the Mailgun service using the+-- command line. This is mainly for the purposes of testing initially. Using this executable should+-- be the basis for our integration tests. It should also be the starting point for everybody that+-- wishes to test this library out.++data Flag + = Help+ | From { email :: UnverifiedEmailAddress }+ | To { email :: UnverifiedEmailAddress }+ | Subject { subject :: MessageSubject }+ | TextMessage { textFilePath :: FilePath }+ | HTMLMessage { htmlFilePath :: FilePath }+ deriving (Eq, Show)+ +options :: [OptDescr Flag]+options =+ [ Option "h" ["help"] (NoArg Help) "displays this help message"+ , Option "f" ["from"] (ReqArg fromP "me@test.test") "You are required to provide sender of this email."+ , Option "t" ["to"] (ReqArg toP "them@test.test") "You will need to provide atleast one person that you wish to send the email to."+ -- TODO Confirm that this is required.+ , Option "s" ["subject"] (ReqArg Subject "subject") "You need to send an email subject."+ , Option "x" ["text"] (ReqArg TextMessage "email.text") "You need to provide a text email file at a minimum."+ , Option "m" ["html"] (ReqArg HTMLMessage "email.html") "You can provide a HTML version of the email to send."+ ]+ where+ fromP = From . BC.pack+ toP = To . BC.pack++hailgunConfFile :: FilePath+hailgunConfFile = "hailgun.send.conf"++mailgunDomainLabel = T.pack "mailgun-domain"+mailgunApiKeyLabel = T.pack "mailgun-api-key"++loadHailgunContext :: FilePath -> IO HailgunContext+loadHailgunContext configFile = do+ hailgunConf <- load [Required configFile]+ domain <- require hailgunConf mailgunDomainLabel+ apiKey <- require hailgunConf mailgunApiKeyLabel+ return HailgunContext + { hailgunDomain = domain+ , hailgunApiKey = apiKey+ }++handleSend :: [Flag] -> MessageContent -> Either HailgunErrorMessage HailgunMessage+handleSend flags emailBody =+ case (unverifiedFrom, subjects) of+ ([from], [subject]) -> hailgunMessage subject emailBody from simpleRecipients+ ([], []) -> fail "You need to provide both a from address and a subject to send an email."+ (_ , []) -> fail "You have more than one from address and only one is allowed"+ ([], _ ) -> fail "You have more than one subject and only one is allowed"+ _ -> fail "You have too many from adresses and subjects, you should only have one of each."+ where+ unverifiedTo = fmap email . filter isTo $ flags+ unverifiedFrom = fmap email . filter isFrom $ flags+ subjects = fmap subject . filter isSubject $ flags++ simpleRecipients = emptyMessageRecipients { recipientsTo = unverifiedTo }++isSubject :: Flag -> Bool+isSubject (Subject _) = True+isSubject _ = False++isTo :: Flag -> Bool+isTo (To _) = True+isTo _ = False++isFrom :: Flag -> Bool+isFrom (From _) = True+isFrom _ = False++isTextMessage :: Flag -> Bool+isTextMessage (TextMessage _) = True+isTextMessage _ = False++isHtmlMessage :: Flag -> Bool+isHtmlMessage (HTMLMessage _) = True+isHtmlMessage _ = False++sendMessage :: HailgunMessage -> IO ()+sendMessage message = do+ hailgunContext <- loadHailgunContext hailgunConfFile+ response <- sendEmail hailgunContext message+ case response of+ Left error -> putStrLn $ "Failed to send email: " ++ herMessage error+ Right result -> do+ putStrLn "Sent Email!"+ putStrLn $ "Id: " ++ hsrId result+ putStrLn $ "Message: " ++ hsrMessage result++usageMessage = "Send emails using the Mailgun api."++main :: IO ()+main = do+ arguments <- getArgs+ case getOpt Permute options arguments of+ (flags, _, []) -> if Help `elem` flags+ then printUsage+ else do+ potentialEmailBody <- prepareEmailBody flags+ case potentialEmailBody of+ Nothing -> putStrLn "At the very least you must provide a text file to send as the email body."+ (Just messageContent) -> case handleSend flags messageContent of+ Left error -> putStrLn $ "Error generating mail: " ++ error + Right message -> sendMessage message+ (_, _, xs) -> do+ putStrLn "Error parsing arguments:"+ mapM_ putStrLn xs+ printUsage+ exitFailure+ where+ printUsage = putStrLn $ usageInfo usageMessage options++prepareEmailBody :: [Flag] -> IO (Maybe MessageContent)+prepareEmailBody flags = case (DL.find isTextMessage flags, DL.find isHtmlMessage flags) of+ (Nothing, _) -> return Nothing+ (Just (TextMessage textPath), Nothing) -> Just . TextOnly <$> BC.readFile textPath+ (Just (TextMessage textPath), Just (HTMLMessage htmlPath)) -> do+ textContents <- BC.readFile textPath+ htmlContents <- BC.readFile htmlPath+ return . Just $ TextAndHTML + { textContent = textContents+ , htmlContent = htmlContents+ }+ _ -> return Nothing -- The type safety should prevent this scenario.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ hailgun-send.cabal view
@@ -0,0 +1,73 @@+-- Initial hailgun-send.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++-- The name of the package.+name: hailgun-send++-- The package version. See the Haskell package versioning policy (PVP) +-- for standards guiding when and how versions should be incremented.+-- http://www.haskell.org/haskellwiki/Package_versioning_policy+-- PVP summary: +-+------- breaking API changes+-- | | +----- non-breaking API additions+-- | | | +--- code changes with no API change+version: 0.1.0.0++-- A short (one-line) description of the package.+synopsis: A program to send emails throught the Mailgun api.++-- A longer description of the package.+description: Use this executable to send emails using the Mailgun api's from the command line. You require a configuraiton file + with your Mailgun API details to make it work. Please run hailgun-send \-\-help for more information.++-- The license under which the package is released.+license: MIT++-- The file containing the license text.+license-file: LICENSE++-- The package author(s).+author: Robert Massaioli++-- An email address to which users can send suggestions, bug reports, and +-- patches.+maintainer: robertmassaioli@gmail.com++-- A copyright notice.+-- copyright: ++category: Network++build-type: Simple++-- Extra files to be distributed with the package, such as examples or a +-- README.+-- extra-source-files: ++-- Constraint on the version of Cabal needed to build this package.+cabal-version: >=1.10+++executable hailgun-send+ -- .hs or .lhs file containing the Main module.+ main-is: Main.hs+ + -- Modules included in this executable, other than Main.+ -- other-modules: + + -- LANGUAGE extensions used by modules in this package.+ -- other-extensions: + + -- Other library packages from which modules are imported.+ build-depends: base >=4.6 && <4.7+ , hailgun > 0.1.0.0 && < 0.2+ , bytestring >= 0.9 && <= 0.11+ , text == 0.11.*+ , configurator == 0.3.*+ + -- Directories containing source files.+ -- hs-source-dirs: + + -- Base language which the package is written in.+ default-language: Haskell2010+ ghc-options: -W+