1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
import Control.Applicative( (<$>) )
import Control.Monad( unless )
import Data.Time.Clock( UTCTime(..) )
import Diddo( DiddoEntry(..), LogEntry(..), parseDiddoLogline, formatDiddoEntry, timestamp, logToDiddoEntry )
import System.Console.GetOpt
import System.Environment( getArgs )
import System.Exit( exitSuccess, exitFailure )
import System.IO( stderr, hPutStr )
import qualified Data.Map as Map
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
data Opt = Opt
{ optVerbose :: Bool
, optVersion :: Bool
, optHelp :: Bool
, optInputFiles :: [String]
, optOutputFile :: String
, optInputFormat :: String
, optOutputFormat :: String
, optStartDate :: String
, optEndDate :: String
}
defaultOpts :: Opt
defaultOpts = Opt
{ optVerbose = False
, optVersion = False
, optHelp = False
, optInputFiles = []
, optOutputFile = ""
, optInputFormat = "%FT%T%z"
, optOutputFormat = "%FT%T%z"
, optStartDate = ""
, optEndDate = ""
}
availableOptions :: [OptDescr (Opt -> IO Opt)]
availableOptions =
[ Option ['h'] ["help"]
(NoArg (\_ -> putStrLn (usageInfo "Usage: diddohs [OPTION...]" availableOptions) >> exitSuccess))
"Display program help"
, Option ['v'] ["verbose"]
(NoArg (\opts -> return opts { optVerbose = True }))
"More detailed output"
, Option ['V'] ["version"]
(NoArg (\opts -> return opts { optVersion = True }))
"Display program version"
, Option ['f'] ["file"]
(ReqArg (\arg opts -> return opts { optInputFiles = optInputFiles opts ++ [arg]}) "FILE" )
"Read from FILE"
, Option ['w'] ["output"]
(ReqArg (\arg opts -> return opts { optOutputFile = arg }) "FILE")
"Write to FILE"
, Option ['i'] ["informat"]
(ReqArg (\arg opts -> return opts { optInputFormat = arg }) "FORMAT")
"Timeformat used in input"
, Option ['o'] ["outformat"]
(ReqArg (\arg opts -> return opts { optOutputFormat = arg }) "FORMAT")
"Timeformat used in output"
, Option ['s'] ["start"]
(ReqArg (\arg opts -> return opts { optStartDate = arg }) "DATE")
"Start of reporting period"
, Option ['e'] ["end"]
(ReqArg (\arg opts -> return opts { optEndDate = arg }) "DATE")
"End of reporting period"
]
-- SECTION: Map of logentries to Map of DiddoEntries
mapToDiddoEntries :: Map.Map UTCTime Diddo.LogEntry -> Map.Map UTCTime Diddo.DiddoEntry
mapToDiddoEntries logmap = Map.mapWithKey toDddEntry logmap
where
toDddEntry key value = Diddo.logToDiddoEntry (preceedingTimestamp key) value
preceedingTimestamp x = case Map.lookupLT x logmap of
Just y -> fst y
Nothing -> fst $ Map.findMin logmap
-- SECTION: Map of logentries to Map of DiddoEntries
main :: IO ()
main = do
-- SECTION: option processing
(givenOptions,args,errs) <- getArgs >>= return . getOpt Permute availableOptions
unless (null errs) $ do
mapM_ (hPutStr stderr) errs
exitFailure
effectiveOptions <- foldl (>>=) (return defaultOpts) givenOptions
-- SECTION: option processing
dddLogEntries <-
map Diddo.parseDiddoLogline <$> case optInputFiles effectiveOptions of
files@(_:_) -> T.lines . T.concat <$> mapM TIO.readFile files
[] -> T.lines <$> TIO.getContents
let
dddLogEntryMap = Map.fromList $ map (\diddo -> (Diddo.timestamp diddo, diddo)) dddLogEntries
diddoEntriesMap = mapToDiddoEntries dddLogEntryMap
inDateFmt = optInputFormat effectiveOptions
outDateFmt = optOutputFormat effectiveOptions
-- DEBUG
mapM_ putStrLn args
-- DEBUG
mapM_ (TIO.putStrLn . snd) $ Map.toAscList $ Map.map (Diddo.formatDiddoEntry outDateFmt) diddoEntriesMap
|