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". : 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". : 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_dnl m4_dnl
m4_define({{_hledgerdescription_}}, {{ 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" ,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 ["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 ["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... -- | Common output-related flags: --output-file, --output-format...

View File

@ -23,12 +23,15 @@ module Hledger.Cli.Utils
) )
where where
import Control.Exception as C import Control.Exception as C
import Data.Hashable (hash)
import Data.List import Data.List
import Data.Maybe import Data.Maybe
import Data.Text (Text) import Data.Text (Text)
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.IO as T import qualified Data.Text.IO as T
import Data.Time (Day) import Data.Time (Day)
import Data.Word
import Numeric
import Safe (readMay) import Safe (readMay)
import System.Console.CmdArgs import System.Console.CmdArgs
import System.Directory (getModificationTime, getDirectoryContents, copyFile) import System.Directory (getModificationTime, getDirectoryContents, copyFile)
@ -73,7 +76,7 @@ withJournalDo opts cmd = do
rulespath <- rulesFilePathFromOpts opts rulespath <- rulesFilePathFromOpts opts
journalpaths <- journalFilePathFromOpts opts journalpaths <- journalFilePathFromOpts opts
ej <- readJournalFiles Nothing rulespath (not $ ignore_assertions_ opts) journalpaths 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. -- | Apply the pivot transformation on a journal, if option is present.
pivotByOpts :: CliOpts -> Journal -> Journal pivotByOpts :: CliOpts -> Journal -> Journal
@ -92,6 +95,30 @@ pivot tag j = j{jtxns = map pivotTrans . jtxns $ j}
| _ <- tagTuple = p | _ <- tagTuple = p
where tagTuple = find ((tag ==) . fst) . ptags $ 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. -- | Write some output to stdout or to a file selected by --output-file.
writeOutput :: CliOpts -> String -> IO () writeOutput :: CliOpts -> String -> IO ()
writeOutput opts s = do writeOutput opts s = do

View File

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

View File

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