-- |Tn Journals module Tn.Journal where import Tn.Paths import qualified Data.ByteString as B import Data.Text (Text, pack) import qualified Data.Text.Encoding as T import Data.Time (UTCTime, getCurrentTime) import Data.Vector (Vector) import qualified Data.Vector as V import Data.Yaml import GHC.Generics import System.Directory import System.IO import System.Pager (printOrPage) type Journal = Vector Entry data Entry = Entry { entryTime :: UTCTime , entryText :: Text } deriving (Eq, Show, Generic) instance ToJSON Entry instance FromJSON Entry -- |Make an entry, using the current Time mkEntry :: String -> IO Entry mkEntry s = Entry <$> getCurrentTime <*> pure (pack s) -- |Add an entry to a journal -- -- Actually just a clever alias for 'V.snoc' addEntry :: Journal -> Entry -> Journal addEntry = V.snoc -- |Read a journal from stdin readStdin :: IO (Either ParseException Journal) readStdin = do contents <- B.hGetContents stdin return $ decodeEither' contents -- |Read a journal from stdin, failing if the parse fails readStdin' :: IO Journal readStdin' = readStdin >>= \case Left x -> fail (show x) Right x -> return x -- |Read a journal from a file readJournalFile :: FilePath -> IO Journal readJournalFile fp = do fp' <- makeAbsolute fp res <- decodeFileEither fp' case res of Left x -> fail (show x) Right x -> return x -- |Read a journal from normal file readJournal :: IO Journal readJournal = do createNeededFiles jp <- journalPath readJournalFile jp -- |Print a journal printJournal :: Journal -- ^Journal to print -> Bool -- ^Whether or not to enable use of a pager. -> IO () printJournal j p | p = printOrPage $ T.decodeUtf8 (encode j) | otherwise = B.hPut stdout (encode j) -- |Write a journal to a file writeJournalFile :: Journal -> FilePath -> IO () writeJournalFile j f = encodeFile f j -- |Read a journal from normal file writeJournal :: Journal -> IO () writeJournal j = do createNeededFiles jp <- journalPath writeJournalFile j jp