{-# 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 Ad (fetchResumes, fetchAds) import Model.Ad import Model.URL import Model.Resume import View.Ad (renderAds) import Page import Parser.Detail import Config (Config) import qualified Config as C 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 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 if not (null newAds) then T.putStrLn (newAdsMessage newAds) else return () waitOneMinute listenToNewAdsWithViewedURLs config (viewedURLs ++ newURLs) newAdsMessage :: [Ad] -> Text newAdsMessage newAds = let newAdsMessage = T.concat [ "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)