{- 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(..) , 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) getUserdata :: FilePath -> IO ([FeedUserdata], Maybe FilePath, Maybe FilePath) getUserdata file = do config <- decodeFileStrict =<< expandPath 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 = 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