From 99670f7d5a3bd5dcae1427e5abcd1990b27cb330 Mon Sep 17 00:00:00 2001 From: Moritz Rumpf Date: Sun, 15 Oct 2023 23:02:03 +0200 Subject: [PATCH 1/2] Read template file from config directory for easier customization. If not present the default template will be used. --- src/Config/Files.hs | 13 +++++++++---- src/Prompt.hs | 8 +++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Config/Files.hs b/src/Config/Files.hs index b39f4a4..6339cb4 100644 --- a/src/Config/Files.hs +++ b/src/Config/Files.hs @@ -1,7 +1,7 @@ {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE TemplateHaskell #-} -module Config.Files (getDefaultConfigDirectory, getConfigFilePath, templateFile, exampleFile, pyfintsFile, ConfigDirectory (..)) where +module Config.Files (getDefaultConfigDirectory, getConfigFilePath, getTemplateFile, exampleFile, pyfintsFile, ConfigDirectory (..)) where import Data.ByteString (ByteString) import Data.FileEmbed (embedDir) @@ -9,7 +9,7 @@ import Data.Map (Map, fromList, (!)) import Data.String (IsString) import Data.Text (Text) import Data.Text.Encoding qualified as T -import System.Directory (getHomeDirectory) +import System.Directory (doesFileExist, getHomeDirectory) import System.FilePath (()) getDefaultConfigDirectory :: IO ConfigDirectory @@ -20,8 +20,13 @@ getDefaultConfigDirectory = do getConfigFilePath :: ConfigDirectory -> FilePath getConfigFilePath configDirectory = configDirectory.get "config.yml" -templateFile :: Text -templateFile = T.decodeUtf8 $ dataFiles ! "template.txt" +getTemplateFile :: ConfigDirectory -> (FilePath -> IO Text) -> IO Text +getTemplateFile configDirectory readTextFile = do + let templateFilePath = configDirectory.get "template.txt" + fileExists <- doesFileExist templateFilePath + if fileExists + then readTextFile templateFilePath + else return $ T.decodeUtf8 $ dataFiles ! "template.txt" exampleFile :: Text exampleFile = T.decodeUtf8 $ dataFiles ! "example.json" diff --git a/src/Prompt.hs b/src/Prompt.hs index 8e6e4a0..2dd8dac 100644 --- a/src/Prompt.hs +++ b/src/Prompt.hs @@ -2,7 +2,7 @@ module Prompt (transactionsToLedger) where import App (App, Env (..), PromptResult (..), printText) import Config.AppConfig (AppConfig (..)) -import Config.Files (templateFile) +import Config.Files (getTemplateFile) import Config.YamlConfig (Fill, Filling (..), LedgerConfig (..)) import Control.Arrow ((>>>)) import Control.Monad (forM_, when) @@ -40,13 +40,14 @@ transactionsToLedger transactions = do config <- asks (.config) readFile <- asks (.readFile) existingMd5Sums <- getExistingMd5Sums <$> liftIO (readFile config.journalFile) + template <- liftIO $ getTemplateFile config.configDirectory readFile printText " Controls:" printText " - Ctrl + D or enter 's' to skip an entry" printText " - Ctrl + C to abort" forM_ transactions do - transactionToLedger existingMd5Sums templateFile + transactionToLedger existingMd5Sums template transactionToLedger :: Set Text -> Text -> Transaction -> App () transactionToLedger existingMd5Sums template transaction = do @@ -152,7 +153,8 @@ md5Regex = "; md5sum: ([A-Za-z0-9]{32})" getExistingMd5Sums :: Text -> Set Text getExistingMd5Sums textToSearchIn = - textToSearchIn =~ md5Regex + textToSearchIn + =~ md5Regex & getAllTextMatches @(Array Int) & elems & map (!! 1) From 536c44798e9100753f1a6ed4104193629be89974 Mon Sep 17 00:00:00 2001 From: Moritz Rumpf Date: Sun, 15 Oct 2023 23:07:38 +0200 Subject: [PATCH 2/2] Use xdgDirectory instead of building the path manually from the home directory. This is less code and more robust to custom config directory locations. --- src/Config/Files.hs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Config/Files.hs b/src/Config/Files.hs index 6339cb4..593f776 100644 --- a/src/Config/Files.hs +++ b/src/Config/Files.hs @@ -9,13 +9,11 @@ import Data.Map (Map, fromList, (!)) import Data.String (IsString) import Data.Text (Text) import Data.Text.Encoding qualified as T -import System.Directory (doesFileExist, getHomeDirectory) +import System.Directory (XdgDirectory (XdgConfig), doesFileExist, getXdgDirectory) import System.FilePath (()) getDefaultConfigDirectory :: IO ConfigDirectory -getDefaultConfigDirectory = do - homeDirectory <- getHomeDirectory - return $ ConfigDirectory $ homeDirectory ".config" "fints2ledger" +getDefaultConfigDirectory = ConfigDirectory <$> getXdgDirectory XdgConfig "fints2ledger" getConfigFilePath :: ConfigDirectory -> FilePath getConfigFilePath configDirectory = configDirectory.get "config.yml"