{-# LANGUAGE OverloadedStrings #-} module ConfigFiles where import Data.ByteString.Lazy.Char8 as L import System.Posix.User import System.FilePath import System.Directory import System.IO -- import System.IO.Strict import System.IO.Error import Control.Exception import Control.Monad import Control.DeepSeq import ByteStringOperators() -- For NFData instance type User = ByteString configDir = ".presence" buddyFile = "buddies" subscriberFile = "subscribers" otherFile = "others" pendingFile = "pending" solicitedFile = "solicited" configPath :: User -> String -> IO String configPath user filename = do ue <- getUserEntryForName (unpack user) return $ (++("/"++configDir++"/"++filename)) $ homeDirectory ue createConfigFile tag path = do let dir = dropFileName path doesDirectoryExist dir >>= flip unless (do createDirectory dir ) withFile path WriteMode $ \h -> L.hPutStrLn h tag addItem item tag path = let doit = do handle (\e -> when (isDoesNotExistError e) (createConfigFile tag path >> doit)) $ withFile path AppendMode $ \h -> L.hPutStrLn h item in doit addBuddy :: User -> ByteString -> IO () addBuddy user buddy = configPath user buddyFile >>= addItem buddy "" addSubscriber :: User -> ByteString -> IO () addSubscriber user subscriber = configPath user subscriberFile >>= addItem subscriber "" getConfigList path = handle (\e -> if isDoesNotExistError e then (return []) else throw e) $ withFile path ReadMode $ L.hGetContents >=> return . Prelude.tail . L.lines >=> (\a -> seq (rnf a) (return a)) getBuddies :: User -> IO [ByteString] getBuddies user = configPath user buddyFile >>= getConfigList getSubscribers :: User -> IO [ByteString] getSubscribers user = configPath user subscriberFile >>= getConfigList getOthers :: User -> IO [ByteString] getOthers user = configPath user otherFile >>= getConfigList getPending :: User -> IO [ByteString] getPending user = configPath user pendingFile >>= getConfigList getSolicited :: User -> IO [ByteString] getSolicited user = configPath user solicitedFile >>= getConfigList