{-# LANGUAGE OverloadedStrings #-} module AdListener ( listenToNewAds ) where import Data.List (intersperse) import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.IO as T import Control.Concurrent (threadDelay) import Fetch (fetchResumes, fetchAds) import Model.Ad import Model.URL import Model.Resume import View.Ad (renderAds) import Page import Parser.Detail import Mail (sendMail) import Config (Config) import qualified Config as C import Time (getCurrentFormattedTime) listenToNewAds :: Config -> IO () listenToNewAds config = do eitherResumes <- fetchResumes (C.url config) case eitherResumes of Left error -> listenError config [] error Right resumes -> let newURLs = map url resumes in do putStrLn "Listening for new ads…" listenToNewAdsWithViewedURLs config newURLs listenToNewAdsWithViewedURLs :: Config -> [URL] -> IO () listenToNewAdsWithViewedURLs config viewedURLs = do eitherResumes <- fetchResumes (C.url config) case eitherResumes of Left error -> listenError config viewedURLs error Right resumes -> listenToNewAdsWithResumes config viewedURLs resumes listenToNewAdsWithResumes :: Config -> [URL] -> [Resume] -> IO () listenToNewAdsWithResumes config viewedURLs resumes = let (newURLs, newResumes) = getNewResumes viewedURLs resumes in do eitherNewAds <- fetchAds newResumes case eitherNewAds of Left error -> listenError config viewedURLs error Right newAds -> do time <- getCurrentFormattedTime if not (null newAds) then let message = newAdsMessage time newAds in do T.putStrLn message trySendMail config message else return () waitOneMinute listenToNewAdsWithViewedURLs config (viewedURLs ++ newURLs) trySendMail :: Config -> Text -> IO () trySendMail config message = case C.mailTo config of Just mailTo -> do eitherMailSuccess <- sendMail mailTo message case eitherMailSuccess of Right () -> putStrLn "Mail sent." Left error -> T.putStrLn . T.concat $ [ "Error sending mail: " , error ] Nothing -> return () newAdsMessage :: Text -> [Ad] -> Text newAdsMessage time newAds = let newAdsMessage = T.concat [ "\nAt " , time , ", got " , T.pack . show . length $ newAds , " new ad" , if length newAds > 1 then "s" else "" ] line = T.map (\_ -> '-') newAdsMessage in T.intercalate "\n" [ newAdsMessage , T.concat [line, "\n"] , renderAds newAds ] listenError :: Config -> [URL] -> Text -> IO () listenError config viewedURLs error = do T.putStrLn error waitOneMinute listenToNewAdsWithViewedURLs config viewedURLs waitOneMinute :: IO () waitOneMinute = threadDelay (1000 * 1000 * 60)