{-# LANGUAGE OverloadedStrings #-} module AdListener ( start ) where import Prelude hiding (error) import Data.Text (Text) import qualified Data.Text.IO as T import qualified Data.Text.Lazy as LT import Data.Text.Lazy.Builder (toLazyText, fromText) import Control.Concurrent (threadDelay) import Fetch (fetchResumes, fetchAds) import Model.Ad import Model.URL import Model.Resume import qualified View.Plain.Ad as P import qualified View.Html.Ad as H import Mail import Model.Mail (Mail(Mail)) import Conf (Conf) import qualified Conf import Time (getCurrentFormattedTime) start :: Conf -> IO () start conf = do eitherResumes <- fetchResumes (Conf.url conf) case eitherResumes of Left error -> showErrorAndListenBack conf [] error Right resumes -> do let newURLs = map url resumes T.putStrLn "Listening to new ads…" waitListenInterval conf listenToNewAdsWithViewedURLs conf newURLs listenToNewAdsWithViewedURLs :: Conf -> [URL] -> IO () listenToNewAdsWithViewedURLs conf viewedURLs = do eitherResumes <- fetchResumes (Conf.url conf) case eitherResumes of Left error -> showErrorAndListenBack conf viewedURLs error Right resumes -> listenToNewAdsWithResumes conf viewedURLs resumes listenToNewAdsWithResumes :: Conf -> [URL] -> [Resume] -> IO () listenToNewAdsWithResumes conf viewedURLs resumes = let (newURLs, newResumes) = getNewResumes viewedURLs resumes in do eitherNewAds <- fetchAds newResumes case eitherNewAds of Left error -> showErrorAndListenBack conf viewedURLs error Right newAds -> do time <- getCurrentFormattedTime if not (null newAds) then let message = P.renderConsoleAds conf time newAds in do T.putStrLn message trySendMail conf newAds else return () waitListenInterval conf listenToNewAdsWithViewedURLs conf (viewedURLs ++ newURLs) trySendMail :: Conf -> [Ad] -> IO () trySendMail conf ads = let (title, plainBody) = P.renderAds conf ads htmlBody = H.renderAds conf ads mail = Mail (Conf.mailFrom conf) (Conf.mailTo conf) title (strictToLazy plainBody) (strictToLazy htmlBody) in Mail.send mail >> return () strictToLazy :: Text -> LT.Text strictToLazy = toLazyText . fromText showErrorAndListenBack :: Conf -> [URL] -> Text -> IO () showErrorAndListenBack conf viewedURLs error = do T.putStrLn error waitListenInterval conf listenToNewAdsWithViewedURLs conf viewedURLs waitListenInterval :: Conf -> IO () waitListenInterval = threadDelay . (*) 1000000 . round . Conf.listenInterval