Anon feature (#412)

* Add anon flag to cli

* Implement anonymisation for accounts

* document the --anon option
This commit is contained in:
Brian Scott 2016-10-26 12:39:13 -05:00 committed by Simon Michael
parent 6b0972b752
commit 8fdea5d11a
5 changed files with 34 additions and 1 deletions

View File

@ -147,6 +147,9 @@ m4_define({{_reportingoptions_}}, {{
: will transform the journal before any other processing by replacing the account name of every posting having the tag TAG with content VALUE by the account name "TAG:VALUE".
: The TAG will only match if it is a full-length match. The pivot will only happen if the TAG is on a posting, not if it is on the transaction. If the tag value is a multi:level:account:name the new account name will be "TAG:multi:level:account:name".
`--anon`
: show anonymized accounts and payees
}} )m4_dnl
m4_dnl
m4_define({{_hledgerdescription_}}, {{

View File

@ -143,6 +143,7 @@ reportflags = [
,flagReq ["depth"] (\s opts -> Right $ setopt "depth" s opts) "N" "hide accounts/postings deeper than N"
,flagNone ["empty","E"] (setboolopt "empty") "show items with zero amount, normally hidden"
,flagNone ["cost","B"] (setboolopt "cost") "show amounts in their cost price's commodity"
,flagNone ["anon"] (setboolopt "anon") "output ledger with anonymized accounts and payees."
]
-- | Common output-related flags: --output-file, --output-format...

View File

@ -23,12 +23,15 @@ module Hledger.Cli.Utils
)
where
import Control.Exception as C
import Data.Hashable (hash)
import Data.List
import Data.Maybe
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Data.Time (Day)
import Data.Word
import Numeric
import Safe (readMay)
import System.Console.CmdArgs
import System.Directory (getModificationTime, getDirectoryContents, copyFile)
@ -73,7 +76,7 @@ withJournalDo opts cmd = do
rulespath <- rulesFilePathFromOpts opts
journalpaths <- journalFilePathFromOpts opts
ej <- readJournalFiles Nothing rulespath (not $ ignore_assertions_ opts) journalpaths
either error' (cmd opts . pivotByOpts opts . journalApplyAliases (aliasesFromOpts opts)) ej
either error' (cmd opts . pivotByOpts opts . anonymiseByOpts opts . journalApplyAliases (aliasesFromOpts opts)) ej
-- | Apply the pivot transformation on a journal, if option is present.
pivotByOpts :: CliOpts -> Journal -> Journal
@ -92,6 +95,30 @@ pivot tag j = j{jtxns = map pivotTrans . jtxns $ j}
| _ <- tagTuple = p
where tagTuple = find ((tag ==) . fst) . ptags $ p
-- | Apply the anonymisation transformation on a journal, if option is present
anonymiseByOpts :: CliOpts -> Journal -> Journal
anonymiseByOpts opts =
case maybestringopt "anon" . rawopts_ $ opts of
Just _ -> anonymise
Nothing -> id
-- | Apply the anonymisation transformation on a journal
anonymise :: Journal -> Journal
anonymise j
= let
pAnons p = p { paccount = T.intercalate (T.pack ":") . map anon . T.splitOn (T.pack ":") . paccount $ p
, pcomment = T.empty
, ptransaction = fmap tAnons . ptransaction $ p
}
tAnons txn = txn { tpostings = map pAnons . tpostings $ txn
, tdescription = anon . tdescription $ txn
, tcomment = T.empty
}
in
j { jtxns = map tAnons . jtxns $ j }
where
anon = T.pack . flip showHex "" . (fromIntegral :: Int -> Word32) . hash
-- | Write some output to stdout or to a file selected by --output-file.
writeOutput :: CliOpts -> String -> IO ()
writeOutput opts s = do

View File

@ -98,6 +98,7 @@ library
, cmdargs >=0.10 && <0.11
, csv
, data-default >=0.5
, hashable >=1.2.4
, haskeline >=0.6 && <=0.8
, HUnit
, mtl

View File

@ -111,6 +111,7 @@ library:
- cmdargs >=0.10 && <0.11
- csv
- data-default >=0.5
- hashable >=1.2.4
- haskeline >=0.6 && <=0.8
- HUnit
- mtl