{-# LANGUAGE DeriveGeneric #-} module F2Md.Config ( getUserdata , FeedUserdata(..) , updateLastUpdated , updateLastUpdated' ) where import Control.Monad import Data.List import F2Md.Utils import F2Md.Types import Data.Maybe import Data.Text (Text) import Data.Time import GHC.Generics import qualified Data.HashMap.Strict as HM import Data.Aeson data Config = Config { dbPath :: String , maildir :: String , feeds :: [Text] } deriving (Generic, Show) instance FromJSON Config data FeedUserdata = FeedUserdata { fuUrl :: Text , fuLastUpdated :: Maybe ZonedTime } deriving (Show) getUserdata :: FilePath -> IO ([FeedUserdata], Maybe FilePath, Maybe FilePath) getUserdata file = do config <- decodeFileStrict file case config of Nothing -> return ([], Nothing, Nothing) Just config' -> do feedData <- getUserdata' config' maildir' <- expandPath $ maildir config' dbPath' <- expandPath $ dbPath config' return (feedData, Just maildir', Just dbPath') getUserdata' :: Config -> IO [FeedUserdata] getUserdata' (Config dbPath _ feeds) = do decoded <- getLastUpdatedMap dbPath return $ map (\url -> FeedUserdata url $ HM.lookup url decoded) feeds getLastUpdatedMap :: FilePath -> IO (HM.HashMap Text ZonedTime) getLastUpdatedMap dbPath = fromMaybe (HM.fromList []) <$> (decodeFileStrict =<< expandPath dbPath) updateLastUpdated' :: FilePath -> FeedUserdata -> [Message] -> IO () updateLastUpdated' path feed msgs = unless (null msgs) $ do decoded <- getLastUpdatedMap path encodeFile path $ HM.insert (fuUrl feed) (utcToZonedTime (zonedTimeZone $ mDate $ head msgs) . maximum $ (zonedTimeToUTC . mDate) <$> msgs) decoded updateLastUpdated :: FilePath -> [FeedUserdata] -> [[Message]] -> IO () updateLastUpdated path feeds feedMsgs = do mapM_ (\(feed, msgs) -> updateLastUpdated' path feed msgs) (zip feeds feedMsgs)