summaryrefslogtreecommitdiff
path: root/src/Simple.hs
blob: 80856d382411235a907e1b361103c4540c23342e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
{-# LANGUAGE RecordWildCards, ApplicativeDo, FlexibleContexts, ViewPatterns, OverloadedStrings #-}

module Main (main) where

import Postdelay.Scan
import Postdelay.Queue

import Data.Function (on)
import Data.List
import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI

import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Catch (MonadCatch)
import Control.Monad.Reader

import Data.ByteString.Lazy as Lazy (ByteString)
import qualified Data.ByteString.Lazy as Lazy.BS

import Data.ByteString.Lazy.Char8 as Lazy.Char8 (ByteString)
import qualified Data.ByteString.Lazy.Char8 as Lazy.Char8.BS

import Data.Conduit

import System.Environment (getProgName)

import qualified Options.Applicative as Opt (Parser)
import Options.Applicative hiding (Parser)


opts :: Opt.Parser (String, [String], StoreConfig)
opts = do
  sConfig <- storeConfig
  sender <- strOption $ mconcat
    [ long "sender"
    , short 'f'
    , metavar "SENDER"
    ]
  recipients <- some . strArgument $ mconcat
    [ metavar "RECIPIENTS"
    ]
  pure (sender, recipients, sConfig)

main :: (MonadIO m, MonadCatch m) => m ()
main = do
  pName <- liftIO getProgName
  (sender, recipients, sConfig) <- liftIO . execParser . info (helper <*> opts) $ mconcat
    [ fullDesc
    , progDesc "Queue an email for later delivery"
    , header pName
    ]
  
  flip runReaderT sConfig $ do
    mailStr <- liftIO Lazy.BS.getContents
    delay <- scan $ Lazy.Char8.BS.unpack mailStr
    let
      (headers, body) = break (== "") $ Lazy.Char8.BS.lines mailStr
      headers' = filter (not . (Lazy.Char8.BS.isPrefixOf `on` CI.foldCase) "X-Delay:") headers 
      mailStr' = Lazy.Char8.BS.unlines $ headers' ++ body

      sendNow = sendmail sender recipients mailStr'
      sendLater sendDelay = pushStore . yield $ StoredMail
        { message = mailStr'
        , ..
        }
    maybe sendNow sendLater delay