{- Copyright (C) 2022 Yuchen Pei. This file is part of f2md. f2md is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. f2md is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with f2md. If not, see . -} {-# LANGUAGE DeriveGeneric #-} module F2Md.Config ( getUserdata , FeedUserdata(..) , ExtConf(..) , 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 import System.Posix.Files 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) data ExtConf = ExtConf { eDbPath :: FilePath , eMaildir :: FilePath , eFeeds :: [FeedUserdata] } getUserdata :: FilePath -> IO [ExtConf] getUserdata confPath = do configs <- decodeFileStrict =<< expandPath confPath case configs of Nothing -> return [] Just configs' -> mapM getUserdata' configs' getUserdata' :: Config -> IO ExtConf getUserdata' (Config dbPath maildir feeds) = do decoded <- getLastUpdatedMap dbPath dbPath' <- expandPath dbPath maildir' <- expandPath maildir return $ ExtConf dbPath' maildir' (map (\url -> FeedUserdata url $ HM.lookup url decoded) feeds) getLastUpdatedMap :: FilePath -> IO (HM.HashMap Text ZonedTime) getLastUpdatedMap dbPath = do exists <- fileExist =<< expandPath dbPath if exists then fromMaybe (HM.fromList []) <$> (decodeFileStrict =<< expandPath dbPath) else return $ HM.fromList [] 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